Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -172,10 +172,13 @@ 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 &getStrTabSec() const { return StrTabSec; } unsigned getNumSymbols() const { return NumVisible + 1; } + ArrayRef getSymbols() const { return Symbols; } + private: void writeLocalSymbols(uint8_t *&Buf); void writeGlobalSymbols(uint8_t *Buf); @@ -184,6 +187,7 @@ SymbolTable &Table; StringTableSection &StrTabSec; + std::vector Symbols; unsigned NumVisible = 0; unsigned NumLocals = 0; }; @@ -275,12 +279,8 @@ public: HashTableSection(); - void addSymbol(SymbolBody *S); void finalize() override; void writeTo(uint8_t *Buf) override; - -private: - std::vector Hashes; }; template Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -250,17 +250,9 @@ return H; } -template void HashTableSection::addSymbol(SymbolBody *S) { - StringRef Name = S->getName(); - Out::DynSymTab->addSymbol(Name); - Hashes.push_back(hash(Name)); - S->setDynamicSymbolTableIndex(Hashes.size()); -} - template void HashTableSection::finalize() { this->Header.sh_link = Out::DynSymTab->SectionIndex; - assert(Out::DynSymTab->getNumSymbols() == Hashes.size() + 1); unsigned NumEntries = 2; // nbucket and nchain. NumEntries += Out::DynSymTab->getNumSymbols(); // The chain entries. @@ -280,8 +272,10 @@ 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::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 @@ 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 -void SymbolTableSection::addSymbol(StringRef Name, bool isLocal) { +void SymbolTableSection::addLocalSymbol(StringRef Name) { StrTabSec.add(Name); ++NumVisible; - if (isLocal) - ++NumLocals; + ++NumLocals; +} + +template +void SymbolTableSection::addSymbol(SymbolBody *Body) { + StrTabSec.add(Body->getName()); + Symbols.push_back(Body); + ++NumVisible; } template void SymbolTableSection::writeTo(uint8_t *Buf) { @@ -754,18 +766,9 @@ void SymbolTableSection::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 &P : Table.getSymbols()) { - StringRef Name = P.first; - Symbol *Sym = P.second; - SymbolBody *Body = Sym->Body; - if (!includeInSymtab(*Body)) - continue; - if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body)) - continue; - - auto *ESym = reinterpret_cast(Buf); - Buf += sizeof(*ESym); + auto *ESym = reinterpret_cast(Buf); + for (SymbolBody *Body : Symbols) { + StringRef Name = Body->getName(); ESym->st_name = StrTabSec.getFileOff(Name); @@ -809,13 +812,9 @@ ESym->st_shndx = SHN_ABS; else if (OutSec) ESym->st_shndx = OutSec->SectionIndex; + + ++ESym; } - if (!StrTabSec.isDynamic()) - std::stable_sort( - reinterpret_cast(Start), reinterpret_cast(Buf), - [](const Elf_Sym &A, const Elf_Sym &B) -> bool { - return A.getBinding() == STB_LOCAL && B.getBinding() != STB_LOCAL; - }); } template Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -282,7 +282,7 @@ StringRef SymName = *SymNameOrErr; if (!shouldKeepInSymtab(*F, SymName, Sym)) continue; - Out::SymTab->addSymbol(SymName, true); + Out::SymTab->addLocalSymbol(SymName); } } } @@ -498,7 +498,6 @@ // FIXME: Try to avoid the extra walk over all global symbols. std::vector *> CommonSymbols; for (auto &P : Symtab.getSymbols()) { - StringRef Name = P.first; SymbolBody *Body = P.second->Body; if (auto *U = dyn_cast>(Body)) if (!U->isWeak() && !U->canKeepUndefined()) @@ -508,10 +507,10 @@ CommonSymbols.push_back(C); if (!includeInSymtab(*Body)) continue; - Out::SymTab->addSymbol(Name); + Out::SymTab->addSymbol(Body); if (isOutputDynamic() && includeInDynamicSymtab(*Body)) - Out::HashTab->addSymbol(Body); + Out::DynSymTab->addSymbol(Body); } addCommonSymbols(CommonSymbols);