[lld] d56b171 - [lld][ELF] Support for R_ARM_THM_JUMP8

Petr Hosek via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 11 09:07:05 PST 2021


Author: Petr Hosek
Date: 2021-11-11T09:06:52-08:00
New Revision: d56b171ee965eba9ba30f4a479a9f2e1703105cf

URL: https://github.com/llvm/llvm-project/commit/d56b171ee965eba9ba30f4a479a9f2e1703105cf
DIFF: https://github.com/llvm/llvm-project/commit/d56b171ee965eba9ba30f4a479a9f2e1703105cf.diff

LOG: [lld][ELF] Support for R_ARM_THM_JUMP8

This change implements support for R_ARM_THM_JUMP8 relocation in
addition to R_ARM_THM_JUMP11 which is already supported by LLD.

Differential Revision: https://reviews.llvm.org/D21225

Added: 
    

Modified: 
    lld/ELF/Arch/ARM.cpp
    lld/ELF/InputSection.cpp
    lld/test/ELF/Inputs/arm-thumb-narrow-branch.o
    lld/test/ELF/Inputs/arm-thumb-narrow-branch.s
    lld/test/ELF/arm-thumb-narrow-branch-check.s
    lld/test/ELF/arm-thumb-undefined-weak-narrow.test

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index e64b0f231198a..f2e4a2a14ad6d 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -90,6 +90,7 @@ RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
   case R_ARM_THM_MOVW_ABS_NC:
   case R_ARM_THM_MOVT_ABS:
     return R_ABS;
+  case R_ARM_THM_JUMP8:
   case R_ARM_THM_JUMP11:
     return R_PC;
   case R_ARM_CALL:
@@ -520,7 +521,13 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
     checkInt(loc, val, 26, rel);
     write32le(loc, (read32le(loc) & ~0x00ffffff) | ((val >> 2) & 0x00ffffff));
     break;
+  case R_ARM_THM_JUMP8:
+    // We do a 9 bit check because val is right-shifted by 1 bit.
+    checkInt(loc, val, 9, rel);
+    write16le(loc, (read32le(loc) & 0xff00) | ((val >> 1) & 0x00ff));
+    break;
   case R_ARM_THM_JUMP11:
+    // We do a 12 bit check because val is right-shifted by 1 bit.
     checkInt(loc, val, 12, rel);
     write16le(loc, (read32le(loc) & 0xf800) | ((val >> 1) & 0x07ff));
     break;
@@ -748,6 +755,8 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
   case R_ARM_PC24:
   case R_ARM_PLT32:
     return SignExtend64<26>(read32le(buf) << 2);
