[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
This commit is contained in:
Job Noorman
2023-06-22 09:32:32 +02:00
parent 89f493392d
commit b410d24a19
4 changed files with 74 additions and 2 deletions

View File

@@ -103,6 +103,8 @@ static bool isSupportedRISCV(uint64_t Type) {
case ELF::R_RISCV_PCREL_LO12_I:
case ELF::R_RISCV_RVC_JUMP:
case ELF::R_RISCV_RVC_BRANCH:
case ELF::R_RISCV_ADD32:
case ELF::R_RISCV_SUB32:
return true;
}
}
@@ -196,6 +198,8 @@ static size_t getSizeForTypeRISCV(uint64_t Type) {
case ELF::R_RISCV_32_PCREL:
case ELF::R_RISCV_CALL:
case ELF::R_RISCV_CALL_PLT:
case ELF::R_RISCV_ADD32:
case ELF::R_RISCV_SUB32:
return 4;
case ELF::R_RISCV_GOT_HI20:
// See extractValueRISCV for why this is necessary.
@@ -509,6 +513,9 @@ static uint64_t extractValueRISCV(uint64_t Type, uint64_t Contents,
return SignExtend64<11>(Contents >> 2);
case ELF::R_RISCV_RVC_BRANCH:
return SignExtend64<8>(((Contents >> 2) & 0x1f) | ((Contents >> 5) & 0xe0));
case ELF::R_RISCV_ADD32:
case ELF::R_RISCV_SUB32:
return Contents;
}
}
@@ -668,6 +675,9 @@ static bool isPCRelativeRISCV(uint64_t Type) {
switch (Type) {
default:
llvm_unreachable("Unknown relocation type");
case ELF::R_RISCV_ADD32:
case ELF::R_RISCV_SUB32:
return false;
case ELF::R_RISCV_JAL:
case ELF::R_RISCV_CALL:
case ELF::R_RISCV_CALL_PLT:
@@ -858,7 +868,16 @@ const MCExpr *Relocation::createExpr(MCStreamer *Streamer,
}
MCBinaryExpr::Opcode Relocation::getComposeOpcodeFor(uint64_t Type) {
llvm_unreachable("not implemented");
assert(Arch == Triple::riscv64 && "only implemented for RISC-V");
switch (Type) {
default:
llvm_unreachable("not implemented");
case ELF::R_RISCV_ADD32:
return MCBinaryExpr::Add;
case ELF::R_RISCV_SUB32:
return MCBinaryExpr::Sub;
}
}
#define ELF_RELOC(name, value) #name,

View File

@@ -2985,7 +2985,9 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
};
if ((ReferencedSection && refersToReorderedSection(ReferencedSection)) ||
(opts::ForceToDataRelocations && checkMaxDataRelocations()))
(opts::ForceToDataRelocations && checkMaxDataRelocations()) ||
// RISC-V has ADD/SUB data-to-data relocations
BC->isRISCV())
ForceRelocation = true;
if (IsFromCode) {

View File

@@ -0,0 +1,28 @@
/// NOTE: assign section addresses explicitly to make the symbol difference
/// calculation below less fragile.
// RUN: %clang %cflags -Wl,--section-start=.text=0x1000,--section-start=.data=0x2000 -o %t %s
// RUN: llvm-bolt -o %t.bolt %t
// RUN: llvm-readelf -x .data %t.bolt | FileCheck %s
.text
.globl _start
.p2align 1
_start:
.LBB0_0:
auipc a1, %pcrel_hi(.LJTI0_0)
addi a1, a1, %pcrel_lo(.LBB0_0)
lw a0, (a1)
add a0, a0, a1
jr a0
.LBB0_1:
ret
.size _start, .-_start
.data
/// .LJTI0_0 = 0x2000
/// .LBB0_1 = 0x40000e
// CHECK: Hex dump of section '.data':
// CHECK-NEXT: 0x00002000 0ee03f00
.LJTI0_0:
.word .LBB0_1 - .LJTI0_0

View File

@@ -0,0 +1,23 @@
// RUN: %clang %cflags -o %t %s
// RUN: llvm-bolt -o %t.bolt %t
// RUN: llvm-readelf -x .data %t.bolt | FileCheck %s
.text
.option norvc
.globl _start
.p2align 1
_start:
// Force BOLT into relocation mode
.reloc 0, R_RISCV_NONE
// BOLT removes this nop so the label difference is initially 8 but should be
// 4 after BOLT processes it.
nop
beq x0, x0, _test_end
_test_end:
ret
.size _start, .-_start
.data
// CHECK: Hex dump of section '.data':
// CHECK: 0x{{.*}} 04000000
.word _test_end - _start