[llvm] [lld] [llvm][lld] Support R_AARCH64_GOTPCREL32 (PR #72584)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 12:42:00 PST 2024


https://github.com/PiJoules updated https://github.com/llvm/llvm-project/pull/72584

>From 43a19d6cfa054ead871cc10bd2a19c877aa17978 Mon Sep 17 00:00:00 2001
From: Leonard Chan <leonardchan at google.com>
Date: Wed, 15 Nov 2023 23:48:40 +0000
Subject: [PATCH] [llvm][lld] Support R_<CLS>_GOTREL32

This is the follopw implementation to
https://github.com/ARM-software/abi-aa/pull/223 that supports this
relocation in llvm and lld.
---
 lld/ELF/Arch/AArch64.cpp                      |  3 +++
 lld/test/ELF/aarch64-reloc-gotpcrel32.s       | 27 +++++++++++++++++++
 .../llvm/BinaryFormat/ELFRelocs/AArch64.def   |  1 +
 .../MCTargetDesc/AArch64ELFObjectWriter.cpp   |  8 ++++--
 llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s   | 14 ++++++++++
 5 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 lld/test/ELF/aarch64-reloc-gotpcrel32.s
 create mode 100644 llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s

diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 54b0a84e52137b..71a1b1111e4298 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_ADR_GOT_PAGE:
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     return R_AARCH64_GOT_PAGE_PC;
+  case R_AARCH64_GOTPCREL32:
+    return R_GOT_PC;
   case R_AARCH64_NONE:
     return R_NONE;
   default:
@@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     write32(loc, val);
     break;
   case R_AARCH64_PLT32:
+  case R_AARCH64_GOTPCREL32:
     checkInt(loc, val, 32, rel);
     write32(loc, val);
     break;
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 00000000000000..4d007776a86a7a
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,27 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared --noinhibit-exec 2>&1 | FileCheck %s --check-prefix=WARN
+// RUN: llvm-readelf -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+// SEC: .got PROGBITS 0000000000020390
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:  // PC = 0x303a0
+// bar at GOTPCREL   = 0x20390 (got entry for `bar`) - 0x303a0 (.) = 0xf0fffeff
+// bar at GOTPCREL+4 = 0x20390 (got entry for `bar`) - 0x303a4 (.) + 4 = 0xf0fffeff
+// bar at GOTPCREL-4 = 0x20390 (got entry for `bar`) - 0x303a8 (.) - 4 = 0xe4fffeff
+// CHECK:      Contents of section .data:
+// CHECK-NEXT:  {{.*}} f0fffeff f0fffeff e4fffeff
+  .word bar at GOTPCREL
+  .word bar at GOTPCREL+4
+  .word bar at GOTPCREL-4
+
+// WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
+// WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
+  .word baz at GOTPCREL+0xffffffff
+  .word baz at GOTPCREL-0xffffffff
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index 30375de420e302..5fb3fa4aeb7beb 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE,                    0x137)
 ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC,                0x138)
 ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15,               0x139)
 ELF_RELOC(R_AARCH64_PLT32,                           0x13a)
+ELF_RELOC(R_AARCH64_GOTPCREL32,                      0x13b)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21,                0x200)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21,                0x201)
 ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC,               0x202)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 496ab18e9b1954..6e074b6a63c41d 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
 
   assert((!Target.getSymA() ||
           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
-          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
          "Should only be expression-level modifiers here");
 
   assert((!Target.getSymB() ||
@@ -206,7 +207,10 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
     case FK_Data_2:
       return R_CLS(ABS16);
     case FK_Data_4:
-      return R_CLS(ABS32);
+      return (!IsILP32 &&
+              Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL)
+                 ? ELF::R_AARCH64_GOTPCREL32
+                 : R_CLS(ABS32);
     case FK_Data_8:
       if (IsILP32) {
         Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
new file mode 100644
index 00000000000000..afbcaad9e1dfdc
--- /dev/null
+++ b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
+// RUN:   llvm-readobj -r - | FileCheck %s
+
+        .section .data
+this:
+        .word this at GOTPCREL
+        .word extern_sym at GOTPCREL+4
+        .word negative_offset at GOTPCREL-4
+
+// CHECK:      Section ({{.*}}) .rela.data
+// CHECK-NEXT:   0x0 R_AARCH64_GOTPCREL32 this 0x0
+// CHECK-NEXT:   0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
+// CHECK-NEXT:   0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }



More information about the llvm-commits mailing list