Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/DeveloperDocs/ARM-Relocations.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ movt r0, #:upper16:symbol @ R_ARM_THM_MOVT_ABS
| `R_ARM_THM_MOVW_BREL_NC` | `((S + A) \| T) - B(S)` | `[15:0]` | none |
| `R_ARM_THM_MOVW_BREL` | `((S + A) \| T) - B(S)` | `[15:0]` | none |
| `R_ARM_ALU_PC_G0` | `((S + A) \| T) - P` | top 8 bits, 4-bit rotation | none |
| `R_ARM_LDR_PC_G1` | `S + A - P` | imm12 (bits 11:0) | [0, 4095] |
| `R_ARM_LDR_PC_G2` | `S + A - P` | imm12 (bits 11:0) | [0, 4095] |
| `R_ARM_LDR_PC_G0` | `S + A - P` | imm12 (bits 11:0) | [0, 4095] |

Expand Down Expand Up @@ -164,7 +165,6 @@ The table below lists every relocation that ELD's ARM backend maps to the `unsup
| 59 | `R_ARM_ALU_PC_G1_NC` | Group reloc — ALU PC-relative G1, no overflow | Implement ALU_PC_G group |
| 60 | `R_ARM_ALU_PC_G1` | Group reloc — ALU PC-relative G1 | Implement ALU_PC_G group |
| 61 | `R_ARM_ALU_PC_G2` | Group reloc — ALU PC-relative G2 | Implement ALU_PC_G group |
| 62 | `R_ARM_LDR_PC_G1` | Group reloc — LDR PC-relative G1 | Implement LDR PC-group |
| 64 | `R_ARM_LDRS_PC_G0` | Group reloc — LDRD/STRD PC-relative G0 | Implement LDRS PC-group |
| 65 | `R_ARM_LDRS_PC_G1` | Group reloc — LDRD/STRD PC-relative G1 | Implement LDRS PC-group |
| 66 | `R_ARM_LDRS_PC_G2` | Group reloc — LDRD/STRD PC-relative G2 | Implement LDRS PC-group |
Expand Down
2 changes: 2 additions & 0 deletions lib/Target/ARM/ARMRelocationFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
DECL_ARM_APPLY_RELOC_FUNC(thm_jump11) \
DECL_ARM_APPLY_RELOC_FUNC(thm_jump19) \
DECL_ARM_APPLY_RELOC_FUNC(alu_pc) \
DECL_ARM_APPLY_RELOC_FUNC(ldr_pc_g1) \
DECL_ARM_APPLY_RELOC_FUNC(ldr_pc_g2) \
DECL_ARM_APPLY_RELOC_FUNC(ldr_pc_g0) \
DECL_ARM_APPLY_RELOC_FUNC(relocAddPREL1) \
Expand Down Expand Up @@ -91,6 +92,7 @@
Func(llvm::ELF::R_ARM_THM_MOVT_PREL, thm_movt_prel, "R_ARM_THM_MOVT_PREL") \
Func(llvm::ELF::R_ARM_THM_JUMP19, thm_jump19, "R_ARM_THM_JUMP19") \
Func(llvm::ELF::R_ARM_ALU_PC_G0, alu_pc, "R_ARM_ALU_PC_G0") \
Func(llvm::ELF::R_ARM_LDR_PC_G1, ldr_pc_g1, "R_ARM_LDR_PC_G1") \
Func(llvm::ELF::R_ARM_LDR_PC_G2, ldr_pc_g2, "R_ARM_LDR_PC_G2") \
Func(llvm::ELF::R_ARM_LDR_PC_G0, ldr_pc_g0, "R_ARM_LDR_PC_G0") \
Func(llvm::ELF::R_ARM_THM_MOVW_BREL_NC, thm_movw_brel, \
Expand Down
5 changes: 5 additions & 0 deletions lib/Target/ARM/ARMRelocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,11 @@ Relocator::Result ldr_pc_g0(Relocation &pReloc, ARMRelocator &pParent) {
return ldr_pc_group(pReloc, pParent, 0);
}

// R_ARM_LDR_PC_G1: S + A - P
Relocator::Result ldr_pc_g1(Relocation &pReloc, ARMRelocator &pParent) {
return ldr_pc_group(pReloc, pParent, 1);
}

// R_ARM_LDR_PC_G2: S + A - P
Relocator::Result ldr_pc_g2(Relocation &pReloc, ARMRelocator &pParent) {
return ldr_pc_group(pReloc, pParent, 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
RUN: %clang %clangopts -target %linuxtarget -fPIC -c %p/Inputs/1.c -o %t.1.o

RUN: %clang %clangopts -target %linuxtarget -c %p/Inputs/ldrpcg1.s -o %tldrpcg1.o
RUN: %not %link %linkopts %t.1.o %tldrpcg1.o -o %t.ldrpcg1.out \
RUN: %link %linkopts %t.1.o %tldrpcg1.o -o %t.ldrpcg1.out \
RUN: 2>&1 | %filecheck %s --check-prefix=INVALID

RUN: %clang %clangopts -target %linuxtarget -c %p/Inputs/thmjump8.s -o %tthmjump8.o
Expand Down
13 changes: 13 additions & 0 deletions test/ARM/standalone/Relocs/R_ARM_LDR_PC_G1/Inputs/1.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.arm

.section .text.1, "ax", %progbits
.space 0x28
.global _start
.type _start, %function
_start:
ldr r0, [r0, #0]
.reloc 0x28, R_ARM_LDR_PC_G1, dat2

.section .text.2, "ax", %progbits
dat2:
.word 0
4 changes: 4 additions & 0 deletions test/ARM/standalone/Relocs/R_ARM_LDR_PC_G1/Inputs/overflow.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SECTIONS {
.text.1 0x0800000 : AT(0x0800000) { *(.text.1) }
.text.2 0x40000000 : AT(0x40000000) { *(.text.2) }
}
4 changes: 4 additions & 0 deletions test/ARM/standalone/Relocs/R_ARM_LDR_PC_G1/Inputs/valid.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SECTIONS {
.text.1 0x1000000 : AT(0x1000000) { *(.text.1) }
.text.2 0x1001000 : AT(0x1001000) { *(.text.2) }
}
18 changes: 18 additions & 0 deletions test/ARM/standalone/Relocs/R_ARM_LDR_PC_G1/R_ARM_LDR_PC_G1.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#---R_ARM_LDR_PC_G1.test--------------------- Executable --------------------#
#BEGIN_COMMENT
# This tests that R_ARM_LDR_PC_G1 patches the LDR literal imm12 field with the
# group residual and reports overflow when that residual does not fit.
#END_COMMENT
#START_TEST
RUN: %clang %clangopts -c %p/Inputs/1.s -o %t1.1.o
RUN: %link %linkopts -march arm -T %p/Inputs/valid.t %t1.1.o -o %t2.out
RUN: %objdump -d --triple=armv7a-none-eabi %t2.out | %filecheck %s --check-prefix=VALID

RUN: %clang %clangopts -c %p/Inputs/1.s -o %t3.1.o
RUN: %not %link %linkopts -march arm -T %p/Inputs/overflow.t %t3.1.o -o %t4.out 2>&1 | %filecheck %s --check-prefix=OVERFLOW

#VALID: 01000028 <_start>:
#VALID-NEXT: 1000028: e5900008 ldr r0, [r0, #0x8]

#OVERFLOW: Error: {{.*}}3.1.o:(.text.1+0x28): relocation R_ARM_LDR_PC_G1 out of range: {{[0-9]+}} is not in [0, 4095]; references 'dat2'
#END_TEST
Loading