| From eaaa91255a4676a8e732a84d13ad70cfa146ab8c Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 17 Sep 2025 09:03:27 -0700 |
| Subject: objtool: Fix weak symbol detection |
| |
| From: Josh Poimboeuf <jpoimboe@kernel.org> |
| |
| [ Upstream commit 72567c630d32bc31f671977f78228c80937ed80e ] |
| |
| find_symbol_hole_containing() fails to find a symbol hole (aka stripped |
| weak symbol) if its section has no symbols before the hole. This breaks |
| weak symbol detection if -ffunction-sections is enabled. |
| |
| Fix that by allowing the interval tree to contain section symbols, which |
| are always at offset zero for a given section. |
| |
| Fixes a bunch of (-ffunction-sections) warnings like: |
| |
| vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable instruction |
| |
| Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") |
| Acked-by: Petr Mladek <pmladek@suse.com> |
| Tested-by: Joe Lawrence <joe.lawrence@redhat.com> |
| Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| tools/objtool/elf.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c |
| index 89b37cd4ab1dc..905253421e8c8 100644 |
| --- a/tools/objtool/elf.c |
| +++ b/tools/objtool/elf.c |
| @@ -74,7 +74,7 @@ struct symbol_hole { |
| }; |
| |
| /* |
| - * Find !section symbol where @offset is after it. |
| + * Find the last symbol before @offset. |
| */ |
| static int symbol_hole_by_offset(const void *key, const struct rb_node *node) |
| { |
| @@ -85,8 +85,7 @@ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) |
| return -1; |
| |
| if (sh->key >= s->offset + s->len) { |
| - if (s->type != STT_SECTION) |
| - sh->sym = s; |
| + sh->sym = s; |
| return 1; |
| } |
| |
| @@ -369,7 +368,8 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) |
| sym->len = sym->sym.st_size; |
| |
| __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { |
| - if (iter->offset == sym->offset && iter->type == sym->type) |
| + if (iter->offset == sym->offset && iter->type == sym->type && |
| + iter->len == sym->len) |
| iter->alias = sym; |
| } |
| |
| -- |
| 2.51.0 |
| |