[llvm] [lld] [llvm][lld] Support R_RISCV_GOT32_PCREL (PR #72587)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 10 15:10:31 PST 2024


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

>From dd3c75bed860595a498ca529d58f544aed37b274 Mon Sep 17 00:00:00 2001
From: Leonard Chan <leonardchan at google.com>
Date: Fri, 17 Nov 2023 00:07:22 +0000
Subject: [PATCH] [llvm][lld] Support R_RISCV_GOT32_PCREL

This is the followup implementation to
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/402 that
supports this relocation in llvm and lld.
---
 lld/ELF/Arch/RISCV.cpp                        |  3 +++
 lld/test/ELF/riscv64-reloc-got32-pcrel.s      | 27 +++++++++++++++++++
 .../ELF/riscv64-reloc-got32_pcrel-overflow.s  | 11 ++++++++
 lld/test/ELF/riscv64-reloc-got32_pcrel.s      | 22 +++++++++++++++
 .../llvm/BinaryFormat/ELFRelocs/RISCV.def     |  3 +--
 .../MCTargetDesc/RISCVELFObjectWriter.cpp     |  2 ++
 llvm/test/MC/RISCV/elf-reloc-got32-pcrel.s    | 14 ++++++++++
 7 files changed, 80 insertions(+), 2 deletions(-)
 create mode 100644 lld/test/ELF/riscv64-reloc-got32-pcrel.s
 create mode 100644 lld/test/ELF/riscv64-reloc-got32_pcrel-overflow.s
 create mode 100644 lld/test/ELF/riscv64-reloc-got32_pcrel.s
 create mode 100644 llvm/test/MC/RISCV/elf-reloc-got32-pcrel.s

diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 1d3d179e5d6fb5a..62498ded1a2b16c 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -290,6 +290,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
   case R_RISCV_PLT32:
     return R_PLT_PC;
   case R_RISCV_GOT_HI20:
+  case R_RISCV_GOT32_PCREL:
     return R_GOT_PC;
   case R_RISCV_PCREL_LO12_I:
   case R_RISCV_PCREL_LO12_S:
@@ -499,6 +500,8 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   case R_RISCV_SET32:
   case R_RISCV_32_PCREL:
   case R_RISCV_PLT32:
+  case R_RISCV_GOT32_PCREL:
+    checkInt(loc, val, 32, rel);
     write32le(loc, val);
     return;
 
diff --git a/lld/test/ELF/riscv64-reloc-got32-pcrel.s b/lld/test/ELF/riscv64-reloc-got32-pcrel.s
new file mode 100644
index 000000000000000..24bd828235b25d3
--- /dev/null
+++ b/lld/test/ELF/riscv64-reloc-got32-pcrel.s
@@ -0,0 +1,27 @@
+// REQUIRES: riscv
+// RUN: llvm-mc -filetype=obj -triple=riscv64 %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 0000000000002390
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:  // PC = 0x33a8
+// bar at GOTPCREL   = 0x2398 (got entry for `bar`) - 0x33a8 (.) = 0xf0efffff
+// bar at GOTPCREL+4 = 0x2398 (got entry for `bar`) - 0x33ac (.) + 4 = 0xf0efffff
+// bar at GOTPCREL-4 = 0x2398 (got entry for `bar`) - 0x33b0 (.) - 4 = 0xe4efffff
+// CHECK:      Contents of section .data:
+// CHECK-NEXT:  {{.*}} f0efffff f0efffff e4efffff
+  .word bar at GOTPCREL
+  .word bar at GOTPCREL+4
+  .word bar at GOTPCREL-4
+
+// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
+// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
+  .word baz at GOTPCREL+0xffffffff
+  .word baz at GOTPCREL-0xffffffff
diff --git a/lld/test/ELF/riscv64-reloc-got32_pcrel-overflow.s b/lld/test/ELF/riscv64-reloc-got32_pcrel-overflow.s
new file mode 100644
index 000000000000000..2ce17ed4269d5a5
--- /dev/null
+++ b/lld/test/ELF/riscv64-reloc-got32_pcrel-overflow.s
@@ -0,0 +1,11 @@
+// REQUIRES: riscv
+// RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
+// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
+
+// CHECK: relocation R_RISCV_GOT32_PCREL out of range: -4294963023 is not in [-2147483648, 2147483647]; references 'bar'
+// CHECK: relocation R_RISCV_GOT32_PCREL out of range: 4294971563 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/riscv64-reloc-got32_pcrel.s b/lld/test/ELF/riscv64-reloc-got32_pcrel.s
new file mode 100644
index 000000000000000..68bf5bc86c1a701
--- /dev/null
+++ b/lld/test/ELF/riscv64-reloc-got32_pcrel.s
@@ -0,0 +1,22 @@
+// REQUIRES: riscv
+// RUN: llvm-mc -filetype=obj -triple=riscv64 %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 0000000000002350
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:
+// bar at GOTPCREL   = 0x2350 (got entry for `bar`) - 0x3360 (.) = 0xffffeff0
+// bar at GOTPCREL+4 = 0x2350 (got entry for `bar`) - 0x3364 (.) + 4 = 0xffffeff0
+// bar at GOTPCREL-4 = 0x2350 (got entry for `bar`) - 0x3368 (.) + 4 = 0xffffefe4
+// CHECK: Contents of section .data:
+//  3360 f0efffff f0efffff e4efffff
+  .word bar at GOTPCREL
+  .word bar at GOTPCREL+4
+  .word bar at GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
index c7fd6490041cd1d..b478799c91fb2f7 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
@@ -40,8 +40,7 @@ ELF_RELOC(R_RISCV_SUB8,              37)
 ELF_RELOC(R_RISCV_SUB16,             38)
 ELF_RELOC(R_RISCV_SUB32,             39)
 ELF_RELOC(R_RISCV_SUB64,             40)
-ELF_RELOC(R_RISCV_GNU_VTINHERIT,     41)
-ELF_RELOC(R_RISCV_GNU_VTENTRY,       42)
+ELF_RELOC(R_RISCV_GOT32_PCREL,       41)
 ELF_RELOC(R_RISCV_ALIGN,             43)
 ELF_RELOC(R_RISCV_RVC_BRANCH,        44)
 ELF_RELOC(R_RISCV_RVC_JUMP,          45)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index 0799267eaf7c769..76e5b3ed402543b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -106,6 +106,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
     if (Expr->getKind() == MCExpr::Target &&
         cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL)
       return ELF::R_RISCV_32_PCREL;
+    if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL)
+      return ELF::R_RISCV_GOT32_PCREL;
     return ELF::R_RISCV_32;
   case FK_Data_8:
     return ELF::R_RISCV_64;
diff --git a/llvm/test/MC/RISCV/elf-reloc-got32-pcrel.s b/llvm/test/MC/RISCV/elf-reloc-got32-pcrel.s
new file mode 100644
index 000000000000000..32a1d57fb536091
--- /dev/null
+++ b/llvm/test/MC/RISCV/elf-reloc-got32-pcrel.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=riscv64 -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_RISCV_GOT32_PCREL this 0x0
+// CHECK-NEXT:   0x4 R_RISCV_GOT32_PCREL extern_sym 0x4
+// CHECK-NEXT:   0x8 R_RISCV_GOT32_PCREL negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }



More information about the llvm-commits mailing list