Skip to content

Commit

Permalink
[RISCV] Support RISC-V TLSDESC in LLD
Browse files Browse the repository at this point in the history
This patch adds support for RISC-V TLSDESC relocations, as described in
riscv-non-isa/riscv-elf-psabi-doc#373.

It does not attempt to handle relaxation for these cases, which will be
handled separately.
  • Loading branch information
ilovepi committed Jan 4, 2024
1 parent cde5cba commit 2e3d34a
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 3 deletions.
20 changes: 20 additions & 0 deletions lld/ELF/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class RISCV final : public TargetInfo {
const uint8_t *loc) const override;
void relocate(uint8_t *loc, const Relocation &rel,
uint64_t val) const override;
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
bool relaxOnce(int pass) const override;
};

Expand Down Expand Up @@ -119,6 +120,8 @@ RISCV::RISCV() {
}
gotRel = symbolicRel;

tlsDescRel = R_RISCV_TLSDESC_CALL;

// .got[0] = _DYNAMIC
gotHeaderEntriesNum = 1;

Expand Down Expand Up @@ -297,6 +300,13 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
return R_TLSGD_PC;
case R_RISCV_TLS_GOT_HI20:
return R_GOT_PC;
case R_RISCV_TLSDESC_HI20:
return R_TLSDESC_PC;
case R_RISCV_TLSDESC_LOAD_LO12:
case R_RISCV_TLSDESC_ADD_LO12:
return R_TLSDESC;
case R_RISCV_TLSDESC_CALL:
return R_TLSDESC_CALL;
case R_RISCV_TPREL_HI20:
case R_RISCV_TPREL_LO12_I:
case R_RISCV_TPREL_LO12_S:
Expand Down Expand Up @@ -418,6 +428,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_RISCV_PCREL_HI20:
case R_RISCV_TLS_GD_HI20:
case R_RISCV_TLS_GOT_HI20:
case R_RISCV_TLSDESC_HI20:
case R_RISCV_TPREL_HI20:
case R_RISCV_HI20: {
uint64_t hi = val + 0x800;
Expand All @@ -428,6 +439,8 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {

case R_RISCV_PCREL_LO12_I:
case R_RISCV_TPREL_LO12_I:
case R_RISCV_TLSDESC_LOAD_LO12:
case R_RISCV_TLSDESC_ADD_LO12:
case R_RISCV_LO12_I: {
uint64_t hi = (val + 0x800) >> 12;
uint64_t lo = val - (hi << 12);
Expand Down Expand Up @@ -515,6 +528,13 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
}
}

RelExpr RISCV::adjustTlsExpr(RelType type, RelExpr expr) const {
if (expr == R_RELAX_TLS_GD_TO_IE) {
return R_RELAX_TLS_GD_TO_IE_ABS;
}
return expr;
}

namespace {
struct SymbolAnchor {
uint64_t offset;
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
return sym.getSize() + a;
case R_TLSDESC:
return in.got->getTlsDescAddr(sym) + a;
case R_RISCV_TLSDESC_HI:
case R_TLSDESC_PC:
return in.got->getTlsDescAddr(sym) + a - p;
case R_TLSDESC_GOTPLT:
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
return handleMipsTlsRelocation(type, sym, c, offset, addend, expr);

if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
R_TLSDESC_GOTPLT>(expr) &&
R_TLSDESC_GOTPLT, R_RISCV_TLSDESC_HI>(expr) &&
config->shared) {
if (expr != R_TLSDESC_CALL) {
sym.setFlags(NEEDS_TLSDESC);
Expand Down Expand Up @@ -1333,7 +1333,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,

if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC,
R_LOONGARCH_TLSGD_PAGE_PC>(expr)) {
R_LOONGARCH_TLSGD_PAGE_PC, R_RISCV_TLSDESC_HI>(expr)) {
if (!toExecRelax) {
sym.setFlags(NEEDS_TLSGD);
c.addReloc({expr, type, offset, addend, &sym});
Expand Down
4 changes: 4 additions & 0 deletions lld/ELF/Relocations.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ enum RelExpr {
R_RISCV_ADD,
R_RISCV_LEB128,
R_RISCV_PC_INDIRECT,
R_RISCV_TLSDESC_HI,
R_RISCV_TLSDESC_LOAD_LO,
R_RISCV_TLSDESC_ADD_LO,
R_RISCV_TLSDESC_CALLER,
// Same as R_PC but with page-aligned semantics.
R_LOONGARCH_PAGE_PC,
// Same as R_PLT_PC but with page-aligned semantics.
Expand Down
3 changes: 2 additions & 1 deletion lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1943,7 +1943,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
}
}

if (config->emachine == EM_386 || config->emachine == EM_X86_64) {
if (config->emachine == EM_386 || config->emachine == EM_X86_64 ||
config->emachine == EM_RISCV) {
// On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
// way that:
//
Expand Down
43 changes: 43 additions & 0 deletions lld/test/ELF/riscv-tlsdesc-le.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// RUN: llvm-mc -filetype=obj -triple=riscv64-pc-linux %s -o %t.o
// RUN: ld.lld -shared %t.o -o %t.so
// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t.so | FileCheck %s
// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=REL %s

// CHECK: 00000000000012d8 <_start>:
// CHECK-NEXT: 12d8: auipc a0, 1
// CHECK-NEXT: 12dc: ld a1, 920(a0)
// CHECK-NEXT: 12e0: addi a0, a0, 920
// CHECK-NEXT: 12e4: jalr t0, a1
// CHECK-NEXT: 12e8: add a0, a0, tp
// CHECK-NEXT: 12ec: ret

// REL: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 2 entries
// REL: R_RISCV_TLSDESC_CALL ffffffffffffffe8
// REL-NEXT: R_RISCV_TLSDESC_CALL 0

.text
.attribute 4, 16
.attribute 5, "rv64i2p1"
.file "<stdin>"
.globl _start # -- Begin function _start
.p2align 2
.type _start,@function
_start: # @_start
# %bb.0: # %entry
.Ltlsdesc_hi0:
auipc a0, %tlsdesc_hi(unspecified)
ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
add a0, a0, tp
ret
.Lfunc_end0:
.size _start, .Lfunc_end0-_start
# -- End function
.section ".note.GNU-stack","",@progbits

.section .tbss,"awT",@nobits
.p2align 2

unspecified:
.zero 4

0 comments on commit 2e3d34a

Please sign in to comment.