[RFC PATCH v2 08/11] objtool/klp: Include symbol identities in reference checksums

From: Longjun Luo

Date: Wed Nov 04 2026 - 08:34:45 EST


Hashing only the target's suffix-stripped name can hide a reference change
between different objects with the same name.

Prepare DWARF identities for checksum calculation and hash the identity
path for named references. Keep the existing checksum section format and
use suffix-stripped ELF names when no DWARF identity is available.

The three tests rejected by policy in earlier patches remain rejected.

Validated the available objtool tests with GCC 16.2.1 and Clang
22.1.8. Only local-to-global-flip, sympos and sympos-vmlinux fail,
reflecting the linkage and duplicate-identity policies.

Assisted-by: LLM
Signed-off-by: Longjun Luo <luolongjuna@xxxxxxxxx>
---
tools/objtool/klp-checksum.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c
index 1a5f2fa89baa..44c0eb784e57 100644
--- a/tools/objtool/klp-checksum.c
+++ b/tools/objtool/klp-checksum.c
@@ -77,6 +77,12 @@ static bool is_const_reference(struct symbol *sym)
static int checksum_object(struct objtool_file *file, struct symbol *sym,
unsigned int depth);

+/* Use suffix-stripped ELF names for references without DWARF identities. */
+static const char *checksum_name(struct symbol *sym)
+{
+ return sym->identity.path ?: sym->identity.demangled_name;
+}
+
static int checksum_update_insn(struct objtool_file *file, struct symbol *func,
struct instruction *insn)
{
@@ -110,8 +116,8 @@ static int checksum_update_insn(struct objtool_file *file, struct symbol *func,
__checksum_update_insn(func, insn, buf, len);

if (call_dest) {
- __checksum_update_insn(func, insn, call_dest->identity.demangled_name,
- strlen(call_dest->identity.demangled_name));
+ __checksum_update_insn(func, insn, checksum_name(call_dest),
+ strlen(checksum_name(call_dest)));

} else if (jump_dest) {
struct symbol *dest_sym;
@@ -127,8 +133,8 @@ static int checksum_update_insn(struct objtool_file *file, struct symbol *func,
if (!dest_sym)
goto alts;

- __checksum_update_insn(func, insn, dest_sym->identity.demangled_name,
- strlen(dest_sym->identity.demangled_name));
+ __checksum_update_insn(func, insn, checksum_name(dest_sym),
+ strlen(checksum_name(dest_sym)));

offset = jump_dest->offset - dest_sym->offset;
__checksum_update_insn(func, insn, &offset, sizeof(offset));
@@ -170,8 +176,8 @@ static int checksum_update_insn(struct objtool_file *file, struct symbol *func,
__checksum_update_insn(func, insn, &sym->csum.checksum,
sizeof(sym->csum.checksum));
} else {
- __checksum_update_insn(func, insn, sym->identity.demangled_name,
- strlen(sym->identity.demangled_name));
+ __checksum_update_insn(func, insn, checksum_name(sym),
+ strlen(checksum_name(sym)));
}
__checksum_update_insn(func, insn, &offset, sizeof(offset));

@@ -265,9 +271,9 @@ static int checksum_update_object(struct objtool_file *file, struct symbol *sym,
&target->csum.checksum,
sizeof(target->csum.checksum));
} else {
- __checksum_update_object(sym, sym_offset, "reloc name",
- target->identity.demangled_name,
- strlen(target->identity.demangled_name));
+ __checksum_update_object(sym, sym_offset, "reloc identity",
+ checksum_name(target),
+ strlen(checksum_name(target)));
}
__checksum_update_object(sym, sym_offset, "reloc addend",
&offset, sizeof(offset));
@@ -387,6 +393,7 @@ static const char * const klp_checksum_usage[] = {
int cmd_klp_checksum(int argc, const char **argv)
{
struct objtool_file *file;
+ struct symbol *sym;
int ret;

const struct option options[] = {
@@ -411,6 +418,12 @@ int cmd_klp_checksum(int argc, const char **argv)
if (ret)
goto out;

+ for_each_sym(file->elf, sym)
+ sym->dont_correlate = dont_correlate(sym);
+ ret = prepare_identities(file->elf);
+ if (ret)
+ goto out;
+
ret = calculate_checksums(file);
if (ret)
goto out;
--
2.55.0