[llvm] [llvm][MC][ARM][Assembly] Emit relocations for ADR instructions (PR #73834)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 29 10:09:29 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: Eleanor Bonnici (eleanor-arm)

<details>
<summary>Changes</summary>

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.


---
Full diff: https://github.com/llvm/llvm-project/pull/73834.diff


6 Files Affected:

- (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (+5-3) 
- (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp (+6) 
- (added) llvm/test/MC/ARM/pcrel-adr16-relocs.s (+23) 
- (added) llvm/test/MC/ARM/pcrel-adr32-relocs.s (+20) 
- (modified) llvm/test/MC/ARM/pcrel-global.s (+2-8) 
- (modified) llvm/test/MC/ARM/thumb1-relax-adr.s (-1) 


``````````diff
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:

``````````

</details>


https://github.com/llvm/llvm-project/pull/73834


More information about the llvm-commits mailing list