From: Rafael Espindola Date: Tue, 8 Mar 2016 20:24:36 +0000 (+0000) Subject: Delete isTlsDynRel. X-Git-Tag: llvmorg-3.9.0-rc1~12236 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1f04c4488501deed5b6bfac098815bec14b8bb73;p=platform%2Fupstream%2Fllvm.git Delete isTlsDynRel. It was a badly specified hack for when a tls relocation should be propagated to the dynamic relocation table. This replaces it with a not as bad hack of saying that a local dynamic tls relocation is never preempted. I will try to remove even that second hack in the next patch. llvm-svn: 262955 --- diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 9e0ecd9..e4e876f 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -271,7 +271,7 @@ void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd, } uintX_t SymVA = Body->getVA(); - bool CBP = canBePreempted(Body); + bool CBP = canBePreempted(Body, Type); if (Target->needsPlt(Type, *Body)) { SymVA = Body->getPltVA(); } else if (Target->needsGot(Type, *Body)) { @@ -284,11 +284,6 @@ void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd, SymVA = Body->getGotVA(); if (Body->IsTls) Type = Target->getTlsGotRel(Type); - } else if (!Target->needsCopyRel(Type, *Body) && - isa>(*Body)) { - continue; - } else if (Target->isTlsDynRel(Type, *Body)) { - continue; } else if (Target->isSizeRel(Type) && CBP) { // A SIZE relocation is supposed to set a symbol size, but if a symbol // can be preempted, the size at runtime may be different than link time. @@ -302,6 +297,8 @@ void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd, SymVA = getMipsGpAddr() - AddrLoc + 4; else if (Body == Config->MipsLocalGp) SymVA = getMipsGpAddr(); + } else if (!Target->needsCopyRel(Type, *Body) && CBP) { + continue; } uintX_t Size = Body->getSize(); Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + A, Size + A, diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8c294f6..b825ba7 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -176,7 +176,7 @@ template void GotSection::writeTo(uint8_t *Buf) { // for detailed description: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf // As the first approach, we can just store addresses for all symbols. - if (Config->EMachine != EM_MIPS && canBePreempted(B)) + if (Config->EMachine != EM_MIPS && canBePreempted(B, 0)) continue; // The dynamic linker will take care of it. uintX_t VA = B->getVA(); write(Entry, VA); @@ -932,9 +932,16 @@ elf::getLocalRelTarget(const ObjectFile &File, // Returns true if a symbol can be replaced at load-time by a symbol // with the same name defined in other ELF executable or DSO. -bool elf::canBePreempted(const SymbolBody *Body) { +bool elf::canBePreempted(const SymbolBody *Body, unsigned Type) { if (!Body) return false; // Body is a local symbol. + + // FIXME: Both gold and bfd consider that a local dynamic tls relocation to + // a symbol will not be preempted. Is that actually relevant? The compiler + // should not use it if the symbol can be preempted. + if (Target->isTlsLocalDynamicRel(Type)) + return false; + if (Body->isShared()) return true; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 6810352..90db2cd 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -53,7 +53,7 @@ getLocalRelTarget(const ObjectFile &File, const llvm::object::Elf_Rel_Impl &Rel, typename llvm::object::ELFFile::uintX_t Addend); -bool canBePreempted(const SymbolBody *Body); +bool canBePreempted(const SymbolBody *Body, unsigned Type); bool isValidCIdentifier(StringRef S); diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index c38a087..83cfef7 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -87,7 +87,6 @@ public: bool isTlsLocalDynamicRel(uint32_t Type) const override; bool isTlsGlobalDynamicRel(uint32_t Type) const override; bool isTlsInitialExecRel(uint32_t Type) const override; - bool isTlsDynRel(uint32_t Type, const SymbolBody &S) const override; void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override; void writePltZero(uint8_t *Buf) const override; void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, @@ -123,7 +122,6 @@ public: bool isTlsLocalDynamicRel(uint32_t Type) const override; bool isTlsGlobalDynamicRel(uint32_t Type) const override; bool isTlsInitialExecRel(uint32_t Type) const override; - bool isTlsDynRel(uint32_t Type, const SymbolBody &S) const override; void writeGotPltHeader(uint8_t *Buf) const override; void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override; void writePltZero(uint8_t *Buf) const override; @@ -185,7 +183,6 @@ public: void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, int32_t Index, unsigned RelOff) const override; uint32_t getTlsGotRel(uint32_t Type) const override; - bool isTlsDynRel(uint32_t Type, const SymbolBody &S) const override; bool isRelRelative(uint32_t Type) const override; bool needsCopyRelImpl(uint32_t Type) const override; bool needsGot(uint32_t Type, SymbolBody &S) const override; @@ -281,7 +278,7 @@ bool TargetInfo::canRelaxTls(uint32_t Type, const SymbolBody *S) const { // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally // defined. if (isTlsInitialExecRel(Type)) - return !canBePreempted(S); + return !canBePreempted(S, Type); return false; } @@ -304,10 +301,6 @@ bool TargetInfo::needsCopyRel(uint32_t Type, const SymbolBody &S) const { return mayNeedCopy(S) && needsCopyRelImpl(Type); } -bool TargetInfo::isTlsDynRel(uint32_t Type, const SymbolBody &S) const { - return false; -} - bool TargetInfo::isGotRelative(uint32_t Type) const { return false; } bool TargetInfo::isHintRel(uint32_t Type) const { return false; } bool TargetInfo::isRelRelative(uint32_t Type) const { return true; } @@ -324,7 +317,7 @@ TargetInfo::PltNeed TargetInfo::needsPlt(uint32_t Type, const SymbolBody &S) const { if (isGnuIFunc(S)) return Plt_Explicit; - if (canBePreempted(&S) && needsPltImpl(Type)) + if (canBePreempted(&S, Type) && needsPltImpl(Type)) return Plt_Explicit; // This handles a non PIC program call to function in a shared library. @@ -428,15 +421,6 @@ bool X86TargetInfo::isTlsInitialExecRel(uint32_t Type) const { return Type == R_386_TLS_IE || Type == R_386_TLS_GOTIE; } -bool X86TargetInfo::isTlsDynRel(uint32_t Type, const SymbolBody &S) const { - if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || - Type == R_386_TLS_GOTIE) - return Config->Shared; - if (Type == R_386_TLS_IE) - return canBePreempted(&S); - return Type == R_386_TLS_GD; -} - void X86TargetInfo::writePltZero(uint8_t *Buf) const { // Executable files and shared object files have // separate procedure linkage tables. @@ -486,7 +470,7 @@ bool X86TargetInfo::needsCopyRelImpl(uint32_t Type) const { bool X86TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const { if (S.IsTls && Type == R_386_TLS_GD) - return Target->canRelaxTls(Type, &S) && canBePreempted(&S); + return Target->canRelaxTls(Type, &S) && canBePreempted(&S, Type); if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE) return !canRelaxTls(Type, &S); return Type == R_386_GOT32 || needsPlt(Type, S); @@ -564,7 +548,7 @@ size_t X86TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, const SymbolBody *S) const { switch (Type) { case R_386_TLS_GD: - if (canBePreempted(S)) + if (canBePreempted(S, Type)) relocateTlsGdToIe(Loc, BufEnd, P, SA); else relocateTlsGdToLe(Loc, BufEnd, P, SA); @@ -748,7 +732,7 @@ bool X86_64TargetInfo::refersToGotEntry(uint32_t Type) const { bool X86_64TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const { if (Type == R_X86_64_TLSGD) - return Target->canRelaxTls(Type, &S) && canBePreempted(&S); + return Target->canRelaxTls(Type, &S) && canBePreempted(&S, Type); if (Type == R_X86_64_GOTTPOFF) return !canRelaxTls(Type, &S); return refersToGotEntry(Type) || needsPlt(Type, S); @@ -774,11 +758,8 @@ bool X86_64TargetInfo::pointsToLocalDynamicGotEntry(uint32_t Type) const { } bool X86_64TargetInfo::isTlsLocalDynamicRel(uint32_t Type) const { - return Type == R_X86_64_DTPOFF32 || Type == R_X86_64_TLSLD; -} - -bool X86_64TargetInfo::isTlsDynRel(uint32_t Type, const SymbolBody &S) const { - return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_TLSGD; + return Type == R_X86_64_DTPOFF32 || Type == R_X86_64_DTPOFF64 || + Type == R_X86_64_TLSLD; } bool X86_64TargetInfo::needsPltImpl(uint32_t Type) const { @@ -918,7 +899,7 @@ size_t X86_64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, relocateTlsIeToLe(Loc, BufEnd, P, SA); return 0; case R_X86_64_TLSGD: { - if (canBePreempted(S)) + if (canBePreempted(S, Type)) relocateTlsGdToIe(Loc, BufEnd, P, SA); else relocateTlsGdToLe(Loc, BufEnd, P, SA); @@ -1309,15 +1290,6 @@ uint32_t AArch64TargetInfo::getTlsGotRel(uint32_t Type) const { return Type; } -bool AArch64TargetInfo::isTlsDynRel(uint32_t Type, const SymbolBody &S) const { - return Type == R_AARCH64_TLSDESC_ADR_PAGE21 || - Type == R_AARCH64_TLSDESC_LD64_LO12_NC || - Type == R_AARCH64_TLSDESC_ADD_LO12_NC || - Type == R_AARCH64_TLSDESC_CALL || - Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 || - Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; -} - bool AArch64TargetInfo::needsCopyRelImpl(uint32_t Type) const { switch (Type) { default: @@ -1494,7 +1466,7 @@ size_t AArch64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, case R_AARCH64_TLSDESC_LD64_LO12_NC: case R_AARCH64_TLSDESC_ADD_LO12_NC: case R_AARCH64_TLSDESC_CALL: { - if (canBePreempted(S)) + if (canBePreempted(S, Type)) fatal("Unsupported TLS optimization"); uint64_t X = S ? S->getVA() : SA; relocateTlsGdToLe(Type, Loc, BufEnd, P, X); diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index 1f9b614..ab4defa 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -27,7 +27,6 @@ public: virtual bool isTlsLocalDynamicRel(uint32_t Type) const; virtual bool isTlsGlobalDynamicRel(uint32_t Type) const; virtual uint32_t getDynRel(uint32_t Type) const { return Type; } - virtual bool isTlsDynRel(uint32_t Type, const SymbolBody &S) const; virtual uint32_t getTlsGotRel(uint32_t Type) const { return TlsGotRel; } virtual void writeGotHeader(uint8_t *Buf) const {} virtual void writeGotPltHeader(uint8_t *Buf) const {} diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index b67e7f1..d2de22f 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -281,10 +281,10 @@ static bool handleTlsRelocation(uint32_t Type, SymbolBody *Body, } return true; } - if (!canBePreempted(Body)) + if (!canBePreempted(Body, Type)) return true; } - return !Target->isTlsDynRel(Type, *Body); + return false; } // The reason we have to do this early scan is as follows @@ -327,7 +327,7 @@ void Writer::scanRelocs( if (Body) Body = Body->repl(); - bool CBP = canBePreempted(Body); + bool CBP = canBePreempted(Body, Type); if (handleTlsRelocation(Type, Body, C, RI)) continue; diff --git a/lld/test/ELF/no-inhibit-exec.s b/lld/test/ELF/no-inhibit-exec.s index fe2240b..2f2a62b 100644 --- a/lld/test/ELF/no-inhibit-exec.s +++ b/lld/test/ELF/no-inhibit-exec.s @@ -6,7 +6,7 @@ # CHECK: Disassembly of section .text: # CHECK-NEXT: _start -# CHECK-NEXT: 11000: e8 fb ef fe ff callq -69637 +# CHECK-NEXT: 11000: e8 00 00 00 00 callq 0 # next code will not link without noinhibit-exec flag # because of undefined symbol _bar