diff options
| author | Eugene Leviant <eleviant@accesssoftek.com> | 2016-11-18 09:06:47 +0000 |
|---|---|---|
| committer | Eugene Leviant <eleviant@accesssoftek.com> | 2016-11-18 09:06:47 +0000 |
| commit | b96e809c7f5e6147fdbdecd728ec0b5bd5d42443 (patch) | |
| tree | 908eae9c8e85c540447a6ba86c910bc6569ad0b5 | |
| parent | f8f6f1e78352fd437771f97fe6cf740fbd921ecf (diff) | |
| download | bcm5719-llvm-b96e809c7f5e6147fdbdecd728ec0b5bd5d42443.tar.gz bcm5719-llvm-b96e809c7f5e6147fdbdecd728ec0b5bd5d42443.zip | |
[ELF] Convert HashTableSection to input section
Differential revision: https://reviews.llvm.org/D26834
llvm-svn: 287326
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 44 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 16 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 48 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.h | 16 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 12 |
5 files changed, 68 insertions, 68 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8270be0dc98..21198828b00 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -140,45 +140,6 @@ template <class ELFT> void PltSection<ELFT>::finalize() { this->Size = Target->PltHeaderSize + Entries.size() * Target->PltEntrySize; } -template <class ELFT> -HashTableSection<ELFT>::HashTableSection() - : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) { - this->Entsize = sizeof(Elf_Word); - this->Addralign = sizeof(Elf_Word); -} - -template <class ELFT> void HashTableSection<ELFT>::finalize() { - this->Link = In<ELFT>::DynSymTab->OutSec->SectionIndex; - - unsigned NumEntries = 2; // nbucket and nchain. - NumEntries += In<ELFT>::DynSymTab->getNumSymbols(); // The chain entries. - - // Create as many buckets as there are symbols. - // FIXME: This is simplistic. We can try to optimize it, but implementing - // support for SHT_GNU_HASH is probably even more profitable. - NumEntries += In<ELFT>::DynSymTab->getNumSymbols(); - this->Size = NumEntries * sizeof(Elf_Word); -} - -template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) { - unsigned NumSymbols = In<ELFT>::DynSymTab->getNumSymbols(); - auto *P = reinterpret_cast<Elf_Word *>(Buf); - *P++ = NumSymbols; // nbucket - *P++ = NumSymbols; // nchain - - Elf_Word *Buckets = P; - Elf_Word *Chains = P + NumSymbols; - - for (const SymbolTableEntry &S : In<ELFT>::DynSymTab->getSymbols()) { - SymbolBody *Body = S.Symbol; - StringRef Name = Body->getName(); - unsigned I = Body->DynsymIndex; - uint32_t Hash = hashSysV(Name) % NumSymbols; - Chains[I] = Buckets[Hash]; - Buckets[Hash] = I; - } -} - // Returns the number of version definition entries. Because the first entry // is for the version definition itself, it is the number of versioned symbols // plus one. Note that we don't support multiple versions yet. @@ -938,11 +899,6 @@ template class PltSection<ELF32BE>; template class PltSection<ELF64LE>; template class PltSection<ELF64BE>; -template class HashTableSection<ELF32LE>; -template class HashTableSection<ELF32BE>; -template class HashTableSection<ELF64LE>; -template class HashTableSection<ELF64BE>; - template class OutputSection<ELF32LE>; template class OutputSection<ELF32BE>; template class OutputSection<ELF64LE>; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index bb51dcc92b6..df4707aeda7 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -44,7 +44,6 @@ public: Base, EHFrame, EHFrameHdr, - HashTable, Merge, Plt, Regular, @@ -317,19 +316,6 @@ private: llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap; }; -template <class ELFT> class HashTableSection final : public OutputSectionBase { - typedef typename ELFT::Word Elf_Word; - -public: - HashTableSection(); - void finalize() override; - void writeTo(uint8_t *Buf) override; - Kind getKind() const override { return HashTable; } - static bool classof(const OutputSectionBase *B) { - return B->getKind() == HashTable; - } -}; - // --eh-frame-hdr option tells linker to construct a header for all the // .eh_frame sections. This header is placed to a section named .eh_frame_hdr // and also to a PT_GNU_EH_FRAME segment. @@ -372,7 +358,6 @@ template <class ELFT> struct Out { static EhFrameHeader<ELFT> *EhFrameHdr; static EhOutputSection<ELFT> *EhFrame; static GdbIndexSection<ELFT> *GdbIndex; - static HashTableSection<ELFT> *HashTab; static OutputSection<ELFT> *Bss; static OutputSection<ELFT> *MipsRldMap; static OutputSectionBase *Opd; @@ -427,7 +412,6 @@ template <class ELFT> uint8_t Out<ELFT>::First; template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr; template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame; template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex; -template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab; template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss; template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap; template <class ELFT> OutputSectionBase *Out<ELFT>::Opd; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b55c316e566..c6c4b75087c 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -796,8 +796,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()}); if (In<ELFT>::GnuHashTab) add({DT_GNU_HASH, In<ELFT>::GnuHashTab}); - if (Out<ELFT>::HashTab) - add({DT_HASH, Out<ELFT>::HashTab}); + if (In<ELFT>::HashTab) + add({DT_HASH, In<ELFT>::HashTab}); if (Out<ELFT>::PreinitArray) { add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray}); @@ -1290,6 +1290,45 @@ void GnuHashTableSection<ELFT>::addSymbols(std::vector<SymbolTableEntry> &V) { V.push_back({Sym.Body, Sym.STName}); } +template <class ELFT> +HashTableSection<ELFT>::HashTableSection() + : SyntheticSection<ELFT>(SHF_ALLOC, SHT_HASH, sizeof(Elf_Word), ".hash") { + this->Entsize = sizeof(Elf_Word); +} + +template <class ELFT> void HashTableSection<ELFT>::finalize() { + this->OutSec->Link = this->Link = In<ELFT>::DynSymTab->OutSec->SectionIndex; + this->OutSec->Entsize = this->Entsize; + + unsigned NumEntries = 2; // nbucket and nchain. + NumEntries += In<ELFT>::DynSymTab->getNumSymbols(); // The chain entries. + + // Create as many buckets as there are symbols. + // FIXME: This is simplistic. We can try to optimize it, but implementing + // support for SHT_GNU_HASH is probably even more profitable. + NumEntries += In<ELFT>::DynSymTab->getNumSymbols(); + this->Size = NumEntries * sizeof(Elf_Word); +} + +template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) { + unsigned NumSymbols = In<ELFT>::DynSymTab->getNumSymbols(); + auto *P = reinterpret_cast<Elf_Word *>(Buf); + *P++ = NumSymbols; // nbucket + *P++ = NumSymbols; // nchain + + Elf_Word *Buckets = P; + Elf_Word *Chains = P + NumSymbols; + + for (const SymbolTableEntry &S : In<ELFT>::DynSymTab->getSymbols()) { + SymbolBody *Body = S.Symbol; + StringRef Name = Body->getName(); + unsigned I = Body->DynsymIndex; + uint32_t Hash = hashSysV(Name) % NumSymbols; + Chains[I] = Buckets[Hash]; + Buckets[Hash] = I; + } +} + template InputSection<ELF32LE> *elf::createCommonSection(); template InputSection<ELF32BE> *elf::createCommonSection(); template InputSection<ELF64LE> *elf::createCommonSection(); @@ -1389,3 +1428,8 @@ 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>; +template class elf::HashTableSection<ELF64BE>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 8434959755b..e3e927a9df4 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -476,6 +476,20 @@ private: uintX_t Size = 0; }; +template <class ELFT> +class HashTableSection final : public SyntheticSection<ELFT> { + typedef typename ELFT::Word Elf_Word; + +public: + HashTableSection(); + void finalize() override; + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return this->Size; } + +private: + size_t Size = 0; +}; + template <class ELFT> InputSection<ELFT> *createCommonSection(); template <class ELFT> InputSection<ELFT> *createInterpSection(); template <class ELFT> MergeInputSection<ELFT> *createCommentSection(); @@ -491,6 +505,7 @@ template <class ELFT> struct In { static GotSection<ELFT> *Got; static MipsGotSection<ELFT> *MipsGot; static GotPltSection<ELFT> *GotPlt; + static HashTableSection<ELFT> *HashTab; static InputSection<ELFT> *Interp; static MipsAbiFlagsSection<ELFT> *MipsAbiFlags; static MipsOptionsSection<ELFT> *MipsOptions; @@ -511,6 +526,7 @@ template <class ELFT> GnuHashTableSection<ELFT> *In<ELFT>::GnuHashTab; template <class ELFT> GotSection<ELFT> *In<ELFT>::Got; template <class ELFT> MipsGotSection<ELFT> *In<ELFT>::MipsGot; template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt; +template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab; template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp; template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags; template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index e8d06261536..e7401833bff 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -241,7 +241,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { if (Config->GnuHash) In<ELFT>::GnuHashTab = make<GnuHashTableSection<ELFT>>(); if (Config->SysvHash) - Out<ELFT>::HashTab = make<HashTableSection<ELFT>>(); + In<ELFT>::HashTab = make<HashTableSection<ELFT>>(); if (Config->GdbIndex) Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>(); @@ -952,10 +952,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { // Dynamic section must be the last one in this list and dynamic // symbol table section (DynSymTab) must be the first one. finalizeSynthetic<ELFT>( - {In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::SymTab, - In<ELFT>::ShStrTab, In<ELFT>::StrTab, In<ELFT>::DynStrTab, In<ELFT>::Got, - In<ELFT>::MipsGot, In<ELFT>::GotPlt, In<ELFT>::RelaDyn, - In<ELFT>::RelaPlt, In<ELFT>::Dynamic}); + {In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab, + In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab, + In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::GotPlt, + In<ELFT>::RelaDyn, In<ELFT>::RelaPlt, In<ELFT>::Dynamic}); } template <class ELFT> bool Writer<ELFT>::needsGot() { @@ -997,7 +997,7 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() { Add(Out<ELFT>::VerNeed); addInputSec(In<ELFT>::GnuHashTab); - Add(Out<ELFT>::HashTab); + addInputSec(In<ELFT>::HashTab); addInputSec(In<ELFT>::Dynamic); addInputSec(In<ELFT>::DynStrTab); if (In<ELFT>::RelaDyn->hasRelocs()) |

