diff options
author | Igor Kudrin <ikudrin.dev@gmail.com> | 2015-10-20 21:47:58 +0000 |
---|---|---|
committer | Igor Kudrin <ikudrin.dev@gmail.com> | 2015-10-20 21:47:58 +0000 |
commit | ab665fc475999da02eb877dbafb411ac0853d876 (patch) | |
tree | f7cd7155ac905d283236ad381f7ecd8f3233d20d | |
parent | 2483d8f4a737a8f542a0927ab1d2e68681527967 (diff) | |
download | bcm5719-llvm-ab665fc475999da02eb877dbafb411ac0853d876.tar.gz bcm5719-llvm-ab665fc475999da02eb877dbafb411ac0853d876.zip |
[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
llvm-svn: 250864
-rw-r--r-- | lld/ELF/OutputSections.cpp | 61 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 10 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 7 |
3 files changed, 38 insertions, 40 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 96d6a413adf..33ca64bd991 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -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 HashTableSection<ELFT>::writeTo(uint8_t *Buf) { 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 SymbolTableSection<ELFT>::finalize() { 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>::writeGlobalSymbols(uint8_t *Buf) { 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> diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 974ac34a31a..65d4604cbe4 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -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 OutputSectionBase<ELFT> { public: HashTableSection(); - void addSymbol(SymbolBody *S); void finalize() override; void writeTo(uint8_t *Buf) override; - -private: - std::vector<uint32_t> Hashes; }; template <class ELFT> diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 6178a94d39b..dc9cafc17e6 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -282,7 +282,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() { 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>::createSections() { // 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>::createSections() { 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); |