Commit 18328546 authored by Josh Poimboeuf's avatar Josh Poimboeuf
Browse files

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: dd590d4d ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Reported-by: default avatarSong Liu <song@kernel.org>
Acked-by: default avatarSong Liu <song@kernel.org>
Link: https://patch.msgid.link/e21ec1141fc749b5f538d7329b531c1ab63a6d1a.1770055235.git.jpoimboe@kernel.org


Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
parent b525fcaf
Loading
Loading
Loading
Loading
+34 −5
Original line number Diff line number Diff line
@@ -364,10 +364,39 @@ 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),
	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) {