Skip to content

Commit 4f0aa25

Browse files
committed
[lld][RISCV] Introduce handling for R_RISCV_PLT32 relocation
This introduces R_RISCV_PLT32, a PC-relative data relocation that takes the 32-bit relative offset to a function or its PLT entry. This is needed to support relative vtables on RISCV. Github PR: riscv-non-isa/riscv-elf-psabi-doc#363 D143226 has the llvm parts. Differential Revision: https://reviews.llvm.org/D143115
1 parent c1b3e88 commit 4f0aa25

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
280280
return R_PC;
281281
case R_RISCV_CALL:
282282
case R_RISCV_CALL_PLT:
283+
case R_RISCV_PLT32:
283284
return R_PLT_PC;
284285
case R_RISCV_GOT_HI20:
285286
return R_GOT_PC;
@@ -473,6 +474,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
473474
return;
474475
case R_RISCV_SET32:
475476
case R_RISCV_32_PCREL:
477+
case R_RISCV_PLT32:
476478
write32le(loc, val);
477479
return;
478480

lld/ELF/InputSection.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ static uint64_t getRISCVUndefinedRelativeWeakVA(uint64_t type, uint64_t p) {
517517
case R_RISCV_CALL_PLT:
518518
case R_RISCV_RVC_BRANCH:
519519
case R_RISCV_RVC_JUMP:
520+
case R_RISCV_PLT32:
520521
return p;
521522
default:
522523
return 0;

lld/test/ELF/riscv-reloc-plt32.s

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
2+
# RUN: llvm-mc -filetype=obj -triple=riscv64 %S/Inputs/abs256.s -o %t256.o
3+
#
4+
# RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t
5+
# RUN: llvm-objdump -s --section=.data %t | FileCheck %s
6+
#
7+
# CHECK: Contents of section .data:
8+
## 12158: S = 0x100, A = 0, P = 0x12158
9+
## S + A - P = 0xfffedfa8
10+
## 1215c: S = 0x100, A = 1, P = 0x1215c
11+
## S + A - P = 0xfffedfa5
12+
## 12160: S = 0x100, A = -1, P = 0x12160
13+
## S + A - P = 0xfffedf9f
14+
# CHECK-NEXT: 12158 a8dffeff a5dffeff 9fdffeff
15+
16+
.globl _start
17+
_start:
18+
.data
19+
.word foo@PLT - .
20+
.word foo@PLT - . + 1
21+
.word foo@PLT - . - 1

lld/test/ELF/riscv-undefined-weak.s

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
# RUN: ld.lld -e absolute %t.o -o %t
66
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,PC %s
7-
# RUN: llvm-readelf -x .data %t | FileCheck --check-prefixes=HEX %s
7+
# RUN: llvm-readelf -x .data %t | FileCheck --check-prefixes=HEX,HEX-WITHOUT-PLT %s
88

99
# RUN: ld.lld -e absolute %t.o -o %t --export-dynamic
1010
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,PLT %s
11-
# RUN: llvm-readelf -x .data %t | FileCheck --check-prefixes=HEX %s
11+
# RUN: llvm-readelf -x .data %t | FileCheck --check-prefixes=HEX,HEX-WITH-PLT %s
1212

1313
.weak target
1414
.global absolute, relative, branch
@@ -75,12 +75,28 @@ branch:
7575
## Absolute relocations are resolved to 0.
7676
# RELOC: 0x0 R_RISCV_64 target 0x3
7777
# RELOC-NEXT: 0x8 R_RISCV_32 target 0x4
78+
# RELOC-NEXT: 0xC R_RISCV_PLT32 target 0x0
79+
7880
# HEX: section '.data':
7981
# HEX-NEXT: 03000000 00000000 04000000
82+
# HEX-WITHOUT-PLT-SAME: 00000000
83+
84+
## A plt entry is created for target, so this is the offset between the
85+
## plt entry and this address.
86+
##
87+
## S = 0x11360 (the address of the plt entry for target)
88+
## A = 0
89+
## P = 0x1343c (the address of `.`)
90+
##
91+
## S - A + P = -0x0x20dc = 0xffffdf24
92+
# HEX-WITH-PLT-SAME: 24dfffff
93+
8094
.data
8195
.p2align 3
8296
.quad target+3
8397
.long target+4
8498

8599
# PC-NOT: .plt:
86100
# PLT: .plt:
101+
102+
.word target@plt - .

0 commit comments

Comments
 (0)