From 0d83da43b1e1c8ce19f2bb10f54a0fdf795364f7 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 17 Sep 2025 09:03:57 -0700 Subject: objtool/klp: Add --checksum option to generate per-function checksums In preparation for the objtool klp diff subcommand, add a command-line option to generate a unique checksum for each function. This will enable detection of functions which have changed between two versions of an object file. Acked-by: Petr Mladek Tested-by: Joe Lawrence Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'tools/objtool/elf.c') diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 6095baba8e9c..0119b3b4c554 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -412,7 +413,38 @@ static int read_sections(struct elf *elf) return 0; } -static void elf_add_symbol(struct elf *elf, struct symbol *sym) +static const char *demangle_name(struct symbol *sym) +{ + char *str; + + if (!is_local_sym(sym)) + return sym->name; + + if (!is_func_sym(sym) && !is_object_sym(sym)) + return sym->name; + + if (!strstarts(sym->name, "__UNIQUE_ID_") && !strchr(sym->name, '.')) + return sym->name; + + str = strdup(sym->name); + if (!str) { + ERROR_GLIBC("strdup"); + return NULL; + } + + for (int i = strlen(str) - 1; i >= 0; i--) { + char c = str[i]; + + if (!isdigit(c) && c != '.') { + str[i + 1] = '\0'; + break; + } + }; + + return str; +} + +static int elf_add_symbol(struct elf *elf, struct symbol *sym) { struct list_head *entry; struct rb_node *pnode; @@ -456,6 +488,12 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) if (is_func_sym(sym) && strstr(sym->name, ".cold")) sym->cold = 1; sym->pfunc = sym->cfunc = sym; + + sym->demangled_name = demangle_name(sym); + if (!sym->demangled_name) + return -1; + + return 0; } static int read_symbols(struct elf *elf) @@ -529,7 +567,8 @@ static int read_symbols(struct elf *elf) } else sym->sec = find_section_by_index(elf, 0); - elf_add_symbol(elf, sym); + if (elf_add_symbol(elf, sym)) + return -1; } if (opts.stats) { @@ -867,7 +906,8 @@ non_local: mark_sec_changed(elf, symtab_shndx, true); } - elf_add_symbol(elf, sym); + if (elf_add_symbol(elf, sym)) + return NULL; return sym; } -- cgit v1.2.3