[lld] [llvm] [llvm][lld] Support R_AARCH64_GOTPCREL32 (PR #72584)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 28 16:02:37 PST 2023
https://github.com/PiJoules updated https://github.com/llvm/llvm-project/pull/72584
>From 718b1c5c527f0bcf5dfd63124da1b9bd1debf86f 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 +++
.../ELF/aarch64-reloc-gotpcrel32-overflow.s | 11 ++++++++++
lld/test/ELF/aarch64-reloc-gotpcrel32.s | 22 +++++++++++++++++++
.../llvm/BinaryFormat/ELFRelocs/AArch64.def | 1 +
.../MCTargetDesc/AArch64ELFObjectWriter.cpp | 8 +++++--
llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s | 14 ++++++++++++
6 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 lld/test/ELF/aarch64-reloc-gotpcrel32-overflow.s
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 048f0ec30ebd283..32cff73955028e4 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-overflow.s b/lld/test/ELF/aarch64-reloc-gotpcrel32-overflow.s
new file mode 100644
index 000000000000000..ca6ac882cd4fd65
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32-overflow.s
@@ -0,0 +1,11 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
+
+// CHECK: relocation R_AARCH64_GOTPCREL32 out of range: -4294901591 is not in [-2147483648, 2147483647]; references 'bar'
+// CHECK: relocation R_AARCH64_GOTPCREL32 out of range: 4295032995 is not in [-2147483648, 2147483647]; references 'bar'
+
+ .globl _start
+_start:
+ .word bar at GOTPCREL-0xffffffff
+ .word bar at GOTPCREL+0xffffffff
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..f71e0004a33a00e
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,22 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// 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 0000000000020350
+
+ .section .data
+ .globl bar
+bar:
+
+ .globl _start
+_start:
+// bar at GOTPCREL = 0x20350 (got entry for `bar`) - 0x30358 (.) = 0xfffefff8
+// bar at GOTPCREL+4 = 0x20350 (got entry for `bar`) - 0x3035c (.) + 4 = 0xfffefff8
+// bar at GOTPCREL-4 = 0x20350 (got entry for `bar`) - 0x30360 (.) + 4 = 0xfffeffec
+// CHECK: Contents of section .data:
+// CHECK: 30358 f8fffeff f8fffeff ecfffeff
+ .word bar at GOTPCREL
+ .word bar at GOTPCREL+4
+ .word bar at GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index b507109b19e1b90..1666abea9864e96 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 9de40661298ccad..e7967a8b0d6811c 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() ||
@@ -202,7 +203,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 000000000000000..afbcaad9e1dfdcc
--- /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