Skip to content

Commit 9726a49

Browse files
committed
[llvm][lld] Support R_RISCV_GOT32_PCREL
This is the followup implementation to riscv-non-isa/riscv-elf-psabi-doc#402 that supports this relocation in llvm and lld.
1 parent a1dc813 commit 9726a49

File tree

5 files changed

+47
-2
lines changed

5 files changed

+47
-2
lines changed

lld/ELF/Arch/RISCV.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
290290
case R_RISCV_PLT32:
291291
return R_PLT_PC;
292292
case R_RISCV_GOT_HI20:
293+
case R_RISCV_GOT32_PCREL:
293294
return R_GOT_PC;
294295
case R_RISCV_PCREL_LO12_I:
295296
case R_RISCV_PCREL_LO12_S:
@@ -499,6 +500,8 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
499500
case R_RISCV_SET32:
500501
case R_RISCV_32_PCREL:
501502
case R_RISCV_PLT32:
503+
case R_RISCV_GOT32_PCREL:
504+
checkInt(loc, val, 32, rel);
502505
write32le(loc, val);
503506
return;
504507

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// REQUIRES: riscv
2+
// RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
3+
// RUN: ld.lld %t.o -o %t.so -shared --noinhibit-exec 2>&1 | FileCheck %s --check-prefix=WARN
4+
// RUN: llvm-readelf -S %t.so | FileCheck --check-prefix=SEC %s
5+
// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
6+
7+
// SEC: .got PROGBITS 0000000000002390
8+
9+
.section .data
10+
.globl bar
11+
bar:
12+
13+
.globl _start
14+
_start: // PC = 0x33a8
15+
// bar@GOTPCREL = 0x2398 (got entry for `bar`) - 0x33a8 (.) = 0xf0efffff
16+
// bar@GOTPCREL+4 = 0x2398 (got entry for `bar`) - 0x33ac (.) + 4 = 0xf0efffff
17+
// bar@GOTPCREL-4 = 0x2398 (got entry for `bar`) - 0x33b0 (.) - 4 = 0xe4efffff
18+
// CHECK: Contents of section .data:
19+
// CHECK-NEXT: {{.*}} f0efffff f0efffff e4efffff
20+
.word bar@GOTPCREL
21+
.word bar@GOTPCREL+4
22+
.word bar@GOTPCREL-4
23+
24+
// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
25+
// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
26+
.word baz@GOTPCREL+0xffffffff
27+
.word baz@GOTPCREL-0xffffffff

llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def

+1-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ ELF_RELOC(R_RISCV_SUB8, 37)
4040
ELF_RELOC(R_RISCV_SUB16, 38)
4141
ELF_RELOC(R_RISCV_SUB32, 39)
4242
ELF_RELOC(R_RISCV_SUB64, 40)
43-
ELF_RELOC(R_RISCV_GNU_VTINHERIT, 41)
44-
ELF_RELOC(R_RISCV_GNU_VTENTRY, 42)
43+
ELF_RELOC(R_RISCV_GOT32_PCREL, 41)
4544
ELF_RELOC(R_RISCV_ALIGN, 43)
4645
ELF_RELOC(R_RISCV_RVC_BRANCH, 44)
4746
ELF_RELOC(R_RISCV_RVC_JUMP, 45)

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
106106
if (Expr->getKind() == MCExpr::Target &&
107107
cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL)
108108
return ELF::R_RISCV_32_PCREL;
109+
if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL)
110+
return ELF::R_RISCV_GOT32_PCREL;
109111
return ELF::R_RISCV_32;
110112
case FK_Data_8:
111113
return ELF::R_RISCV_64;
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o - | \
2+
// RUN: llvm-readobj -r - | FileCheck %s
3+
4+
.section .data
5+
this:
6+
.word this@GOTPCREL
7+
.word extern_sym@GOTPCREL+4
8+
.word negative_offset@GOTPCREL-4
9+
10+
// CHECK: Section ({{.*}}) .rela.data
11+
// CHECK-NEXT: 0x0 R_RISCV_GOT32_PCREL this 0x0
12+
// CHECK-NEXT: 0x4 R_RISCV_GOT32_PCREL extern_sym 0x4
13+
// CHECK-NEXT: 0x8 R_RISCV_GOT32_PCREL negative_offset 0xFFFFFFFFFFFFFFFC
14+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)