[lld] r287326 - [ELF] Convert HashTableSection to input section

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 18 01:06:49 PST 2016


Author: evgeny777
Date: Fri Nov 18 03:06:47 2016
New Revision: 287326

URL: http://llvm.org/viewvc/llvm-project?rev=287326&view=rev
Log:
[ELF] Convert HashTableSection to input section

Differential revision: https://reviews.llvm.org/D26834

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=287326&r1=287325&r2=287326&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Nov 18 03:06:47 2016
@@ -140,45 +140,6 @@ template <class ELFT> void PltSection<EL
   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>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=287326&r1=287325&r2=287326&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Nov 18 03:06:47 2016
@@ -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>:
 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;

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=287326&r1=287325&r2=287326&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Nov 18 03:06:47 2016
@@ -796,8 +796,8 @@ template <class ELFT> void DynamicSectio
   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>::addSymbo
     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<
 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>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=287326&r1=287325&r2=287326&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Nov 18 03:06:47 2016
@@ -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> GnuHashTableSectio
 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;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=287326&r1=287325&r2=287326&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Nov 18 03:06:47 2016
@@ -241,7 +241,7 @@ template <class ELFT> void Writer<ELFT>:
   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>:
   // 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>:
       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())




More information about the llvm-commits mailing list