https://github.com/MaskRay updated
https://github.com/llvm/llvm-project/pull/79239
>From 3725fa4eac3d3d946289d7eb7213f3a1751a2770 Mon Sep 17 00:00:00 2001
From: Fangrui Song
Date: Tue, 23 Jan 2024 17:58:07 -0800
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
---
lld/ELF/Arch/RISCV.cpp| 158 +
lld/ELF/Relocations.cpp | 25 ++--
lld/test/ELF/riscv-tlsdesc-gd-mixed.s | 26
lld/test/ELF/riscv-tlsdesc-relax.s| 125 +
lld/test/ELF/riscv-tlsdesc.s | 192 ++
5 files changed, 492 insertions(+), 34 deletions(-)
create mode 100644 lld/test/ELF/riscv-tlsdesc-gd-mixed.s
create mode 100644 lld/test/ELF/riscv-tlsdesc-relax.s
create mode 100644 lld/test/ELF/riscv-tlsdesc.s
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index d7d3d3e47814971..67d7e2562e9b178 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -61,6 +61,7 @@ enum Op {
AUIPC = 0x17,
JALR = 0x67,
LD = 0x3003,
+ LUI = 0x37,
LW = 0x2003,
SRLI = 0x5013,
SUB = 0x4033,
@@ -73,6 +74,7 @@ enum Reg {
X_T0 = 5,
X_T1 = 6,
X_T2 = 7,
+ X_A0 = 10,
X_T3 = 28,
};
@@ -102,6 +104,26 @@ static uint32_t setLO12_S(uint32_t insn, uint32_t imm) {
(extractBits(imm, 4, 0) << 7);
}
+namespace {
+struct SymbolAnchor {
+ uint64_t offset;
+ Defined *d;
+ bool end; // true for the anchor of st_value+st_size
+};
+} // namespace
+
+struct elf::RISCVRelaxAux {
+ // This records symbol start and end offsets which will be adjusted according
+ // to the nearest relocDeltas element.
+ SmallVector anchors;
+ // For relocations[i], the actual offset is r_offset - (i ? relocDeltas[i-1]
:
+ // 0).
+ std::unique_ptr relocDeltas;
+ // For relocations[i], the actual type is relocTypes[i].
+ std::unique_ptr relocTypes;
+ SmallVector writes;
+};
+
RISCV::RISCV() {
copyRel = R_RISCV_COPY;
pltRel = R_RISCV_JUMP_SLOT;
@@ -119,6 +141,7 @@ RISCV::RISCV() {
tlsGotRel = R_RISCV_TLS_TPREL32;
}
gotRel = symbolicRel;
+ tlsDescRel = R_RISCV_TLSDESC;
// .got[0] = _DYNAMIC
gotHeaderEntriesNum = 1;
@@ -187,6 +210,8 @@ int64_t RISCV::getImplicitAddend(const uint8_t *buf,
RelType type) const {
case R_RISCV_JUMP_SLOT:
// These relocations are defined as not having an implicit addend.
return 0;
+ case R_RISCV_TLSDESC:
+return config->is64 ? read64le(buf + 8) : read32le(buf + 4);
}
}
@@ -295,6 +320,12 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol
,
case R_RISCV_PCREL_LO12_I:
case R_RISCV_PCREL_LO12_S:
return R_RISCV_PC_INDIRECT;
+ case R_RISCV_TLSDESC_HI20:
+ case R_RISCV_TLSDESC_LOAD_LO12:
+ case R_RISCV_TLSDESC_ADD_LO12:
+return R_TLSDESC_PC;
+ case R_RISCV_TLSDESC_CALL:
+return R_TLSDESC_CALL;
case R_RISCV_TLS_GD_HI20:
return R_TLSGD_PC;
case R_RISCV_TLS_GOT_HI20:
@@ -419,6 +450,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation ,
uint64_t val) const {
case R_RISCV_GOT_HI20:
case R_RISCV_PCREL_HI20:
+ case R_RISCV_TLSDESC_HI20:
case R_RISCV_TLS_GD_HI20:
case R_RISCV_TLS_GOT_HI20:
case R_RISCV_TPREL_HI20:
@@ -430,6 +462,8 @@ void RISCV::relocate(uint8_t *loc, const Relocation ,
uint64_t val) const {
}
case R_RISCV_PCREL_LO12_I:
+ case R_RISCV_TLSDESC_LOAD_LO12:
+ case R_RISCV_TLSDESC_ADD_LO12:
case R_RISCV_TPREL_LO12_I:
case R_RISCV_LO12_I: {
uint64_t hi = (val + 0x800) >> 12;
@@ -513,29 +547,113 @@ void RISCV::relocate(uint8_t *loc, const Relocation
, uint64_t val) const {
break;
case R_RISCV_RELAX:
-return; // Ignored (for now)
-
+return;
+ case R_RISCV_TLSDESC:
+// The addend is stored in the second word.
+if (config->is64)
+ write64le(loc + 8, val);
+else
+ write32le(loc + 4, val);
+break;
default:
llvm_unreachable("unknown relocation");
}
}
+static void tlsdescToIe(uint8_t *loc, const Relocation , uint64_t val) {
+ switch (rel.type) {
+ case R_RISCV_TLSDESC_HI20:
+ case R_RISCV_TLSDESC_LOAD_LO12:
+write32le(loc, 0x0013); // nop
+return;
+ case R_RISCV_TLSDESC_ADD_LO12:
+write32le(loc, utype(AUIPC, X_A0, hi20(val))); // auipc a0,
+return;
+ case R_RISCV_TLSDESC_CALL:
+if (config->is64)
+ write32le(loc, itype(LD, X_A0, X_A0, lo12(val))); // ld a0,(a0)
+else
+ write32le(loc, itype(LW, X_A0, X_A0, lo12(val))); // lw a0,(a0)
+return;
+ default:
+llvm_unreachable("unsupported relocation for TLSDESC to IE relaxation");
+ }
+}
+
+static void tlsdescToLe(uint8_t *loc, const Relocation , uint64_t val) {
+ switch (rel.type) {
+ case R_RISCV_TLSDESC_HI20:
+ case R_RISCV_TLSDESC_LOAD_LO12:
+write32le(loc, 0x0013); // nop
+return;
+ case R_RISCV_TLSDESC_ADD_LO12:
+