Index: lld/trunk/ELF/InputFiles.h =================================================================== --- lld/trunk/ELF/InputFiles.h +++ lld/trunk/ELF/InputFiles.h @@ -180,10 +180,6 @@ // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. uint32_t MipsGp0 = 0; - // The number is the offset in the string table. It will be used as the - // st_name of the symbol. - std::vector *, unsigned>> KeptLocalSyms; - // Name of source file obtained from STT_FILE symbol value, // or empty string if there is no such symbol in object file // symbol table. Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -247,7 +247,8 @@ if (Config->Rela) P->r_addend = getAddend(Rel); P->r_offset = RelocatedSection->getOffset(Rel.r_offset); - P->setSymbolAndType(Body.DynsymIndex, Type, Config->Mips64EL); + P->setSymbolAndType(In::SymTab->getSymbolIndex(&Body), Type, + Config->Mips64EL); } } Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -366,23 +366,26 @@ void finalize() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); } - void addSymbol(SymbolBody *Body); + void addGlobal(SymbolBody *Body); + void addLocal(SymbolBody *Body); StringTableSection &getStrTabSec() const { return StrTabSec; } - unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; } + unsigned getNumSymbols() const { return Symbols.size() + 1; } + size_t getSymbolIndex(SymbolBody *Body); ArrayRef getSymbols() const { return Symbols; } static const OutputSectionBase *getOutputSection(SymbolBody *Sym); - unsigned NumLocals = 0; - StringTableSection &StrTabSec; - private: void writeLocalSymbols(uint8_t *&Buf); void writeGlobalSymbols(uint8_t *Buf); // A vector of symbols and their string table offsets. std::vector Symbols; + + StringTableSection &StrTabSec; + + unsigned NumLocals = 0; }; // Outputs GNU Hash section. For detailed explanation see: Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1065,22 +1065,19 @@ this->OutSec->Info = this->Info = NumLocals + 1; this->OutSec->Entsize = this->Entsize; - if (Config->Relocatable) { - size_t I = NumLocals; - for (const SymbolTableEntry &S : Symbols) - S.Symbol->DynsymIndex = ++I; + if (Config->Relocatable) return; - } if (!StrTabSec.isDynamic()) { - std::stable_sort( - Symbols.begin(), Symbols.end(), - [](const SymbolTableEntry &L, const SymbolTableEntry &R) { - return L.Symbol->symbol()->computeBinding() == STB_LOCAL && - R.Symbol->symbol()->computeBinding() != STB_LOCAL; - }); + auto GlobBegin = Symbols.begin() + NumLocals; + std::stable_sort(GlobBegin, Symbols.end(), [](const SymbolTableEntry &L, + const SymbolTableEntry &R) { + return L.Symbol->symbol()->computeBinding() == STB_LOCAL && + R.Symbol->symbol()->computeBinding() != STB_LOCAL; + }); return; } + if (In::GnuHashTab) // NB: It also sorts Symbols to meet the GNU hash table requirements. In::GnuHashTab->addSymbols(Symbols); @@ -1094,10 +1091,23 @@ S.Symbol->DynsymIndex = ++I; } -template void SymbolTableSection::addSymbol(SymbolBody *B) { +template void SymbolTableSection::addGlobal(SymbolBody *B) { Symbols.push_back({B, StrTabSec.addString(B->getName(), false)}); } +template void SymbolTableSection::addLocal(SymbolBody *B) { + assert(!StrTabSec.isDynamic()); + ++NumLocals; + Symbols.push_back({B, StrTabSec.addString(B->getName())}); +} + +template +size_t SymbolTableSection::getSymbolIndex(SymbolBody *Body) { + auto I = llvm::find_if( + Symbols, [&](const SymbolTableEntry &E) { return E.Symbol == Body; }); + return I - Symbols.begin() + 1; +} + template void SymbolTableSection::writeTo(uint8_t *Buf) { Buf += sizeof(Elf_Sym); @@ -1113,26 +1123,24 @@ void SymbolTableSection::writeLocalSymbols(uint8_t *&Buf) { // Iterate over all input object files to copy their local symbols // to the output symbol table pointed by Buf. - for (ObjectFile *File : Symtab::X->getObjectFiles()) { - for (const std::pair *, size_t> &P : - File->KeptLocalSyms) { - const DefinedRegular &Body = *P.first; - InputSectionBase *Section = Body.Section; - auto *ESym = reinterpret_cast(Buf); - - if (!Section) { - ESym->st_shndx = SHN_ABS; - ESym->st_value = Body.Value; - } else { - const OutputSectionBase *OutSec = Section->OutSec; - ESym->st_shndx = OutSec->SectionIndex; - ESym->st_value = OutSec->Addr + Section->getOffset(Body); - } - ESym->st_name = P.second; - ESym->st_size = Body.template getSize(); - ESym->setBindingAndType(STB_LOCAL, Body.Type); - Buf += sizeof(*ESym); + + for (auto I = Symbols.begin(); I != Symbols.begin() + NumLocals; ++I) { + const DefinedRegular &Body = *cast>(I->Symbol); + InputSectionBase *Section = Body.Section; + auto *ESym = reinterpret_cast(Buf); + + if (!Section) { + ESym->st_shndx = SHN_ABS; + ESym->st_value = Body.Value; + } else { + const OutputSectionBase *OutSec = Section->OutSec; + ESym->st_shndx = OutSec->SectionIndex; + ESym->st_value = OutSec->Addr + Section->getOffset(Body); } + ESym->st_name = I->StrTabOffset; + ESym->st_size = Body.template getSize(); + ESym->setBindingAndType(STB_LOCAL, Body.Type); + Buf += sizeof(*ESym); } } @@ -1141,7 +1149,9 @@ // Write the internal symbol table contents to the output symbol table // pointed by Buf. auto *ESym = reinterpret_cast(Buf); - for (const SymbolTableEntry &S : Symbols) { + + for (auto I = Symbols.begin() + NumLocals; I != Symbols.end(); ++I) { + const SymbolTableEntry &S = *I; SymbolBody *Body = S.Symbol; size_t StrOff = S.StrTabOffset; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -466,11 +466,7 @@ InputSectionBase *Sec = DR->Section; if (!shouldKeepInSymtab(Sec, B->getName(), *B)) continue; - ++In::SymTab->NumLocals; - if (Config->Relocatable) - B->DynsymIndex = In::SymTab->NumLocals; - F->KeptLocalSyms.push_back(std::make_pair( - DR, In::SymTab->StrTabSec.addString(B->getName()))); + In::SymTab->addLocal(B); } } } @@ -1040,10 +1036,10 @@ if (!includeInSymtab(*Body)) continue; if (In::SymTab) - In::SymTab->addSymbol(Body); + In::SymTab->addGlobal(Body); if (In::DynSymTab && S->includeInDynsym()) { - In::DynSymTab->addSymbol(Body); + In::DynSymTab->addGlobal(Body); if (auto *SS = dyn_cast>(Body)) if (SS->file()->isNeeded()) In::VerNeed->addSymbol(SS);