On Tue, Feb 03, 2026 at 01:40:06PM -0800, Song Liu wrote:
> With CONFIG_LTO_CLANG_THIN, __UNIQUE_ID_* can be global. Therefore, it
> is necessary to demangle global symbols.

Ouch, so LTO is changing symbol bindings :-/

If a patch causes a symbol to change from LOCAL to GLOBAL between the
original and patched builds, that will break some fundamental
assumptions in the correlation logic.

Also, notice sym->demangled_name isn't used for correlating global
symbols in correlate_symbols().  That code currently assumes all global
symbols are uniquely named (and don't change between orig and patched).
So this first fix seems incomplete.

> Also, LTO may generate symbols like:

The "also" is a clue that this should probably be two separate patches.

Also, for objtool patches, please prefix the subject with "objtool:", or
in this case, for klp-specific code, "objtool/klp:".

> __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695
>
> Remove trailing '_' together with numbers and '.' so that both numbers
> added to the end of the symbol are removed. For example, the above s
> ymbol will be demangled as
> 
> __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar

This is indeed a bug in demangle_name(), but not specific to LTO.  The
unique number is added by the __UNIQUE_ID() macro.

I guess in this case LTO is doing some kind of nested __UNIQUE_ID() to
get two "__UNIQUE_ID" strings and two numbers?  But the bug still exists
for the non-nested case.

> Signed-off-by: Song Liu <[email protected]>
> ---
>  tools/objtool/elf.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
> index 2c02c7b49265..b4a7ea4720e1 100644
> --- a/tools/objtool/elf.c
> +++ b/tools/objtool/elf.c
> @@ -445,9 +445,6 @@ 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;
>  
> @@ -463,7 +460,13 @@ static const char *demangle_name(struct symbol *sym)
>       for (int i = strlen(str) - 1; i >= 0; i--) {
>               char c = str[i];
>  
> -             if (!isdigit(c) && c != '.') {
> +             /*
> +              * With CONFIG_LTO_CLANG_THIN, the UNIQUE_ID field could
> +              * be like:
> +              *   __UNIQUE_ID_addressable___UNIQUE_ID_<name>_628_629
> +              * Remove all the trailing number, '.', and '_'.
> +              */

A comment is indeed probably warranted, though I'm thinking it should
instead go above the function, with examples of both __UNIQUE_ID and "."
symbols.

> +             if (!isdigit(c) && c != '.' && c != '_') {

Ack.

-- 
Josh

Reply via email to