+  case R_ARM_THM_JUMP8:
+    return SignExtend64<9>(read16le(buf) << 1);
   case R_ARM_THM_JUMP11:
     return SignExtend64<12>(read16le(buf) << 1);
   case R_ARM_THM_JUMP19: {

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index eafa3f3a460cf..74d4dd309c79b 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -495,6 +495,7 @@ static uint32_t getARMUndefinedRelativeWeakVA(RelType type, uint32_t a,
   switch (type) {
   // Unresolved branch relocations to weak references resolve to next
   // instruction, this will be either 2 or 4 bytes on from P.
+  case R_ARM_THM_JUMP8:
   case R_ARM_THM_JUMP11:
     return p + 2 + a;
   case R_ARM_CALL:

diff  --git a/lld/test/ELF/Inputs/arm-thumb-narrow-branch.o b/lld/test/ELF/Inputs/arm-thumb-narrow-branch.o
index 9816ec703a521..02f5671c97ace 100644
Binary files a/lld/test/ELF/Inputs/arm-thumb-narrow-branch.o and b/lld/test/ELF/Inputs/arm-thumb-narrow-branch.o 
diff er

diff  --git a/lld/test/ELF/Inputs/arm-thumb-narrow-branch.s b/lld/test/ELF/Inputs/arm-thumb-narrow-branch.s
index 473a8e64ef74b..1b2484c92dc06 100644
--- a/lld/test/ELF/Inputs/arm-thumb-narrow-branch.s
+++ b/lld/test/ELF/Inputs/arm-thumb-narrow-branch.s
@@ -1,7 +1,8 @@
 // This input must be assembled by the GNU assembler, as llvm-mc does not emit
-// the R_ARM_JUMP11 relocation for a Thumb narrow branch. This is permissible
-// by the ABI for the ARM architecture as the range of the Thumb narrow branch
-// is short enough (+- 2048 bytes) that widespread use would be impractical.
+// the R_ARM_THM_JUMP11 and R_ARM_THM_JUMP8 relocations for a Thumb narrow
+// branch. This is permissible by the ABI for the ARM architecture as the range
+// of the Thumb narrow branch is short enough (+- 2048 bytes and +- 256 bytes
+// respeticely) that widespread use would be impractical.
 //
 // The test case will use a pre compiled object arm-thumb-narrow-branch.o
  .syntax unified
@@ -15,4 +16,8 @@ callers:
  b.n callee_low
  b.n callee_high
  b.n callee_high_far
+ beq.n callee_low_near
+ beq.n callee_low
+ beq.n callee_high
+ beq.n callee_high_near
  bx lr

diff  --git a/lld/test/ELF/arm-thumb-narrow-branch-check.s b/lld/test/ELF/arm-thumb-narrow-branch-check.s
index 322978d379dc2..cd782c4c25eaa 100644
--- a/lld/test/ELF/arm-thumb-narrow-branch-check.s
+++ b/lld/test/ELF/arm-thumb-narrow-branch-check.s
@@ -2,15 +2,17 @@
 // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:          . = SIZEOF_HEADERS; \
-// RUN:          .R_ARM_PC11_1 : { *(.R_ARM_PC11_1) } \
+// RUN:          .callee_low : { *(.callee_low) } \
 // RUN:          .caller : { *(.caller) } \
-// RUN:          .R_ARM_PC11_2 : { *(.R_ARM_PC11_2) } \
+// RUN:          .callee_high : { *(.callee_high) } \
 // RUN:          .text : { *(.text) } } " > %t.script
 // RUN: ld.lld --script %t.script %t %S/Inputs/arm-thumb-narrow-branch.o -o %t2
 // RUN: llvm-objdump -d %t2 | FileCheck %s
 
-// Test the R_ARM_PC11 relocation which is used with the narrow encoding of B.N
-// the source of these relocations is a binary file arm-thumb-narrow-branch.o
+// Test the R_ARM_THM_JUMP11 and R_ARM_THM_JUMP8 relocations which are used
+// with the narrow encoding of B.N and BEQ.N.
+//
+// The source of these relocations is a binary file arm-thumb-narrow-branch.o
 // which has been assembled with the GNU assembler as llvm-mc doesn't emit it
 // as the range of +-2048 bytes is too small to be practically useful for out
 // of section branches.
@@ -20,7 +22,11 @@
 .type callee_low_far,%function
 callee_low_far = 0x809
 
- .section .R_ARM_PC11_1,"ax",%progbits
+.global callee_low_near
+.type callee_low_near,%function
+callee_low_near = 0xfff
+
+ .section .callee_low,"ax",%progbits
  .thumb
  .balign 0x1000
  .type callee_low,%function
@@ -37,7 +43,7 @@ _start:
  bl callers
  bx lr
 
- .section .R_ARM_PC11_2,"ax",%progbits
+ .section .callee_high,"ax",%progbits
  .thumb
  .align 2
  .type callee_high,%function
@@ -45,11 +51,15 @@ _start:
 callee_high:
  bx lr
 
+.global callee_high_near
+.type callee_high_near,%function
+callee_high_near = 0x10ff
+
 .global callee_high_far
 .type callee_high_far,%function
 callee_high_far = 0x180d
 
-// CHECK: Disassembly of section .R_ARM_PC11_1:
+// CHECK: Disassembly of section .callee_low:
 // CHECK-EMPTY:
 // CHECK-NEXT: <callee_low>:
 // CHECK-NEXT:    1000:       70 47   bx      lr
@@ -60,19 +70,25 @@ callee_high_far = 0x180d
 /// callee_low_far = 0x809
 // CHECK-NEXT:    1004:       00 e4   b       0x808
 // CHECK-NEXT:    1006:       fb e7   b       0x1000 <callee_low>
-// CHECK-NEXT:    1008:       02 e0   b       0x1010 <callee_high>
+// CHECK-NEXT:    1008:       06 e0   b       0x1018 <callee_high>
 /// callee_high_far = 0x180d
 // CHECK-NEXT:    100a:       ff e3   b       0x180c
-// CHECK-NEXT:    100c:       70 47   bx      lr
-// CHECK-NEXT:    100e:       00 bf   nop
+/// callee_low_near = 0xfff
+// CHECK-NEXT:    100c:       f7 d0   beq     0xffe
+// CHECK-NEXT:    100e:       f7 d0   beq     0x1000 <callee_low>
+// CHECK-NEXT:    1010:       02 d0   beq     0x1018 <callee_high>
+/// callee_high_near = 0x10ff
+// CHECK-NEXT:    1012:       74 d0   beq     0x10fe
+// CHECK-NEXT:    1014:       70 47   bx      lr
+// CHECK-NEXT:    1016:       c0 46   mov     r8, r8
 // CHECK-EMPTY:
-// CHECK-NEXT: Disassembly of section .R_ARM_PC11_2:
+// CHECK-NEXT: Disassembly of section .callee_high:
 // CHECK-EMPTY:
 // CHECK-NEXT: <callee_high>:
-// CHECK-NEXT:    1010:       70 47   bx      lr
+// CHECK-NEXT:    1018:       70 47   bx      lr
 // CHECK-EMPTY:
 // CHECK-NEXT: Disassembly of section .text:
 // CHECK-EMPTY:
 // CHECK-NEXT: <_start>:
-// CHECK-NEXT:    1014:       ff f7 f6 ff     bl      0x1004 <callers>
-// CHECK-NEXT:    1018:       70 47   bx      lr
+// CHECK-NEXT:    101c:       ff f7 f2 ff     bl      0x1004 <callers>
+// CHECK-NEXT:    1020:       70 47   bx      lr

diff  --git a/lld/test/ELF/arm-thumb-undefined-weak-narrow.test b/lld/test/ELF/arm-thumb-undefined-weak-narrow.test
index 85d2efe0cd0b5..d0b969b6147b5 100644
--- a/lld/test/ELF/arm-thumb-undefined-weak-narrow.test
+++ b/lld/test/ELF/arm-thumb-undefined-weak-narrow.test
@@ -7,11 +7,12 @@
 # CHECK-EMPTY:
 # CHECK-NEXT: <_start>:
 # CHECK-NEXT:    ff e7   b       0x200b6 <_start+0x2> @ imm = #-2
+# CHECK-NEXT:    fe d0   beq     0x200b6 <_start+0x2> @ imm = #-4
 
-# Test the R_ARM_THM_JUMP11 relocation (102) to an undefined weak reference
-# It should resolve to the next instruction, which is an offset of -2 which
-# when added to the Thumb PC-bias of 4 is +2. We can't use llvm-mc to construct
-# the object as it relaxes b.n to b.w (R_ARM_JUMP24).
+# Test the R_ARM_THM_JUMP11 (102) and R_ARM_THM_JUMP8 (103) relocations to an
+# undefined weak reference.  It should resolve to the next instruction, which
+# is an offset of -2 which when added to the Thumb PC-bias of 4 is +2. We can't
+# use llvm-mc to construct the object as it relaxes b.n to b.w (R_ARM_JUMP24).
 
 !ELF
 FileHeader:
@@ -23,7 +24,7 @@ Sections:
   - Type:            SHT_PROGBITS
     Name:            .text
     Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
-    Content:         "fee7"
+    Content:         "fee7fed0"
   - Type:            SHT_REL
     Name:            .rel.text
     Link:            .symtab
@@ -31,6 +32,8 @@ Sections:
     Relocations:
       - Symbol:          undefined_weak
         Type:            R_ARM_THM_JUMP11
+      - Symbol:          undefined_weak
+        Type:            R_ARM_THM_JUMP8
 
 Symbols:
   - Type:             STT_NOTYPE


        


More information about the llvm-commits mailing list