From b96e809c7f5e6147fdbdecd728ec0b5bd5d42443 Mon Sep 17 00:00:00 2001 From: Eugene Leviant Date: Fri, 18 Nov 2016 09:06:47 +0000 Subject: [PATCH] [ELF] Convert HashTableSection to input section Differential revision: https://reviews.llvm.org/D26834 llvm-svn: 287326 --- lld/ELF/OutputSections.cpp | 44 --------------------------------------- lld/ELF/OutputSections.h | 16 --------------- lld/ELF/SyntheticSections.cpp | 48 +++++++++++++++++++++++++++++++++++++++++-- lld/ELF/SyntheticSections.h | 16 +++++++++++++++ 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 8270be0..2119882 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -140,45 +140,6 @@ template void PltSection::finalize() { this->Size = Target->PltHeaderSize + Entries.size() * Target->PltEntrySize; } -template -HashTableSection::HashTableSection() - : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) { - this->Entsize = sizeof(Elf_Word); - this->Addralign = sizeof(Elf_Word); -} - -template void HashTableSection::finalize() { - this->Link = In::DynSymTab->OutSec->SectionIndex; - - unsigned NumEntries = 2; // nbucket and nchain. - NumEntries += In::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::DynSymTab->getNumSymbols(); - this->Size = NumEntries * sizeof(Elf_Word); -} - -template void HashTableSection::writeTo(uint8_t *Buf) { - unsigned NumSymbols = In::DynSymTab->getNumSymbols(); - auto *P = reinterpret_cast(Buf); - *P++ = NumSymbols; // nbucket - *P++ = NumSymbols; // nchain - - Elf_Word *Buckets = P; - Elf_Word *Chains = P + NumSymbols; - - for (const SymbolTableEntry &S : In::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; template class PltSection; template class PltSection; -template class HashTableSection; -template class HashTableSection; -template class HashTableSection; -template class HashTableSection; - template class OutputSection; template class OutputSection; template class OutputSection; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index bb51dcc..df4707a 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, SymbolBody *>, CieRecord> CieMap; }; -template 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 struct Out { static EhFrameHeader *EhFrameHdr; static EhOutputSection *EhFrame; static GdbIndexSection *GdbIndex; - static HashTableSection *HashTab; static OutputSection *Bss; static OutputSection *MipsRldMap; static OutputSectionBase *Opd; @@ -427,7 +412,6 @@ template uint8_t Out::First; template EhFrameHeader *Out::EhFrameHdr; template EhOutputSection *Out::EhFrame; template GdbIndexSection *Out::GdbIndex; -template HashTableSection *Out::HashTab; template OutputSection *Out::Bss; template OutputSection *Out::MipsRldMap; template OutputSectionBase *Out::Opd; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b55c316..c6c4b75 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -796,8 +796,8 @@ template void DynamicSection::finalize() { add({DT_STRSZ, In::DynStrTab->getSize()}); if (In::GnuHashTab) add({DT_GNU_HASH, In::GnuHashTab}); - if (Out::HashTab) - add({DT_HASH, Out::HashTab}); + if (In::HashTab) + add({DT_HASH, In::HashTab}); if (Out::PreinitArray) { add({DT_PREINIT_ARRAY, Out::PreinitArray}); @@ -1290,6 +1290,45 @@ void GnuHashTableSection::addSymbols(std::vector &V) { V.push_back({Sym.Body, Sym.STName}); } +template +HashTableSection::HashTableSection() + : SyntheticSection(SHF_ALLOC, SHT_HASH, sizeof(Elf_Word), ".hash") { + this->Entsize = sizeof(Elf_Word); +} + +template void HashTableSection::finalize() { + this->OutSec->Link = this->Link = In::DynSymTab->OutSec->SectionIndex; + this->OutSec->Entsize = this->Entsize; + + unsigned NumEntries = 2; // nbucket and nchain. + NumEntries += In::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::DynSymTab->getNumSymbols(); + this->Size = NumEntries * sizeof(Elf_Word); +} + +template void HashTableSection::writeTo(uint8_t *Buf) { + unsigned NumSymbols = In::DynSymTab->getNumSymbols(); + auto *P = reinterpret_cast(Buf); + *P++ = NumSymbols; // nbucket + *P++ = NumSymbols; // nchain + + Elf_Word *Buckets = P; + Elf_Word *Chains = P + NumSymbols; + + for (const SymbolTableEntry &S : In::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 *elf::createCommonSection(); template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); @@ -1389,3 +1428,8 @@ 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; +template class elf::HashTableSection; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 8434959..e3e927a9 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -476,6 +476,20 @@ private: uintX_t Size = 0; }; +template +class HashTableSection final : public SyntheticSection { + 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 InputSection *createCommonSection(); template InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); @@ -491,6 +505,7 @@ template struct In { static GotSection *Got; static MipsGotSection *MipsGot; static GotPltSection *GotPlt; + static HashTableSection *HashTab; static InputSection *Interp; static MipsAbiFlagsSection *MipsAbiFlags; static MipsOptionsSection *MipsOptions; @@ -511,6 +526,7 @@ template GnuHashTableSection *In::GnuHashTab; template GotSection *In::Got; template MipsGotSection *In::MipsGot; template GotPltSection *In::GotPlt; +template HashTableSection *In::HashTab; template InputSection *In::Interp; template MipsAbiFlagsSection *In::MipsAbiFlags; template MipsOptionsSection *In::MipsOptions; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index e8d0626..e740183 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -241,7 +241,7 @@ template void Writer::createSyntheticSections() { if (Config->GnuHash) In::GnuHashTab = make>(); if (Config->SysvHash) - Out::HashTab = make>(); + In::HashTab = make>(); if (Config->GdbIndex) Out::GdbIndex = make>(); @@ -952,10 +952,10 @@ template void Writer::finalizeSections() { // Dynamic section must be the last one in this list and dynamic // symbol table section (DynSymTab) must be the first one. finalizeSynthetic( - {In::DynSymTab, In::GnuHashTab, In::SymTab, - In::ShStrTab, In::StrTab, In::DynStrTab, In::Got, - In::MipsGot, In::GotPlt, In::RelaDyn, - In::RelaPlt, In::Dynamic}); + {In::DynSymTab, In::GnuHashTab, In::HashTab, + In::SymTab, In::ShStrTab, In::StrTab, + In::DynStrTab, In::Got, In::MipsGot, In::GotPlt, + In::RelaDyn, In::RelaPlt, In::Dynamic}); } template bool Writer::needsGot() { @@ -997,7 +997,7 @@ template void Writer::addPredefinedSections() { Add(Out::VerNeed); addInputSec(In::GnuHashTab); - Add(Out::HashTab); + addInputSec(In::HashTab); addInputSec(In::Dynamic); addInputSec(In::DynStrTab); if (In::RelaDyn->hasRelocs()) -- 2.7.4