Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

objtool: Fix unreachable instruction warnings for weak functions

In the presence of both weak and strong function definitions, the
linker drops the weak symbol in favor of a strong symbol, but
leaves the code in place. Code in ignore_unreachable_insn() has
some heuristics to suppress the warning, but it does not work when
-ffunction-sections is enabled.

Suppose function foo has both strong and weak definitions.
Case 1: The strong definition has an annotated section name,
like .init.text. Only the weak definition will be placed into
.text.foo. But since the section has no symbols, there will be no
"hole" in the section.

Case 2: Both sections are without an annotated section name.
Both will be placed into .text.foo section, but there will be only one
symbol (the strong one). If the weak code is before the strong code,
there is no "hole" as it fails to find the right-most symbol before
the offset.

The fix is to use the first node to compute the hole if hole.sym
is empty. If there is no symbol in the section, the first node
will be NULL, in which case, -1 is returned to skip the whole
section.

Co-developed-by: Han Shen <shenhan@google.com>
Signed-off-by: Han Shen <shenhan@google.com>
Signed-off-by: Rong Xu <xur@google.com>
Suggested-by: Sriraman Tallam <tmsriram@google.com>
Suggested-by: Krzysztof Pszeniczny <kpszeniczny@google.com>
Tested-by: Yonghong Song <yonghong.song@linux.dev>
Tested-by: Yabin Cui <yabinc@google.com>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>

authored by

Rong Xu and committed by
Masahiro Yamada
18e88509 315ad878

+10 -5
+10 -5
tools/objtool/elf.c
··· 224 224 if (n) 225 225 return 0; /* not a hole */ 226 226 227 - /* didn't find a symbol for which @offset is after it */ 228 - if (!hole.sym) 229 - return 0; /* not a hole */ 227 + /* 228 + * @offset >= sym->offset + sym->len, find symbol after it. 229 + * When hole.sym is empty, use the first node to compute the hole. 230 + * If there is no symbol in the section, the first node will be NULL, 231 + * in which case, -1 is returned to skip the whole section. 232 + */ 233 + if (hole.sym) 234 + n = rb_next(&hole.sym->node); 235 + else 236 + n = rb_first_cached(&sec->symbol_tree); 230 237 231 - /* @offset >= sym->offset + sym->len, find symbol after it */ 232 - n = rb_next(&hole.sym->node); 233 238 if (!n) 234 239 return -1; /* until end of address space */ 235 240