[llvm] [llvm][MC][ARM][Assembly] Emit relocations for ADR instructions (PR #73834)
Eleanor Bonnici via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 29 10:08:58 PST 2023
https://github.com/eleanor-arm created https://github.com/llvm/llvm-project/pull/73834
Follow-up on https://github.com/llvm/llvm-project/pull/72873/
When ADR instructions reference a label in a different section, the
generated code might be incorrect because the relative position of
sections is not known at assembly time.
This patch ensures relocations are generated for ADR instructions,
similarly to the relocations generated for LDRs in the previous patch.
This will again push the resolution of instruction immediates to the
linker, which already implements the three relocations added here.
Tests for big-endian targets will follow.
>From d17d0a378d6cfc1d54516ca0827fd968c5e5e72b Mon Sep 17 00:00:00 2001
From: Eleanor Bonnici <eleanor.bonnici at arm.com>
Date: Wed, 29 Nov 2023 16:24:52 +0000
Subject: [PATCH] [llvm][MC][ARM][Assembly] Emit relocations for ADR
instructions
Follow-up on https://github.com/llvm/llvm-project/pull/72873/
When ADR instructions reference a label in a different section, the
generated code might be incorrect because the relative position of
sections is not known at assembly time.
This patch ensures relocations are generated for ADR instructions,
similarly to the relocations generated for LDRs in the previous patch.
This will again push the resolution of instruction immediates to the
linker, which already implements the three relocations added here.
Tests for big-endian targets will follow.
---
.../Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 8 ++++---
.../ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 6 +++++
llvm/test/MC/ARM/pcrel-adr16-relocs.s | 23 +++++++++++++++++++
llvm/test/MC/ARM/pcrel-adr32-relocs.s | 20 ++++++++++++++++
llvm/test/MC/ARM/pcrel-global.s | 10 ++------
llvm/test/MC/ARM/thumb1-relax-adr.s | 1 -
6 files changed, 56 insertions(+), 12 deletions(-)
create mode 100644 llvm/test/MC/ARM/pcrel-adr16-relocs.s
create mode 100644 llvm/test/MC/ARM/pcrel-adr32-relocs.s
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index ca3b77e4a356535..b3e90ac7e7cb4ec 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -88,10 +88,12 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_arm_ldst_abs_12", 0, 32, 0},
{"fixup_thumb_adr_pcrel_10", 0, 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", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
index 985097fc3281051..44695a86c4e36c7 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
@@ -164,6 +164,12 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
return ELF::R_ARM_LDRS_PC_G0;
case ARM::fixup_t2_ldst_pcrel_12:
return ELF::R_ARM_THM_PC12;
+ case ARM::fixup_arm_adr_pcrel_12:
+ return ELF::R_ARM_ALU_PC_G0;
+ case ARM::fixup_thumb_adr_pcrel_10:
+ return ELF::R_ARM_THM_PC8;
+ case ARM::fixup_t2_adr_pcrel_12:
+ return ELF::R_ARM_THM_ALU_PREL_11_0;
case ARM::fixup_bf_target:
return ELF::R_ARM_THM_BF16;
case ARM::fixup_bfc_target:
diff --git a/llvm/test/MC/ARM/pcrel-adr16-relocs.s b/llvm/test/MC/ARM/pcrel-adr16-relocs.s
new file mode 100644
index 000000000000000..dd73c9d28a6822b
--- /dev/null
+++ b/llvm/test/MC/ARM/pcrel-adr16-relocs.s
@@ -0,0 +1,23 @@
+@ RUN: llvm-mc -filetype=obj --triple=thumbv6m-none-eabi %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=thumbv6m-none-eabi %t | FileCheck %s --check-prefix=ADDEND
+
+ .section .text._func1, "ax"
+
+ .balign 4
+ .global _func1
+ .type _func1, %function
+_func1:
+ adr r0, _func2
+@ RELOC: R_ARM_THM_PC8
+ bx lr
+
+// Checking the encoding only, as the disassembly is not quite correct here.
+
+// Thumb16 encoding supports only adding of the encoded immediate (not
+// subtracting, see [Arm ARM]), therefore sign change is required if the pcrel
+// offset is negative. This makes the calculation of the addend for
+// R_ARM_THM_PC8 more complex, for details see [ELF for the Arm 32-bit
+// architecture].
+@ ADDEND: a0ff
+
diff --git a/llvm/test/MC/ARM/pcrel-adr32-relocs.s b/llvm/test/MC/ARM/pcrel-adr32-relocs.s
new file mode 100644
index 000000000000000..5e64125b7ea82e8
--- /dev/null
+++ b/llvm/test/MC/ARM/pcrel-adr32-relocs.s
@@ -0,0 +1,20 @@
+@ RUN: llvm-mc -filetype=obj -triple=armv7 %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=armv7 %t | FileCheck %s --check-prefix=ADDEND
+
+ .section .text._func1, "ax"
+
+ .balign 4
+ .global _func1
+ .type _func1, %function
+_func1:
+ adr r0, _func2
+@ RELOC: R_ARM_ALU_PC_G0
+ .thumb
+ adr r0, _func2
+@ RELOC: R_ARM_THM_ALU_PREL_11_0
+ bx lr
+
+@ ADDEND: sub r0, pc, #8
+@ ADDEND-NEXT: adr.w r0, #-4
+
diff --git a/llvm/test/MC/ARM/pcrel-global.s b/llvm/test/MC/ARM/pcrel-global.s
index 15d46cf2063ecff..1e9e6e989356ecc 100644
--- a/llvm/test/MC/ARM/pcrel-global.s
+++ b/llvm/test/MC/ARM/pcrel-global.s
@@ -7,11 +7,9 @@
@ CHECK: There are no relocations in this file.
@ DISASM-LABEL: <bar>:
-@ DISASM-NEXT: adr.w r0, #-4
-@ DISASM-NEXT: adr.w r0, #-8
-@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x14 <bar+0xc>
+@ DISASM-NEXT: ldr r0, [pc, #0x0] @ 0x8 <bar+0x4>
@ DISASM-NEXT: add r0, pc
-@ DISASM-NEXT: .word 0xfffffff3
+@ DISASM-NEXT: .word 0xfffffffb
@@ GNU assembler creates an R_ARM_REL32 referencing bar.
@ DISASM-NOT: {{.}}
@@ -20,16 +18,12 @@
.globl foo
foo:
vldr d0, foo @ arm_pcrel_10
-adr r2, foo @ arm_adr_pcrel_12
.thumb
.thumb_func
.type bar, %function
.globl bar
bar:
-adr r0, bar @ thumb_adr_pcrel_10
-adr.w r0, bar @ t2_adr_pcrel_12
-
ldr r0, .LCPI
.LPC0_1:
add r0, pc
diff --git a/llvm/test/MC/ARM/thumb1-relax-adr.s b/llvm/test/MC/ARM/thumb1-relax-adr.s
index fc5c7c39df5ae1c..97b566f4833e632 100644
--- a/llvm/test/MC/ARM/thumb1-relax-adr.s
+++ b/llvm/test/MC/ARM/thumb1-relax-adr.s
@@ -1,6 +1,5 @@
@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
@ RUN: not llvm-mc -triple thumbv7m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
-@ RUN: not llvm-mc -triple thumbv7m-none-eabi -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
.global func1
_func1:
More information about the llvm-commits
mailing list