Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -405,31 +405,35 @@ size_t StrTabOffset; }; -template class SymbolTableSection final : public SyntheticSection { +class SymbolTableBaseSection : public SyntheticSection { public: - typedef typename ELFT::Sym Elf_Sym; - - SymbolTableSection(StringTableSection &StrTabSec); - + SymbolTableBaseSection(StringTableSection &StrTabSec); void finalizeContents() override; void postThunkContents() override; - void writeTo(uint8_t *Buf) override; - size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); } + size_t getSize() const override { return getNumSymbols() * Entsize; } void addSymbol(SymbolBody *Body); unsigned getNumSymbols() const { return Symbols.size() + 1; } size_t getSymbolIndex(SymbolBody *Body); ArrayRef getSymbols() const { return Symbols; } -private: +protected: // A vector of symbols and their string table offsets. std::vector Symbols; StringTableSection &StrTabSec; }; +template +class SymbolTableSection final : public SymbolTableBaseSection { + typedef typename ELFT::Sym Elf_Sym; + +public: + SymbolTableSection(StringTableSection &StrTabSec); + void writeTo(uint8_t *Buf) override; +}; + // Outputs GNU Hash section. For detailed explanation see: // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections -template class GnuHashTableSection final : public SyntheticSection { public: GnuHashTableSection(); @@ -756,6 +760,8 @@ static InputSection *Common; static SyntheticSection *Dynamic; static StringTableSection *DynStrTab; + static SymbolTableBaseSection *DynSymTab; + static GnuHashTableSection *GnuHashTab; static InputSection *Interp; static GdbIndexSection *GdbIndex; static GotBaseSection *Got; @@ -767,32 +773,27 @@ static PltSection *Iplt; static StringTableSection *ShStrTab; static StringTableSection *StrTab; + static SymbolTableBaseSection *SymTab; }; template struct In : public InX { - static SymbolTableSection *DynSymTab; static EhFrameHeader *EhFrameHdr; - static GnuHashTableSection *GnuHashTab; static EhFrameSection *EhFrame; static HashTableSection *HashTab; static RelocationSection *RelaDyn; static RelocationSection *RelaPlt; static RelocationSection *RelaIplt; - static SymbolTableSection *SymTab; static VersionDefinitionSection *VerDef; static VersionTableSection *VerSym; static VersionNeedSection *VerNeed; }; -template SymbolTableSection *In::DynSymTab; template EhFrameHeader *In::EhFrameHdr; -template GnuHashTableSection *In::GnuHashTab; template EhFrameSection *In::EhFrame; template HashTableSection *In::HashTab; template RelocationSection *In::RelaDyn; template RelocationSection *In::RelaPlt; template RelocationSection *In::RelaIplt; -template SymbolTableSection *In::SymTab; template VersionDefinitionSection *In::VerDef; template VersionTableSection *In::VerSym; template VersionNeedSection *In::VerNeed; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1261,15 +1261,12 @@ this->OutSec->Link = this->Link; } -template -SymbolTableSection::SymbolTableSection(StringTableSection &StrTabSec) +SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec) : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0, StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, Config->Wordsize, StrTabSec.isDynamic() ? ".dynsym" : ".symtab"), - StrTabSec(StrTabSec) { - this->Entsize = sizeof(Elf_Sym); -} + StrTabSec(StrTabSec) {} // Orders symbols according to their positions in the GOT, // in compliance with MIPS ABI rules. @@ -1291,7 +1288,7 @@ // symbols precede global symbols, so we sort symbol entries in this // function. (For .dynsym, we don't do that because symbols for // dynamic linking are inherently all globals.) -template void SymbolTableSection::finalizeContents() { +void SymbolTableBaseSection::finalizeContents() { this->OutSec->Link = StrTabSec.OutSec->SectionIndex; // If it is a .dynsym, there should be no local symbols, but we need @@ -1301,9 +1298,9 @@ // Because the first symbol entry is a null entry, 1 is the first. this->OutSec->Info = 1; - if (In::GnuHashTab) { + if (InX::GnuHashTab) { // NB: It also sorts Symbols to meet the GNU hash table requirements. - In::GnuHashTab->addSymbols(Symbols); + InX::GnuHashTab->addSymbols(Symbols); } else if (Config->EMachine == EM_MIPS) { std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols); } @@ -1315,7 +1312,7 @@ } } -template void SymbolTableSection::postThunkContents() { +void SymbolTableBaseSection::postThunkContents() { if (this->Type == SHT_DYNSYM) return; // move all local symbols before global symbols. @@ -1328,7 +1325,7 @@ this->OutSec->Info = NumLocals + 1; } -template void SymbolTableSection::addSymbol(SymbolBody *B) { +void SymbolTableBaseSection::addSymbol(SymbolBody *B) { // Adding a local symbol to a .dynsym is a bug. assert(this->Type != SHT_DYNSYM || !B->isLocal()); @@ -1336,8 +1333,7 @@ Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)}); } -template -size_t SymbolTableSection::getSymbolIndex(SymbolBody *Body) { +size_t SymbolTableBaseSection::getSymbolIndex(SymbolBody *Body) { auto I = llvm::find_if(Symbols, [&](const SymbolTableEntry &E) { if (E.Symbol == Body) return true; @@ -1353,6 +1349,12 @@ return I - Symbols.begin() + 1; } +template +SymbolTableSection::SymbolTableSection(StringTableSection &StrTabSec) + : SymbolTableBaseSection(StrTabSec) { + this->Entsize = sizeof(Elf_Sym); +} + // Write the internal symbol table contents to the output symbol table. template void SymbolTableSection::writeTo(uint8_t *Buf) { // The first entry is a null entry as per the ELF spec. @@ -1445,13 +1447,12 @@ // DSOs very quickly. If you are sure that your dynamic linker knows // about .gnu.hash, you want to specify -hash-style=gnu. Otherwise, a // safe bet is to specify -hash-style=both for backward compatibilty. -template -GnuHashTableSection::GnuHashTableSection() +GnuHashTableSection::GnuHashTableSection() : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") { } -template void GnuHashTableSection::finalizeContents() { - this->OutSec->Link = In::DynSymTab->OutSec->SectionIndex; +void GnuHashTableSection::finalizeContents() { + this->OutSec->Link = InX::DynSymTab->OutSec->SectionIndex; // Computes bloom filter size in word size. We want to allocate 8 // bits for each symbol. It must be a power of two. @@ -1466,11 +1467,10 @@ Size += Symbols.size() * 4; // Hash values } -template -void GnuHashTableSection::writeTo(uint8_t *Buf) { +void GnuHashTableSection::writeTo(uint8_t *Buf) { // Write a header. write32(Buf, NBuckets, Config->Endianness); - write32(Buf + 4, In::DynSymTab->getNumSymbols() - Symbols.size(), + write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size(), Config->Endianness); write32(Buf + 8, MaskWords, Config->Endianness); write32(Buf + 12, getShift2(), Config->Endianness); @@ -1489,8 +1489,7 @@ // // [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2), // p.9, https://www.akkadia.org/drepper/dsohowto.pdf -template -void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) { +void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) { const unsigned C = Config->Wordsize * 8; for (const Entry &Sym : Symbols) { size_t I = (Sym.Hash / C) & (MaskWords - 1); @@ -1501,8 +1500,7 @@ } } -template -void GnuHashTableSection::writeHashTable(uint8_t *Buf) { +void GnuHashTableSection::writeHashTable(uint8_t *Buf) { // Group symbols by hash value. std::vector> Syms(NBuckets); for (const Entry &Ent : Symbols) @@ -1555,8 +1553,7 @@ // Add symbols to this symbol hash table. Note that this function // destructively sort a given vector -- which is needed because // GNU-style hash table places some sorting requirements. -template -void GnuHashTableSection::addSymbols(std::vector &V) { +void GnuHashTableSection::addSymbols(std::vector &V) { // We cannot use 'auto' for Mid because GCC 6.1 cannot deduce // its type correctly. std::vector::iterator Mid = @@ -2243,10 +2240,12 @@ InputSection *InX::Common; SyntheticSection *InX::Dynamic; StringTableSection *InX::DynStrTab; +SymbolTableBaseSection *InX::DynSymTab; InputSection *InX::Interp; GdbIndexSection *InX::GdbIndex; GotBaseSection *InX::Got; GotPltSection *InX::GotPlt; +GnuHashTableSection *InX::GnuHashTab; IgotPltSection *InX::IgotPlt; MipsGotSection *InX::MipsGot; MipsRldMapSection *InX::MipsRldMap; @@ -2254,6 +2253,7 @@ PltSection *InX::Iplt; StringTableSection *InX::ShStrTab; StringTableSection *InX::StrTab; +SymbolTableBaseSection *InX::SymTab; template void PltSection::addEntry(SymbolBody &Sym); template void PltSection::addEntry(SymbolBody &Sym); @@ -2318,11 +2318,6 @@ template class elf::SymbolTableSection; template class elf::SymbolTableSection; -template class elf::GnuHashTableSection; -template class elf::GnuHashTableSection; -template class elf::GnuHashTableSection; -template class elf::GnuHashTableSection; - template class elf::HashTableSection; template class elf::HashTableSection; template class elf::HashTableSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -334,7 +334,7 @@ if (Config->Strip != StripPolicy::All) { InX::StrTab = make(".strtab", false); - In::SymTab = make>(*InX::StrTab); + InX::SymTab = make>(*InX::StrTab); } if (Config->BuildId != BuildIdKind::None) { @@ -383,7 +383,7 @@ Add(In::VerNeed); if (Config->GnuHash) { - In::GnuHashTab = make>(); + In::GnuHashTab = make(); Add(In::GnuHashTab); }