aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEleanor Bonnici <eleanor.bonnici@arm.com>2024-01-15 18:41:11 +0000
committerGitHub <noreply@github.com>2024-01-15 18:41:11 +0000
commitc0944f52c17a30762b81446183967ce3ef6b9aed (patch)
tree2728e93091c06a6c63d5f84c79e7f145e4e95593
parentadd189cdf01e92ca30687291a98e936b7706ee38 (diff)
downloadllvm-c0944f52c17a30762b81446183967ce3ef6b9aed.zip
llvm-c0944f52c17a30762b81446183967ce3ef6b9aed.tar.gz
llvm-c0944f52c17a30762b81446183967ce3ef6b9aed.tar.bz2
[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 https://github.com/llvm/llvm-project/pull/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: https://github.com/llvm/llvm-project/pull/72873 - LDRx https://github.com/llvm/llvm-project/pull/73834 - ADR this PR - LDRD and VLDR
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp20
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h2
-rw-r--r--llvm/test/MC/ARM/pcrel-global.s6
-rw-r--r--llvm/test/MC/ARM/pcrel-ldr-relocs.s8
-rw-r--r--llvm/test/MC/ARM/pcrel-ldrd-diff-section.s36
-rw-r--r--llvm/test/MC/ARM/pcrel-ldrd-same-section.s39
-rw-r--r--llvm/test/MC/ARM/pcrel-vldr-diff-section.s14
-rw-r--r--llvm/test/MC/ARM/pcrel-vldr-same-section.s61
8 files changed, 167 insertions, 19 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 534434f..1d17bb3 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -67,8 +67,6 @@ ARMAsmBackendELF::getFixupKind(StringRef Name) const {
}
const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
- unsigned IsPCRelConstant =
- MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_Constant;
const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = {
// This table *must* be in the order that the fixup_* kinds are defined in
// ARMFixupKinds.h.
@@ -79,13 +77,14 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
- {"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
+ {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_pcrel_10", 0, 32,
MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_pcrel_9", 0, 32,
- IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_ldst_abs_12", 0, 32, 0},
{"fixup_thumb_adr_pcrel_10", 0, 8,
MCFixupKindInfo::FKF_IsPCRel |
@@ -140,19 +139,22 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
- {"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
+ {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_pcrel_10", 0, 32,
MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_pcrel_9", 0, 32,
- IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_ldst_abs_12", 0, 32, 0},
{"fixup_thumb_adr_pcrel_10", 8, 8,
- IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
- {"fixup_arm_adr_pcrel_12", 0, 32, IsPCRelConstant},
+ MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_adr_pcrel_12", 0, 32,
- IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h
index 3bcea57..003d541 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h
@@ -28,7 +28,7 @@ enum Fixups {
// immediate).
fixup_arm_pcrel_10,
// Equivalent to fixup_arm_pcrel_10, accounting for the short-swapped encoding
- // of Thumb2 instructions.
+ // of Thumb2 instructions. Also used by LDRD in Thumb mode.
fixup_t2_pcrel_10,
// 9-bit PC relative relocation for symbol addresses used in VFP instructions
// where bit 0 not encoded (so it's encoded as an 8-bit immediate).
diff --git a/llvm/test/MC/ARM/pcrel-global.s b/llvm/test/MC/ARM/pcrel-global.s
index 1e9e6e9..702f3d1 100644
--- a/llvm/test/MC/ARM/pcrel-global.s
+++ b/llvm/test/MC/ARM/pcrel-global.s
@@ -7,7 +7,7 @@
@ CHECK: There are no relocations in this file.
@ DISASM-LABEL: <bar>:
-@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x8 <bar+0x4>
+@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x4 <bar+0x4>
@ DISASM-NEXT: add r0, pc
@ DISASM-NEXT: .word 0xfffffffb
@@ GNU assembler creates an R_ARM_REL32 referencing bar.
@@ -15,10 +15,6 @@
.syntax unified
-.globl foo
-foo:
-vldr d0, foo @ arm_pcrel_10
-
.thumb
.thumb_func
.type bar, %function
diff --git a/llvm/test/MC/ARM/pcrel-ldr-relocs.s b/llvm/test/MC/ARM/pcrel-ldr-relocs.s
index e0f27f2..4a182be 100644
--- a/llvm/test/MC/ARM/pcrel-ldr-relocs.s
+++ b/llvm/test/MC/ARM/pcrel-ldr-relocs.s
@@ -34,10 +34,10 @@
.global bar
.type bar, %function
bar:
- ldr r0, foo1
- ldrb r0, foo1
- ldr r0, foo2-8
- ldrb r0, foo1+8
+ ldr r0, foo1 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
+ ldrb r0, foo1 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
+ ldr r0, foo2-8 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
+ ldrb r0, foo1+8 @ arm_ldst_pcrel_12 / t2_ldst_pcrel_12
bx lr
.section .data.foo, "a", %progbits
diff --git a/llvm/test/MC/ARM/pcrel-ldrd-diff-section.s b/llvm/test/MC/ARM/pcrel-ldrd-diff-section.s
new file mode 100644
index 0000000..0b745a9
--- /dev/null
+++ b/llvm/test/MC/ARM/pcrel-ldrd-diff-section.s
@@ -0,0 +1,36 @@
+@ RUN: not llvm-mc -filetype=obj --defsym=ERR=1 -o /dev/null %s 2>&1 -triple=thumbv7 | FileCheck %s --check-prefix=ERR
+@ RUN: not llvm-mc -filetype=obj --defsym=ERR=1 -o /dev/null %s 2>&1 -triple=thumbebv7 | FileCheck %s --check-prefix=ERR
+@ RUN: llvm-mc -filetype=obj -triple=armv7 %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
+@ RUN: llvm-objdump -d --triple=armv7 %t | FileCheck %s --check-prefix=ARM_ADDEND
+@ RUN: llvm-mc -filetype=obj -triple=armebv7 %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
+@ RUN: llvm-objdump -d --triple=armebv7 %t | FileCheck %s --check-prefix=ARM_ADDEND
+
+ .section .text.bar, "ax"
+ .balign 4
+ .global bar
+ .type bar, %function
+
+bar:
+ ldrd r0, r1, foo1 @ arm_pcrel_10_unscaled
+ ldrd r0, r1, foo2-8 @ arm_pcrel_10_unscaled
+.ifdef ERR
+ @ ERR:[[#@LINE-3]]:5: error: unsupported relocation type
+ @ ERR:[[#@LINE-3]]:5: error: unsupported relocation type
+.endif
+ bx lr
+
+ .section .data.foo, "a", %progbits
+ .balign 4
+ .global foo1
+ .global foo2
+foo1:
+ .word 0x11223344, 0x55667788
+foo2:
+ .word 0x99aabbcc, 0xddeeff00
+
+@ ARM: R_ARM_LDRS_PC_G0
+
+@ ARM_ADDEND: ldrd r0, r1, [pc, #-8]
+@ ARM_ADDEND: ldrd r0, r1, [pc, #-16]
diff --git a/llvm/test/MC/ARM/pcrel-ldrd-same-section.s b/llvm/test/MC/ARM/pcrel-ldrd-same-section.s
new file mode 100644
index 0000000..b176a75
--- /dev/null
+++ b/llvm/test/MC/ARM/pcrel-ldrd-same-section.s
@@ -0,0 +1,39 @@
+@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armv7
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=armv7 %t | FileCheck %s --check-prefix=ARM_OFFSET
+
+@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armebv7
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=armebv7 %t | FileCheck %s --check-prefix=ARM_OFFSET
+
+@ RUN: llvm-mc -filetype=obj -o %t %s -triple=thumbv7
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=thumbv7 %t | FileCheck %s --check-prefix=THUMB_OFFSET
+
+@ RUN: llvm-mc -filetype=obj -o %y %s -triple=thumbebv7
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=thumbebv7 %t | FileCheck %s --check-prefix=THUMB_OFFSET
+
+baz:
+ .word 0x11223344, 0x55667788
+label:
+
+ ldrd r0, r1, foo @ arm_pcrel_10_unscaled / t2_pcrel_10
+ ldrd r0, r1, bar-8 @ arm_pcrel_10_unscaled / t2_pcrel_10
+
+ ldrd r0, r1, baz @ arm_pcrel_10_unscaled / t2_pcrel_10
+ ldrd r0, r1, label-8 @ arm_pcrel_10_unscaled / t2_pcrel_10
+foo:
+ .word 0x11223344, 0x55667788
+bar:
+
+@ RELOC: There are no relocations in this file.
+
+@ ARM_OFFSET: ldrd r0, r1, [pc, #8] @ 0x18 <foo>
+@ ARM_OFFSET: ldrd r0, r1, [pc, #4] @ 0x18 <foo>
+@ ARM_OFFSET: ldrd r0, r1, [pc, #-24] @ 0x0 <baz>
+@ ARM_OFFSET: ldrd r0, r1, [pc, #-28] @ 0x0 <baz>
+@ THUMB_OFFSET: ldrd r0, r1, [pc, #12] @ 0x18 <foo>
+@ THUMB_OFFSET: ldrd r0, r1, [pc, #8] @ 0x18 <foo>
+@ THUMB_OFFSET: ldrd r0, r1, [pc, #-20] @ 0x0 <baz>
+@ THUMB_OFFSET: ldrd r0, r1, [pc, #-24] @ 0x0 <baz>
diff --git a/llvm/test/MC/ARM/pcrel-vldr-diff-section.s b/llvm/test/MC/ARM/pcrel-vldr-diff-section.s
new file mode 100644
index 0000000..44b1032
--- /dev/null
+++ b/llvm/test/MC/ARM/pcrel-vldr-diff-section.s
@@ -0,0 +1,14 @@
+@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=armv8.2a-eabi | FileCheck %s
+@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=armebv8.2a-eabi | FileCheck %s
+@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=thumbv8.2a-eabi | FileCheck %s
+@ RUN: not llvm-mc -filetype=obj -o /dev/null %s 2>&1 -triple=thumbebv8.2a-eabi | FileCheck %s
+
+ .arch_extension fp16
+
+vldr s0, foo @ arm_pcrel_10 / t2_pcrel_10
+vldr d0, foo @ arm_pcrel_10 / t2_pcrel_10
+vldr.16 s0,foo @ arm_pcrel_9 / t2_pcrel_9
+
+@ CHECK: :[[#@LINE-4]]:1: error: unsupported relocation type
+@ CHECK: :[[#@LINE-4]]:1: error: unsupported relocation type
+@ CHECK: :[[#@LINE-4]]:1: error: unsupported relocation type
diff --git a/llvm/test/MC/ARM/pcrel-vldr-same-section.s b/llvm/test/MC/ARM/pcrel-vldr-same-section.s
new file mode 100644
index 0000000..0727c01
--- /dev/null
+++ b/llvm/test/MC/ARM/pcrel-vldr-same-section.s
@@ -0,0 +1,61 @@
+@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armv8.2a-eabi
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=armv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=ARM_OFFSET
+@ RUN: llvm-mc -filetype=obj -o %t %s -triple=armebv8.2a-eabi
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=armebv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=ARM_OFFSET
+@ RUN: llvm-mc -filetype=obj -o %t %s -triple=thumbv8.2a-eabi
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=thumbv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=THUMB_OFFSET
+@ RUN: llvm-mc -filetype=obj -o %y %s -triple=thumbebv8.2a-eabi
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=thumbebv8.2a-eabi --mattr=+fullfp16 %t | FileCheck %s --check-prefix=THUMB_OFFSET
+
+ .arch_extension fp16
+baz:
+ .word 0x11223344, 0x55667788
+label:
+
+ vldr s0, foo @ arm_pcrel_10 / t2_pcrel_10
+ vldr d0, foo @ arm_pcrel_10 / t2_pcrel_10
+ vldr.16 s0, foo @ arm_pcrel_9 / t2_pcrel_9
+ vldr s0, bar-8
+ vldr d0, bar-8
+ vldr.16 s0, bar-8
+ vldr s0, baz
+ vldr d0, baz
+ vldr.16 s0, baz
+ vldr s0, label-8
+ vldr d0, label-8
+ vldr.16 s0, label-8
+
+foo:
+ .word 0x11223344, 0x55667788
+bar:
+
+@ RELOC: There are no relocations in this file.
+
+@ ARM_OFFSET: vldr s0, [pc, #40] @ 0x38 <foo>
+@ ARM_OFFSET: vldr d0, [pc, #36] @ 0x38 <foo>
+@ ARM_OFFSET: vldr.16 s0, [pc, #32] @ 0x38 <foo>
+@ ARM_OFFSET: vldr s0, [pc, #28] @ 0x38 <foo>
+@ ARM_OFFSET: vldr d0, [pc, #24] @ 0x38 <foo>
+@ ARM_OFFSET: vldr.16 s0, [pc, #20] @ 0x38 <foo>
+@ ARM_OFFSET: vldr s0, [pc, #-40] @ 0x0 <baz>
+@ ARM_OFFSET: vldr d0, [pc, #-44] @ 0x0 <baz>
+@ ARM_OFFSET: vldr.16 s0, [pc, #-48] @ 0x0 <baz>
+@ ARM_OFFSET: vldr s0, [pc, #-52] @ 0x0 <baz>
+@ ARM_OFFSET: vldr d0, [pc, #-56] @ 0x0 <baz>
+@ ARM_OFFSET: vldr.16 s0, [pc, #-60] @ 0x0 <baz>
+@ THUMB_OFFSET: vldr s0, [pc, #44] @ 0x38 <foo>
+@ THUMB_OFFSET: vldr d0, [pc, #40] @ 0x38 <foo>
+@ THUMB_OFFSET: vldr.16 s0, [pc, #36] @ 0x38 <foo>
+@ THUMB_OFFSET: vldr s0, [pc, #32] @ 0x38 <foo>
+@ THUMB_OFFSET: vldr d0, [pc, #28] @ 0x38 <foo>
+@ THUMB_OFFSET: vldr.16 s0, [pc, #24] @ 0x38 <foo>
+@ THUMB_OFFSET: vldr s0, [pc, #-36] @ 0x0 <baz>
+@ THUMB_OFFSET: vldr d0, [pc, #-40] @ 0x0 <baz>
+@ THUMB_OFFSET: vldr.16 s0, [pc, #-44] @ 0x0 <baz>
+@ THUMB_OFFSET: vldr s0, [pc, #-48] @ 0x0 <baz>
+@ THUMB_OFFSET: vldr d0, [pc, #-52] @ 0x0 <baz>
+@ THUMB_OFFSET: vldr.16 s0, [pc, #-56] @ 0x0 <baz>