[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
This commit is contained in:
Petr Hosek 2021-11-09 12:35:44 -08:00
parent 893efd0d66
commit d56b171ee9
6 changed files with 56 additions and 22 deletions

View File

@ -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: {

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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