diff options
-rw-r--r-- | lld/ELF/InputSection.cpp | 23 | ||||
-rw-r--r-- | lld/ELF/Relocations.cpp | 52 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 20 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 15 | ||||
-rw-r--r-- | lld/ELF/Target.cpp | 6 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 8 |
7 files changed, 63 insertions, 63 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index bd6d3baf32c..a151e086c21 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -402,16 +402,16 @@ getRelocTargetVA(uint32_t Type, int64_t A, typename ELFT::uint P, case R_RELAX_TLS_GD_TO_IE_ABS: return Body.getGotVA<ELFT>() + A; case R_GOTONLY_PC: - return In<ELFT>::Got->getVA() + A - P; + return InX::Got->getVA() + A - P; case R_GOTONLY_PC_FROM_END: - return In<ELFT>::Got->getVA() + A - P + In<ELFT>::Got->getSize(); + return InX::Got->getVA() + A - P + InX::Got->getSize(); case R_GOTREL: - return Body.getVA(A) - In<ELFT>::Got->getVA(); + return Body.getVA(A) - InX::Got->getVA(); case R_GOTREL_FROM_END: - return Body.getVA(A) - In<ELFT>::Got->getVA() - In<ELFT>::Got->getSize(); + return Body.getVA(A) - InX::Got->getVA() - InX::Got->getSize(); case R_GOT_FROM_END: case R_RELAX_TLS_GD_TO_IE_END: - return Body.getGotOffset() + A - In<ELFT>::Got->getSize(); + return Body.getGotOffset() + A - InX::Got->getSize(); case R_GOT_OFF: return Body.getGotOffset() + A; case R_GOT_PAGE_PC: @@ -520,19 +520,18 @@ getRelocTargetVA(uint32_t Type, int64_t A, typename ELFT::uint P, case R_SIZE: return Body.getSize<ELFT>() + A; case R_TLSDESC: - return In<ELFT>::Got->getGlobalDynAddr(Body) + A; + return InX::Got->getGlobalDynAddr(Body) + A; case R_TLSDESC_PAGE: - return getAArch64Page(In<ELFT>::Got->getGlobalDynAddr(Body) + A) - + return getAArch64Page(InX::Got->getGlobalDynAddr(Body) + A) - getAArch64Page(P); case R_TLSGD: - return In<ELFT>::Got->getGlobalDynOffset(Body) + A - - In<ELFT>::Got->getSize(); + return InX::Got->getGlobalDynOffset(Body) + A - InX::Got->getSize(); case R_TLSGD_PC: - return In<ELFT>::Got->getGlobalDynAddr(Body) + A - P; + return InX::Got->getGlobalDynAddr(Body) + A - P; case R_TLSLD: - return In<ELFT>::Got->getTlsIndexOff() + A - In<ELFT>::Got->getSize(); + return InX::Got->getTlsIndexOff() + A - InX::Got->getSize(); case R_TLSLD_PC: - return In<ELFT>::Got->getTlsIndexVA() + A - P; + return InX::Got->getTlsIndexVA() + A - P; } llvm_unreachable("Invalid expression"); } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 4071b065d35..ea7477e0384 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -156,17 +156,17 @@ static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, auto AddTlsReloc = [&](uint64_t Off, uint32_t Type, SymbolBody *Dest, bool Dyn) { if (Dyn) - In<ELFT>::RelaDyn->addReloc({Type, In<ELFT>::Got, Off, false, Dest, 0}); + In<ELFT>::RelaDyn->addReloc({Type, InX::Got, Off, false, Dest, 0}); else - In<ELFT>::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); + InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); }; // Local Dynamic is for access to module local TLS variables, while still // being suitable for being dynamically loaded via dlopen. // GOT[e0] is the module index, with a special value of 0 for the current // module. GOT[e1] is unused. There only needs to be one module index entry. - if (Expr == R_TLSLD_PC && In<ELFT>::Got->addTlsIndex()) { - AddTlsReloc(In<ELFT>::Got->getTlsIndexOff(), Target->TlsModuleIndexRel, + if (Expr == R_TLSLD_PC && InX::Got->addTlsIndex()) { + AddTlsReloc(InX::Got->getTlsIndexOff(), Target->TlsModuleIndexRel, NeedDynId ? nullptr : &Body, NeedDynId); C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; @@ -176,8 +176,8 @@ static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, // the module index and offset of symbol in TLS block we can fill these in // using static GOT relocations. if (Expr == R_TLSGD_PC) { - if (In<ELFT>::Got->addDynTlsEntry(Body)) { - uint64_t Off = In<ELFT>::Got->getGlobalDynOffset(Body); + if (InX::Got->addDynTlsEntry(Body)) { + uint64_t Off = InX::Got->getGlobalDynOffset(Body); AddTlsReloc(Off, Target->TlsModuleIndexRel, &Body, NeedDynId); AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Body, NeedDynOff); @@ -207,10 +207,10 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, bool IsPreemptible = isPreemptible(Body, Type); if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) && Config->Shared) { - if (In<ELFT>::Got->addDynTlsEntry(Body)) { - uint64_t Off = In<ELFT>::Got->getGlobalDynOffset(Body); - In<ELFT>::RelaDyn->addReloc({Target->TlsDescRel, In<ELFT>::Got, Off, - !IsPreemptible, &Body, 0}); + if (InX::Got->addDynTlsEntry(Body)) { + uint64_t Off = InX::Got->getGlobalDynOffset(Body); + In<ELFT>::RelaDyn->addReloc( + {Target->TlsDescRel, InX::Got, Off, !IsPreemptible, &Body, 0}); } if (Expr != R_TLSDESC_CALL) C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); @@ -224,10 +224,10 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body}); return 2; } - if (In<ELFT>::Got->addTlsIndex()) - In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got, - In<ELFT>::Got->getTlsIndexOff(), false, - nullptr, 0}); + if (InX::Got->addTlsIndex()) + In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::Got, + InX::Got->getTlsIndexOff(), false, nullptr, + 0}); C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; } @@ -242,19 +242,19 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD, R_TLSGD_PC>(Expr)) { if (Config->Shared) { - if (In<ELFT>::Got->addDynTlsEntry(Body)) { - uint64_t Off = In<ELFT>::Got->getGlobalDynOffset(Body); + if (InX::Got->addDynTlsEntry(Body)) { + uint64_t Off = InX::Got->getGlobalDynOffset(Body); In<ELFT>::RelaDyn->addReloc( - {Target->TlsModuleIndexRel, In<ELFT>::Got, Off, false, &Body, 0}); + {Target->TlsModuleIndexRel, InX::Got, Off, false, &Body, 0}); // If the symbol is preemptible we need the dynamic linker to write // the offset too. uint64_t OffsetOff = Off + Config->Wordsize; if (IsPreemptible) - In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got, - OffsetOff, false, &Body, 0}); + In<ELFT>::RelaDyn->addReloc( + {Target->TlsOffsetRel, InX::Got, OffsetOff, false, &Body, 0}); else - In<ELFT>::Got->Relocations.push_back( + InX::Got->Relocations.push_back( {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Body}); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); @@ -268,8 +268,8 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type, Offset, Addend, &Body}); if (!Body.isInGot()) { - In<ELFT>::Got->addEntry(Body); - In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::Got, + InX::Got->addEntry(Body); + In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, InX::Got, Body.getGotOffset(), false, &Body, 0}); } } else { @@ -774,7 +774,7 @@ static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt, template <class ELFT> static void addGotEntry(SymbolBody &Sym, bool Preemptible) { - In<ELFT>::Got->addEntry(Sym); + InX::Got->addEntry(Sym); uint64_t Off = Sym.getGotOffset(); uint32_t DynType; @@ -792,10 +792,10 @@ static void addGotEntry(SymbolBody &Sym, bool Preemptible) { bool Constant = !Preemptible && !(Config->Pic && !isAbsolute(Sym)); if (!Constant) In<ELFT>::RelaDyn->addReloc( - {DynType, In<ELFT>::Got, Off, !Preemptible, &Sym, 0}); + {DynType, InX::Got, Off, !Preemptible, &Sym, 0}); if (Constant || (!Config->IsRela && !Preemptible)) - In<ELFT>::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym}); + InX::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym}); } // The reason we have to do this early scan is as follows @@ -856,7 +856,7 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { // needs it to be created. Here we request for that. if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL, R_GOTREL_FROM_END, R_PPC_TOC>(Expr)) - In<ELFT>::Got->HasGotOffRel = true; + InX::Got->HasGotOffRel = true; // Read an addend. int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data()); diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 2090b33e8cd..4032504f437 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -164,7 +164,7 @@ uint64_t SymbolBody::getVA(int64_t Addend) const { } template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const { - return In<ELFT>::Got->getVA() + getGotOffset(); + return InX::Got->getVA() + getGotOffset(); } uint64_t SymbolBody::getGotOffset() const { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index be8b12c9f76..ccdd6c9ffc4 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -618,17 +618,16 @@ template <class ELFT> void EhFrameSection<ELFT>::writeTo(uint8_t *Buf) { } } -template <class ELFT> -GotSection<ELFT>::GotSection() +GotBaseSection::GotBaseSection() : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Target->GotEntrySize, ".got") {} -template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody &Sym) { +void GotBaseSection::addEntry(SymbolBody &Sym) { Sym.GotIndex = NumEntries; ++NumEntries; } -template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) { +bool GotBaseSection::addDynTlsEntry(SymbolBody &Sym) { if (Sym.GlobalDynIndex != -1U) return false; Sym.GlobalDynIndex = NumEntries; @@ -639,7 +638,7 @@ template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) { // Reserves TLS entries for a TLS module ID and a TLS block offset. // In total it takes two GOT slots. -template <class ELFT> bool GotSection<ELFT>::addTlsIndex() { +bool GotBaseSection::addTlsIndex() { if (TlsIndexOff != uint32_t(-1)) return false; TlsIndexOff = NumEntries * Config->Wordsize; @@ -647,21 +646,19 @@ template <class ELFT> bool GotSection<ELFT>::addTlsIndex() { return true; } -template <class ELFT> -uint64_t GotSection<ELFT>::getGlobalDynAddr(const SymbolBody &B) const { +uint64_t GotBaseSection::getGlobalDynAddr(const SymbolBody &B) const { return this->getVA() + B.GlobalDynIndex * Config->Wordsize; } -template <class ELFT> -uint64_t GotSection<ELFT>::getGlobalDynOffset(const SymbolBody &B) const { +uint64_t GotBaseSection::getGlobalDynOffset(const SymbolBody &B) const { return B.GlobalDynIndex * Config->Wordsize; } -template <class ELFT> void GotSection<ELFT>::finalizeContents() { +void GotBaseSection::finalizeContents() { Size = NumEntries * Config->Wordsize; } -template <class ELFT> bool GotSection<ELFT>::empty() const { +bool GotBaseSection::empty() const { // If we have a relocation that is relative to GOT (such as GOTOFFREL), // we need to emit a GOT even if it's empty. return NumEntries == 0 && !HasGotOffRel; @@ -2249,6 +2246,7 @@ SyntheticSection *InX::Dynamic; StringTableSection *InX::DynStrTab; InputSection *InX::Interp; GdbIndexSection *InX::GdbIndex; +GotBaseSection *InX::Got; GotPltSection *InX::GotPlt; IgotPltSection *InX::IgotPlt; MipsGotSection *InX::MipsGot; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 006ba420c97..43ee30e084f 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -104,10 +104,9 @@ private: llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap; }; -template <class ELFT> class GotSection final : public SyntheticSection { +class GotBaseSection : public SyntheticSection { public: - GotSection(); - void writeTo(uint8_t *Buf) override; + GotBaseSection(); size_t getSize() const override { return Size; } void finalizeContents() override; bool empty() const override; @@ -125,12 +124,17 @@ public: // that relies on its address. bool HasGotOffRel = false; -private: +protected: size_t NumEntries = 0; uint32_t TlsIndexOff = -1; uint64_t Size = 0; }; +template <class ELFT> class GotSection final : public GotBaseSection { +public: + void writeTo(uint8_t *Buf) override; +}; + // .note.gnu.build-id section. class BuildIdSection : public SyntheticSection { // First 16 bytes are a header. @@ -754,6 +758,7 @@ struct InX { static StringTableSection *DynStrTab; static InputSection *Interp; static GdbIndexSection *GdbIndex; + static GotBaseSection *Got; static GotPltSection *GotPlt; static IgotPltSection *IgotPlt; static MipsGotSection *MipsGot; @@ -768,7 +773,6 @@ template <class ELFT> struct In : public InX { static SymbolTableSection<ELFT> *DynSymTab; static EhFrameHeader<ELFT> *EhFrameHdr; static GnuHashTableSection<ELFT> *GnuHashTab; - static GotSection<ELFT> *Got; static EhFrameSection<ELFT> *EhFrame; static HashTableSection<ELFT> *HashTab; static RelocationSection<ELFT> *RelaDyn; @@ -783,7 +787,6 @@ template <class ELFT> struct In : public InX { template <class ELFT> SymbolTableSection<ELFT> *In<ELFT>::DynSymTab; template <class ELFT> EhFrameHeader<ELFT> *In<ELFT>::EhFrameHdr; template <class ELFT> GnuHashTableSection<ELFT> *In<ELFT>::GnuHashTab; -template <class ELFT> GotSection<ELFT> *In<ELFT>::Got; template <class ELFT> EhFrameSection<ELFT> *In<ELFT>::EhFrame; template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab; template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn; diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 6ba6d5b7763..86c79427bfd 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -460,7 +460,7 @@ void X86TargetInfo::writePltHeader(uint8_t *Buf) const { }; memcpy(Buf, V, sizeof(V)); - uint32_t Ebx = In<ELF32LE>::Got->getVA() + In<ELF32LE>::Got->getSize(); + uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); uint32_t GotPlt = InX::GotPlt->getVA() - Ebx; write32le(Buf + 2, GotPlt + 4); write32le(Buf + 8, GotPlt + 8); @@ -490,7 +490,7 @@ void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, if (Config->Pic) { // jmp *foo@GOT(%ebx) - uint32_t Ebx = In<ELF32LE>::Got->getVA() + In<ELF32LE>::Got->getSize(); + uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); Buf[1] = 0xa3; write32le(Buf + 2, GotPltEntryAddr - Ebx); } else { @@ -1140,7 +1140,7 @@ uint64_t getPPC64TocBase() { // TOC starts where the first of these sections starts. We always create a // .got when we see a relocation that uses it, so for us the start is always // the .got. - uint64_t TocVA = In<ELF64BE>::Got->getVA(); + uint64_t TocVA = InX::Got->getVA(); // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 // thus permitting a full 64 Kbytes segment. Note that the glibc startup diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index faa6997357e..1958c90f895 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -404,8 +404,8 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { InX::MipsGot = make<MipsGotSection>(); Add(InX::MipsGot); } else { - In<ELFT>::Got = make<GotSection<ELFT>>(); - Add(In<ELFT>::Got); + InX::Got = make<GotSection<ELFT>>(); + Add(InX::Got); } InX::GotPlt = make<GotPltSection>(); @@ -613,7 +613,7 @@ template <class ELFT> bool elf::isRelroSection(const OutputSection *Sec) { // .got contains pointers to external symbols. They are resolved by // the dynamic linker when a module is loaded into memory, and after // that they are not expected to change. So, it can be in RELRO. - if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec) + if (InX::Got && Sec == InX::Got->OutSec) return true; // .got.plt contains pointers to external function symbols. They are @@ -1184,7 +1184,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { applySynthetic({In<ELFT>::DynSymTab, InX::Bss, InX::BssRelRo, In<ELFT>::GnuHashTab, In<ELFT>::HashTab, In<ELFT>::SymTab, InX::ShStrTab, InX::StrTab, In<ELFT>::VerDef, - InX::DynStrTab, InX::GdbIndex, In<ELFT>::Got, + InX::DynStrTab, InX::GdbIndex, InX::Got, InX::MipsGot, InX::IgotPlt, InX::GotPlt, In<ELFT>::RelaDyn, In<ELFT>::RelaIplt, In<ELFT>::RelaPlt, InX::Plt, InX::Iplt, In<ELFT>::EhFrameHdr, |