[llvm] [llvm][MC][ARM][Assembly] Emit relocations for ADRs and big-endian targets (PR #73834)
Eleanor Bonnici via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 1 02:52:50 PST 2023
https://github.com/eleanor-arm updated https://github.com/llvm/llvm-project/pull/73834
>From d04434959746b346914c5a801f24fecd4cbbaa7d 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 1/2] [llvm][MC][ARM][Assembly] Emit relocations for ADRs and
big-endian targets
Follow-up on https://github.com/llvm/llvm-project/pull/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.
---
.../Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 15 ++++++-----
.../ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 6 +++++
llvm/test/MC/ARM/pcrel-adr16-relocs.s | 23 +++++++++++++++++
llvm/test/MC/ARM/pcrel-adr32-relocs.s | 25 +++++++++++++++++++
llvm/test/MC/ARM/pcrel-arm-ldr-imm8-relocs.s | 6 +++++
llvm/test/MC/ARM/pcrel-global.s | 10 ++------
llvm/test/MC/ARM/pcrel-ldr-relocs.s | 8 ++++--
llvm/test/MC/ARM/pcrel-thumb-ldr2-relocs.s | 3 +++
llvm/test/MC/ARM/thumb1-relax-adr.s | 1 -
9 files changed, 80 insertions(+), 17 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..41b3c6005231e81 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},
@@ -133,10 +135,11 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
// ARMFixupKinds.h.
//
// Name Offset (bits) Size (bits) Flags
- {"fixup_arm_ldst_pcrel_12", 0, 32, IsPCRelConstant},
+ {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_t2_ldst_pcrel_12", 0, 32,
- IsPCRelConstant | MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
- {"fixup_arm_pcrel_10_unscaled", 0, 32, IsPCRelConstant},
+ MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
{"fixup_t2_pcrel_10", 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..015a4d79ccf6856
--- /dev/null
+++ b/llvm/test/MC/ARM/pcrel-adr32-relocs.s
@@ -0,0 +1,25 @@
+@ 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
+
+@ RUN: llvm-mc -filetype=obj --triple=armebv7-unknown-unknown %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+@ RUN: llvm-objdump -d --triple=armebv7-unknown-unknown %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-arm-ldr-imm8-relocs.s b/llvm/test/MC/ARM/pcrel-arm-ldr-imm8-relocs.s
index 40453d6ef341a4b..f8b166d4c24858a 100644
--- a/llvm/test/MC/ARM/pcrel-arm-ldr-imm8-relocs.s
+++ b/llvm/test/MC/ARM/pcrel-arm-ldr-imm8-relocs.s
@@ -1,6 +1,9 @@
@ 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-unknown-unknown %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=ARM
+@ RUN: llvm-objdump -d --triple=armebv7-unknown-unknown %t | FileCheck %s --check-prefix=ARM_ADDEND
@ ARM: R_ARM_LDRS_PC_G0
@ ARM: R_ARM_LDRS_PC_G0
@@ -8,6 +11,7 @@
@ ARM: R_ARM_LDRS_PC_G0
@ ARM: R_ARM_LDRS_PC_G0
@ ARM: R_ARM_LDRS_PC_G0
+@ ARM: R_ARM_LDRS_PC_G0
// The value format is decimal in these specific cases, but it's hex for other
// ldr instructions. These checks are valid for both formats.
@@ -18,6 +22,7 @@
@ ARM_ADDEND: r0, [pc, #-{{16|0x10}}]
@ ARM_ADDEND: r0, [pc, #-{{16|0x10}}]
@ ARM_ADDEND: r0, [pc]
+@ ARM_ADDEND: r0, r1, [pc]
.arm
.section .text.bar, "ax"
@@ -31,6 +36,7 @@ bar:
ldrh r0, just_after-8
ldrsb r0, just_after-8
ldrsh r0, foo+8
+ ldrd r0,r1, foo+8
bx lr
.section .data.foo, "a", %progbits
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/pcrel-ldr-relocs.s b/llvm/test/MC/ARM/pcrel-ldr-relocs.s
index 120d54ebafe0876..e0f27f299499935 100644
--- a/llvm/test/MC/ARM/pcrel-ldr-relocs.s
+++ b/llvm/test/MC/ARM/pcrel-ldr-relocs.s
@@ -4,12 +4,17 @@
@ RUN: llvm-mc -filetype=obj -triple=thumbv7 %s -o %t
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
@ RUN: llvm-objdump -d --triple=thumbv7 %t | FileCheck %s --check-prefix=THUMB_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
+@ RUN: llvm-mc -filetype=obj -triple=thumbebv7 %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
+@ RUN: llvm-objdump -d --triple=thumbebv7 %t | FileCheck %s --check-prefix=THUMB_ADDEND
@ ARM: R_ARM_LDR_PC_G0
@ ARM: R_ARM_LDR_PC_G0
@ ARM: R_ARM_LDR_PC_G0
@ ARM: R_ARM_LDR_PC_G0
-
@ ARM_ADDEND: r0, [pc, #-0x8]
@ ARM_ADDEND: r0, [pc, #-0x8]
@ ARM_ADDEND: r0, [pc, #-0x10]
@@ -19,7 +24,6 @@
@ THUMB: R_ARM_THM_PC12
@ THUMB: R_ARM_THM_PC12
@ THUMB: R_ARM_THM_PC12
-
@ THUMB_ADDEND: r0, [pc, #-0x4]
@ THUMB_ADDEND: r0, [pc, #-0x4]
@ THUMB_ADDEND: r0, [pc, #-0xc]
diff --git a/llvm/test/MC/ARM/pcrel-thumb-ldr2-relocs.s b/llvm/test/MC/ARM/pcrel-thumb-ldr2-relocs.s
index 17ca72bd3f00cad..3aa371fc7d702fc 100644
--- a/llvm/test/MC/ARM/pcrel-thumb-ldr2-relocs.s
+++ b/llvm/test/MC/ARM/pcrel-thumb-ldr2-relocs.s
@@ -1,6 +1,9 @@
@ RUN: llvm-mc -filetype=obj -triple=thumbv7 %s -o %t
@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
@ RUN: llvm-objdump -d --triple=thumbv7 %t | FileCheck %s --check-prefix=THUMB_ADDEND
+@ RUN: llvm-mc -filetype=obj --triple=thumbebv7-unknown-unknown %s -o %t
+@ RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=THUMB
+@ RUN: llvm-objdump -d --triple=thumbebv7-unknown-unknown %t | FileCheck %s --check-prefix=THUMB_ADDEND
@ All the ldr variants produce a relocation
@ THUMB: R_ARM_THM_PC12
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:
>From eed3aa3a4e0866aa1b131902a26d563fb716f609 Mon Sep 17 00:00:00 2001
From: Eleanor Bonnici <eleanor.bonnici at arm.com>
Date: Fri, 1 Dec 2023 10:43:09 +0000
Subject: [PATCH 2/2] fixup! [llvm][MC][ARM][Assembly] Emit relocations for
ADRs and big-endian targets
Address David's review comments
---
llvm/test/MC/ARM/pcrel-adr16-relocs.s | 5 ++++-
llvm/test/MC/ARM/pcrel-adr32-relocs.s | 1 -
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/test/MC/ARM/pcrel-adr16-relocs.s b/llvm/test/MC/ARM/pcrel-adr16-relocs.s
index dd73c9d28a6822b..adef746c3607a54 100644
--- a/llvm/test/MC/ARM/pcrel-adr16-relocs.s
+++ b/llvm/test/MC/ARM/pcrel-adr16-relocs.s
@@ -13,11 +13,14 @@ _func1:
bx lr
// Checking the encoding only, as the disassembly is not quite correct here.
+//00000000 <_func1>:
+// 0: a0ff adr r0, #1020 <_func1+0x103>
// 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
+
+@ ADDEND: a0ff adr
diff --git a/llvm/test/MC/ARM/pcrel-adr32-relocs.s b/llvm/test/MC/ARM/pcrel-adr32-relocs.s
index 015a4d79ccf6856..5fd30f24630f903 100644
--- a/llvm/test/MC/ARM/pcrel-adr32-relocs.s
+++ b/llvm/test/MC/ARM/pcrel-adr32-relocs.s
@@ -22,4 +22,3 @@ _func1:
@ ADDEND: sub r0, pc, #8
@ ADDEND-NEXT: adr.w r0, #-4
-
More information about the llvm-commits
mailing list