Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -406,22 +406,21 @@ size_t StrTabOffset; }; -template class SymbolTableSection final : public SyntheticSection { +class SymbolTableSection final : public SyntheticSection { public: - typedef typename ELFT::Sym Elf_Sym; - typedef typename ELFT::uint uintX_t; - - SymbolTableSection(StringTableSection &StrTabSec); + SymbolTableSection(StringTableSection &StrTabSec, uint64_t EntSize); 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() * this->Entsize; } void addSymbol(SymbolBody *Body); unsigned getNumSymbols() const { return Symbols.size() + 1; } size_t getSymbolIndex(SymbolBody *Body); ArrayRef getSymbols() const { return Symbols; } + template void writeContent(uint8_t *Buf); + private: // A vector of symbols and their string table offsets. std::vector Symbols; @@ -431,7 +430,6 @@ // 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(); @@ -759,6 +757,8 @@ static BuildIdSection *BuildId; static InputSection *Common; static StringTableSection *DynStrTab; + static SymbolTableSection *DynSymTab; + static GnuHashTableSection *GnuHashTab; static InputSection *Interp; static GdbIndexSection *GdbIndex; static GotPltSection *GotPlt; @@ -767,38 +767,33 @@ static MipsRldMapSection *MipsRldMap; static PltSection *Plt; static PltSection *Iplt; + static SymbolTableSection *SymTab; static StringTableSection *ShStrTab; static StringTableSection *StrTab; }; template struct In : public InX { static DynamicSection *Dynamic; - static SymbolTableSection *DynSymTab; static EhFrameHeader *EhFrameHdr; - static GnuHashTableSection *GnuHashTab; static GotSection *Got; 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 DynamicSection *In::Dynamic; -template SymbolTableSection *In::DynSymTab; template EhFrameHeader *In::EhFrameHdr; -template GnuHashTableSection *In::GnuHashTab; template GotSection *In::Got; 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: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1259,14 +1259,14 @@ this->OutSec->Link = this->Link; } -template -SymbolTableSection::SymbolTableSection(StringTableSection &StrTabSec) - : SyntheticSection(StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0, +SymbolTableSection::SymbolTableSection(StringTableSection &StrTabSec, + uint64_t EntSize) + : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0, StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, - sizeof(uintX_t), + Config->Wordsize, StrTabSec.isDynamic() ? ".dynsym" : ".symtab"), StrTabSec(StrTabSec) { - this->Entsize = sizeof(Elf_Sym); + this->Entsize = EntSize; } // Orders symbols according to their positions in the GOT, @@ -1289,7 +1289,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 SymbolTableSection::finalizeContents() { this->OutSec->Link = StrTabSec.OutSec->SectionIndex; // If it is a .dynsym, there should be no local symbols, but we need @@ -1299,9 +1299,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); } @@ -1313,7 +1313,7 @@ } } -template void SymbolTableSection::postThunkContents() { +void SymbolTableSection::postThunkContents() { if (this->Type == SHT_DYNSYM) return; // move all local symbols before global symbols. @@ -1326,7 +1326,7 @@ this->OutSec->Info = NumLocals + 1; } -template void SymbolTableSection::addSymbol(SymbolBody *B) { +void SymbolTableSection::addSymbol(SymbolBody *B) { // Adding a local symbol to a .dynsym is a bug. assert(this->Type != SHT_DYNSYM || !B->isLocal()); @@ -1334,8 +1334,7 @@ Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)}); } -template -size_t SymbolTableSection::getSymbolIndex(SymbolBody *Body) { +size_t SymbolTableSection::getSymbolIndex(SymbolBody *Body) { auto I = llvm::find_if(Symbols, [&](const SymbolTableEntry &E) { if (E.Symbol == Body) return true; @@ -1351,8 +1350,25 @@ return I - Symbols.begin() + 1; } +void SymbolTableSection::writeTo(uint8_t *Buf) { + switch (Config->EKind) { + case ELF32LEKind: + return this->writeContent(Buf); + case ELF32BEKind: + return this->writeContent(Buf); + case ELF64LEKind: + return this->writeContent(Buf); + case ELF64BEKind: + return this->writeContent(Buf); + default: + llvm_unreachable("unknown Config->EKind"); + } +} + // Write the internal symbol table contents to the output symbol table. -template void SymbolTableSection::writeTo(uint8_t *Buf) { +template void SymbolTableSection::writeContent(uint8_t *Buf) { + typedef typename ELFT::Sym Elf_Sym; + // The first entry is a null entry as per the ELF spec. Buf += sizeof(Elf_Sym); @@ -1443,13 +1459,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. @@ -1464,11 +1479,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); @@ -1487,8 +1501,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); @@ -1499,8 +1512,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) @@ -1553,8 +1565,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 = @@ -2235,6 +2246,8 @@ BuildIdSection *InX::BuildId; InputSection *InX::Common; StringTableSection *InX::DynStrTab; +SymbolTableSection *InX::DynSymTab; +GnuHashTableSection *InX::GnuHashTab; InputSection *InX::Interp; GdbIndexSection *InX::GdbIndex; GotPltSection *InX::GotPlt; @@ -2245,12 +2258,18 @@ PltSection *InX::Iplt; StringTableSection *InX::ShStrTab; StringTableSection *InX::StrTab; +SymbolTableSection *InX::SymTab; template void PltSection::addEntry(SymbolBody &Sym); template void PltSection::addEntry(SymbolBody &Sym); template void PltSection::addEntry(SymbolBody &Sym); template void PltSection::addEntry(SymbolBody &Sym); +template void SymbolTableSection::writeContent(uint8_t *Buf); +template void SymbolTableSection::writeContent(uint8_t *Buf); +template void SymbolTableSection::writeContent(uint8_t *Buf); +template void SymbolTableSection::writeContent(uint8_t *Buf); + template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); @@ -2304,16 +2323,6 @@ template class elf::RelocationSection; template class elf::RelocationSection; -template class elf::SymbolTableSection; -template class elf::SymbolTableSection; -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: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -348,7 +348,8 @@ if (Config->Strip != StripPolicy::All) { In::StrTab = make(".strtab", false); - In::SymTab = make>(*In::StrTab); + In::SymTab = + make(*In::StrTab, sizeof(typename ELFT::Sym)); } if (Config->BuildId != BuildIdKind::None) { @@ -382,7 +383,8 @@ } if (HasDynSymTab) { - In::DynSymTab = make>(*In::DynStrTab); + In::DynSymTab = make(*In::DynStrTab, + sizeof(typename ELFT::Sym)); Add(In::DynSymTab); In::VerSym = make>(); @@ -397,7 +399,7 @@ Add(In::VerNeed); if (Config->GnuHash) { - In::GnuHashTab = make>(); + In::GnuHashTab = make(); Add(In::GnuHashTab); }