Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ 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: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -585,6 +585,11 @@ // DynStrTab but .dynstr may appear before .dynamic. Out::Dynamic->finalize(); + // The dynamic symbols section should be finalized before the others + // because it can fill up the GNU hash section. + if (isOutputDynamic()) + Out::DynSymTab->finalize(); + // Fill other section headers. for (OutputSectionBase *Sec : OutputSections) Sec->finalize();