Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -1015,10 +1015,6 @@ template static void scanRelocs(InputSectionBase &Sec, ArrayRef Rels) { OffsetGetter GetOffset(Sec); - - // Not all relocations end up in Sec.Relocations, but a lot do. - Sec.Relocations.reserve(Rels.size()); - for (auto I = Rels.begin(), End = Rels.end(); I != End;) scanReloc(Sec, GetOffset, I, End); } Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -859,6 +859,19 @@ template void Writer::forEachRelSec(std::function Fn) { + std::vector Buffer; + + // We allocate a lot of relocations. By using a single buffer for + // all sections we ensure that the final vector in each section has + // the exact size. + auto WithBuffer = [&](InputSectionBase &Sec) { + swap(Sec.Relocations, Buffer); + Fn(Sec); + swap(Sec.Relocations, Buffer); + Sec.Relocations.insert(Sec.Relocations.end(), Buffer.begin(), Buffer.end()); + Buffer.clear(); + }; + // Scan all relocations. Each relocation goes through a series // of tests to determine if it needs special treatment, such as // creating GOT, PLT, copy relocations, etc. @@ -866,9 +879,9 @@ // processed by InputSection::relocateNonAlloc. for (InputSectionBase *IS : InputSections) if (IS->Live && isa(IS) && (IS->Flags & SHF_ALLOC)) - Fn(*IS); + WithBuffer(*IS); for (EhInputSection *ES : InX::EhFrame->Sections) - Fn(*ES); + WithBuffer(*ES); } // This function generates assignments for predefined symbols (e.g. _end or