From 0f6f162b95d066c51afed1448b505b543e4545d2 Mon Sep 17 00:00:00 2001 From: wanglei Date: Wed, 5 Jun 2024 17:45:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5-bogner --- lld/ELF/Arch/LoongArch.cpp | 40 +++++++ lld/ELF/InputSection.cpp | 2 + lld/ELF/Relocations.cpp | 13 +++ lld/ELF/Relocations.h | 1 + lld/test/ELF/loongarch-tlsdesc-gd-mixed.s | 23 ++++ lld/test/ELF/loongarch-tlsdesc.s | 134 ++++++++++++++++++++++ 6 files changed, 213 insertions(+) create mode 100644 lld/test/ELF/loongarch-tlsdesc-gd-mixed.s create mode 100644 lld/test/ELF/loongarch-tlsdesc.s diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp index 2c5d5df922c0f6..c6ee73f23d471a 100644 --- a/lld/ELF/Arch/LoongArch.cpp +++ b/lld/ELF/Arch/LoongArch.cpp @@ -98,11 +98,13 @@ uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc, RelType type) { case R_LARCH_PCALA64_LO20: case R_LARCH_GOT64_PC_LO20: case R_LARCH_TLS_IE64_PC_LO20: + case R_LARCH_TLS_DESC64_PC_LO20: pcalau12i_pc = pc - 8; break; case R_LARCH_PCALA64_HI12: case R_LARCH_GOT64_PC_HI12: case R_LARCH_TLS_IE64_PC_HI12: + case R_LARCH_TLS_DESC64_PC_HI12: pcalau12i_pc = pc - 12; break; default: @@ -190,11 +192,13 @@ LoongArch::LoongArch() { tlsModuleIndexRel = R_LARCH_TLS_DTPMOD64; tlsOffsetRel = R_LARCH_TLS_DTPREL64; tlsGotRel = R_LARCH_TLS_TPREL64; + tlsDescRel = R_LARCH_TLS_DESC64; } else { symbolicRel = R_LARCH_32; tlsModuleIndexRel = R_LARCH_TLS_DTPMOD32; tlsOffsetRel = R_LARCH_TLS_DTPREL32; tlsGotRel = R_LARCH_TLS_TPREL32; + tlsDescRel = R_LARCH_TLS_DESC32; } gotRel = symbolicRel; @@ -294,6 +298,10 @@ int64_t LoongArch::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_LARCH_JUMP_SLOT: // These relocations are defined as not having an implicit addend. return 0; + case R_LARCH_TLS_DESC32: + return read32le(buf + 4); + case R_LARCH_TLS_DESC64: + return read64le(buf + 8); } } @@ -486,6 +494,19 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, return config->relax ? R_RELAX_HINT : R_NONE; case R_LARCH_ALIGN: return R_RELAX_HINT; + case R_LARCH_TLS_DESC_PC_HI20: + case R_LARCH_TLS_DESC64_PC_LO20: + case R_LARCH_TLS_DESC64_PC_HI12: + return R_LOONGARCH_TLSDESC_PAGE_PC; + case R_LARCH_TLS_DESC_PC_LO12: + case R_LARCH_TLS_DESC_LD: + case R_LARCH_TLS_DESC_HI20: + case R_LARCH_TLS_DESC_LO12: + case R_LARCH_TLS_DESC64_LO20: + case R_LARCH_TLS_DESC64_HI12: + return R_TLSDESC; + case R_LARCH_TLS_DESC_CALL: + return R_TLSDESC_CALL; // Other known relocs that are explicitly unimplemented: // @@ -510,6 +531,8 @@ bool LoongArch::usesOnlyLowPageBits(RelType type) const { case R_LARCH_GOT_LO12: case R_LARCH_GOT_PC_LO12: case R_LARCH_TLS_IE_PC_LO12: + case R_LARCH_TLS_DESC_LO12: + case R_LARCH_TLS_DESC_PC_LO12: return true; } } @@ -594,6 +617,8 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_TLS_LE_LO12: case R_LARCH_TLS_IE_PC_LO12: case R_LARCH_TLS_IE_LO12: + case R_LARCH_TLS_DESC_PC_LO12: + case R_LARCH_TLS_DESC_LO12: write32le(loc, setK12(read32le(loc), extractBits(val, 11, 0))); return; @@ -609,6 +634,8 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_TLS_LD_HI20: case R_LARCH_TLS_GD_PC_HI20: case R_LARCH_TLS_GD_HI20: + case R_LARCH_TLS_DESC_PC_HI20: + case R_LARCH_TLS_DESC_HI20: write32le(loc, setJ20(read32le(loc), extractBits(val, 31, 12))); return; @@ -620,6 +647,8 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_TLS_LE64_LO20: case R_LARCH_TLS_IE64_PC_LO20: case R_LARCH_TLS_IE64_LO20: + case R_LARCH_TLS_DESC64_PC_LO20: + case R_LARCH_TLS_DESC64_LO20: write32le(loc, setJ20(read32le(loc), extractBits(val, 51, 32))); return; @@ -631,6 +660,8 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_TLS_LE64_HI12: case R_LARCH_TLS_IE64_PC_HI12: case R_LARCH_TLS_IE64_HI12: + case R_LARCH_TLS_DESC64_PC_HI12: + case R_LARCH_TLS_DESC64_HI12: write32le(loc, setK12(read32le(loc), extractBits(val, 63, 52))); return; @@ -679,6 +710,15 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_RELAX: return; // Ignored (for now) + case R_LARCH_TLS_DESC_LD: + return; // nothing to do. + case R_LARCH_TLS_DESC32: + write32le(loc + 4, val); + return; + case R_LARCH_TLS_DESC64: + write64le(loc + 8, val); + return; + default: llvm_unreachable("unknown relocation"); } diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index e6c5996c0b392a..03a66552d075b3 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -877,6 +877,8 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, return in.got->getTlsDescAddr(sym) + a - in.gotPlt->getVA(); case R_AARCH64_TLSDESC_PAGE: return getAArch64Page(in.got->getTlsDescAddr(sym) + a) - getAArch64Page(p); + case R_LOONGARCH_TLSDESC_PAGE_PC: + return getLoongArchPageDelta(in.got->getTlsDescAddr(sym) + a, p, type); case R_TLSGD_GOT: return in.got->getGlobalDynOffset(sym) + a; case R_TLSGD_GOTPLT: diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 2c02c2e572bfd0..b6a4a6d7953b1e 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1303,6 +1303,19 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym, if (config->emachine == EM_MIPS) return handleMipsTlsRelocation(type, sym, c, offset, addend, expr); + + // LoongArch does not yet implemented TLSDESC transition of DESC to LE/IE. + // Generates TLSDESC dynamic relocation for the symbol that is handled by the + // dynamic linker. + if (config->emachine == EM_LOONGARCH && + oneof(expr)) { + if (expr != R_TLSDESC_CALL) { + sym.setFlags(NEEDS_TLSDESC); + c.addReloc({expr, type, offset, addend, &sym}); + } + return 1; + } + bool isRISCV = config->emachine == EM_RISCV; if (oneof Date: Thu, 6 Jun 2024 09:15:08 +0800 Subject: [PATCH 2/2] modify the comment suggested by @xen0n Created using spr 1.3.5-bogner --- lld/ELF/Relocations.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index b6a4a6d7953b1e..6fd181c0358678 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1304,9 +1304,8 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym, if (config->emachine == EM_MIPS) return handleMipsTlsRelocation(type, sym, c, offset, addend, expr); - // LoongArch does not yet implemented TLSDESC transition of DESC to LE/IE. - // Generates TLSDESC dynamic relocation for the symbol that is handled by the - // dynamic linker. + // LoongArch does not yet implement transition from TLS DESC to LE/IE, so + // generate TLSDESC dynamic relocation for the dynamic linker to handle. if (config->emachine == EM_LOONGARCH && oneof(expr)) { if (expr != R_TLSDESC_CALL) {