[lld] r303150 - [ELF] - Detemplate GnuHashTableSection and SymbolTableSection sections.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Tue May 16 01:53:30 PDT 2017
Author: grimar
Date: Tue May 16 03:53:30 2017
New Revision: 303150
URL: http://llvm.org/viewvc/llvm-project?rev=303150&view=rev
Log:
[ELF] - Detemplate GnuHashTableSection and SymbolTableSection sections.
SymbolTableBaseSection was introduced.
Detemplation of SymbolTableSection should allow to detemplate more things.
Differential revision: https://reviews.llvm.org/D33124
Modified:
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=303150&r1=303149&r2=303150&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue May 16 03:53:30 2017
@@ -1261,15 +1261,12 @@ template <class ELFT> void RelocationSec
this->OutSec->Link = this->Link;
}
-template <class ELFT>
-SymbolTableSection<ELFT>::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 @@ static bool sortMipsSymbols(const Symbol
// 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 <class ELFT> void SymbolTableSection<ELFT>::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 @@ template <class ELFT> void SymbolTableSe
// Because the first symbol entry is a null entry, 1 is the first.
this->OutSec->Info = 1;
- if (In<ELFT>::GnuHashTab) {
+ if (InX::GnuHashTab) {
// NB: It also sorts Symbols to meet the GNU hash table requirements.
- In<ELFT>::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 <class ELFT> void SymbolTableSe
}
}
-template <class ELFT> void SymbolTableSection<ELFT>::postThunkContents() {
+void SymbolTableBaseSection::postThunkContents() {
if (this->Type == SHT_DYNSYM)
return;
// move all local symbols before global symbols.
@@ -1328,7 +1325,7 @@ template <class ELFT> void SymbolTableSe
this->OutSec->Info = NumLocals + 1;
}
-template <class ELFT> void SymbolTableSection<ELFT>::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 @@ template <class ELFT> void SymbolTableSe
Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)});
}
-template <class ELFT>
-size_t SymbolTableSection<ELFT>::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 @@ size_t SymbolTableSection<ELFT>::getSymb
return I - Symbols.begin() + 1;
}
+template <class ELFT>
+SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec)
+ : SymbolTableBaseSection(StrTabSec) {
+ this->Entsize = sizeof(Elf_Sym);
+}
+
// Write the internal symbol table contents to the output symbol table.
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
// The first entry is a null entry as per the ELF spec.
@@ -1445,13 +1447,12 @@ template <class ELFT> void SymbolTableSe
// 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 <class ELFT>
-GnuHashTableSection<ELFT>::GnuHashTableSection()
+GnuHashTableSection::GnuHashTableSection()
: SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") {
}
-template <class ELFT> void GnuHashTableSection<ELFT>::finalizeContents() {
- this->OutSec->Link = In<ELFT>::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 @@ template <class ELFT> void GnuHashTableS
Size += Symbols.size() * 4; // Hash values
}
-template <class ELFT>
-void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
+void GnuHashTableSection::writeTo(uint8_t *Buf) {
// Write a header.
write32(Buf, NBuckets, Config->Endianness);
- write32(Buf + 4, In<ELFT>::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 @@ void GnuHashTableSection<ELFT>::writeTo(
//
// [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2),
// p.9, https://www.akkadia.org/drepper/dsohowto.pdf
-template <class ELFT>
-void GnuHashTableSection<ELFT>::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 @@ void GnuHashTableSection<ELFT>::writeBlo
}
}
-template <class ELFT>
-void GnuHashTableSection<ELFT>::writeHashTable(uint8_t *Buf) {
+void GnuHashTableSection::writeHashTable(uint8_t *Buf) {
// Group symbols by hash value.
std::vector<std::vector<Entry>> Syms(NBuckets);
for (const Entry &Ent : Symbols)
@@ -1555,8 +1553,7 @@ static size_t getBucketSize(size_t NumSy
// 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 <class ELFT>
-void GnuHashTableSection<ELFT>::addSymbols(std::vector<SymbolTableEntry> &V) {
+void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
// We cannot use 'auto' for Mid because GCC 6.1 cannot deduce
// its type correctly.
std::vector<SymbolTableEntry>::iterator Mid =
@@ -2243,10 +2240,12 @@ BuildIdSection *InX::BuildId;
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::Plt;
PltSection *InX::Iplt;
StringTableSection *InX::ShStrTab;
StringTableSection *InX::StrTab;
+SymbolTableBaseSection *InX::SymTab;
template void PltSection::addEntry<ELF32LE>(SymbolBody &Sym);
template void PltSection::addEntry<ELF32BE>(SymbolBody &Sym);
@@ -2318,11 +2318,6 @@ template class elf::SymbolTableSection<E
template class elf::SymbolTableSection<ELF64LE>;
template class elf::SymbolTableSection<ELF64BE>;
-template class elf::GnuHashTableSection<ELF32LE>;
-template class elf::GnuHashTableSection<ELF32BE>;
-template class elf::GnuHashTableSection<ELF64LE>;
-template class elf::GnuHashTableSection<ELF64BE>;
-
template class elf::HashTableSection<ELF32LE>;
template class elf::HashTableSection<ELF32BE>;
template class elf::HashTableSection<ELF64LE>;
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=303150&r1=303149&r2=303150&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Tue May 16 03:53:30 2017
@@ -405,31 +405,35 @@ struct SymbolTableEntry {
size_t StrTabOffset;
};
-template <class ELFT> 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<SymbolTableEntry> getSymbols() const { return Symbols; }
-private:
+protected:
// A vector of symbols and their string table offsets.
std::vector<SymbolTableEntry> Symbols;
StringTableSection &StrTabSec;
};
+template <class ELFT>
+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 ELFT>
class GnuHashTableSection final : public SyntheticSection {
public:
GnuHashTableSection();
@@ -756,6 +760,8 @@ struct InX {
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 @@ struct InX {
static PltSection *Iplt;
static StringTableSection *ShStrTab;
static StringTableSection *StrTab;
+ static SymbolTableBaseSection *SymTab;
};
template <class ELFT> struct In : public InX {
- static SymbolTableSection<ELFT> *DynSymTab;
static EhFrameHeader<ELFT> *EhFrameHdr;
- static GnuHashTableSection<ELFT> *GnuHashTab;
static EhFrameSection<ELFT> *EhFrame;
static HashTableSection<ELFT> *HashTab;
static RelocationSection<ELFT> *RelaDyn;
static RelocationSection<ELFT> *RelaPlt;
static RelocationSection<ELFT> *RelaIplt;
- static SymbolTableSection<ELFT> *SymTab;
static VersionDefinitionSection<ELFT> *VerDef;
static VersionTableSection<ELFT> *VerSym;
static VersionNeedSection<ELFT> *VerNeed;
};
-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> EhFrameSection<ELFT> *In<ELFT>::EhFrame;
template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt;
-template <class ELFT> SymbolTableSection<ELFT> *In<ELFT>::SymTab;
template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;
template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;
template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=303150&r1=303149&r2=303150&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue May 16 03:53:30 2017
@@ -334,7 +334,7 @@ template <class ELFT> void Writer<ELFT>:
if (Config->Strip != StripPolicy::All) {
InX::StrTab = make<StringTableSection>(".strtab", false);
- In<ELFT>::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
+ InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
}
if (Config->BuildId != BuildIdKind::None) {
@@ -383,7 +383,7 @@ template <class ELFT> void Writer<ELFT>:
Add(In<ELFT>::VerNeed);
if (Config->GnuHash) {
- In<ELFT>::GnuHashTab = make<GnuHashTableSection<ELFT>>();
+ In<ELFT>::GnuHashTab = make<GnuHashTableSection>();
Add(In<ELFT>::GnuHashTab);
}
More information about the llvm-commits
mailing list