Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[llvm][lld] Support R_RISCV_GOT32_PCREL #72587

Merged
merged 1 commit into from
Jan 10, 2024

Conversation

PiJoules
Copy link
Contributor

This is the followup implementation to
riscv-non-isa/riscv-elf-psabi-doc#402 that supports this relocation in llvm and lld.

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 17, 2023

@llvm/pr-subscribers-backend-risc-v
@llvm/pr-subscribers-mc
@llvm/pr-subscribers-lld

@llvm/pr-subscribers-llvm-binary-utilities

Author: None (PiJoules)

Changes

This is the followup implementation to
riscv-non-isa/riscv-elf-psabi-doc#402 that supports this relocation in llvm and lld.


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

5 Files Affected:

  • (modified) lld/ELF/Arch/RISCV.cpp (+2)
  • (added) lld/test/ELF/riscv64-reloc-got32_pcrel.s (+35)
  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def (+1-2)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp (+2)
  • (added) llvm/test/MC/RISCV/elf-reloc-got32_pcrel.s (+14)
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 6413dcd7dcd7976..7567703bb5ce648 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -289,6 +289,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:
@@ -495,6 +496,7 @@ 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:
     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..e9a7849ff847689
--- /dev/null
+++ b/lld/test/ELF/riscv64-reloc-got32_pcrel.s
@@ -0,0 +1,35 @@
+// REQUIRES: riscv
+// RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC:         Name: .got (58)
+// SEC-NEXT:    Type: SHT_PROGBITS (0x1)
+// SEC-NEXT:    Flags [ (0x3)
+// SEC-NEXT:      SHF_ALLOC (0x2)
+// SEC-NEXT:      SHF_WRITE (0x1)
+// SEC-NEXT:    ]
+// SEC-NEXT:    Address: 0x2350
+// SEC-NEXT:    Offset: 0x350
+// SEC-NEXT:    Size: 16
+// SEC-NEXT:    Link: 0
+// SEC-NEXT:    Info: 0
+// SEC-NEXT:    AddressAlignment: 8
+// SEC-NEXT:    EntrySize: 0
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:
+// bar@GOTPCREL   = 0x2350 (got entry for `bar`) - 0x3360 (.) = 0xffffeff0
+// bar@GOTPCREL+4 = 0x2350 (got entry for `bar`) - 0x3364 (.) + 4 = 0xffffeff0
+// bar@GOTPCREL-4 = 0x2350 (got entry for `bar`) - 0x3368 (.) + 4 = 0xffffefe4
+// CHECK: Contents of section .data:
+//  3360 f0efffff f0efffff e4efffff
+  .word bar@GOTPCREL
+  .word bar@GOTPCREL+4
+  .word bar@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@GOTPCREL
+        .word extern_sym@GOTPCREL+4
+        .word negative_offset@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: }

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 17, 2023

@llvm/pr-subscribers-lld-elf

Author: None (PiJoules)

Changes

This is the followup implementation to
riscv-non-isa/riscv-elf-psabi-doc#402 that supports this relocation in llvm and lld.


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

5 Files Affected:

  • (modified) lld/ELF/Arch/RISCV.cpp (+2)
  • (added) lld/test/ELF/riscv64-reloc-got32_pcrel.s (+35)
  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def (+1-2)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp (+2)
  • (added) llvm/test/MC/RISCV/elf-reloc-got32_pcrel.s (+14)
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 6413dcd7dcd7976..7567703bb5ce648 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -289,6 +289,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:
@@ -495,6 +496,7 @@ 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:
     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..e9a7849ff847689
--- /dev/null
+++ b/lld/test/ELF/riscv64-reloc-got32_pcrel.s
@@ -0,0 +1,35 @@
+// REQUIRES: riscv
+// RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC:         Name: .got (58)
+// SEC-NEXT:    Type: SHT_PROGBITS (0x1)
+// SEC-NEXT:    Flags [ (0x3)
+// SEC-NEXT:      SHF_ALLOC (0x2)
+// SEC-NEXT:      SHF_WRITE (0x1)
+// SEC-NEXT:    ]
+// SEC-NEXT:    Address: 0x2350
+// SEC-NEXT:    Offset: 0x350
+// SEC-NEXT:    Size: 16
+// SEC-NEXT:    Link: 0
+// SEC-NEXT:    Info: 0
+// SEC-NEXT:    AddressAlignment: 8
+// SEC-NEXT:    EntrySize: 0
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:
+// bar@GOTPCREL   = 0x2350 (got entry for `bar`) - 0x3360 (.) = 0xffffeff0
+// bar@GOTPCREL+4 = 0x2350 (got entry for `bar`) - 0x3364 (.) + 4 = 0xffffeff0
+// bar@GOTPCREL-4 = 0x2350 (got entry for `bar`) - 0x3368 (.) + 4 = 0xffffefe4
+// CHECK: Contents of section .data:
+//  3360 f0efffff f0efffff e4efffff
+  .word bar@GOTPCREL
+  .word bar@GOTPCREL+4
+  .word bar@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@GOTPCREL
+        .word extern_sym@GOTPCREL+4
+        .word negative_offset@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: }

@PiJoules
Copy link
Contributor Author

Didn't notice until now that 41 was taken up by R_RISCV_GNU_VTINHERIT which I believe is a very old relocation that's unsupported by most linkers along with R_RISCV_GNU_VTENTRY. Not sure if we want to remove them altogether or change their codes or give R_RISCV_GOT32_PCREL a new code. For now, I just removed them.

@asb
Copy link
Contributor

asb commented Jan 4, 2024

@PiJoules happy new year! Might you have a moment to address @MaskRay's review feedback?

This is the followup implementation to
riscv-non-isa/riscv-elf-psabi-doc#402 that
supports this relocation in llvm and lld.
@PiJoules
Copy link
Contributor Author

@PiJoules happy new year! Might you have a moment to address @MaskRay's review feedback?

Done. Sorry, just got back from vacation then got sick for a bit :/

@PiJoules PiJoules requested a review from MaskRay January 10, 2024 23:12
@PiJoules PiJoules merged commit f7678c8 into llvm:main Jan 10, 2024
3 of 4 checks passed
@PiJoules PiJoules deleted the riscv64-got32_pcrel branch January 11, 2024 00:10
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
This is the followup implementation to
riscv-non-isa/riscv-elf-psabi-doc#402 that
supports this relocation in llvm and lld.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants