Skip to content

Commit 56a24b8

Browse files
committed
modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24}
addend_arm_rel() processes R_ARM_PC24, R_ARM_CALL, R_ARM_JUMP24 in a wrong way. Here, test code. [test code for R_ARM_JUMP24] .section .init.text,"ax" bar: bx lr .section .text,"ax" .globl foo foo: b bar [test code for R_ARM_CALL] .section .init.text,"ax" bar: bx lr .section .text,"ax" .globl foo foo: push {lr} bl bar pop {pc} If you compile it with ARM multi_v7_defconfig, modpost will show the symbol name, (unknown). WARNING: modpost: vmlinux.o: section mismatch in reference: foo (section: .text) -> (unknown) (section: .init.text) (You need to use GNU linker instead of LLD to reproduce it.) Fix the code to make modpost show the correct symbol name. I imported (with adjustment) sign_extend32() from include/linux/bitops.h. The '+8' is the compensation for pc-relative instruction. It is documented in "ELF for the Arm Architecture" [1]. "If the relocation is pc-relative then compensation for the PC bias (the PC value is 8 bytes ahead of the executing instruction in Arm state and 4 bytes in Thumb state) must be encoded in the relocation by the object producer." [1]: https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst Fixes: 56a974f ("kbuild: make better section mismatch reports on arm") Fixes: 6e2e340 ("ARM: 7324/1: modpost: Fix section warnings for ARM for many compilers") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
1 parent b7c6352 commit 56a24b8

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

scripts/mod/modpost.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,12 +1277,20 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
12771277
#define R_ARM_THM_JUMP19 51
12781278
#endif
12791279

1280+
static int32_t sign_extend32(int32_t value, int index)
1281+
{
1282+
uint8_t shift = 31 - index;
1283+
1284+
return (int32_t)(value << shift) >> shift;
1285+
}
1286+
12801287
static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
12811288
{
12821289
unsigned int r_typ = ELF_R_TYPE(r->r_info);
12831290
Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
12841291
void *loc = reloc_location(elf, sechdr, r);
12851292
uint32_t inst;
1293+
int32_t offset;
12861294

12871295
switch (r_typ) {
12881296
case R_ARM_ABS32:
@@ -1292,6 +1300,10 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
12921300
case R_ARM_PC24:
12931301
case R_ARM_CALL:
12941302
case R_ARM_JUMP24:
1303+
inst = TO_NATIVE(*(uint32_t *)loc);
1304+
offset = sign_extend32((inst & 0x00ffffff) << 2, 25);
1305+
r->r_addend = offset + sym->st_value + 8;
1306+
break;
12951307
case R_ARM_THM_CALL:
12961308
case R_ARM_THM_JUMP24:
12971309
case R_ARM_THM_JUMP19:

0 commit comments

Comments
 (0)