Skip to content

Commit d044349

Browse files
committed
[llvm][MC][ARM][Assembly] Emit relocations for ADRs and big-endian targets
Follow-up on #72873 When ADR/LDR instructions reference a label in a different section, the offset is not known until link time, however, the assembler assumes it can resolve them in some cases. The previous patch addressed the issue for most LDR instructions, focusing on little-endian targets. This patch addresses the remaining work for ADRs and big-endian targets.
1 parent 6976dac commit d044349

File tree

9 files changed

+80
-17
lines changed

9 files changed

+80
-17
lines changed

llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,12 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
8888
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
8989
{"fixup_arm_ldst_abs_12", 0, 32, 0},
9090
{"fixup_thumb_adr_pcrel_10", 0, 8,
91-
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
92-
{"fixup_arm_adr_pcrel_12", 0, 32, IsPCRelConstant},
91+
MCFixupKindInfo::FKF_IsPCRel |
92+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
93+
{"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
9394
{"fixup_t2_adr_pcrel_12", 0, 32,
94-
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
95+
MCFixupKindInfo::FKF_IsPCRel |
96+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
9597
{"fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
9698
{"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
9799
{"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
@@ -133,10 +135,11 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
133135
// ARMFixupKinds.h.
134136
//
135137
// Name Offset (bits) Size (bits) Flags
136-
{"fixup_arm_ldst_pcrel_12", 0, 32, IsPCRelConstant},
138+
{"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
137139
{"fixup_t2_ldst_pcrel_12", 0, 32,
138-
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
139-
{"fixup_arm_pcrel_10_unscaled", 0, 32, IsPCRelConstant},
140+
MCFixupKindInfo::FKF_IsPCRel |
141+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
142+
{"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
140143
{"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
141144
{"fixup_t2_pcrel_10", 0, 32,
142145
MCFixupKindInfo::FKF_IsPCRel |

llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
164164
return ELF::R_ARM_LDRS_PC_G0;
165165
case ARM::fixup_t2_ldst_pcrel_12:
166166
return ELF::R_ARM_THM_PC12;
167+
case ARM::fixup_arm_adr_pcrel_12:
168+
return ELF::R_ARM_ALU_PC_G0;
169+
case ARM::fixup_thumb_adr_pcrel_10:
170+
return ELF::R_ARM_THM_PC8;
171+
case ARM::fixup_t2_adr_pcrel_12:
172+
return ELF::R_ARM_THM_ALU_PREL_11_0;
167173
case ARM::fixup_bf_target:
168174
return ELF::R_ARM_THM_BF16;
169175
case ARM::fixup_bfc_target:

llvm/test/MC/ARM/pcrel-adr16-relocs.s

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@ RUN: llvm-mc -filetype=obj --triple=thumbv6m-none-eabi %s -o %t
2+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
3+
@ RUN: llvm-objdump -d --triple=thumbv6m-none-eabi %t | FileCheck %s --check-prefix=ADDEND
4+
5+
.section .text._func1, "ax"
6+
7+
.balign 4
8+
.global _func1
9+
.type _func1, %function
10+
_func1:
11+
adr r0, _func2
12+
@ RELOC: R_ARM_THM_PC8
13+
bx lr
14+
15+
// Checking the encoding only, as the disassembly is not quite correct here.
16+
17+
// Thumb16 encoding supports only adding of the encoded immediate (not
18+
// subtracting, see [Arm ARM]), therefore sign change is required if the pcrel
19+
// offset is negative. This makes the calculation of the addend for
20+
// R_ARM_THM_PC8 more complex, for details see [ELF for the Arm 32-bit
21+
// architecture].
22+
@ ADDEND: a0ff
23+

llvm/test/MC/ARM/pcrel-adr32-relocs.s

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
@ RUN: llvm-mc -filetype=obj -triple=armv7 %s -o %t
2+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
3+
@ RUN: llvm-objdump -d --triple=armv7 %t | FileCheck %s --check-prefix=ADDEND
4+
5+
@ RUN: llvm-mc -filetype=obj --triple=armebv7-unknown-unknown %s -o %t
6+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
7+
@ RUN: llvm-objdump -d --triple=armebv7-unknown-unknown %t | FileCheck %s --check-prefix=ADDEND
8+
9+
.section .text._func1, "ax"
10+
11+
.balign 4
12+
.global _func1
13+
.type _func1, %function
14+
_func1:
15+
adr r0, _func2
16+
@ RELOC: R_ARM_ALU_PC_G0
17+
.thumb
18+
adr r0, _func2
19+
@ RELOC: R_ARM_THM_ALU_PREL_11_0
20+
bx lr
21+
22+
@ ADDEND: sub r0, pc, #8
23+
@ ADDEND-NEXT: adr.w r0, #-4
24+
25+

llvm/test/MC/ARM/pcrel-arm-ldr-imm8-relocs.s

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
@ RUN: llvm-mc -filetype=obj -triple=armv7 %s -o %t
22
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
33
@ RUN: llvm-objdump -d --triple=armv7 %t | FileCheck %s --check-prefix=ARM_ADDEND
4+
@ RUN: llvm-mc -filetype=obj --triple=armebv7-unknown-unknown %s -o %t
5+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
6+
@ RUN: llvm-objdump -d --triple=armebv7-unknown-unknown %t | FileCheck %s --check-prefix=ARM_ADDEND
47

58
@ ARM: R_ARM_LDRS_PC_G0
69
@ ARM: R_ARM_LDRS_PC_G0
710
@ ARM: R_ARM_LDRS_PC_G0
811
@ ARM: R_ARM_LDRS_PC_G0
912
@ ARM: R_ARM_LDRS_PC_G0
1013
@ ARM: R_ARM_LDRS_PC_G0
14+
@ ARM: R_ARM_LDRS_PC_G0
1115

1216
// The value format is decimal in these specific cases, but it's hex for other
1317
// ldr instructions. These checks are valid for both formats.
@@ -18,6 +22,7 @@
1822
@ ARM_ADDEND: r0, [pc, #-{{16|0x10}}]
1923
@ ARM_ADDEND: r0, [pc, #-{{16|0x10}}]
2024
@ ARM_ADDEND: r0, [pc]
25+
@ ARM_ADDEND: r0, r1, [pc]
2126

2227
.arm
2328
.section .text.bar, "ax"
@@ -31,6 +36,7 @@ bar:
3136
ldrh r0, just_after-8
3237
ldrsb r0, just_after-8
3338
ldrsh r0, foo+8
39+
ldrd r0,r1, foo+8
3440
bx lr
3541

3642
.section .data.foo, "a", %progbits

llvm/test/MC/ARM/pcrel-global.s

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
@ CHECK: There are no relocations in this file.
88

99
@ DISASM-LABEL: <bar>:
10-
@ DISASM-NEXT: adr.w r0, #-4
11-
@ DISASM-NEXT: adr.w r0, #-8
12-
@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x14 <bar+0xc>
10+
@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x8 <bar+0x4>
1311
@ DISASM-NEXT: add r0, pc
14-
@ DISASM-NEXT: .word 0xfffffff3
12+
@ DISASM-NEXT: .word 0xfffffffb
1513
@@ GNU assembler creates an R_ARM_REL32 referencing bar.
1614
@ DISASM-NOT: {{.}}
1715

@@ -20,16 +18,12 @@
2018
.globl foo
2119
foo:
2220
vldr d0, foo @ arm_pcrel_10
23-
adr r2, foo @ arm_adr_pcrel_12
2421

2522
.thumb
2623
.thumb_func
2724
.type bar, %function
2825
.globl bar
2926
bar:
30-
adr r0, bar @ thumb_adr_pcrel_10
31-
adr.w r0, bar @ t2_adr_pcrel_12
32-
3327
ldr r0, .LCPI
3428
.LPC0_1:
3529
add r0, pc

llvm/test/MC/ARM/pcrel-ldr-relocs.s

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
@ RUN: llvm-mc -filetype=obj -triple=thumbv7 %s -o %t
55
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
66
@ RUN: llvm-objdump -d --triple=thumbv7 %t | FileCheck %s --check-prefix=THUMB_ADDEND
7+
@ RUN: llvm-mc -filetype=obj -triple=armebv7 %s -o %t
8+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
9+
@ RUN: llvm-objdump -d --triple=armebv7 %t | FileCheck %s --check-prefix=ARM_ADDEND
10+
@ RUN: llvm-mc -filetype=obj -triple=thumbebv7 %s -o %t
11+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
12+
@ RUN: llvm-objdump -d --triple=thumbebv7 %t | FileCheck %s --check-prefix=THUMB_ADDEND
713

814
@ ARM: R_ARM_LDR_PC_G0
915
@ ARM: R_ARM_LDR_PC_G0
1016
@ ARM: R_ARM_LDR_PC_G0
1117
@ ARM: R_ARM_LDR_PC_G0
12-
1318
@ ARM_ADDEND: r0, [pc, #-0x8]
1419
@ ARM_ADDEND: r0, [pc, #-0x8]
1520
@ ARM_ADDEND: r0, [pc, #-0x10]
@@ -19,7 +24,6 @@
1924
@ THUMB: R_ARM_THM_PC12
2025
@ THUMB: R_ARM_THM_PC12
2126
@ THUMB: R_ARM_THM_PC12
22-
2327
@ THUMB_ADDEND: r0, [pc, #-0x4]
2428
@ THUMB_ADDEND: r0, [pc, #-0x4]
2529
@ THUMB_ADDEND: r0, [pc, #-0xc]

llvm/test/MC/ARM/pcrel-thumb-ldr2-relocs.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
@ RUN: llvm-mc -filetype=obj -triple=thumbv7 %s -o %t
22
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
33
@ RUN: llvm-objdump -d --triple=thumbv7 %t | FileCheck %s --check-prefix=THUMB_ADDEND
4+
@ RUN: llvm-mc -filetype=obj --triple=thumbebv7-unknown-unknown %s -o %t
5+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
6+
@ RUN: llvm-objdump -d --triple=thumbebv7-unknown-unknown %t | FileCheck %s --check-prefix=THUMB_ADDEND
47

58
@ All the ldr variants produce a relocation
69
@ THUMB: R_ARM_THM_PC12

llvm/test/MC/ARM/thumb1-relax-adr.s

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
22
@ RUN: not llvm-mc -triple thumbv7m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
3-
@ RUN: not llvm-mc -triple thumbv7m-none-eabi -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
43

54
.global func1
65
_func1:

0 commit comments

Comments
 (0)