1. 03 Jun, 2023 1 commit
    • Masahiro Yamada's avatar
      modpost: detect section mismatch for R_ARM_THM_{MOVW_ABS_NC,MOVT_ABS} · cd1824fb
      Masahiro Yamada authored
      When CONFIG_THUMB2_KERNEL is enabled, modpost fails to detect some
      types of section mismatches.
      
        [test code]
      
          #include <linux/init.h>
      
          int __initdata foo;
          int get_foo(void) { return foo; }
      
      It is apparently a bad reference, but modpost does not report anything.
      
      The test code above produces the following relocations.
      
        Relocation section '.rel.text' at offset 0x1e8 contains 2 entries:
         Offset     Info    Type            Sym.Value  Sym. Name
        00000000  0000052f R_ARM_THM_MOVW_AB 00000000   .LANCHOR0
        00000004  00000530 R_ARM_THM_MOVT_AB 00000000   .LANCHOR0
      
      Currently, R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS are just skipped.
      
      Add code to handle them. I checked arch/arm/kernel/module.c to learn
      how the offset is encoded in the instruction.
      
      One more thing to note for Thumb instructions - the st_value is an odd
      value, so you need to mask the bit 0 to get the offset. Otherwise, you
      will get an off-by-one error in the nearest symbol look-up.
      
      It is documented in "ELF for the ARM Architecture" [1]:
      
        In addition to the normal rules for symbol values the following rules
        shall also apply to symbols of type STT_FUNC:
      
         * If the symbol addresses an Arm instruction, its value is the
           address of the instruction (in a relocatable object, the offset
           of the instruction from the start of the section containing it).
      
         * If the symbol addresses a Thumb instruction, its value is the
           address of the instruction with bit zero set (in a relocatable
           object, the section offset with bit zero set).
      
         * For the purposes of relocation the value used shall be the address
           of the instruction (st_value & ~1).
      
      [1]: https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rstSigned-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      cd1824fb
  2. 02 Jun, 2023 4 commits
    • Masahiro Yamada's avatar
      modpost: refactor find_fromsym() and find_tosym() · b1a9651d
      Masahiro Yamada authored
      find_fromsym() and find_tosym() are similar - both of them iterate
      in the .symtab section and return the nearest symbol.
      
      The difference between them is that find_tosym() allows a negative
      distance, but the distance must be less than 20.
      
      Factor out the common part into find_nearest_sym().
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      Reviewed-by: default avatarNick Desaulniers <ndesaulniers@google.com>
      b1a9651d
    • Masahiro Yamada's avatar
      modpost: detect section mismatch for R_ARM_{MOVW_ABS_NC,MOVT_ABS} · 12ca2c67
      Masahiro Yamada authored
      For ARM defconfig (i.e. multi_v7_defconfig), modpost fails to detect
      some types of section mismatches.
      
        [test code]
      
          #include <linux/init.h>
      
          int __initdata foo;
          int get_foo(void) { return foo; }
      
      It is apparently a bad reference, but modpost does not report anything.
      
      The test code above produces the following relocations.
      
        Relocation section '.rel.text' at offset 0x200 contains 2 entries:
         Offset     Info    Type            Sym.Value  Sym. Name
        00000000  0000062b R_ARM_MOVW_ABS_NC 00000000   .LANCHOR0
        00000004  0000062c R_ARM_MOVT_ABS    00000000   .LANCHOR0
      
      Currently, R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS are just skipped.
      
      Add code to handle them. I checked arch/arm/kernel/module.c to learn
      how the offset is encoded in the instruction.
      
      The referenced symbol in relocation might be a local anchor.
      If is_valid_name() returns false, let's search for a better symbol name.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      12ca2c67
    • Masahiro Yamada's avatar
      modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24} · 56a24b8c
      Masahiro Yamada authored
      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: 56a974fa ("kbuild: make better section mismatch reports on arm")
      Fixes: 6e2e340b ("ARM: 7324/1: modpost: Fix section warnings for ARM for many compilers")
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      56a24b8c
    • Masahiro Yamada's avatar
      modpost: fix section mismatch message for R_ARM_ABS32 · b7c63520
      Masahiro Yamada authored
      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: 56a974fa ("kbuild: make better section mismatch reports on arm")
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      b7c63520
  3. 28 May, 2023 10 commits
  4. 22 May, 2023 14 commits
  5. 14 May, 2023 11 commits