[PATCH 10/48] objtool/klp: Fix --debug-checksum for duplicate symbol names

Josh Poimboeuf
2026-04-23T04:04:28Z

find_symbol_by_name() only returns the first match, so
--debug-checksum=<func> silently ignores any subsequent duplicately
named functions after the first.

Add a new iterate_sym_by_name() to fix that.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/check.c | 19 ++++++++++++++-----
tools/objtool/elf.c | 12 ++++++++++++
tools/objtool/include/objtool/elf.h | 3 +++
3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 5722d4568401..f14212a8c179 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3657,6 +3657,17 @@ static bool skip_alt_group(struct instruction *insn)
return alt_insn->type == INSN_CLAC || alt_insn->type == INSN_STAC;
}

+static void enable_debug_checksum_cb(struct symbol *sym, void *d)
+{
+ bool *found = d;
+
+ if (!is_func_sym(sym))
+ return;
+
+ sym->debug_checksum = 1;
+ *found = true;
+}
+
static int checksum_debug_init(struct objtool_file *file)
{
char *dup, *s;
@@ -3672,18 +3683,16 @@ static int checksum_debug_init(struct objtool_file *file)

s = dup;
while (*s) {
- struct symbol *func;
+ bool found = false;
char *comma;

comma = strchr(s, ',');
if (comma)
*comma = '\0';

- func = find_symbol_by_name(file->elf, s);
- if (!func || !is_func_sym(func))
+ iterate_sym_by_name(file->elf, s, enable_debug_checksum_cb, &found);
+ if (!found)
WARN("--debug-checksum: can't find '%s'", s);
- else
- func->debug_checksum = 1;

if (!comma)
break;
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index ac9da81a7a2f..a5486e172e5c 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -335,6 +335,18 @@ void iterate_global_symbol_by_demangled_name(const struct elf *elf,
}
}

+void iterate_sym_by_name(const struct elf *elf, const char *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->name, name))
+ process(sym, data);
+ }
+}
+
struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
unsigned long offset, unsigned int len)
{
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index c61bd57767f9..cd5844c7b4e2 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -189,6 +189,9 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam
void iterate_global_symbol_by_demangled_name(const struct elf *elf, const char *demangled_name,
void (*process)(struct symbol *sym, void *data),
void *data);
+void iterate_sym_by_name(const struct elf *elf, const char *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);
--
2.53.0