diff options
author | Tiezhu Yang <yangtiezhu@loongson.cn> | 2024-03-11 22:23:47 +0800 |
---|---|---|
committer | Huacai Chen <chenhuacai@loongson.cn> | 2024-03-11 22:23:47 +0800 |
commit | e91c5e4c21b0339376ee124cda5c9b27d41f2cbc (patch) | |
tree | 68c9c3aba90b0c4ea61ef5b0ec1c115551d9b62a /tools/objtool | |
parent | d5ab2bc36c6b0ce2f3409f934ff9cdf6d6768fa2 (diff) |
objtool: Check local label in read_unwind_hints()
When update the latest upstream gcc and binutils, it generates some
objtool warnings on LoongArch, like this:
arch/loongarch/kernel/entry.o: warning: objtool: ret_from_fork+0x0: unreachable instruction
We can see that the reloc sym name is local label instead of section
in relocation section '.rela.discard.unwind_hints', in this case, the
reloc sym type is STT_NOTYPE instead of STT_SECTION. Let us check it
to not return -1, then use reloc->sym->offset instead of reloc addend
which is 0 to find the corresponding instruction.
Here are some detailed info:
[fedora@linux 6.8.test]$ gcc --version
gcc (GCC) 14.0.1 20240129 (experimental)
[fedora@linux 6.8.test]$ as --version
GNU assembler (GNU Binutils) 2.42.50.20240129
[fedora@linux 6.8.test]$ readelf -r arch/loongarch/kernel/entry.o | grep -A 3 "rela.discard.unwind_hints"
Relocation section '.rela.discard.unwind_hints' at offset 0x3a8 contains 7 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000000 000a00000063 R_LARCH_32_PCREL 0000000000000000 .Lhere_1 + 0
00000000000c 000b00000063 R_LARCH_32_PCREL 00000000000000a8 .Lhere_50 + 0
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'tools/objtool')
-rw-r--r-- | tools/objtool/check.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d0e82c729dd9..1009d144f756 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2227,6 +2227,7 @@ static int read_unwind_hints(struct objtool_file *file) struct unwind_hint *hint; struct instruction *insn; struct reloc *reloc; + unsigned long offset; int i; sec = find_section_by_name(file->elf, ".discard.unwind_hints"); @@ -2254,7 +2255,16 @@ static int read_unwind_hints(struct objtool_file *file) return -1; } - insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); + if (reloc->sym->type == STT_SECTION) { + offset = reloc_addend(reloc); + } else if (reloc->sym->local_label) { + offset = reloc->sym->offset; + } else { + WARN("unexpected relocation symbol type in %s", sec->rsec->name); + return -1; + } + + insn = find_insn(file, reloc->sym->sec, offset); if (!insn) { WARN("can't find insn for unwind_hints[%d]", i); return -1; |