Commit 8c6f1e77 authored by Tiezhu Yang's avatar Tiezhu Yang
Browse files

objtool: Check local label in read_unwind_hints()

mainline inclusion
from mainline-v6.9
commit e91c5e4c21b0339376ee124cda5c9b27d41f2cbc
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IB3IRE

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e91c5e4c21b0339376ee124cda5c9b27d41f2cbc



---------------------------------------------------------------------------

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: default avatarTiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 4070f787
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -2211,6 +2211,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");
@@ -2238,7 +2239,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;