Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -340,8 +340,7 @@ } template void GnuHashTableSection::finalize() { - ArrayRef A = Out::DynSymTab->getSymbols(); - unsigned NumHashed = std::count_if(A.begin(), A.end(), includeInGnuHashTable); + unsigned NumHashed = HashedSymbols.size(); NBuckets = calcNBuckets(NumHashed); MaskWords = calcMaskWords(NumHashed); // Second hash shift estimation: just predefined values. @@ -900,6 +899,9 @@ } template void SymbolTableSection::finalize() { + if (this->Header.sh_size) + return; // Already finalized. + this->Header.sh_size = getNumSymbols() * sizeof(Elf_Sym); this->Header.sh_link = StrTabSec.SectionIndex; this->Header.sh_info = NumLocals + 1; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -581,9 +581,13 @@ for (OutputSectionBase *Sec : OutputSections) Out::ShStrTab->add(Sec->getName()); - // Fill the DynStrTab early because Dynamic adds strings to - // DynStrTab but .dynstr may appear before .dynamic. + // Finalizers fix each section's size. + // .dynamic section's finalizer may add strings to .dynstr, + // so finalize that early. + // Likewise, .dynsym is finalized early since that may fill up .gnu.hash. Out::Dynamic->finalize(); + if (isOutputDynamic()) + Out::DynSymTab->finalize(); // Fill other section headers. for (OutputSectionBase *Sec : OutputSections)