Patch "modpost: fix section mismatch message for R_ARM_ABS32" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    modpost: fix section mismatch message for R_ARM_ABS32

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     modpost-fix-section-mismatch-message-for-r_arm_abs32.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 20def63b530d07096c52c0a287ada543f35a00b8
Author: Masahiro Yamada <masahiroy@xxxxxxxxxx>
Date:   Thu Jun 1 21:09:55 2023 +0900

    modpost: fix section mismatch message for R_ARM_ABS32
    
    [ Upstream commit b7c63520f6703a25eebb4f8138fed764fcae1c6f ]
    
    addend_arm_rel() processes R_ARM_ABS32 in a wrong way.
    
    Here, test code.
    
      [test code 1]
    
        #include <linux/init.h>
    
        int __initdata foo;
        int get_foo(void) { return foo; }
    
    If you compile it with ARM versatile_defconfig, modpost will show the
    symbol name, (unknown).
    
      WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> (unknown) (section: .init.data)
    
    (You need to use GNU linker instead of LLD to reproduce it.)
    
    If you compile it for other architectures, modpost will show the correct
    symbol name.
    
      WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data)
    
    For R_ARM_ABS32, addend_arm_rel() sets r->r_addend to a wrong value.
    
    I just mimicked the code in arch/arm/kernel/module.c.
    
    However, there is more difficulty for ARM.
    
    Here, test code.
    
      [test code 2]
    
        #include <linux/init.h>
    
        int __initdata foo;
        int get_foo(void) { return foo; }
    
        int __initdata bar;
        int get_bar(void) { return bar; }
    
    With this commit applied, modpost will show the following messages
    for ARM versatile_defconfig:
    
      WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data)
      WARNING: modpost: vmlinux.o: section mismatch in reference: get_bar (section: .text) -> foo (section: .init.data)
    
    The reference from 'get_bar' to 'foo' seems wrong.
    
    I have no solution for this because it is true in assembly level.
    
    In the following output, relocation at 0x1c is no longer associated
    with 'bar'. The two relocation entries point to the same symbol, and
    the offset to 'bar' is encoded in the instruction 'r0, [r3, #4]'.
    
      Disassembly of section .text:
    
      00000000 <get_foo>:
         0: e59f3004          ldr     r3, [pc, #4]   @ c <get_foo+0xc>
         4: e5930000          ldr     r0, [r3]
         8: e12fff1e          bx      lr
         c: 00000000          .word   0x00000000
    
      00000010 <get_bar>:
        10: e59f3004          ldr     r3, [pc, #4]   @ 1c <get_bar+0xc>
        14: e5930004          ldr     r0, [r3, #4]
        18: e12fff1e          bx      lr
        1c: 00000000          .word   0x00000000
    
      Relocation section '.rel.text' at offset 0x244 contains 2 entries:
       Offset     Info    Type            Sym.Value  Sym. Name
      0000000c  00000c02 R_ARM_ABS32       00000000   .init.data
      0000001c  00000c02 R_ARM_ABS32       00000000   .init.data
    
    When find_elf_symbol() gets into a situation where relsym->st_name is
    zero, there is no guarantee to get the symbol name as written in C.
    
    I am keeping the current logic because it is useful in many architectures,
    but the symbol name is not always correct depending on the optimization.
    I left some comments in find_tosym().
    
    Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm")
    Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index e5aeaf72dcdb8..ad955c45d7a53 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1325,6 +1325,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
 	if (relsym->st_name != 0)
 		return relsym;
 
+	/*
+	 * Strive to find a better symbol name, but the resulting name may not
+	 * match the symbol referenced in the original code.
+	 */
 	relsym_secindex = get_secindex(elf, relsym);
 	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
 		if (get_secindex(elf, sym) != relsym_secindex)
@@ -1811,12 +1815,14 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 {
 	unsigned int r_typ = ELF_R_TYPE(r->r_info);
+	Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info);
+	void *loc = reloc_location(elf, sechdr, r);
+	uint32_t inst;
 
 	switch (r_typ) {
 	case R_ARM_ABS32:
-		/* From ARM ABI: (S + A) | T */
-		r->r_addend = (int)(long)
-			      (elf->symtab_start + ELF_R_SYM(r->r_info));
+		inst = TO_NATIVE(*(uint32_t *)loc);
+		r->r_addend = inst + sym->st_value;
 		break;
 	case R_ARM_PC24:
 	case R_ARM_CALL:



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux