From: Josh Poimboeuf <jpoimboe@kernel.org>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org,
Peter Zijlstra <peterz@infradead.org>,
Joe Lawrence <joe.lawrence@redhat.com>,
Song Liu <song@kernel.org>, Miroslav Benes <mbenes@suse.cz>,
Petr Mladek <pmladek@suse.com>
Subject: [PATCH v2 09/53] objtool: Replace iterator callback with for_each_sym_by_mangled_name()
Date: Thu, 30 Apr 2026 21:07:57 -0700 [thread overview]
Message-ID: <cb95eae9cc63ca04f881c69c93eed6bac0c751fe.1777575752.git.jpoimboe@kernel.org> (raw)
In-Reply-To: <cover.1777575752.git.jpoimboe@kernel.org>
Convert the callback-based iterate_sym_by_demangled_name() with a new
for_each_sym_by_demangled_name() macro. This eliminates the callback
struct/function and makes the code more compact and readable.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/elf.c | 68 ++++++++---------------------
tools/objtool/include/objtool/elf.h | 32 ++++++++++++--
tools/objtool/klp-diff.c | 42 ++++++------------
3 files changed, 60 insertions(+), 82 deletions(-)
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index f3df2bde119f..dc39132f71c1 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -27,27 +27,16 @@
static ssize_t demangled_name_len(const char *name);
-static inline u32 str_hash(const char *str)
-{
- return jhash(str, strlen(str), 0);
-}
-
-static inline u32 str_hash_demangled(const char *str)
+u32 str_hash_demangled(const char *str)
{
return jhash(str, demangled_name_len(str), 0);
}
-#define __elf_table(name) (elf->name##_hash)
-#define __elf_bits(name) (elf->name##_bits)
-
-#define __elf_table_entry(name, key) \
- __elf_table(name)[hash_min(key, __elf_bits(name))]
-
#define elf_hash_add(name, node, key) \
({ \
struct elf_hash_node *__node = node; \
- __node->next = __elf_table_entry(name, key); \
- __elf_table_entry(name, key) = __node; \
+ __node->next = __elf_table_entry(elf, name, key); \
+ __elf_table_entry(elf, name, key) = __node; \
})
static inline void __elf_hash_del(struct elf_hash_node *node,
@@ -69,30 +58,20 @@ static inline void __elf_hash_del(struct elf_hash_node *node,
}
#define elf_hash_del(name, node, key) \
- __elf_hash_del(node, &__elf_table_entry(name, key))
-
-#define elf_list_entry(ptr, type, member) \
-({ \
- typeof(ptr) __ptr = (ptr); \
- __ptr ? container_of(__ptr, type, member) : NULL; \
-})
-
-#define elf_hash_for_each_possible(name, obj, member, key) \
- for (obj = elf_list_entry(__elf_table_entry(name, key), typeof(*obj), member); \
- obj; \
- obj = elf_list_entry(obj->member.next, typeof(*(obj)), member))
+ __elf_hash_del(node, &__elf_table_entry(elf, name, key))
#define elf_alloc_hash(name, size) \
({ \
- __elf_bits(name) = max(10, ilog2(size)); \
- __elf_table(name) = mmap(NULL, sizeof(struct elf_hash_node *) << __elf_bits(name), \
+ __elf_bits(elf, name) = max(10, ilog2(size)); \
+ __elf_table(elf, name) = mmap(NULL, \
+ sizeof(struct elf_hash_node *) << __elf_bits(elf, name), \
PROT_READ|PROT_WRITE, \
MAP_PRIVATE|MAP_ANON, -1, 0); \
- if (__elf_table(name) == (void *)-1L) { \
+ if (__elf_table(elf, name) == (void *)-1L) { \
ERROR_GLIBC("mmap fail " #name); \
- __elf_table(name) = NULL; \
+ __elf_table(elf, name) = NULL; \
} \
- __elf_table(name); \
+ __elf_table(elf, name); \
})
static inline unsigned long __sym_start(struct symbol *s)
@@ -141,7 +120,7 @@ struct section *find_section_by_name(const struct elf *elf, const char *name)
{
struct section *sec;
- elf_hash_for_each_possible(section_name, sec, name_hash, str_hash(name)) {
+ elf_hash_for_each_possible(elf, section_name, sec, name_hash, str_hash(name)) {
if (!strcmp(sec->name, name))
return sec;
}
@@ -154,7 +133,7 @@ static struct section *find_section_by_index(struct elf *elf,
{
struct section *sec;
- elf_hash_for_each_possible(section, sec, hash, idx) {
+ elf_hash_for_each_possible(elf, section, sec, hash, idx) {
if (sec->idx == idx)
return sec;
}
@@ -166,7 +145,7 @@ static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx)
{
struct symbol *sym;
- elf_hash_for_each_possible(symbol, sym, hash, idx) {
+ elf_hash_for_each_possible(elf, symbol, sym, hash, idx) {
if (sym->idx == idx)
return sym;
}
@@ -285,7 +264,7 @@ struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
{
struct symbol *sym;
- elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
+ elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash(name)) {
if (!strcmp(sym->name, name))
return sym;
}
@@ -300,7 +279,7 @@ static struct symbol *find_local_symbol_by_file_and_name(const struct elf *elf,
{
struct symbol *sym;
- elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) {
+ elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_demangled(name)) {
if (sym->bind == STB_LOCAL && sym->file == file &&
!strcmp(sym->name, name)) {
return sym;
@@ -314,7 +293,7 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam
{
struct symbol *sym;
- elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) {
+ elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_demangled(name)) {
if (!strcmp(sym->name, name) && !is_local_sym(sym))
return sym;
}
@@ -322,19 +301,6 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam
return NULL;
}
-void iterate_global_symbol_by_demangled_name(const struct elf *elf,
- const char *demangled_name,
- void (*process)(struct symbol *sym, void *data),
- void *data)
-{
- struct symbol *sym;
-
- elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(demangled_name)) {
- if (!strcmp(sym->demangled_name, demangled_name) && !is_local_sym(sym))
- process(sym, data);
- }
-}
-
struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
unsigned long offset, unsigned int len)
{
@@ -347,7 +313,7 @@ struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *se
return NULL;
for_offset_range(o, offset, offset + len) {
- elf_hash_for_each_possible(reloc, reloc, hash,
+ elf_hash_for_each_possible(elf, reloc, reloc, hash,
sec_offset_hash(rsec, o)) {
if (reloc->sec != rsec)
continue;
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index 25573e5af76e..b142984eb9b5 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -21,6 +21,13 @@
#define SEC_NAME_LEN 1024
#define SYM_NAME_LEN 512
+static inline u32 str_hash(const char *str)
+{
+ return jhash(str, strlen(str), 0);
+}
+
+u32 str_hash_demangled(const char *str);
+
#define bswap_if_needed(elf, val) __bswap_if_needed(&elf->ehdr, val)
#ifdef LIBELF_USE_DEPRECATED
@@ -130,6 +137,23 @@ struct elf {
struct symbol *symbol_data;
};
+#define __elf_table(elf, name) ((elf)->name##_hash)
+#define __elf_bits(elf, name) ((elf)->name##_bits)
+
+#define __elf_table_entry(elf, name, key) \
+ __elf_table(elf, name)[hash_min(key, __elf_bits(elf, name))]
+
+#define elf_list_entry(ptr, type, member) \
+({ \
+ typeof(ptr) __ptr = (ptr); \
+ __ptr ? container_of(__ptr, type, member) : NULL; \
+})
+
+#define elf_hash_for_each_possible(elf, name, obj, member, key) \
+ for (obj = elf_list_entry(__elf_table_entry(elf, name, key), typeof(*obj), member); \
+ obj; \
+ obj = elf_list_entry(obj->member.next, typeof(*(obj)), member))
+
struct elf *elf_open_read(const char *name, int flags);
struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name);
@@ -186,9 +210,6 @@ struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name);
-void iterate_global_symbol_by_demangled_name(const struct elf *elf, const char *demangled_name,
- void (*process)(struct symbol *sym, void *data),
- void *data);
struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
int find_symbol_hole_containing(const struct section *sec, unsigned long offset);
struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
@@ -468,6 +489,11 @@ static inline void set_sym_next_reloc(struct reloc *reloc, struct reloc *next)
#define for_each_sym_continue(elf, sym) \
list_for_each_entry_continue(sym, &elf->symbols, global_list)
+#define for_each_sym_by_demangled_name(elf, name, sym) \
+ elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, \
+ str_hash(name)) \
+ if (strcmp(sym->demangled_name, name)) {} else
+
#define rsec_next_reloc(rsec, reloc) \
reloc_idx(reloc) < sec_num_entries(rsec) - 1 ? reloc + 1 : NULL
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 0653bf6a33bd..30ce234e01a1 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -46,11 +46,6 @@ static const struct option klp_diff_options[] = {
static DEFINE_HASHTABLE(exports, 15);
-static inline u32 str_hash(const char *str)
-{
- return jhash(str, strlen(str), 0);
-}
-
static char *escape_str(const char *orig)
{
size_t len = 0;
@@ -396,22 +391,6 @@ static bool dont_correlate(struct symbol *sym)
is_special_section_aux(sym->sec);
}
-struct process_demangled_name_data {
- struct symbol *ret;
- int count;
-};
-
-static void process_demangled_name(struct symbol *sym, void *d)
-{
- struct process_demangled_name_data *data = d;
-
- if (sym->twin)
- return;
-
- data->count++;
- data->ret = sym;
-}
-
/*
* When there is no full name match, try match demangled_name. This would
* match original foo.llvm.123 to patched foo.llvm.456.
@@ -423,16 +402,23 @@ static void process_demangled_name(struct symbol *sym, void *d)
static int find_global_symbol_by_demangled_name(struct elf *elf, struct symbol *sym,
struct symbol **out_sym)
{
- struct process_demangled_name_data data = {};
+ struct symbol *sym2, *result = NULL;
+ int count = 0;
- iterate_global_symbol_by_demangled_name(elf, sym->demangled_name,
- process_demangled_name,
- &data);
- if (data.count > 1) {
- ERROR("Multiple (%d) correlation candidates for %s", data.count, sym->name);
+ for_each_sym_by_demangled_name(elf, sym->demangled_name, sym2) {
+ if (is_local_sym(sym2) || sym2->twin)
+ continue;
+
+ count++;
+ result = sym2;
+ }
+
+ if (count > 1) {
+ ERROR("Multiple (%d) correlation candidates for %s", count, sym->name);
return -1;
}
- *out_sym = data.ret;
+
+ *out_sym = result;
return 0;
}
--
2.53.0
next prev parent reply other threads:[~2026-05-01 4:08 UTC|newest]
Thread overview: 103+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-01 4:07 [PATCH v2 00/53] objtool/klp: Some klp-build fixes and improvements Josh Poimboeuf
2026-05-01 4:07 ` [PATCH v2 01/53] objtool/klp: Fix is_uncorrelated_static_local() for Clang Josh Poimboeuf
2026-05-01 4:07 ` [PATCH v2 02/53] objtool/klp: Fix .data..once static local non-correlation Josh Poimboeuf
2026-05-01 4:07 ` [PATCH v2 03/53] objtool/klp: Don't correlate __ADDRESSABLE() symbols Josh Poimboeuf
2026-05-01 10:26 ` Song Liu
2026-05-01 4:07 ` [PATCH v2 04/53] objtool/klp: Don't correlate absolute symbols Josh Poimboeuf
2026-05-01 4:07 ` [PATCH v2 05/53] objtool/klp: Don't correlate __initstub__ symbols Josh Poimboeuf
2026-05-01 4:07 ` [PATCH v2 06/53] objtool/klp: Don't report uncorrelated functions as new Josh Poimboeuf
2026-05-01 4:07 ` [PATCH v2 07/53] objtool/klp: Improve local label check Josh Poimboeuf
2026-05-01 10:27 ` Song Liu
2026-05-01 4:07 ` [PATCH v2 08/53] objtool/klp: Fix create_fake_symbols() skipping entsize-based sections Josh Poimboeuf
2026-05-01 4:07 ` Josh Poimboeuf [this message]
2026-05-01 10:28 ` [PATCH v2 09/53] objtool: Replace iterator callback with for_each_sym_by_mangled_name() Song Liu
2026-05-04 13:59 ` Miroslav Benes
2026-05-01 4:07 ` [PATCH v2 10/53] objtool/klp: Fix --debug-checksum for duplicate symbol names Josh Poimboeuf
2026-05-04 14:04 ` Miroslav Benes
2026-05-01 4:07 ` [PATCH v2 11/53] objtool/klp: Fix handling of zero-length .altinstr_replacement sections Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 12/53] objtool/klp: Fix cloning of zero-length section symbols Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 13/53] objtool/klp: Fix XXH3 state memory leak Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 14/53] objtool/klp: Fix extraction of text annotations for alternatives Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 15/53] objtool/klp: Fix kCFI trap handling Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 16/53] objtool/klp: Fix relocation conversion failures for R_X86_64_NONE Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 17/53] objtool: Move mark_rodata() to elf.c Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 18/53] objtool/klp: Simplify reloc symbol conversion Josh Poimboeuf
2026-05-01 10:31 ` Song Liu
2026-05-04 14:04 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 19/53] objtool/klp: Fix pointer comparisons for rodata objects Josh Poimboeuf
2026-05-01 10:35 ` Song Liu
2026-05-05 9:44 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 20/53] objtool/klp: Don't correlate .rodata.cst* constant pool objects Josh Poimboeuf
2026-05-01 10:37 ` Song Liu
2026-05-01 17:04 ` Josh Poimboeuf
2026-05-01 17:31 ` Song Liu
2026-05-05 9:44 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 21/53] objtool/klp: Fix reloc corruption in convert_reloc_sym_to_secsym() Josh Poimboeuf
2026-05-01 10:38 ` Song Liu
2026-05-05 9:44 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 22/53] objtool: Fix reloc hash collision in find_reloc_by_dest_range() Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 23/53] klp-build: Fix hang on out-of-date .config Josh Poimboeuf
2026-05-01 10:39 ` Song Liu
2026-05-05 9:44 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 24/53] klp-build: Fix checksum comparison for changed offsets Josh Poimboeuf
2026-05-01 10:41 ` Song Liu
2026-05-05 10:05 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 25/53] klp-build: Don't use errexit Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 26/53] klp-build: Validate patch file existence Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 27/53] klp-build: Suppress excessive fuzz output by default Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 28/53] klp-build: Fix patch cleanup on interrupt Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 29/53] klp-build: Reject patches to vDSO Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 30/53] klp-build: Reject patches to realmode Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 31/53] klp-build: Print "objtool klp diff" command in verbose mode Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 32/53] klp-build: Remove redundant SRC and OBJ variables Josh Poimboeuf
2026-05-01 10:42 ` Song Liu
2026-05-05 11:26 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 33/53] objtool/klp: Don't set sym->file for section symbols Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 34/53] objtool: Include libsubcmd headers directly from source tree Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 35/53] objtool/klp: Create empty checksum sections for function-less object files Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 36/53] objtool/klp: Handle Clang .data..Lanon anonymous data sections Josh Poimboeuf
2026-05-05 11:26 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 37/53] objtool: Add is_alias_sym() helper Josh Poimboeuf
2026-05-05 11:31 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 38/53] objtool: Add is_cold_func() helper Josh Poimboeuf
2026-05-01 10:43 ` Song Liu
2026-05-05 11:26 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 39/53] objtool/klp: Extricate checksum calculation from validate_branch() Josh Poimboeuf
2026-05-05 11:43 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 40/53] objtool: Consolidate file decoding into decode_file() Josh Poimboeuf
2026-05-05 11:43 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 41/53] objtool/klp: Add "objtool klp checksum" subcommand Josh Poimboeuf
2026-05-05 11:43 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 42/53] klp-build: Use " Josh Poimboeuf
2026-05-05 11:58 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 43/53] objtool/klp: Remove "objtool --checksum" Josh Poimboeuf
2026-05-05 11:59 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 44/53] klp-build: Validate short-circuit prerequisites Josh Poimboeuf
2026-05-01 10:49 ` Song Liu
2026-05-05 12:00 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 45/53] objtool/klp: Calculate object checksums Josh Poimboeuf
2026-05-01 10:53 ` Song Liu
2026-05-05 12:07 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 46/53] objtool/klp: Rewrite symbol correlation algorithm Josh Poimboeuf
2026-05-01 12:07 ` Song Liu
2026-05-05 13:07 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 47/53] objtool/klp: Add correlation debugging output Josh Poimboeuf
2026-05-05 13:28 ` Miroslav Benes
2026-05-01 4:08 ` [PATCH v2 48/53] objtool: Add insn_sym() helper Josh Poimboeuf
2026-05-01 12:11 ` Song Liu
2026-05-01 4:08 ` [PATCH v2 49/53] objtool/klp: Fix position-dependent checksums for non-relocated jumps/calls Josh Poimboeuf
2026-05-01 12:16 ` Song Liu
2026-05-01 4:08 ` [PATCH v2 50/53] objtool: Grow __cfi_* prefix symbols for all CFI+CALL_PADDING Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 51/53] objtool/klp: Fix kCFI prefix finding/cloning Josh Poimboeuf
2026-05-01 12:17 ` Song Liu
2026-05-01 4:08 ` [PATCH v2 52/53] objtool: Improve and simplify prefix symbol detection Josh Poimboeuf
2026-05-01 4:08 ` [PATCH v2 53/53] objtool/klp: Cache dont_correlate() result Josh Poimboeuf
2026-05-05 13:40 ` Miroslav Benes
2026-05-01 18:47 ` [PATCH v2 00/53] objtool/klp: Some klp-build fixes and improvements Josh Poimboeuf
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=cb95eae9cc63ca04f881c69c93eed6bac0c751fe.1777575752.git.jpoimboe@kernel.org \
--to=jpoimboe@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=song@kernel.org \
--cc=x86@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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox