mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-30 13:47:32 +00:00
[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:
parent
89ccfa1b39
commit
5421ab4625
@ -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:
|
||||
|
114
lld/test/ELF/arm-thumb-alu.s
Normal file
114
lld/test/ELF/arm-thumb-alu.s
Normal 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
|
Loading…
x
Reference in New Issue
Block a user