Skip to content

Commit b410d24

Browse files
committed
[BOLT][RISCV] Implement R_RISCV_ADD32/SUB32
Thispatch implements the R_RISCV_ADD32 and R_RISCV_SUB32 relocations for RISC-V. Reviewed By: rafauler Differential Revision: https://reviews.llvm.org/D146554
1 parent 89f4933 commit b410d24

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

bolt/lib/Core/Relocation.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ static bool isSupportedRISCV(uint64_t Type) {
103103
case ELF::R_RISCV_PCREL_LO12_I:
104104
case ELF::R_RISCV_RVC_JUMP:
105105
case ELF::R_RISCV_RVC_BRANCH:
106+
case ELF::R_RISCV_ADD32:
107+
case ELF::R_RISCV_SUB32:
106108
return true;
107109
}
108110
}
@@ -196,6 +198,8 @@ static size_t getSizeForTypeRISCV(uint64_t Type) {
196198
case ELF::R_RISCV_32_PCREL:
197199
case ELF::R_RISCV_CALL:
198200
case ELF::R_RISCV_CALL_PLT:
201+
case ELF::R_RISCV_ADD32:
202+
case ELF::R_RISCV_SUB32:
199203
return 4;
200204
case ELF::R_RISCV_GOT_HI20:
201205
// See extractValueRISCV for why this is necessary.
@@ -509,6 +513,9 @@ static uint64_t extractValueRISCV(uint64_t Type, uint64_t Contents,
509513
return SignExtend64<11>(Contents >> 2);
510514
case ELF::R_RISCV_RVC_BRANCH:
511515
return SignExtend64<8>(((Contents >> 2) & 0x1f) | ((Contents >> 5) & 0xe0));
516+
case ELF::R_RISCV_ADD32:
517+
case ELF::R_RISCV_SUB32:
518+
return Contents;
512519
}
513520
}
514521

@@ -668,6 +675,9 @@ static bool isPCRelativeRISCV(uint64_t Type) {
668675
switch (Type) {
669676
default:
670677
llvm_unreachable("Unknown relocation type");
678+
case ELF::R_RISCV_ADD32:
679+
case ELF::R_RISCV_SUB32:
680+
return false;
671681
case ELF::R_RISCV_JAL:
672682
case ELF::R_RISCV_CALL:
673683
case ELF::R_RISCV_CALL_PLT:
@@ -858,7 +868,16 @@ const MCExpr *Relocation::createExpr(MCStreamer *Streamer,
858868
}
859869

860870
MCBinaryExpr::Opcode Relocation::getComposeOpcodeFor(uint64_t Type) {
861-
llvm_unreachable("not implemented");
871+
assert(Arch == Triple::riscv64 && "only implemented for RISC-V");
872+
873+
switch (Type) {
874+
default:
875+
llvm_unreachable("not implemented");
876+
case ELF::R_RISCV_ADD32:
877+
return MCBinaryExpr::Add;
878+
case ELF::R_RISCV_SUB32:
879+
return MCBinaryExpr::Sub;
880+
}
862881
}
863882

864883
#define ELF_RELOC(name, value) #name,

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2985,7 +2985,9 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
29852985
};
29862986

29872987
if ((ReferencedSection && refersToReorderedSection(ReferencedSection)) ||
2988-
(opts::ForceToDataRelocations && checkMaxDataRelocations()))
2988+
(opts::ForceToDataRelocations && checkMaxDataRelocations()) ||
2989+
// RISC-V has ADD/SUB data-to-data relocations
2990+
BC->isRISCV())
29892991
ForceRelocation = true;
29902992

29912993
if (IsFromCode) {

bolt/test/RISCV/reloc-jt.s

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/// NOTE: assign section addresses explicitly to make the symbol difference
2+
/// calculation below less fragile.
3+
// RUN: %clang %cflags -Wl,--section-start=.text=0x1000,--section-start=.data=0x2000 -o %t %s
4+
// RUN: llvm-bolt -o %t.bolt %t
5+
// RUN: llvm-readelf -x .data %t.bolt | FileCheck %s
6+
7+
.text
8+
9+
.globl _start
10+
.p2align 1
11+
_start:
12+
.LBB0_0:
13+
auipc a1, %pcrel_hi(.LJTI0_0)
14+
addi a1, a1, %pcrel_lo(.LBB0_0)
15+
lw a0, (a1)
16+
add a0, a0, a1
17+
jr a0
18+
.LBB0_1:
19+
ret
20+
.size _start, .-_start
21+
22+
.data
23+
/// .LJTI0_0 = 0x2000
24+
/// .LBB0_1 = 0x40000e
25+
// CHECK: Hex dump of section '.data':
26+
// CHECK-NEXT: 0x00002000 0ee03f00
27+
.LJTI0_0:
28+
.word .LBB0_1 - .LJTI0_0

bolt/test/RISCV/reloc-label-diff.s

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang %cflags -o %t %s
2+
// RUN: llvm-bolt -o %t.bolt %t
3+
// RUN: llvm-readelf -x .data %t.bolt | FileCheck %s
4+
5+
.text
6+
.option norvc
7+
.globl _start
8+
.p2align 1
9+
_start:
10+
// Force BOLT into relocation mode
11+
.reloc 0, R_RISCV_NONE
12+
// BOLT removes this nop so the label difference is initially 8 but should be
13+
// 4 after BOLT processes it.
14+
nop
15+
beq x0, x0, _test_end
16+
_test_end:
17+
ret
18+
.size _start, .-_start
19+
20+
.data
21+
// CHECK: Hex dump of section '.data':
22+
// CHECK: 0x{{.*}} 04000000
23+
.word _test_end - _start

0 commit comments

Comments
 (0)