Skip to content

Commit c0944f5

Browse files
authored
[llvm][MC][ARM] Don't autoresolve fixups (#76574)
Removes logic that caused some fixups to be marked as resolved in the assembler without actually resolving them. Assembler must either resolve the fixup, reject the code (error out) or defer the resolution to the linker. In general assembler can resolve offsets in pcrel instructions if the symbol referred to is in the same section and it cannot make assumptions about relative position of sections. For example, when LDRD instruction in arm mode is encountered, fixup_arm_pcrel_10_unscaled is raised. Prior to #72873 the assembler would always mark it as resolved without generating a relocation. The resulting code would likely be incorrect whenever the label referred to is in a different section. This patch finishes the series to prevent incorrect code being generated for pcrel instructions referring to labels in different sections. This kind of assembly code is very rare and most likely a user error, so both options (relocation or error) are acceptable. In previous patches this was resolved by adding relocations. Here, for VLDR instructions an error is generated as relocation does not exist for Thumb mode and we wanted the tool's behaviour to be consistent across modes. In the LDRD case, Thumb mode does not have a relocation and errors out, but LDRD in Arm mode generates R_ARM_LDRS_PC_G0 relocation because its fixup kind is shared with other instructions. It also fixed the case when ADR is used in the big-endian mode, which is not covered by the ADR patch. Patch series: #72873 - LDRx #73834 - ADR this PR - LDRD and VLDR
1 parent add189c commit c0944f5

File tree

8 files changed

+167
-19
lines changed

8 files changed

+167
-19
lines changed

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ ARMAsmBackendELF::getFixupKind(StringRef Name) const {
6767
}
6868

