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);