objtool/klp: Fix is_uncorrelated_static_local() for Clang

For naming function-local static locals, GCC uses <var>.<id>, e.g.
__already_done.15, while Clang uses <func>.<var> with optional .<id>,
e.g. create_worker.__already_done.111

The existing is_uncorrelated_static_local() check only matches the GCC
convention where the variable name is a prefix.  Handle both cases by
checking for a prefix match (GCC) and by checking after the first dot
separator (Clang).

Fixes: dd590d4d57 ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
This commit is contained in:
Joe Lawrence 2026-04-08 10:49:19 -04:00 committed by Josh Poimboeuf
parent 7fd2df204f
commit 84c304a534

View File

@ -242,16 +242,17 @@ static struct symbol *next_file_symbol(struct elf *elf, struct symbol *sym)
static bool is_uncorrelated_static_local(struct symbol *sym)
{
static const char * const vars[] = {
"__already_done.",
"__func__.",
"__key.",
"__warned.",
"_entry.",
"_entry_ptr.",
"_rs.",
"descriptor.",
"CSWTCH.",
"__already_done",
"__func__",
"__key",
"__warned",
"_entry",
"_entry_ptr",
"_rs",
"descriptor",
"CSWTCH",
};
const char *dot;
if (!is_object_sym(sym) || !is_local_sym(sym))
return false;
@ -259,8 +260,20 @@ static bool is_uncorrelated_static_local(struct symbol *sym)
if (!strcmp(sym->sec->name, ".data.once"))
return true;
dot = strchr(sym->name, '.');
if (!dot)
return false;
for (int i = 0; i < ARRAY_SIZE(vars); i++) {
if (strstarts(sym->name, vars[i]))
size_t len = strlen(vars[i]);
/* GCC: <var>.<id> */
if (strstarts(sym->name, vars[i]) && (sym->name[len] == '.'))
return true;
/* Clang: <func>.<var>[.<id>] */
if (strstarts(dot + 1, vars[i]) &&
(dot[1 + len] == '.' || dot[1 + len] == '\0'))
return true;
}