Index: ELF/Arch/PPC64.cpp =================================================================== --- ELF/Arch/PPC64.cpp +++ 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 need to 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: ELF/Arch/X86.cpp =================================================================== --- ELF/Arch/X86.cpp +++ 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; +} + static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; } RelExpr X86::getRelExpr(RelType Type, const Symbol &S, Index: ELF/Arch/X86_64.cpp =================================================================== --- ELF/Arch/X86_64.cpp +++ 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). @@ -73,6 +73,11 @@ DefaultImageBase = 0x200000; } +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 { Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ 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: ELF/Target.h =================================================================== --- ELF/Target.h +++ 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: test/ELF/ppc64-gd-to-ie.s =================================================================== --- test/ELF/ppc64-gd-to-ie.s +++ 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: test/ELF/ppc64-tls-gd-le.s =================================================================== --- test/ELF/ppc64-tls-gd-le.s +++ 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