Skip to content

Commit 1832854

Browse files
committed
objtool/klp: Fix symbol correlation for orphaned local symbols
When compiling with CONFIG_LTO_CLANG_THIN, vmlinux.o has __irf_[start|end] before the first FILE entry: $ readelf -sW vmlinux.o Symbol table '.symtab' contains 597706 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT 18 __irf_start 2: 0000000000000200 0 NOTYPE LOCAL DEFAULT 18 __irf_end 3: 0000000000000000 0 SECTION LOCAL DEFAULT 17 .text 4: 0000000000000000 0 SECTION LOCAL DEFAULT 18 .init.ramfs This causes klp-build warnings like: vmlinux.o: warning: objtool: no correlation: __irf_start vmlinux.o: warning: objtool: no correlation: __irf_end The problem is that Clang LTO is stripping the initramfs_data.o FILE symbol, causing those two symbols to be orphaned and not noticed by klp-diff's correlation logic. Add a loop to correlate any symbols found before the first FILE symbol. Fixes: dd590d4 ("objtool/klp: Introduce klp diff subcommand for diffing object files") Reported-by: Song Liu <song@kernel.org> Acked-by: Song Liu <song@kernel.org> Link: https://patch.msgid.link/e21ec1141fc749b5f538d7329b531c1ab63a6d1a.1770055235.git.jpoimboe@kernel.org Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
1 parent b525fca commit 1832854

1 file changed

Lines changed: 34 additions & 5 deletions

File tree

tools/objtool/klp-diff.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,40 @@ static int correlate_symbols(struct elfs *e)
364364
struct symbol *file1_sym, *file2_sym;
365365
struct symbol *sym1, *sym2;
366366

367-
/* Correlate locals */
368-
for (file1_sym = first_file_symbol(e->orig),
369-
file2_sym = first_file_symbol(e->patched); ;
370-
file1_sym = next_file_symbol(e->orig, file1_sym),
371-
file2_sym = next_file_symbol(e->patched, file2_sym)) {
367+
file1_sym = first_file_symbol(e->orig);
368+
file2_sym = first_file_symbol(e->patched);
369+
370+
/*
371+
* Correlate any locals before the first FILE symbol. This has been
372+
* seen when LTO inexplicably strips the initramfs_data.o FILE symbol
373+
* due to the file only containing data and no code.
374+
*/
375+
for_each_sym(e->orig, sym1) {
376+
if (sym1 == file1_sym || !is_local_sym(sym1))
377+
break;
378+
379+
if (dont_correlate(sym1))
380+
continue;
381+
382+
for_each_sym(e->patched, sym2) {
383+
if (sym2 == file2_sym || !is_local_sym(sym2))
384+
break;
385+
386+
if (sym2->twin || dont_correlate(sym2))
387+
continue;
388+
389+
if (strcmp(sym1->demangled_name, sym2->demangled_name))
390+
continue;
391+
392+
sym1->twin = sym2;
393+
sym2->twin = sym1;
394+
break;
395+
}
396+
}
397+
398+
/* Correlate locals after the first FILE symbol */
399+
for (; ; file1_sym = next_file_symbol(e->orig, file1_sym),
400+
file2_sym = next_file_symbol(e->patched, file2_sym)) {
372401

373402
if (!file1_sym && file2_sym) {
374403
ERROR("FILE symbol mismatch: NULL != %s", file2_sym->name);

0 commit comments

Comments
 (0)