On Fri, Jan 30, 2026 at 6:27 PM Josh Poimboeuf <[email protected]> wrote:
[...]
> It's a bit worrisome that Clang is stripping FILE entries and moving
> symbols, but I looked at the symbol table for a thin LTO vmlinux.o and
> it only seems to have stripped this one FILE symbol for initramfs_data.o
> and made its symbols orphans.  Presumably because this file only has
> data and no code.
>
> I actually think the warning is valid.  We should try to correlate those
> pre-FILE symbols, otherwise things like klp_reloc_needed() might not
> work as intended.
>
> Does the below patch work instead?

Yes, this does look better. Let's ship this version.

Thanks,
Song

>
> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> index d94531e3f64e..ea292ebe217f 100644
> --- a/tools/objtool/klp-diff.c
> +++ b/tools/objtool/klp-diff.c
> @@ -364,11 +364,40 @@ static int correlate_symbols(struct elfs *e)
>         struct symbol *file1_sym, *file2_sym;
>         struct symbol *sym1, *sym2;
>
> -       /* Correlate locals */
> -       for (file1_sym = first_file_symbol(e->orig),
> -            file2_sym = first_file_symbol(e->patched); ;
> -            file1_sym = next_file_symbol(e->orig, file1_sym),
> -            file2_sym = next_file_symbol(e->patched, file2_sym)) {
> +       file1_sym = first_file_symbol(e->orig);
> +       file2_sym = first_file_symbol(e->patched);
> +
> +       /*
> +        * Correlate any locals before the first FILE symbol.  This has been
> +        * seen when LTO inexplicably strips the initramfs_data.o FILE symbol
> +        * due to the file only containing data and no code.
> +        */
> +       for_each_sym(e->orig, sym1) {
> +               if (sym1 == file1_sym || !is_local_sym(sym1))
> +                       break;
> +
> +               if (dont_correlate(sym1))
> +                       continue;
> +
> +               for_each_sym(e->patched, sym2) {
> +                       if (sym2 == file2_sym || !is_local_sym(sym2))
> +                               break;
> +
> +                       if (sym2->twin || dont_correlate(sym2))
> +                               continue;
> +
> +                       if (strcmp(sym1->demangled_name, 
> sym2->demangled_name))
> +                               continue;
> +
> +                       sym1->twin = sym2;
> +                       sym2->twin = sym1;
> +                       break;
> +               }
> +       }
> +
> +       /* Correlate locals after the first FILE symbol */
> +       for (; ; file1_sym = next_file_symbol(e->orig, file1_sym),
> +                file2_sym = next_file_symbol(e->patched, file2_sym)) {
>
>                 if (!file1_sym && file2_sym) {
>                         ERROR("FILE symbol mismatch: NULL != %s", 
> file2_sym->name);

Reply via email to