| From b1169cd7e4b056f65ef6562bd70b52752cac97cf Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 1 Nov 2023 02:46:27 +0900 |
| Subject: modpost: fix section mismatch message for RELA |
| |
| From: Masahiro Yamada <masahiroy@kernel.org> |
| |
| [ 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> |
| --- |
| scripts/mod/modpost.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c |
| index b3dee80497cb2..ac4ef3e206bbd 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); |
| } |
| } |
| -- |
| 2.42.0 |
| |