[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