summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorMasahiro Yamada <masahiroy@kernel.org>2023-11-01 02:46:27 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-12-13 18:44:59 +0100
commitb1205cc72b47765dbfd40ca6c0cfb33da0274008 (patch)
tree8e336495adafe960b86551d0fea2fa1dfbda1197 /scripts
parent9a07b662e54ed0c8a795d38f42c731ea58a9f09d (diff)
downloadlinux-stable-b1205cc72b47765dbfd40ca6c0cfb33da0274008.tar.gz
linux-stable-b1205cc72b47765dbfd40ca6c0cfb33da0274008.tar.bz2
linux-stable-b1205cc72b47765dbfd40ca6c0cfb33da0274008.zip
modpost: fix section mismatch message for RELA
[ Upstream commit 1c4a7587d1bbee0fd53b63af60e4244a62775f57 ] The section mismatch check prints a bogus symbol name on some architectures. [test code] #include <linux/init.h> int __initdata foo; int get_foo(void) { return foo; } If you compile it with GCC for riscv or loongarch, modpost will show an incorrect symbol name: WARNING: modpost: vmlinux: section mismatch in reference: get_foo+0x8 (section: .text) -> done (section: .init.data) To get the correct symbol address, the st_value must be added. This issue has never been noticed since commit 93684d3b8062 ("kbuild: include symbol names in section mismatch warnings") presumably because st_value becomes zero on most architectures when the referenced symbol is looked up. It is not true for riscv or loongarch, at least. With this fix, modpost will show the correct symbol name: WARNING: modpost: vmlinux: section mismatch in reference: get_foo+0x8 (section: .text) -> foo (section: .init.data) Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/mod/modpost.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index b3dee80497cb..ac4ef3e206bb 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1496,13 +1496,15 @@ static void section_rela(struct module *mod, struct elf_info *elf,
return;
for (rela = start; rela < stop; rela++) {
+ Elf_Sym *tsym;
Elf_Addr taddr, r_offset;
unsigned int r_type, r_sym;
r_offset = TO_NATIVE(rela->r_offset);
get_rel_type_and_sym(elf, rela->r_info, &r_type, &r_sym);
- taddr = TO_NATIVE(rela->r_addend);
+ tsym = elf->symtab_start + r_sym;
+ taddr = tsym->st_value + TO_NATIVE(rela->r_addend);
switch (elf->hdr->e_machine) {
case EM_RISCV:
@@ -1517,7 +1519,7 @@ static void section_rela(struct module *mod, struct elf_info *elf,
break;
}
- check_section_mismatch(mod, elf, elf->symtab_start + r_sym,
+ check_section_mismatch(mod, elf, tsym,
fsecndx, fromsec, r_offset, taddr);
}
}