[lld] r250864 - [ELF2] Determine the order of entries of symbol tables in the finalize() phase.

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 20 14:47:58 PDT 2015


Author: ikudrin
Date: Tue Oct 20 16:47:58 2015
New Revision: 250864

URL: http://llvm.org/viewvc/llvm-project?rev=250864&view=rev
Log:
[ELF2] Determine the order of entries of symbol tables in the finalize() phase.

* Move the responsibility to call SymbolBody::setDynamicSymbolTableIndex()
  from the hash table to the dynamic symbol table.
* Hash table is not longer responsible for filling the dynamic symbol table.
* The final order of symbols of both symbol tables is set before writing
  phase starts.
* Remove repeaded scan of the symbol table during writting SymbolTableSection.

Differential Revision: http://reviews.llvm.org/D13911

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.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=250864&r1=250863&r2=250864&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Oct 20 16:47:58 2015
@@ -250,17 +250,9 @@ static uint32_t hash(StringRef Name) {
   return H;
 }
 
-template <class ELFT> void HashTableSection<ELFT>::addSymbol(SymbolBody *S) {
-  StringRef Name = S->getName();
-  Out<ELFT>::DynSymTab->addSymbol(Name);
-  Hashes.push_back(hash(Name));
-  S->setDynamicSymbolTableIndex(Hashes.size());
-}
-
 template <class ELFT> void HashTableSection<ELFT>::finalize() {
   this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex;
 
-  assert(Out<ELFT>::DynSymTab->getNumSymbols() == Hashes.size() + 1);
   unsigned NumEntries = 2;                 // nbucket and nchain.
   NumEntries += Out<ELFT>::DynSymTab->getNumSymbols(); // The chain entries.
 
@@ -280,8 +272,10 @@ template <class ELFT> void HashTableSect
   Elf_Word *Buckets = P;
   Elf_Word *Chains = P + NumSymbols;
 
-  for (unsigned I = 1; I < NumSymbols; ++I) {
-    uint32_t Hash = Hashes[I - 1] % NumSymbols;
+  for (SymbolBody *Body : Out<ELFT>::DynSymTab->getSymbols()) {
+    StringRef Name = Body->getName();
+    unsigned I = Body->getDynamicSymbolTableIndex();
+    uint32_t Hash = hash(Name) % NumSymbols;
     Chains[I] = Buckets[Hash];
     Buckets[Hash] = I;
   }
@@ -696,14 +690,32 @@ template <class ELFT> void SymbolTableSe
   this->Header.sh_size = getNumSymbols() * sizeof(Elf_Sym);
   this->Header.sh_link = StrTabSec.SectionIndex;
   this->Header.sh_info = NumLocals + 1;
+
+  if (!StrTabSec.isDynamic()) {
+    std::stable_sort(Symbols.begin(), Symbols.end(),
+                     [](SymbolBody *L, SymbolBody *R) {
+                       return getSymbolBinding(L) == STB_LOCAL &&
+                              getSymbolBinding(R) != STB_LOCAL;
+                     });
+    return;
+  }
+  size_t I = 0;
+  for (SymbolBody *Body : Symbols)
+    Body->setDynamicSymbolTableIndex(++I);
 }
 
 template <class ELFT>
-void SymbolTableSection<ELFT>::addSymbol(StringRef Name, bool isLocal) {
+void SymbolTableSection<ELFT>::addLocalSymbol(StringRef Name) {
   StrTabSec.add(Name);
   ++NumVisible;
-  if (isLocal)
-    ++NumLocals;
+  ++NumLocals;
+}
+
+template <class ELFT>
+void SymbolTableSection<ELFT>::addSymbol(SymbolBody *Body) {
+  StrTabSec.add(Body->getName());
+  Symbols.push_back(Body);
+  ++NumVisible;
 }
 
 template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
@@ -754,18 +766,9 @@ template <class ELFT>
 void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
   // Write the internal symbol table contents to the output symbol table
   // pointed by Buf.
-  uint8_t *Start = Buf;
-  for (const std::pair<StringRef, Symbol *> &P : Table.getSymbols()) {
-    StringRef Name = P.first;
-    Symbol *Sym = P.second;
-    SymbolBody *Body = Sym->Body;
-    if (!includeInSymtab<ELFT>(*Body))
-      continue;
-    if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body))
-      continue;
-
-    auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
-    Buf += sizeof(*ESym);
+  auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
+  for (SymbolBody *Body : Symbols) {
+    StringRef Name = Body->getName();
 
     ESym->st_name = StrTabSec.getFileOff(Name);
 
@@ -809,13 +812,9 @@ void SymbolTableSection<ELFT>::writeGlob
       ESym->st_shndx = SHN_ABS;
     else if (OutSec)
       ESym->st_shndx = OutSec->SectionIndex;
+
+    ++ESym;
   }
-  if (!StrTabSec.isDynamic())
-    std::stable_sort(
-        reinterpret_cast<Elf_Sym *>(Start), reinterpret_cast<Elf_Sym *>(Buf),
-        [](const Elf_Sym &A, const Elf_Sym &B) -> bool {
-          return A.getBinding() == STB_LOCAL && B.getBinding() != STB_LOCAL;
-        });
 }
 
 template <class ELFT>

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=250864&r1=250863&r2=250864&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Oct 20 16:47:58 2015
@@ -172,10 +172,13 @@ public:
 
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  void addSymbol(StringRef Name, bool isLocal = false);
+  void addLocalSymbol(StringRef Name);
+  void addSymbol(SymbolBody *Body);
   StringTableSection<ELFT> &getStrTabSec() const { return StrTabSec; }
   unsigned getNumSymbols() const { return NumVisible + 1; }
 
