Index: lld/trunk/ELF/Arch/PPC64.cpp =================================================================== --- lld/trunk/ELF/Arch/PPC64.cpp +++ lld/trunk/ELF/Arch/PPC64.cpp @@ -111,6 +111,7 @@ class PPC64 final : public TargetInfo { public: PPC64(); + int getTlsGdRelaxSkip(RelType Type) const override; uint32_t calcEFlags() const override; RelExpr getRelExpr(RelType Type, const Symbol &S, const uint8_t *Loc) const override; @@ -241,6 +242,20 @@ write32(TrapInstr.data(), 0x7fe00008); } +int PPC64::getTlsGdRelaxSkip(RelType Type) const { + // A __tls_get_addr call instruction is marked with 2 relocations: + // + // R_PPC64_TLSGD / R_PPC64_TLSLD: marker relocation + // R_PPC64_REL24: __tls_get_addr + // + // After the relaxation we no longer call __tls_get_addr and should skip both + // relocations to not create a false dependence on __tls_get_addr being + // defined. + if (Type == R_PPC64_TLSGD || Type == R_PPC64_TLSLD) + return 2; + return 1; +} + static uint32_t getEFlags(InputFile *File) { if (Config->EKind == ELF64BEKind) return cast>(File)->getObj().getHeader()->e_flags; Index: lld/trunk/ELF/Arch/X86.cpp =================================================================== --- lld/trunk/ELF/Arch/X86.cpp +++ lld/trunk/ELF/Arch/X86.cpp @@ -23,6 +23,7 @@ class X86 : public TargetInfo { public: X86(); + int getTlsGdRelaxSkip(RelType Type) const override; RelExpr getRelExpr(RelType Type, const Symbol &S, const uint8_t *Loc) const override; int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; @@ -58,7 +59,6 @@ GotPltEntrySize = 4; PltEntrySize = 16; PltHeaderSize = 16; - TlsGdRelaxSkip = 2; TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3 // Align to the non-PAE large page size (known as a superpage or huge page). @@ -66,6 +66,10 @@ DefaultImageBase = 0x400000; } +int X86::getTlsGdRelaxSkip(RelType Type) const { + return 2; +} + RelExpr X86::getRelExpr(RelType Type, const Symbol &S, const uint8_t *Loc) const { switch (Type) { Index: lld/trunk/ELF/Arch/X86_64.cpp =================================================================== --- lld/trunk/ELF/Arch/X86_64.cpp +++ lld/trunk/ELF/Arch/X86_64.cpp @@ -25,6 +25,7 @@ template class X86_64 : public TargetInfo { public: X86_64(); + int getTlsGdRelaxSkip(RelType Type) const override; RelExpr getRelExpr(RelType Type, const Symbol &S, const uint8_t *Loc) const override; RelType getDynRel(RelType Type) const override; @@ -65,7 +66,6 @@ GotPltEntrySize = 8; PltEntrySize = 16; PltHeaderSize = 16; - TlsGdRelaxSkip = 2; TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3 // Align to the large page size (known as a superpage or huge page). @@ -74,6 +74,11 @@ } template +int X86_64::getTlsGdRelaxSkip(RelType Type) const { + return 2; +} + +template RelExpr X86_64::getRelExpr(RelType Type, const Symbol &S, const uint8_t *Loc) const { switch (Type) { Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -205,7 +205,7 @@ C.Relocations.push_back( {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type, Offset, Addend, &Sym}); - return Target->TlsGdRelaxSkip; + return Target->getTlsGdRelaxSkip(Type); } if (Expr == R_TLSLD_HINT) return 1; @@ -278,7 +278,7 @@ {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type, Offset, Addend, &Sym}); } - return Target->TlsGdRelaxSkip; + return Target->getTlsGdRelaxSkip(Type); } // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally Index: lld/trunk/ELF/Target.h =================================================================== --- lld/trunk/ELF/Target.h +++ lld/trunk/ELF/Target.h @@ -32,6 +32,7 @@ virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {}; virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const; virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const; + virtual int getTlsGdRelaxSkip(RelType Type) const { return 1; } // If lazy binding is supported, the first entry of the PLT has code // to call the dynamic linker to resolve PLT entries the first time @@ -80,7 +81,6 @@ virtual ~TargetInfo(); - unsigned TlsGdRelaxSkip = 1; unsigned PageSize = 4096; unsigned DefaultMaxPageSize = 4096; Index: lld/trunk/test/ELF/ppc64-gd-to-ie.s =================================================================== --- lld/trunk/test/ELF/ppc64-gd-to-ie.s +++ lld/trunk/test/ELF/ppc64-gd-to-ie.s @@ -69,10 +69,6 @@ mtlr 0 blr - .globl __tls_get_addr - .type __tls_get_addr,@function -__tls_get_addr: - # CheckGot: .got 00000018 00000000100200c0 DATA # .got is at 0x100200c0 so the toc-base is 100280c0. Index: lld/trunk/test/ELF/ppc64-tls-gd-le.s =================================================================== --- lld/trunk/test/ELF/ppc64-tls-gd-le.s +++ lld/trunk/test/ELF/ppc64-tls-gd-le.s @@ -50,10 +50,6 @@ .Lfunc_end0: .size _start, .Lfunc_end0-.Lfunc_begin0 -.globl __tls_get_addr -.type __tls_get_addr,@function -__tls_get_addr: - # -- End function .type a,@object # @a .section .tdata,"awT",@progbits