6969
const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
70-
unsigned IsPCRelConstant =
71-
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_Constant;
7270
const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = {
7371
// This table *must* be in the order that the fixup_* kinds are defined in
7472
// ARMFixupKinds.h.
@@ -79,13 +77,14 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
7977
MCFixupKindInfo::FKF_IsPCRel |
8078
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
8179
{"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
82-
{"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
80+
{"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
8381
{"fixup_t2_pcrel_10", 0, 32,
8482
MCFixupKindInfo::FKF_IsPCRel |
8583
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
8684
{"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
8785
{"fixup_t2_pcrel_9", 0, 32,
88-
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
86+
MCFixupKindInfo::FKF_IsPCRel |
87+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
8988
{"fixup_arm_ldst_abs_12", 0, 32, 0},
9089
{"fixup_thumb_adr_pcrel_10", 0, 8,
9190
MCFixupKindInfo::FKF_IsPCRel |
@@ -140,19 +139,22 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
140139
MCFixupKindInfo::FKF_IsPCRel |
141140
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
142141
{"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
143-
{"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
142+
{"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
144143
{"fixup_t2_pcrel_10", 0, 32,
145144
MCFixupKindInfo::FKF_IsPCRel |
146145
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
147146
{"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
148147
{"fixup_t2_pcrel_9", 0, 32,
149-
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
148+
MCFixupKindInfo::FKF_IsPCRel |
149+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
150150
{"fixup_arm_ldst_abs_12", 0, 32, 0},
151151
{"fixup_thumb_adr_pcrel_10", 8, 8,
152-
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
153-
{"fixup_arm_adr_pcrel_12", 0, 32, IsPCRelConstant},
152+
MCFixupKindInfo::FKF_IsPCRel |
153+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
154+
{"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
154155
{"fixup_t2_adr_pcrel_12", 0, 32,
155-
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
156+
MCFixupKindInfo::FKF_IsPCRel |
157+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
156158
{"fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
157159
{"fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
158160
{"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},

llvm/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ enum Fixups {
2828
// immediate).
2929
fixup_arm_pcrel_10,
3030
// Equivalent to fixup_arm_pcrel_10, accounting for the short-swapped encoding
31-
// of Thumb2 instructions.
31+
// of Thumb2 instructions. Also used by LDRD in Thumb mode.
3232
fixup_t2_pcrel_10,
3333
// 9-bit PC relative relocation for symbol addresses used in VFP instructions
3434
// where bit 0 not encoded (so it's encoded as an 8-bit immediate).

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,14 @@
77
@ CHECK: There are no relocations in this file.
88

99
@ DISASM-LABEL: <bar>:
10-
@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x8 <bar+0x4>
10+
@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x4 <bar+0x4>
1111
@ DISASM-NEXT: add r0, pc
1212
@ DISASM-NEXT: .word 0xfffffffb
1313
@@ GNU assembler creates an R_ARM_REL32 referencing bar.
1414
@ DISASM-NOT: {{.}}
1515

1616
.syntax unified
1717

18-
.globl foo
19-
foo:
20-
vldr d0, foo @ arm_pcrel_10
21-
2218
.thumb
2319
.thumb_func
2420
.type bar, %function

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434
.global bar
3535
.type bar, %function
3636
bar:
37-
ldr r0, foo1
38-
ldrb r0, foo1
39-
ldr r0, foo2-8
40-
ldrb r0, foo1+8
37+
ldr r0, foo1 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
38+
ldrb r0, foo1 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
39+
ldr r0, foo2-8 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
40+
ldrb r0, foo1+8 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
4141
bx lr
4242

4343
.section .data.foo, "a", %progbits
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@ RUN: not llvm-mc -filetype=obj --defsym=ERR=1 -o /dev/null %s 2>&1 -triple=thumbv7 | FileCheck %s --check-prefix=ERR
2+
@ RUN: not llvm-mc -filetype=obj --defsym=ERR=1 -o /dev/null %s 2>&1 -triple=thumbebv7 | FileCheck %s --check-prefix=ERR
3+
@ RUN: llvm-mc -filetype=obj -triple=armv7 %s -o %t
4+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
5+
@ RUN: llvm-objdump -d --triple=armv7 %t | FileCheck %s --check-prefix=ARM_ADDEND
6+
@ RUN: llvm-mc -filetype=obj -triple=armebv7 %s -o %t
7+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
8+
@ RUN: llvm-objdump -d --triple=armebv7 %t | FileCheck %s --check-prefix=ARM_ADDEND
9+
10+
.section .text.bar, "ax"
11+
.balign 4
12+
.global bar
13+
.type bar, %function
14+
15+
bar:
16+
ldrd r0, r1, foo1 @ arm_pcrel_10_unscaled
17+
ldrd r0, r1, foo2-8 @ arm_pcrel_10_unscaled
18+
.ifdef ERR
19+
@ ERR:[[#@LINE-3]]:5: error: unsupported relocation type
20+
@ ERR:[[#@LINE-3]]:5: error: unsupported relocation type
21+
.endif
22+
bx lr
23+
24+
.section .data.foo, "a", %progbits
25+
.balign 4
26+
.global foo1
27+
.global foo2
28+
foo1:
29+
.word 0x11223344, 0x55667788
30+
foo2:
31+
.word 0x99aabbcc, 0xddeeff00
32+
33+
@ ARM: R_ARM_LDRS_PC_G0
34+
35+
@ ARM_ADDEND: ldrd r0, r1, [pc, #-8]
36+
@ ARM_ADDEND: ldrd r0, r1, [pc, #-16]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armv7
2+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
3+
@ RUN: llvm-objdump -d --triple=armv7 %t | FileCheck %s --check-prefix=ARM_OFFSET
4+
5+
@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armebv7
6+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
7+
@ RUN: llvm-objdump -d --triple=armebv7 %t | FileCheck %s --check-prefix=ARM_OFFSET
8+
9+
@ RUN: llvm-mc -filetype=obj -o %t %s -triple=thumbv7
10+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
11+
@ RUN: llvm-objdump -d --triple=thumbv7 %t | FileCheck %s --check-prefix=THUMB_OFFSET
12+
13+
@ RUN: llvm-mc -filetype=obj -o %y %s -triple=thumbebv7
14+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
15+
@ RUN: llvm-objdump -d --triple=thumbebv7 %t | FileCheck %s --check-prefix=THUMB_OFFSET
16+
17+
baz:
18+
.word 0x11223344, 0x55667788
19+
label:
20+
21+
ldrd r0, r1, foo @ arm_pcrel_10_unscaled / t2_pcrel_10
22+
ldrd r0, r1, bar-8 @ arm_pcrel_10_unscaled / t2_pcrel_10
23+
24+
ldrd r0, r1, baz @ arm_pcrel_10_unscaled / t2_pcrel_10
25+
ldrd r0, r1, label-8 @ arm_pcrel_10_unscaled / t2_pcrel_10
26+
foo:
27+
.word 0x11223344, 0x55667788
28+
bar:
29+
30+
@ RELOC: There are no relocations in this file.
31+
32+
@ ARM_OFFSET: ldrd r0, r1, [pc, #8] @ 0x18 <foo>
33+
@ ARM_OFFSET: ldrd r0, r1, [pc, #4] @ 0x18 <foo>
34+
@ ARM_OFFSET: ldrd r0, r1, [pc, #-24] @ 0x0 <baz>
35+
@ ARM_OFFSET: ldrd r0, r1, [pc, #-28] @ 0x0 <baz>
36+
@ THUMB_OFFSET: ldrd r0, r1, [pc, #12] @ 0x18 <foo>
37+
@ THUMB_OFFSET: ldrd r0, r1, [pc, #8] @ 0x18 <foo>
38+
@ THUMB_OFFSET: ldrd r0, r1, [pc, #-20] @ 0x0 <baz>
39+
@ THUMB_OFFSET: ldrd r0, r1, [pc, #-24] @ 0x0 <baz>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=armv8.2a-eabi | FileCheck %s
2+
@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=armebv8.2a-eabi | FileCheck %s
3+
@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=thumbv8.2a-eabi | FileCheck %s
4+
@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=thumbebv8.2a-eabi | FileCheck %s
5+
6+
.arch_extension fp16
7+
8+
vldr s0, foo @ arm_pcrel_10 / t2_pcrel_10
9+
vldr d0, foo @ arm_pcrel_10 / t2_pcrel_10
10+
vldr.16 s0,foo @ arm_pcrel_9 / t2_pcrel_9
11+
12+
@ CHECK: :[[#@LINE-4]]:1: error: unsupported relocation type
13+
@ CHECK: :[[#@LINE-4]]:1: error: unsupported relocation type
14+
@ CHECK: :[[#@LINE-4]]:1: error: unsupported relocation type
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armv8.2a-eabi
2+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
3+
@ RUN: llvm-objdump -d --triple=armv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=ARM_OFFSET
4+
@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armebv8.2a-eabi
5+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
6+
@ RUN: llvm-objdump -d --triple=armebv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=ARM_OFFSET
7+
@ RUN: llvm-mc -filetype=obj -o %t %s -triple=thumbv8.2a-eabi
8+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
9+
@ RUN: llvm-objdump -d --triple=thumbv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=THUMB_OFFSET
10+
@ RUN: llvm-mc -filetype=obj -o %y %s -triple=thumbebv8.2a-eabi
11+
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
12+
@ RUN: llvm-objdump -d --triple=thumbebv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=THUMB_OFFSET
13+
14+
.arch_extension fp16
15+
baz:
16+
.word 0x11223344, 0x55667788
17+
label:
18+
19+
vldr s0, foo @ arm_pcrel_10 / t2_pcrel_10
20+
vldr d0, foo @ arm_pcrel_10 / t2_pcrel_10
21+
vldr.16 s0, foo @ arm_pcrel_9 / t2_pcrel_9
22+
vldr s0, bar-8
23+
vldr d0, bar-8
24+
vldr.16 s0, bar-8
25+
vldr s0, baz
26+
vldr d0, baz
27+
vldr.16 s0, baz
28+
vldr s0, label-8
29+
vldr d0, label-8
30+
vldr.16 s0, label-8
31+
32+
foo:
33+
.word 0x11223344, 0x55667788
34+
bar:
35+
36+
@ RELOC: There are no relocations in this file.
37+
38+
@ ARM_OFFSET: vldr s0, [pc, #40] @ 0x38 <foo>
39+
@ ARM_OFFSET: vldr d0, [pc, #36] @ 0x38 <foo>
40+
@ ARM_OFFSET: vldr.16 s0, [pc, #32] @ 0x38 <foo>
41+
@ ARM_OFFSET: vldr s0, [pc, #28] @ 0x38 <foo>
42+
@ ARM_OFFSET: vldr d0, [pc, #24] @ 0x38 <foo>
43+
@ ARM_OFFSET: vldr.16 s0, [pc, #20] @ 0x38 <foo>
44+
@ ARM_OFFSET: vldr s0, [pc, #-40] @ 0x0 <baz>
45+
@ ARM_OFFSET: vldr d0, [pc, #-44] @ 0x0 <baz>
46+
@ ARM_OFFSET: vldr.16 s0, [pc, #-48] @ 0x0 <baz>
47+
@ ARM_OFFSET: vldr s0, [pc, #-52] @ 0x0 <baz>
48+
@ ARM_OFFSET: vldr d0, [pc, #-56] @ 0x0 <baz>
49+
@ ARM_OFFSET: vldr.16 s0, [pc, #-60] @ 0x0 <baz>
50+
@ THUMB_OFFSET: vldr s0, [pc, #44] @ 0x38 <foo>
51+
@ THUMB_OFFSET: vldr d0, [pc, #40] @ 0x38 <foo>
52+
@ THUMB_OFFSET: vldr.16 s0, [pc, #36] @ 0x38 <foo>
53+
@ THUMB_OFFSET: vldr s0, [pc, #32] @ 0x38 <foo>
54+
@ THUMB_OFFSET: vldr d0, [pc, #28] @ 0x38 <foo>
55+
@ THUMB_OFFSET: vldr.16 s0, [pc, #24] @ 0x38 <foo>
56+
@ THUMB_OFFSET: vldr s0, [pc, #-36] @ 0x0 <baz>
57+
@ THUMB_OFFSET: vldr d0, [pc, #-40] @ 0x0 <baz>
58+
@ THUMB_OFFSET: vldr.16 s0, [pc, #-44] @ 0x0 <baz>
59+
@ THUMB_OFFSET: vldr s0, [pc, #-48] @ 0x0 <baz>
60+
@ THUMB_OFFSET: vldr d0, [pc, #-52] @ 0x0 <baz>
61+
@ THUMB_OFFSET: vldr.16 s0, [pc, #-56] @ 0x0 <baz>

0 commit comments

Comments
 (0)