+  ArrayRef<SymbolBody *> getSymbols() const { return Symbols; }
+
 private:
   void writeLocalSymbols(uint8_t *&Buf);
   void writeGlobalSymbols(uint8_t *Buf);
@@ -184,6 +187,7 @@ private:
 
   SymbolTable<ELFT> &Table;
   StringTableSection<ELFT> &StrTabSec;
+  std::vector<SymbolBody *> Symbols;
   unsigned NumVisible = 0;
   unsigned NumLocals = 0;
 };
@@ -275,12 +279,8 @@ class HashTableSection final : public Ou
 
 public:
   HashTableSection();
-  void addSymbol(SymbolBody *S);
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-
-private:
-  std::vector<uint32_t> Hashes;
 };
 
 template <class ELFT>

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=250864&r1=250863&r2=250864&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Oct 20 16:47:58 2015
@@ -282,7 +282,7 @@ template <class ELFT> void Writer<ELFT>:
       StringRef SymName = *SymNameOrErr;
       if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
         continue;
-      Out<ELFT>::SymTab->addSymbol(SymName, true);
+      Out<ELFT>::SymTab->addLocalSymbol(SymName);
     }
   }
 }
@@ -498,7 +498,6 @@ template <class ELFT> void Writer<ELFT>:
   // FIXME: Try to avoid the extra walk over all global symbols.
   std::vector<DefinedCommon<ELFT> *> CommonSymbols;
   for (auto &P : Symtab.getSymbols()) {
-    StringRef Name = P.first;
     SymbolBody *Body = P.second->Body;
     if (auto *U = dyn_cast<Undefined<ELFT>>(Body))
       if (!U->isWeak() && !U->canKeepUndefined())
@@ -508,10 +507,10 @@ template <class ELFT> void Writer<ELFT>:
       CommonSymbols.push_back(C);
     if (!includeInSymtab<ELFT>(*Body))
       continue;
-    Out<ELFT>::SymTab->addSymbol(Name);
+    Out<ELFT>::SymTab->addSymbol(Body);
 
     if (isOutputDynamic() && includeInDynamicSymtab(*Body))
-      Out<ELFT>::HashTab->addSymbol(Body);
+      Out<ELFT>::DynSymTab->addSymbol(Body);
   }
   addCommonSymbols(CommonSymbols);
 




More information about the llvm-commits mailing list