[lld][ARM] Add support for 16-bit thumb group relocations

This adds support for the following relocations:
 * R_ARM_THM_ALU_ABS_G0_NC
 * R_ARM_THM_ALU_ABS_G1_NC
 * R_ARM_THM_ALU_ABS_G2_NC
 * R_ARM_THM_ALU_ABS_G3
as defined in:
https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#5615static-thumb16-relocations

Differential Revision: https://reviews.llvm.org/D153407
This commit is contained in:
John Brawn 2023-06-12 16:43:12 +01:00
parent 89ccfa1b39
commit 5421ab4625
2 changed files with 135 additions and 0 deletions

View File

@ -100,6 +100,10 @@ RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
case R_ARM_MOVT_ABS:
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_ALU_ABS_G0_NC:
case R_ARM_THM_ALU_ABS_G1_NC:
case R_ARM_THM_ALU_ABS_G2_NC:
case R_ARM_THM_ALU_ABS_G3:
return R_ABS;
case R_ARM_THM_JUMP8:
case R_ARM_THM_JUMP11:
@ -681,6 +685,18 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
((val << 4) & 0x7000) | // imm3
(val & 0x00ff)); // imm8
break;
case R_ARM_THM_ALU_ABS_G3:
write16(loc, (read16(loc) &~ 0x00ff) | ((val >> 24) & 0x00ff));
break;
case R_ARM_THM_ALU_ABS_G2_NC:
write16(loc, (read16(loc) &~ 0x00ff) | ((val >> 16) & 0x00ff));
break;
case R_ARM_THM_ALU_ABS_G1_NC:
write16(loc, (read16(loc) &~ 0x00ff) | ((val >> 8) & 0x00ff));
break;
case R_ARM_THM_ALU_ABS_G0_NC:
write16(loc, (read16(loc) &~ 0x00ff) | (val & 0x00ff));
break;
case R_ARM_ALU_PC_G0:
encodeAluGroup(loc, rel, val, 0, true);
break;
@ -858,6 +874,11 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
((lo & 0x7000) >> 4) | // imm3
(lo & 0x00ff)); // imm8
}
case R_ARM_THM_ALU_ABS_G0_NC:
case R_ARM_THM_ALU_ABS_G1_NC:
case R_ARM_THM_ALU_ABS_G2_NC:
case R_ARM_THM_ALU_ABS_G3:
return read16(buf) & 0xff;
case R_ARM_ALU_PC_G0:
case R_ARM_ALU_PC_G0_NC:
case R_ARM_ALU_PC_G1:

View File

@ -0,0 +1,114 @@
// REQUIRES: arm
// RUN: split-file %s %t
// RUN: llvm-mc -filetype=obj -triple=thumbv6m-unknown-linux-gnueabi %t/asm -o %t.o
// RUN: ld.lld --script %t/lds %t.o -o %t2
// RUN: llvm-objdump -d %t2 --triple=thumbv6m-unknown-linux-gnueabi --no-show-raw-insn | FileCheck %s
//--- lds
SECTIONS {
.tests 0x00001000 : AT(0x00001000) { *(.tests) }
.sym1 0x11223344 : AT(0x11223344) { *(.sym1) }
.sym2 0x00ffffff : AT(0x00ffffff) { *(.sym2) }
.fn 0x55667788 : AT(0x55667788) { *(.fn) }
}
//--- asm
.section .tests, "ax", %progbits
// CHECK-LABEL: <R_ARM_THM_ALU_ABS_G0_NC>:
// CHECK: adds r0, #0x44
// CHECK-NEXT: movs r0, #0x44
// CHECK-NEXT: movs r0, #0x45
// CHECK-NEXT: movs r0, #0x43
// CHECK-NEXT: movs r0, #0xff
// CHECK-NEXT: movs r0, #0x0
// CHECK-NEXT: movs r0, #0xfe
// CHECK-NEXT: movs r0, #0x89
// CHECK-NEXT: movs r0, #0x8b
R_ARM_THM_ALU_ABS_G0_NC:
adds r0, :lower0_7:sym1
movs r0, :lower0_7:sym1
movs r0, :lower0_7:sym1+1
movs r0, :lower0_7:sym1+0xff
movs r0, :lower0_7:sym2
movs r0, :lower0_7:sym2+1
movs r0, :lower0_7:sym2+0xff
movs r0, :lower0_7:fn
movs r0, :lower0_7:fn+2
// CHECK-LABEL: <R_ARM_THM_ALU_ABS_G1_NC>:
// CHECK: adds r0, #0x33
// CHECK-NEXT: movs r0, #0x33
// CHECK-NEXT: movs r0, #0x33
// CHECK-NEXT: movs r0, #0x34
// CHECK-NEXT: movs r0, #0xff
// CHECK-NEXT: movs r0, #0x0
// CHECK-NEXT: movs r0, #0x0
// CHECK-NEXT: movs r0, #0x77
// CHECK-NEXT: movs r0, #0x77
R_ARM_THM_ALU_ABS_G1_NC:
adds r0, :lower8_15:sym1
movs r0, :lower8_15:sym1
movs r0, :lower8_15:sym1+1
movs r0, :lower8_15:sym1+0xff
movs r0, :lower8_15:sym2
movs r0, :lower8_15:sym2+1
movs r0, :lower8_15:sym2+0xff
movs r0, :lower8_15:fn
movs r0, :lower8_15:fn+2
// CHECK-LABEL: <R_ARM_THM_ALU_ABS_G2_NC>:
// CHECK: adds r0, #0x22
// CHECK-NEXT: movs r0, #0x22
// CHECK-NEXT: movs r0, #0x22
// CHECK-NEXT: movs r0, #0x22
// CHECK-NEXT: movs r0, #0xff
// CHECK-NEXT: movs r0, #0x0
// CHECK-NEXT: movs r0, #0x0
// CHECK-NEXT: movs r0, #0x66
// CHECK-NEXT: movs r0, #0x66
R_ARM_THM_ALU_ABS_G2_NC:
adds r0, :upper0_7:sym1
movs r0, :upper0_7:sym1
movs r0, :upper0_7:sym1+1
movs r0, :upper0_7:sym1+0xff
movs r0, :upper0_7:sym2
movs r0, :upper0_7:sym2+1
movs r0, :upper0_7:sym2+0xff
movs r0, :upper0_7:fn
movs r0, :upper0_7:fn+2
// CHECK-LABEL: <R_ARM_THM_ALU_ABS_G3>:
// CHECK: adds r0, #0x11
// CHECK-NEXT: movs r0, #0x11
// CHECK-NEXT: movs r0, #0x11
// CHECK-NEXT: movs r0, #0x11
// CHECK-NEXT: movs r0, #0x0
// CHECK-NEXT: movs r0, #0x1
// CHECK-NEXT: movs r0, #0x1
// CHECK-NEXT: movs r0, #0x55
// CHECK-NEXT: movs r0, #0x55
R_ARM_THM_ALU_ABS_G3:
adds r0, :upper8_15:sym1
movs r0, :upper8_15:sym1
movs r0, :upper8_15:sym1+1
movs r0, :upper8_15:sym1+0xff
movs r0, :upper8_15:sym2
movs r0, :upper8_15:sym2+1
movs r0, :upper8_15:sym2+0xff
movs r0, :upper8_15:fn
movs r0, :upper8_15:fn+2
.section .sym1, "aw", %progbits
sym1:
.byte 0
.section .sym2, "aw", %progbits
sym2:
.byte 0
.section .fn, "ax", %progbits
.thumb_func
fn:
bx lr