diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -144,8 +144,9 @@ case R_AARCH64_ADR_PREL_PG_HI21_NC: return R_AARCH64_PAGE_PC; case R_AARCH64_LD64_GOT_LO12_NC: - case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: return R_GOT; + case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: + return R_TLS_GOT; case R_AARCH64_LD64_GOTPAGE_LO15: return R_AARCH64_GOT_PAGE; case R_AARCH64_ADR_GOT_PAGE: diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp --- a/lld/ELF/Arch/ARM.cpp +++ b/lld/ELF/Arch/ARM.cpp @@ -108,9 +108,10 @@ // GOT(S) + A - GOT_ORG return R_GOT_OFF; case R_ARM_GOT_PREL: - case R_ARM_TLS_IE32: // GOT(S) + A - P return R_GOT_PC; + case R_ARM_TLS_IE32: + return R_TLS_GOT_PC; case R_ARM_SBREL32: return R_ARM_SBREL; case R_ARM_TARGET1: diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp --- a/lld/ELF/Arch/Hexagon.cpp +++ b/lld/ELF/Arch/Hexagon.cpp @@ -126,7 +126,7 @@ case R_HEX_IE_16_X: case R_HEX_IE_HI16: case R_HEX_IE_LO16: - return R_GOT; + return R_TLS_GOT; case R_HEX_GD_GOT_11_X: case R_HEX_GD_GOT_16_X: case R_HEX_GD_GOT_32_6_X: diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp --- a/lld/ELF/Arch/PPC.cpp +++ b/lld/ELF/Arch/PPC.cpp @@ -247,7 +247,7 @@ case R_PPC_GOT_TLSLD16: return R_TLSLD_GOT; case R_PPC_GOT_TPREL16: - return R_GOT_OFF; + return R_TLS_GOTOFF; case R_PPC_TLS: return R_TLSIE_HINT; case R_PPC_TLSGD: diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -972,9 +972,10 @@ case R_PPC64_TOC16_LO: return R_GOTREL; case R_PPC64_GOT_PCREL34: - case R_PPC64_GOT_TPREL_PCREL34: case R_PPC64_PCREL_OPT: return R_GOT_PC; + case R_PPC64_GOT_TPREL_PCREL34: + return R_TLS_GOT_PC; case R_PPC64_TOC16_HA: case R_PPC64_TOC16_LO_DS: return config->tocOptimize ? R_PPC64_RELAX_TOC : R_GOTREL; @@ -1010,7 +1011,7 @@ case R_PPC64_GOT_TPREL16_LO_DS: case R_PPC64_GOT_TPREL16_DS: case R_PPC64_GOT_TPREL16_HI: - return R_GOT_OFF; + return R_TLS_GOTOFF; case R_PPC64_GOT_DTPREL16_HA: case R_PPC64_GOT_DTPREL16_LO_DS: case R_PPC64_GOT_DTPREL16_DS: diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -262,7 +262,7 @@ return R_TLSGD_PC; case R_RISCV_TLS_GOT_HI20: config->hasStaticTlsModel = true; - return R_GOT_PC; + return R_TLS_GOT_PC; case R_RISCV_TPREL_HI20: case R_RISCV_TPREL_LO12_I: case R_RISCV_TPREL_LO12_S: diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp --- a/lld/ELF/Arch/X86.cpp +++ b/lld/ELF/Arch/X86.cpp @@ -106,7 +106,7 @@ case R_386_GOTPC: return R_GOTPLTONLY_PC; case R_386_TLS_IE: - return R_GOT; + return R_TLS_GOT; case R_386_GOT32: case R_386_GOT32X: // These relocations are arguably mis-designed because their calculations @@ -150,7 +150,7 @@ case R_386_TLS_DESC_CALL: return R_TLSDESC_CALL; case R_386_TLS_GOTIE: - return R_GOTPLT; + return R_TLS_GOT_GOTPLT; case R_386_GOTOFF: return R_GOTPLTREL; case R_386_TLS_LE: diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -352,8 +352,9 @@ case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: - case R_X86_64_GOTTPOFF: return R_GOT_PC; + case R_X86_64_GOTTPOFF: + return R_TLS_GOT_PC; case R_X86_64_GOTOFF64: return R_GOTPLTREL; case R_X86_64_PLTOFF64: diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -677,6 +677,7 @@ case R_ARM_SBREL: return sym.getVA(a) - getARMStaticBase(sym); case R_GOT: + case R_TLS_GOT: case R_RELAX_TLS_GD_TO_IE_ABS: return sym.getGotVA() + a; case R_GOTONLY_PC: @@ -689,10 +690,12 @@ case R_GOTPLTREL: return sym.getVA(a) - in.gotPlt->getVA(); case R_GOTPLT: + case R_TLS_GOT_GOTPLT: case R_RELAX_TLS_GD_TO_IE_GOTPLT: return sym.getGotVA() + a - in.gotPlt->getVA(); case R_TLSLD_GOT_OFF: case R_GOT_OFF: + case R_TLS_GOTOFF: case R_RELAX_TLS_GD_TO_IE_GOT_OFF: return sym.getGotOffset() + a; case R_AARCH64_GOT_PAGE_PC: @@ -701,6 +704,7 @@ case R_AARCH64_GOT_PAGE: return sym.getGotVA() + a - getAArch64Page(in.got->getVA()); case R_GOT_PC: + case R_TLS_GOT_PC: case R_RELAX_TLS_GD_TO_IE: return sym.getGotVA() + a - p; case R_MIPS_GOTREL: diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -73,6 +73,10 @@ R_TLSLD_GOT_OFF, R_TLSLD_HINT, R_TLSLD_PC, + R_TLS_GOT, + R_TLS_GOT_PC, + R_TLS_GOT_GOTPLT, + R_TLS_GOTOFF, // The following is abstract relocation types used for only one target. // diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -212,7 +212,6 @@ R_RISCV_PC_INDIRECT, R_PPC64_RELAX_GOT_PC>(expr); } - static RelExpr toPlt(RelExpr expr) { switch (expr) { case R_PPC64_CALL: @@ -903,14 +902,14 @@ // These expressions always compute a constant if (oneof(e)) + R_AARCH64_GOT_PAGE, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, + R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTPLT, R_PPC32_PLTREL, + R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD>(e)) return true; // These never do, except if the entire file is position dependent or if // only the low bits are used. - if (e == R_GOT || e == R_PLT) + if (e == R_GOT || e == R_PLT || e == R_TLS_GOT) return target->usesOnlyLowPageBits(type) || !config->isPic; if (sym.isPreemptible) @@ -1266,8 +1265,8 @@ return target->getTlsGdRelaxSkip(type); } - if (oneof(expr)) { + if (oneof(expr)) { // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally // defined. if (toExecRelax && isLocalInExecutable) { @@ -1276,8 +1275,9 @@ } else if (expr != R_TLSIE_HINT) { if (!sym.isInGot()) addTpOffsetGotEntry(sym); - // R_GOT needs a relative relocation for PIC on i386 and Hexagon. - if (expr == R_GOT && config->isPic && !target->usesOnlyLowPageBits(type)) + // R_TLS_GOT needs a relative relocation for PIC on i386 and Hexagon. + if (expr == R_TLS_GOT && config->isPic && + !target->usesOnlyLowPageBits(type)) addRelativeReloc(&c, offset, sym, addend, expr, type); else c.relocations.push_back({expr, type, offset, addend, &sym}); @@ -1389,7 +1389,7 @@ // // The 5 types that relative GOTPLT are all x86 and x86-64 specific. if (oneof(expr)) { + R_TLSDESC_GOTPLT, R_TLSGD_GOTPLT, R_TLS_GOT_GOTPLT>(expr)) { in.gotPlt->hasGotPltOffRel = true; } else if (oneof( expr)) { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1619,7 +1619,7 @@ // This function should only be called for non-preemptible symbols or // RelExpr values that refer to an address inside the output file (e.g. the // address of the GOT entry for a potentially preemptible symbol). - assert((!sym.isPreemptible || expr == R_GOT) && + assert((!sym.isPreemptible || expr == R_GOT || expr == R_TLS_GOT) && "cannot add relative relocation against preemptible symbol"); assert(expr != R_ADDEND && "expected non-addend relocation expression"); addReloc(DynamicReloc::AddendOnlyWithTargetVA, dynType, inputSec, offsetInSec,