diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1443,8 +1443,6 @@ // all linker scripts have already been parsed. template void LinkerDriver::link(opt::InputArgList &Args) { Target = getTarget(); - InX::VerSym = nullptr; - InX::VerNeed = nullptr; Config->MaxPageSize = getMaxPageSize(Args); Config->ImageBase = getImageBase(Args); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -777,7 +777,6 @@ // identifier defined in the either .gnu.version_r or .gnu.version_d section. // The values 0 and 1 are reserved. All other values are used for versions in // the own object or in any of the dependencies. -template class VersionTableSection final : public SyntheticSection { public: VersionTableSection(); @@ -787,12 +786,24 @@ bool empty() const override; }; +class VersionNeedBaseSection : public SyntheticSection { +protected: + // The next available version identifier. + unsigned NextIndex; + +public: + VersionNeedBaseSection(); + virtual void addSymbol(Symbol *Sym) = 0; + virtual size_t getNeedNum() const = 0; +}; + // The .gnu.version_r section defines the version identifiers used by // .gnu.version. It contains a linked list of Elf_Verneed data structures. Each // Elf_Verneed specifies the version requirements for a single DSO, and contains // a reference to a linked list of Elf_Vernaux data structures which define the // mapping from version identifiers to version names. -template class VersionNeedSection final : public SyntheticSection { +template +class VersionNeedSection final : public VersionNeedBaseSection { typedef typename ELFT::Verneed Elf_Verneed; typedef typename ELFT::Vernaux Elf_Vernaux; @@ -800,16 +811,12 @@ // string table offsets of their sonames. std::vector *, size_t>> Needed; - // The next available version identifier. - unsigned NextIndex; - public: - VersionNeedSection(); - void addSymbol(Symbol *Sym); + void addSymbol(Symbol *Sym) override; void finalizeContents() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override; - size_t getNeedNum() const { return Needed.size(); } + size_t getNeedNum() const override { return Needed.size(); } bool empty() const override; }; @@ -1025,17 +1032,12 @@ SymbolTableBaseSection *SymTab; SymtabShndxSection *SymTabShndx; VersionDefinitionSection *VerDef; + VersionNeedBaseSection *VerNeed; + VersionTableSection *VerSym; }; extern InStruct In; -template struct InX { - static VersionTableSection *VerSym; - static VersionNeedSection *VerNeed; -}; - -template VersionTableSection *InX::VerSym; -template VersionNeedSection *InX::VerNeed; } // namespace elf } // namespace lld diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1405,16 +1405,16 @@ if (B->isDefined()) addSym(DT_FINI, B); - bool HasVerNeed = InX::VerNeed->getNeedNum() != 0; + bool HasVerNeed = In.VerNeed->getNeedNum() != 0; if (HasVerNeed || In.VerDef) - addInSec(DT_VERSYM, InX::VerSym); + addInSec(DT_VERSYM, In.VerSym); if (In.VerDef) { addInSec(DT_VERDEF, In.VerDef); addInt(DT_VERDEFNUM, getVerDefNum()); } if (HasVerNeed) { - addInSec(DT_VERNEED, InX::VerNeed); - addInt(DT_VERNEEDNUM, InX::VerNeed->getNeedNum()); + addInSec(DT_VERNEED, In.VerNeed); + addInt(DT_VERNEEDNUM, In.VerNeed->getNeedNum()); } if (Config->EMachine == EM_MIPS) { @@ -2769,24 +2769,23 @@ } // .gnu.version is a table where each entry is 2 byte long. -template -VersionTableSection::VersionTableSection() +VersionTableSection::VersionTableSection() : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t), ".gnu.version") { this->Entsize = 2; } -template void VersionTableSection::finalizeContents() { +void VersionTableSection::finalizeContents() { // At the moment of june 2016 GNU docs does not mention that sh_link field // should be set, but Sun docs do. Also readelf relies on this field. getParent()->Link = In.DynSymTab->getParent()->SectionIndex; } -template size_t VersionTableSection::getSize() const { +size_t VersionTableSection::getSize() const { return (In.DynSymTab->getSymbols().size() + 1) * 2; } -template void VersionTableSection::writeTo(uint8_t *Buf) { +void VersionTableSection::writeTo(uint8_t *Buf) { Buf += 2; for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) { write16(Buf, S.Sym->VersionId); @@ -2794,12 +2793,11 @@ } } -template bool VersionTableSection::empty() const { - return !In.VerDef && InX::VerNeed->empty(); +bool VersionTableSection::empty() const { + return !In.VerDef && In.VerNeed->empty(); } -template -VersionNeedSection::VersionNeedSection() +VersionNeedBaseSection::VersionNeedBaseSection() : SyntheticSection(SHF_ALLOC, SHT_GNU_verneed, sizeof(uint32_t), ".gnu.version_r") { // Identifiers in verneed section start at 2 because 0 and 1 are reserved @@ -3239,11 +3237,6 @@ template class elf::SymbolTableSection; template class elf::SymbolTableSection; -template class elf::VersionTableSection; -template class elf::VersionTableSection; -template class elf::VersionTableSection; -template class elf::VersionTableSection; - template class elf::VersionNeedSection; template class elf::VersionNeedSection; template class elf::VersionNeedSection; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -332,16 +332,16 @@ In.DynSymTab = make>(*In.DynStrTab); Add(In.DynSymTab); - InX::VerSym = make>(); - Add(InX::VerSym); + In.VerSym = make(); + Add(In.VerSym); if (!Config->VersionDefinitions.empty()) { In.VerDef = make(); Add(In.VerDef); } - InX::VerNeed = make>(); - Add(InX::VerNeed); + In.VerNeed = make>(); + Add(In.VerNeed); if (Config->GnuHash) { In.GnuHashTab = make(); @@ -1714,7 +1714,7 @@ In.DynSymTab->addSymbol(Sym); if (auto *File = dyn_cast_or_null>(Sym->File)) if (File->IsNeeded && !Sym->isUndefined()) - InX::VerNeed->addSymbol(Sym); + In.VerNeed->addSymbol(Sym); } } @@ -1804,8 +1804,8 @@ finalizeSynthetic(In.Plt); finalizeSynthetic(In.Iplt); finalizeSynthetic(In.EhFrameHdr); - finalizeSynthetic(InX::VerSym); - finalizeSynthetic(InX::VerNeed); + finalizeSynthetic(In.VerSym); + finalizeSynthetic(In.VerNeed); finalizeSynthetic(In.Dynamic); if (!Script->HasSectionsCommand && !Config->Relocatable)