From: madvenka@linux.microsoft.com To: mark.rutland@arm.com, broonie@kernel.org, jpoimboe@redhat.com, ardb@kernel.org, nobuta.keiya@fujitsu.com, sjitindarsingh@gmail.com, catalin.marinas@arm.com, will@kernel.org, jmorris@namei.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v1 4/9] dwarf: Implement DWARF rule processing in the kernel Date: Thu, 7 Apr 2022 15:25:13 -0500 [thread overview] Message-ID: <20220407202518.19780-5-madvenka@linux.microsoft.com> (raw) In-Reply-To: <20220407202518.19780-1-madvenka@linux.microsoft.com> From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com> Define a struct dwarf_info to store all of the DWARF information needed to lookup the DWARF rules for an instruction address. There is one dwarf_info for vmlinux and one for every module. Implement a lookup function dwarf_lookup(). Given an instruction address, the function looks up the corresponding DWARF rules. The unwinder will use the lookup function in the future. Sort the rules based on instruction address. This allows a binary search. Divide the text range into fixed sized blocks and map the rules to their respective blocks. Given an instruction address, first locate the block for the address. Then, perform a binary search within the rules in the block. This minimizes the number of rules to consider in the binary search. dwarf_info contains an array of PCs to search. In order to save space, store the PCs array as an array of offsets from the base PC of the text range. This way, we only need 32 bits to store the PC. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> --- arch/arm64/include/asm/sections.h | 4 + include/linux/dwarf.h | 21 +++ kernel/Makefile | 1 + kernel/dwarf_fp.c | 244 ++++++++++++++++++++++++++++++ tools/include/linux/dwarf.h | 21 +++ 5 files changed, 291 insertions(+) create mode 100644 kernel/dwarf_fp.c diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h index 152cb35bf9df..d9095a9094b7 100644 --- a/arch/arm64/include/asm/sections.h +++ b/arch/arm64/include/asm/sections.h @@ -22,5 +22,9 @@ extern char __irqentry_text_start[], __irqentry_text_end[]; extern char __mmuoff_data_start[], __mmuoff_data_end[]; extern char __entry_tramp_text_start[], __entry_tramp_text_end[]; extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[]; +#ifdef CONFIG_DWARF_FP +extern char __dwarf_rules_start[], __dwarf_rules_end[]; +extern char __dwarf_pcs_start[], __dwarf_pcs_end[]; +#endif #endif /* __ASM_SECTIONS_H */ diff --git a/include/linux/dwarf.h b/include/linux/dwarf.h index 16e9dd8c60c8..3df15e79003c 100644 --- a/include/linux/dwarf.h +++ b/include/linux/dwarf.h @@ -40,4 +40,25 @@ struct dwarf_rule { short fp_offset; }; +/* + * The whole text area is divided into fixed sized blocks. Rules are mapped + * to their respective blocks. To find a block for an instruction address, + * the block of the address is located. Then, a binary search is performed + * on just the rules in the block. This minimizes the number of rules to + * be considered for the search. + */ +struct dwarf_block { + int first_rule; + int last_rule; +}; + +#ifdef CONFIG_DWARF_FP +extern struct dwarf_rule *dwarf_lookup(unsigned long pc); +#else +static inline struct dwarf_rule *dwarf_lookup(unsigned long pc) +{ + return NULL; +} +#endif + #endif /* _LINUX_DWARF_H */ diff --git a/kernel/Makefile b/kernel/Makefile index 186c49582f45..7582a6323446 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -130,6 +130,7 @@ obj-$(CONFIG_WATCH_QUEUE) += watch_queue.o obj-$(CONFIG_RESOURCE_KUNIT_TEST) += resource_kunit.o obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o +obj-$(CONFIG_DWARF_FP) += dwarf_fp.o CFLAGS_stackleak.o += $(DISABLE_STACKLEAK_PLUGIN) obj-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak.o diff --git a/kernel/dwarf_fp.c b/kernel/dwarf_fp.c new file mode 100644 index 000000000000..bb14fbe3f3e1 --- /dev/null +++ b/kernel/dwarf_fp.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * dwarf_fp.c - Allocate DWARF info. There will be one info for vmlinux + * and one for every module. Implement a lookup function that + * can locate the rule for a given instruction address. + * + * Copyright (C) 2021 Microsoft, Inc. + * Author: Madhavan T. Venkataraman <madvenka@microsoft.com> + */ +#include <linux/dwarf.h> +#include <linux/slab.h> +#include <linux/sort.h> +#include <linux/types.h> +#include <asm/sections.h> +#include <asm/memory.h> + +#define OFFSET_BLOCK_SHIFT 12 +#define OFFSET_BLOCK(pc) ((pc) >> OFFSET_BLOCK_SHIFT) + +/* + * There is one struct dwarf_info for vmlinux and one for each module. + */ +struct dwarf_info { + struct dwarf_rule *rules; + int nrules; + unsigned int *offsets; + + struct dwarf_block *blocks; + int nblocks; + + unsigned long *pcs; + unsigned long base_pc; + unsigned long end_pc; +}; + +static DEFINE_MUTEX(dwarf_mutex); + +static struct dwarf_info *vmlinux_dwarf_info; +static struct dwarf_info *cur_info; + +static int dwarf_compare(const void *arg1, const void *arg2) +{ + const unsigned long *pc1 = arg1; + const unsigned long *pc2 = arg2; + + if (*pc1 > *pc2) + return 1; + if (*pc1 < *pc2) + return -1; + return 0; +} + +static void dwarf_swap(void *arg1, void *arg2, int size) +{ + struct dwarf_rule *rules = cur_info->rules; + unsigned long *pc1 = arg1; + unsigned long *pc2 = arg2; + int i = (int) (pc1 - cur_info->pcs); + int j = (int) (pc2 - cur_info->pcs); + unsigned long tmp_pc; + struct dwarf_rule tmp_rule; + + tmp_pc = *pc1; + *pc1 = *pc2; + *pc2 = tmp_pc; + + tmp_rule = rules[i]; + rules[i] = rules[j]; + rules[j] = tmp_rule; +} + +/* + * Sort DWARF Records based on instruction addresses. + */ +static void dwarf_sort(struct dwarf_info *info) +{ + mutex_lock(&dwarf_mutex); + + /* + * cur_info is a global that allows us to sort both arrays in one go. + */ + cur_info = info; + sort(info->pcs, info->nrules, sizeof(*info->pcs), + dwarf_compare, dwarf_swap); + + mutex_unlock(&dwarf_mutex); +} + +#define INVALID_RULE -1 + +static struct dwarf_info *dwarf_alloc(struct dwarf_rule *rules, int nrules, + unsigned long *pcs) +{ + struct dwarf_info *info; + unsigned int *offsets, last_offset; + struct dwarf_block *blocks; + int r, b, nblocks; + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return NULL; + + info->rules = rules; + info->nrules = nrules; + info->pcs = pcs; + + /* Sort pcs[] and rules[] in the increasing order of PC. */ + dwarf_sort(info); + + /* Compute the boundaries for the rules. */ + info->base_pc = pcs[0]; + info->end_pc = pcs[nrules - 1] + rules[nrules - 1].size; + + offsets = kmalloc_array(nrules, sizeof(*offsets), GFP_KERNEL); + if (!offsets) + goto free_info; + + /* Store the PCs as offsets from the base PC. This is to save memory. */ + for (r = 0; r < nrules; r++) + offsets[r] = pcs[r] - info->base_pc; + + /* Compute the number of blocks. */ + last_offset = offsets[nrules - 1]; + nblocks = OFFSET_BLOCK(last_offset) + 1; + + blocks = kmalloc_array(nblocks, sizeof(*blocks), GFP_KERNEL); + if (!blocks) + goto free_offsets; + + /* Initialize blocks. */ + for (b = 0; b < nblocks; b++) { + blocks[b].first_rule = INVALID_RULE; + blocks[b].last_rule = INVALID_RULE; + } + + /* Map rules to blocks. */ + for (r = 0; r < nrules; r++) { + b = OFFSET_BLOCK(offsets[r]); + if (blocks[b].first_rule == INVALID_RULE) + blocks[b].first_rule = r; + blocks[b].last_rule = r; + } + + /* Initialize empty blocks. */ + for (b = 0; b < nblocks; b++) { + if (blocks[b].first_rule == INVALID_RULE) { + blocks[b].first_rule = blocks[b - 1].last_rule; + blocks[b].last_rule = blocks[b - 1].last_rule; + } + } + + info->blocks = blocks; + info->nblocks = nblocks; + info->offsets = offsets; + + /* PCs for vmlinux is in init data. It will discarded. */ + info->pcs = NULL; + + return info; +free_offsets: + kfree(offsets); +free_info: + kfree(info); + return NULL; +} + +static struct dwarf_rule *dwarf_lookup_rule(struct dwarf_info *info, + unsigned long pc) +{ + struct dwarf_block *blocks = info->blocks; + unsigned int *offsets = info->offsets, off; + struct dwarf_rule *rule; + int start, mid, end, n, b; + + if (pc < info->base_pc || pc >= info->end_pc) + return NULL; + + /* Make PC relative to the base for binary search. */ + off = pc - info->base_pc; + + /* + * Locate the block for the offset. Do a binary search between the + * start and end rules in the block. + */ + b = OFFSET_BLOCK(off); + start = blocks[b].first_rule; + end = blocks[b].last_rule + 1; + + if (off < offsets[start]) + start--; + + /* + * Binary search. For cache performance, we search in offsets[] + * first and locate a candidate rule. Then, we perform a range check + * for the candidate rule at the end. This is so that rules[] + * is only accessed at the end of the search. + */ + for (n = end - start; n > 1; n = end - start) { + mid = start + (n >> 1); + + if (off >= offsets[mid]) + start = mid; + else + end = mid; + } + + /* Do a final range check. */ + rule = &info->rules[start]; + if (off >= offsets[start] && off < (offsets[start] + rule->size)) + return rule; + + return NULL; +} + +struct dwarf_rule *dwarf_lookup(unsigned long pc) +{ + /* + * Currently, only looks up vmlinux. Support for modules will be + * added later. + */ + return dwarf_lookup_rule(vmlinux_dwarf_info, pc); +} + +static int __init dwarf_init_feature(void) +{ + struct dwarf_rule *rules; + unsigned long *pcs; + int nrules, npcs; + + rules = (struct dwarf_rule *) __dwarf_rules_start; + nrules = (__dwarf_rules_end - __dwarf_rules_start) / sizeof(*rules); + if (!nrules) + return -EINVAL; + + pcs = (unsigned long *) __dwarf_pcs_start; + npcs = (__dwarf_pcs_end - __dwarf_pcs_start) / sizeof(*pcs); + if (npcs != nrules) + return -EINVAL; + + vmlinux_dwarf_info = dwarf_alloc(rules, nrules, pcs); + + return vmlinux_dwarf_info ? 0 : -EINVAL; +} +early_initcall(dwarf_init_feature); diff --git a/tools/include/linux/dwarf.h b/tools/include/linux/dwarf.h index 16e9dd8c60c8..3df15e79003c 100644 --- a/tools/include/linux/dwarf.h +++ b/tools/include/linux/dwarf.h @@ -40,4 +40,25 @@ struct dwarf_rule { short fp_offset; }; +/* + * The whole text area is divided into fixed sized blocks. Rules are mapped + * to their respective blocks. To find a block for an instruction address, + * the block of the address is located. Then, a binary search is performed + * on just the rules in the block. This minimizes the number of rules to + * be considered for the search. + */ +struct dwarf_block { + int first_rule; + int last_rule; +}; + +#ifdef CONFIG_DWARF_FP +extern struct dwarf_rule *dwarf_lookup(unsigned long pc); +#else +static inline struct dwarf_rule *dwarf_lookup(unsigned long pc) +{ + return NULL; +} +#endif + #endif /* _LINUX_DWARF_H */ -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: madvenka@linux.microsoft.com To: mark.rutland@arm.com, broonie@kernel.org, jpoimboe@redhat.com, ardb@kernel.org, nobuta.keiya@fujitsu.com, sjitindarsingh@gmail.com, catalin.marinas@arm.com, will@kernel.org, jmorris@namei.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [RFC PATCH v1 4/9] dwarf: Implement DWARF rule processing in the kernel Date: Thu, 7 Apr 2022 15:25:13 -0500 [thread overview] Message-ID: <20220407202518.19780-5-madvenka@linux.microsoft.com> (raw) In-Reply-To: <20220407202518.19780-1-madvenka@linux.microsoft.com> From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com> Define a struct dwarf_info to store all of the DWARF information needed to lookup the DWARF rules for an instruction address. There is one dwarf_info for vmlinux and one for every module. Implement a lookup function dwarf_lookup(). Given an instruction address, the function looks up the corresponding DWARF rules. The unwinder will use the lookup function in the future. Sort the rules based on instruction address. This allows a binary search. Divide the text range into fixed sized blocks and map the rules to their respective blocks. Given an instruction address, first locate the block for the address. Then, perform a binary search within the rules in the block. This minimizes the number of rules to consider in the binary search. dwarf_info contains an array of PCs to search. In order to save space, store the PCs array as an array of offsets from the base PC of the text range. This way, we only need 32 bits to store the PC. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> --- arch/arm64/include/asm/sections.h | 4 + include/linux/dwarf.h | 21 +++ kernel/Makefile | 1 + kernel/dwarf_fp.c | 244 ++++++++++++++++++++++++++++++ tools/include/linux/dwarf.h | 21 +++ 5 files changed, 291 insertions(+) create mode 100644 kernel/dwarf_fp.c diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h index 152cb35bf9df..d9095a9094b7 100644 --- a/arch/arm64/include/asm/sections.h +++ b/arch/arm64/include/asm/sections.h @@ -22,5 +22,9 @@ extern char __irqentry_text_start[], __irqentry_text_end[]; extern char __mmuoff_data_start[], __mmuoff_data_end[]; extern char __entry_tramp_text_start[], __entry_tramp_text_end[]; extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[]; +#ifdef CONFIG_DWARF_FP +extern char __dwarf_rules_start[], __dwarf_rules_end[]; +extern char __dwarf_pcs_start[], __dwarf_pcs_end[]; +#endif #endif /* __ASM_SECTIONS_H */ diff --git a/include/linux/dwarf.h b/include/linux/dwarf.h index 16e9dd8c60c8..3df15e79003c 100644 --- a/include/linux/dwarf.h +++ b/include/linux/dwarf.h @@ -40,4 +40,25 @@ struct dwarf_rule { short fp_offset; }; +/* + * The whole text area is divided into fixed sized blocks. Rules are mapped + * to their respective blocks. To find a block for an instruction address, + * the block of the address is located. Then, a binary search is performed + * on just the rules in the block. This minimizes the number of rules to + * be considered for the search. + */ +struct dwarf_block { + int first_rule; + int last_rule; +}; + +#ifdef CONFIG_DWARF_FP +extern struct dwarf_rule *dwarf_lookup(unsigned long pc); +#else +static inline struct dwarf_rule *dwarf_lookup(unsigned long pc) +{ + return NULL; +} +#endif + #endif /* _LINUX_DWARF_H */ diff --git a/kernel/Makefile b/kernel/Makefile index 186c49582f45..7582a6323446 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -130,6 +130,7 @@ obj-$(CONFIG_WATCH_QUEUE) += watch_queue.o obj-$(CONFIG_RESOURCE_KUNIT_TEST) += resource_kunit.o obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o +obj-$(CONFIG_DWARF_FP) += dwarf_fp.o CFLAGS_stackleak.o += $(DISABLE_STACKLEAK_PLUGIN) obj-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak.o diff --git a/kernel/dwarf_fp.c b/kernel/dwarf_fp.c new file mode 100644 index 000000000000..bb14fbe3f3e1 --- /dev/null +++ b/kernel/dwarf_fp.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * dwarf_fp.c - Allocate DWARF info. There will be one info for vmlinux + * and one for every module. Implement a lookup function that + * can locate the rule for a given instruction address. + * + * Copyright (C) 2021 Microsoft, Inc. + * Author: Madhavan T. Venkataraman <madvenka@microsoft.com> + */ +#include <linux/dwarf.h> +#include <linux/slab.h> +#include <linux/sort.h> +#include <linux/types.h> +#include <asm/sections.h> +#include <asm/memory.h> + +#define OFFSET_BLOCK_SHIFT 12 +#define OFFSET_BLOCK(pc) ((pc) >> OFFSET_BLOCK_SHIFT) + +/* + * There is one struct dwarf_info for vmlinux and one for each module. + */ +struct dwarf_info { + struct dwarf_rule *rules; + int nrules; + unsigned int *offsets; + + struct dwarf_block *blocks; + int nblocks; + + unsigned long *pcs; + unsigned long base_pc; + unsigned long end_pc; +}; + +static DEFINE_MUTEX(dwarf_mutex); + +static struct dwarf_info *vmlinux_dwarf_info; +static struct dwarf_info *cur_info; + +static int dwarf_compare(const void *arg1, const void *arg2) +{ + const unsigned long *pc1 = arg1; + const unsigned long *pc2 = arg2; + + if (*pc1 > *pc2) + return 1; + if (*pc1 < *pc2) + return -1; + return 0; +} + +static void dwarf_swap(void *arg1, void *arg2, int size) +{ + struct dwarf_rule *rules = cur_info->rules; + unsigned long *pc1 = arg1; + unsigned long *pc2 = arg2; + int i = (int) (pc1 - cur_info->pcs); + int j = (int) (pc2 - cur_info->pcs); + unsigned long tmp_pc; + struct dwarf_rule tmp_rule; + + tmp_pc = *pc1; + *pc1 = *pc2; + *pc2 = tmp_pc; + + tmp_rule = rules[i]; + rules[i] = rules[j]; + rules[j] = tmp_rule; +} + +/* + * Sort DWARF Records based on instruction addresses. + */ +static void dwarf_sort(struct dwarf_info *info) +{ + mutex_lock(&dwarf_mutex); + + /* + * cur_info is a global that allows us to sort both arrays in one go. + */ + cur_info = info; + sort(info->pcs, info->nrules, sizeof(*info->pcs), + dwarf_compare, dwarf_swap); + + mutex_unlock(&dwarf_mutex); +} + +#define INVALID_RULE -1 + +static struct dwarf_info *dwarf_alloc(struct dwarf_rule *rules, int nrules, + unsigned long *pcs) +{ + struct dwarf_info *info; + unsigned int *offsets, last_offset; + struct dwarf_block *blocks; + int r, b, nblocks; + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return NULL; + + info->rules = rules; + info->nrules = nrules; + info->pcs = pcs; + + /* Sort pcs[] and rules[] in the increasing order of PC. */ + dwarf_sort(info); + + /* Compute the boundaries for the rules. */ + info->base_pc = pcs[0]; + info->end_pc = pcs[nrules - 1] + rules[nrules - 1].size; + + offsets = kmalloc_array(nrules, sizeof(*offsets), GFP_KERNEL); + if (!offsets) + goto free_info; + + /* Store the PCs as offsets from the base PC. This is to save memory. */ + for (r = 0; r < nrules; r++) + offsets[r] = pcs[r] - info->base_pc; + + /* Compute the number of blocks. */ + last_offset = offsets[nrules - 1]; + nblocks = OFFSET_BLOCK(last_offset) + 1; + + blocks = kmalloc_array(nblocks, sizeof(*blocks), GFP_KERNEL); + if (!blocks) + goto free_offsets; + + /* Initialize blocks. */ + for (b = 0; b < nblocks; b++) { + blocks[b].first_rule = INVALID_RULE; + blocks[b].last_rule = INVALID_RULE; + } + + /* Map rules to blocks. */ + for (r = 0; r < nrules; r++) { + b = OFFSET_BLOCK(offsets[r]); + if (blocks[b].first_rule == INVALID_RULE) + blocks[b].first_rule = r; + blocks[b].last_rule = r; + } + + /* Initialize empty blocks. */ + for (b = 0; b < nblocks; b++) { + if (blocks[b].first_rule == INVALID_RULE) { + blocks[b].first_rule = blocks[b - 1].last_rule; + blocks[b].last_rule = blocks[b - 1].last_rule; + } + } + + info->blocks = blocks; + info->nblocks = nblocks; + info->offsets = offsets; + + /* PCs for vmlinux is in init data. It will discarded. */ + info->pcs = NULL; + + return info; +free_offsets: + kfree(offsets); +free_info: + kfree(info); + return NULL; +} + +static struct dwarf_rule *dwarf_lookup_rule(struct dwarf_info *info, + unsigned long pc) +{ + struct dwarf_block *blocks = info->blocks; + unsigned int *offsets = info->offsets, off; + struct dwarf_rule *rule; + int start, mid, end, n, b; + + if (pc < info->base_pc || pc >= info->end_pc) + return NULL; + + /* Make PC relative to the base for binary search. */ + off = pc - info->base_pc; + + /* + * Locate the block for the offset. Do a binary search between the + * start and end rules in the block. + */ + b = OFFSET_BLOCK(off); + start = blocks[b].first_rule; + end = blocks[b].last_rule + 1; + + if (off < offsets[start]) + start--; + + /* + * Binary search. For cache performance, we search in offsets[] + * first and locate a candidate rule. Then, we perform a range check + * for the candidate rule at the end. This is so that rules[] + * is only accessed at the end of the search. + */ + for (n = end - start; n > 1; n = end - start) { + mid = start + (n >> 1); + + if (off >= offsets[mid]) + start = mid; + else + end = mid; + } + + /* Do a final range check. */ + rule = &info->rules[start]; + if (off >= offsets[start] && off < (offsets[start] + rule->size)) + return rule; + + return NULL; +} + +struct dwarf_rule *dwarf_lookup(unsigned long pc) +{ + /* + * Currently, only looks up vmlinux. Support for modules will be + * added later. + */ + return dwarf_lookup_rule(vmlinux_dwarf_info, pc); +} + +static int __init dwarf_init_feature(void) +{ + struct dwarf_rule *rules; + unsigned long *pcs; + int nrules, npcs; + + rules = (struct dwarf_rule *) __dwarf_rules_start; + nrules = (__dwarf_rules_end - __dwarf_rules_start) / sizeof(*rules); + if (!nrules) + return -EINVAL; + + pcs = (unsigned long *) __dwarf_pcs_start; + npcs = (__dwarf_pcs_end - __dwarf_pcs_start) / sizeof(*pcs); + if (npcs != nrules) + return -EINVAL; + + vmlinux_dwarf_info = dwarf_alloc(rules, nrules, pcs); + + return vmlinux_dwarf_info ? 0 : -EINVAL; +} +early_initcall(dwarf_init_feature); diff --git a/tools/include/linux/dwarf.h b/tools/include/linux/dwarf.h index 16e9dd8c60c8..3df15e79003c 100644 --- a/tools/include/linux/dwarf.h +++ b/tools/include/linux/dwarf.h @@ -40,4 +40,25 @@ struct dwarf_rule { short fp_offset; }; +/* + * The whole text area is divided into fixed sized blocks. Rules are mapped + * to their respective blocks. To find a block for an instruction address, + * the block of the address is located. Then, a binary search is performed + * on just the rules in the block. This minimizes the number of rules to + * be considered for the search. + */ +struct dwarf_block { + int first_rule; + int last_rule; +}; + +#ifdef CONFIG_DWARF_FP +extern struct dwarf_rule *dwarf_lookup(unsigned long pc); +#else +static inline struct dwarf_rule *dwarf_lookup(unsigned long pc) +{ + return NULL; +} +#endif + #endif /* _LINUX_DWARF_H */ -- 2.25.1
next prev parent reply other threads:[~2022-04-07 20:28 UTC|newest] Thread overview: 150+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <95691cae4f4504f33d0fc9075541b1e7deefe96f> 2022-01-17 14:55 ` [PATCH v13 00/11] arm64: Reorganize the unwinder and implement stack trace reliability checks madvenka 2022-01-17 14:55 ` madvenka 2022-01-17 14:55 ` [PATCH v13 01/11] arm64: Remove NULL task check from unwind_frame() madvenka 2022-01-17 14:55 ` madvenka 2022-01-17 14:55 ` [PATCH v13 02/11] arm64: Rename unwinder functions madvenka 2022-01-17 14:55 ` madvenka 2022-01-17 14:56 ` [PATCH v13 03/11] arm64: Rename stackframe to unwind_state madvenka 2022-01-17 14:56 ` madvenka 2022-01-17 14:56 ` [PATCH v13 04/11] arm64: Split unwind_init() madvenka 2022-01-17 14:56 ` madvenka 2022-02-02 18:44 ` Mark Brown 2022-02-02 18:44 ` Mark Brown 2022-02-03 0:26 ` Madhavan T. Venkataraman 2022-02-03 0:26 ` Madhavan T. Venkataraman 2022-02-03 0:39 ` Madhavan T. Venkataraman 2022-02-03 0:39 ` Madhavan T. Venkataraman 2022-02-03 11:29 ` Mark Brown 2022-02-03 11:29 ` Mark Brown 2022-02-15 13:07 ` Mark Rutland 2022-02-15 13:07 ` Mark Rutland 2022-02-15 18:04 ` Madhavan T. Venkataraman 2022-02-15 18:04 ` Madhavan T. Venkataraman 2022-01-17 14:56 ` [PATCH v13 05/11] arm64: Copy the task argument to unwind_state madvenka 2022-01-17 14:56 ` madvenka 2022-02-02 18:45 ` Mark Brown 2022-02-02 18:45 ` Mark Brown 2022-02-15 13:22 ` Mark Rutland 2022-02-15 13:22 ` Mark Rutland 2022-02-22 16:53 ` Madhavan T. Venkataraman 2022-02-22 16:53 ` Madhavan T. Venkataraman 2022-01-17 14:56 ` [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind() madvenka 2022-01-17 14:56 ` madvenka 2022-02-02 18:46 ` Mark Brown 2022-02-02 18:46 ` Mark Brown 2022-02-03 0:34 ` Madhavan T. Venkataraman 2022-02-03 0:34 ` Madhavan T. Venkataraman 2022-02-03 11:30 ` Mark Brown 2022-02-03 11:30 ` Mark Brown 2022-02-03 14:45 ` Madhavan T. Venkataraman 2022-02-03 14:45 ` Madhavan T. Venkataraman 2022-02-15 13:39 ` Mark Rutland 2022-02-15 13:39 ` Mark Rutland 2022-02-15 18:12 ` Madhavan T. Venkataraman 2022-02-15 18:12 ` Madhavan T. Venkataraman 2022-03-07 16:51 ` Madhavan T. Venkataraman 2022-03-07 16:51 ` Madhavan T. Venkataraman 2022-03-07 17:01 ` Mark Brown 2022-03-07 17:01 ` Mark Brown 2022-03-08 22:00 ` Madhavan T. Venkataraman 2022-03-08 22:00 ` Madhavan T. Venkataraman 2022-03-09 11:47 ` Mark Brown 2022-03-09 11:47 ` Mark Brown 2022-03-09 15:34 ` Madhavan T. Venkataraman 2022-03-09 15:34 ` Madhavan T. Venkataraman 2022-03-10 8:33 ` Miroslav Benes 2022-03-10 8:33 ` Miroslav Benes 2022-03-10 12:36 ` Madhavan T. Venkataraman 2022-03-10 12:36 ` Madhavan T. Venkataraman 2022-03-16 3:43 ` Josh Poimboeuf 2022-03-16 3:43 ` Josh Poimboeuf 2022-04-08 14:44 ` Mark Rutland 2022-04-08 14:44 ` Mark Rutland 2022-04-08 17:58 ` Mark Rutland 2022-04-08 17:58 ` Mark Rutland 2022-04-10 17:42 ` Madhavan T. Venkataraman 2022-04-10 17:42 ` Madhavan T. Venkataraman 2022-04-10 17:33 ` Madhavan T. Venkataraman 2022-04-10 17:33 ` Madhavan T. Venkataraman 2022-04-10 17:45 ` Madhavan T. Venkataraman 2022-04-10 17:45 ` Madhavan T. Venkataraman 2022-01-17 14:56 ` [PATCH v13 07/11] arm64: Make the unwind loop in unwind() similar to other architectures madvenka 2022-01-17 14:56 ` madvenka 2022-01-17 14:56 ` [PATCH v13 08/11] arm64: Introduce stack trace reliability checks in the unwinder madvenka 2022-01-17 14:56 ` madvenka 2022-01-17 14:56 ` [PATCH v13 09/11] arm64: Create a list of SYM_CODE functions, check return PC against list madvenka 2022-01-17 14:56 ` madvenka 2022-01-17 14:56 ` [PATCH v13 10/11] arm64: Introduce arch_stack_walk_reliable() madvenka 2022-01-17 14:56 ` madvenka 2022-01-17 14:56 ` [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE madvenka 2022-01-17 14:56 ` madvenka 2022-01-25 5:21 ` nobuta.keiya 2022-01-25 5:21 ` nobuta.keiya 2022-01-25 13:43 ` Madhavan T. Venkataraman 2022-01-25 13:43 ` Madhavan T. Venkataraman 2022-01-26 10:20 ` nobuta.keiya 2022-01-26 10:20 ` nobuta.keiya 2022-01-26 17:14 ` Madhavan T. Venkataraman 2022-01-26 17:14 ` Madhavan T. Venkataraman 2022-01-27 1:13 ` nobuta.keiya 2022-01-27 1:13 ` nobuta.keiya 2022-01-26 17:16 ` Mark Brown 2022-01-26 17:16 ` Mark Brown 2022-04-07 20:25 ` [RFC PATCH v1 0/9] arm64: livepatch: Use DWARF Call Frame Information for frame pointer validation madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` [RFC PATCH v1 1/9] objtool: Parse DWARF Call Frame Information in object files madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` [RFC PATCH v1 2/9] objtool: Generate DWARF rules and place them in a special section madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` [RFC PATCH v1 3/9] dwarf: Build the kernel with DWARF information madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` madvenka [this message] 2022-04-07 20:25 ` [RFC PATCH v1 4/9] dwarf: Implement DWARF rule processing in the kernel madvenka 2022-04-07 20:25 ` [RFC PATCH v1 5/9] dwarf: Implement DWARF support for modules madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` [RFC PATCH v1 6/9] arm64: unwinder: Add a reliability check in the unwinder based on DWARF CFI madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` [RFC PATCH v1 7/9] arm64: dwarf: Implement unwind hints madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` [RFC PATCH v1 8/9] dwarf: Miscellaneous changes required for enabling livepatch madvenka 2022-04-07 20:25 ` madvenka 2022-04-07 20:25 ` [RFC PATCH v1 9/9] dwarf: Enable livepatch for ARM64 madvenka 2022-04-07 20:25 ` madvenka 2022-04-08 0:21 ` [RFC PATCH v1 0/9] arm64: livepatch: Use DWARF Call Frame Information for frame pointer validation Josh Poimboeuf 2022-04-08 0:21 ` Josh Poimboeuf 2022-04-08 11:41 ` Peter Zijlstra 2022-04-08 11:41 ` Peter Zijlstra 2022-04-11 17:26 ` Madhavan T. Venkataraman 2022-04-11 17:26 ` Madhavan T. Venkataraman 2022-04-11 17:18 ` Madhavan T. Venkataraman 2022-04-11 17:18 ` Madhavan T. Venkataraman 2022-04-12 8:32 ` Chen Zhongjin 2022-04-12 8:32 ` Chen Zhongjin 2022-04-16 0:56 ` Josh Poimboeuf 2022-04-16 0:56 ` Josh Poimboeuf 2022-04-18 12:28 ` Chen Zhongjin 2022-04-18 12:28 ` Chen Zhongjin 2022-04-18 16:11 ` Josh Poimboeuf 2022-04-18 16:11 ` Josh Poimboeuf 2022-04-18 18:38 ` Madhavan T. Venkataraman 2022-04-18 18:38 ` Madhavan T. Venkataraman [not found] ` <844b3ede-eddb-cbe6-80e0-3529e2da2eb6@huawei.com> 2022-04-12 17:27 ` Madhavan T. Venkataraman 2022-04-12 17:27 ` Madhavan T. Venkataraman 2022-04-16 1:07 ` Josh Poimboeuf 2022-04-16 1:07 ` Josh Poimboeuf 2022-04-14 14:11 ` Madhavan T. Venkataraman 2022-04-14 14:11 ` Madhavan T. Venkataraman 2022-04-08 10:55 ` Peter Zijlstra 2022-04-08 10:55 ` Peter Zijlstra 2022-04-08 11:54 ` Peter Zijlstra 2022-04-08 11:54 ` Peter Zijlstra 2022-04-08 14:34 ` Josh Poimboeuf 2022-04-08 14:34 ` Josh Poimboeuf 2022-04-10 17:47 ` Madhavan T. Venkataraman 2022-04-10 17:47 ` Madhavan T. Venkataraman 2022-04-11 16:34 ` Josh Poimboeuf 2022-04-11 16:34 ` Josh Poimboeuf 2022-04-08 12:06 ` Peter Zijlstra 2022-04-08 12:06 ` Peter Zijlstra 2022-04-11 17:35 ` Madhavan T. Venkataraman 2022-04-11 17:35 ` Madhavan T. Venkataraman
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220407202518.19780-5-madvenka@linux.microsoft.com \ --to=madvenka@linux.microsoft.com \ --cc=ardb@kernel.org \ --cc=broonie@kernel.org \ --cc=catalin.marinas@arm.com \ --cc=jmorris@namei.org \ --cc=jpoimboe@redhat.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=live-patching@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=nobuta.keiya@fujitsu.com \ --cc=sjitindarsingh@gmail.com \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.