Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -53,7 +53,6 @@ ScriptConfig = ≻ Driver->main(Args, CanExitEarly); - InputFile::freePool(); return !HasError; } @@ -753,7 +752,8 @@ // MergeInputSection::splitIntoPieces needs to be called before // any call of MergeInputSection::getOffset. Do that. for (elf::ObjectFile *F : Symtab.getObjectFiles()) { - for (InputSectionBase *S : F->getSections()) { + for (const auto &Iter : F->getSections()) { + InputSectionBase *S = Iter.get(); if (!S || S == &InputSection::Discarded || !S->Live) continue; if (S->Compressed) @@ -765,4 +765,5 @@ // Write the result to the file. writeResult(); + InputFile::freePool(); } Index: ELF/ICF.cpp =================================================================== --- ELF/ICF.cpp +++ ELF/ICF.cpp @@ -148,9 +148,11 @@ std::vector *> ICF::getSections() { std::vector *> V; for (ObjectFile *F : Symtab::X->getObjectFiles()) - for (InputSectionBase *S : F->getSections()) + for (const auto &Iter : F->getSections()) { + InputSectionBase *S = Iter.get(); if (isEligible(S)) V.push_back(cast>(S)); + } return V; } Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -158,6 +158,13 @@ StringRef getShtGroupSignature(const Elf_Shdr &Sec); ArrayRef getShtGroupEntries(const Elf_Shdr &Sec); + struct Deleter { + void operator()(InputSectionBase *P); + }; + typedef std::unique_ptr, Deleter> SecPtr; + static_assert(sizeof(SecPtr) == sizeof(InputSectionBase *), + "Should have no overhead"); + public: static bool classof(const InputFile *F) { return F->kind() == Base::ObjectKind; @@ -170,7 +177,7 @@ explicit ObjectFile(llvm::BumpPtrAllocator &Alloc, MemoryBufferRef M); void parse(llvm::DenseSet &ComdatGroups); - ArrayRef *> getSections() const { return Sections; } + ArrayRef getSections() const { return Sections; } InputSectionBase *getSection(const Elf_Sym &Sym) const; SymbolBody &getSymbolBody(uint32_t SymbolIndex) const { @@ -221,21 +228,18 @@ SymbolBody *createSymbolBody(const Elf_Sym *Sym); // List of all sections defined by this file. - std::vector *> Sections; + std::vector Sections; // List of all symbols referenced or defined by this file. std::vector SymbolBodies; // MIPS .reginfo section defined by this file. - std::unique_ptr> MipsReginfo; + MipsReginfoInputSection *MipsReginfo = nullptr; // MIPS .MIPS.options section defined by this file. - std::unique_ptr> MipsOptions; + MipsOptionsInputSection *MipsOptions = nullptr; // MIPS .MIPS.abiflags section defined by this file. - std::unique_ptr> MipsAbiFlags; + MipsAbiFlagsInputSection *MipsAbiFlags = nullptr; - llvm::SpecificBumpPtrAllocator> IAlloc; - llvm::SpecificBumpPtrAllocator> MAlloc; - llvm::SpecificBumpPtrAllocator> EHAlloc; std::unique_ptr> DIH; }; Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -139,6 +139,34 @@ StringTable = check(ELFObj.getStringTableForSymtab(*Symtab)); } +template static void destruct(T *P) { P->~T(); } + +template +void elf::ObjectFile::Deleter::operator()(InputSectionBase *P) { + if (!P || P == &InputSection::Discarded) + return; + switch (P->kind()) { + case InputSectionData::Regular: + destruct(cast>(P)); + return; + case InputSectionData::EHFrame: + destruct(cast>(P)); + return; + case InputSectionData::Merge: + destruct(cast>(P)); + return; + case InputSectionData::MipsReginfo: + destruct(cast>(P)); + return; + case InputSectionData::MipsOptions: + destruct(cast>(P)); + return; + case InputSectionData::MipsAbiFlags: + destruct(cast>(P)); + return; + }; +} + template elf::ObjectFile::ObjectFile(BumpPtrAllocator &Alloc, MemoryBufferRef M) : ELFFileBase(Base::ObjectKind, M), Alloc(Alloc) {} @@ -275,20 +303,20 @@ const ELFFile &Obj = this->ELFObj; for (const Elf_Shdr &Sec : Obj.sections()) { ++I; - if (Sections[I] == &InputSection::Discarded) + if (Sections[I].get() == &InputSection::Discarded) continue; // SHF_EXCLUDE'ed sections are discarded by the linker. However, // if -r is given, we'll let the final link discard such sections. // This is compatible with GNU. if ((Sec.sh_flags & SHF_EXCLUDE) && !Config->Relocatable) { - Sections[I] = &InputSection::Discarded; + Sections[I].reset(&InputSection::Discarded); continue; } switch (Sec.sh_type) { case SHT_GROUP: - Sections[I] = &InputSection::Discarded; + Sections[I].reset(&InputSection::Discarded); if (ComdatGroups.insert(CachedHashStringRef(getShtGroupSignature(Sec))) .second) continue; @@ -296,7 +324,7 @@ if (SecIndex >= Size) fatal(getFilename(this) + ": invalid section index in group: " + Twine(SecIndex)); - Sections[SecIndex] = &InputSection::Discarded; + Sections[SecIndex].reset(&InputSection::Discarded); } break; case SHT_SYMTAB: @@ -309,7 +337,7 @@ case SHT_NULL: break; default: - Sections[I] = createInputSection(Sec); + Sections[I].reset(createInputSection(Sec)); } } } @@ -321,14 +349,15 @@ unsigned I = -1; for (const Elf_Shdr &Sec : this->ELFObj.sections()) { ++I; - if ((Sections[I] == &InputSection::Discarded) || + InputSectionBase *CurSec = Sections[I].get(); + if ((CurSec == &InputSection::Discarded) || !(Sec.sh_flags & SHF_LINK_ORDER)) continue; if (Sec.sh_link >= Sections.size()) fatal(getFilename(this) + ": invalid sh_link index: " + Twine(Sec.sh_link)); - auto *IS = cast>(Sections[Sec.sh_link]); - IS->DependentSection = Sections[I]; + auto &IS = cast>(*Sections[Sec.sh_link]); + IS.DependentSection = CurSec; } } @@ -339,7 +368,7 @@ if (Idx >= Sections.size()) fatal(getFilename(this) + ": invalid relocated section index: " + Twine(Idx)); - InputSectionBase *Target = Sections[Idx]; + InputSectionBase *Target = Sections[Idx].get(); // Strictly speaking, a relocation section must be included in the // group of the section it relocates. However, LLVM 3.3 and earlier @@ -366,27 +395,27 @@ if (MipsReginfo) fatal(getFilename(this) + ": multiple SHT_MIPS_REGINFO sections are not allowed"); - MipsReginfo.reset(new MipsReginfoInputSection(this, &Sec, Name)); - return MipsReginfo.get(); + MipsReginfo = new (Alloc) MipsReginfoInputSection(this, &Sec, Name); + return MipsReginfo; case SHT_MIPS_OPTIONS: if (MipsOptions) fatal(getFilename(this) + ": multiple SHT_MIPS_OPTIONS sections are not allowed"); - MipsOptions.reset(new MipsOptionsInputSection(this, &Sec, Name)); - return MipsOptions.get(); + MipsOptions = new (Alloc) MipsOptionsInputSection(this, &Sec, Name); + return MipsOptions; case SHT_MIPS_ABIFLAGS: if (MipsAbiFlags) fatal(getFilename(this) + ": multiple SHT_MIPS_ABIFLAGS sections are not allowed"); - MipsAbiFlags.reset(new MipsAbiFlagsInputSection(this, &Sec, Name)); - return MipsAbiFlags.get(); + MipsAbiFlags = new (Alloc) MipsAbiFlagsInputSection(this, &Sec, Name); + return MipsAbiFlags; case SHT_RELA: case SHT_REL: { // This section contains relocation information. // If -r is given, we do not interpret or apply relocation // but just copy relocation sections to output. if (Config->Relocatable) - return new (IAlloc.Allocate()) InputSection(this, &Sec, Name); + return new (Alloc) InputSection(this, &Sec, Name); // Find the relocation target section and associate this // section with it. @@ -428,11 +457,11 @@ // .eh_frame_hdr section for runtime. So we handle them with a special // class. For relocatable outputs, they are just passed through. if (Name == ".eh_frame" && !Config->Relocatable) - return new (EHAlloc.Allocate()) EhInputSection(this, &Sec, Name); + return new (Alloc) EhInputSection(this, &Sec, Name); if (shouldMerge(Sec)) - return new (MAlloc.Allocate()) MergeInputSection(this, &Sec, Name); - return new (IAlloc.Allocate()) InputSection(this, &Sec, Name); + return new (Alloc) MergeInputSection(this, &Sec, Name); + return new (Alloc) InputSection(this, &Sec, Name); } template void elf::ObjectFile::initializeSymbols() { @@ -450,7 +479,7 @@ uint32_t Index = this->getSectionIndex(Sym); if (Index >= Sections.size()) fatal(getFilename(this) + ": invalid section index: " + Twine(Index)); - InputSectionBase *S = Sections[Index]; + InputSectionBase *S = Sections[Index].get(); // We found that GNU assembler 2.17.50 [FreeBSD] 2007-07-03 // could generate broken objects. STT_SECTION symbols can be Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -183,7 +183,7 @@ template InputSectionBase *InputSectionBase::getLinkOrderDep() const { if ((Flags & SHF_LINK_ORDER) && Link != 0) - return getFile()->getSections()[Link]; + return getFile()->getSections()[Link].get(); return nullptr; } @@ -207,8 +207,7 @@ template InputSectionBase *InputSection::getRelocatedSection() { assert(this->Type == SHT_RELA || this->Type == SHT_REL); - ArrayRef *> Sections = this->File->getSections(); - return Sections[this->Info]; + return this->File->getSections()[this->Info].get(); } template void InputSection::addThunk(const Thunk *T) { Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -180,9 +180,11 @@ if (!I->FileRe.match(Filename) || Pat.ExcludedFileRe.match(Filename)) continue; - for (InputSectionBase *S : F->getSections()) + for (const auto &Iter : F->getSections()) { + InputSectionBase *S = Iter.get(); if (!isDiscarded(S) && !S->OutSec && Pat.SectionRe.match(S->Name)) I->Sections.push_back(S); + } if (Pat.SectionRe.match("COMMON")) I->Sections.push_back(InputSection::CommonInputSection); } @@ -348,9 +350,11 @@ processCommands(Factory); // Add orphan sections. for (ObjectFile *F : Symtab::X->getObjectFiles()) - for (InputSectionBase *S : F->getSections()) + for (const auto &Iter : F->getSections()) { + InputSectionBase *S = Iter.get(); if (!isDiscarded(S) && !S->OutSec) addSection(Factory, S, getOutputSectionName(S->Name, Opt.Alloc)); + } } // Sets value of a section-defined symbol. Two kinds of Index: ELF/MarkLive.cpp =================================================================== --- ELF/MarkLive.cpp +++ ELF/MarkLive.cpp @@ -239,7 +239,8 @@ // Preserve special sections and those which are specified in linker // script KEEP command. for (ObjectFile *F : Symtab::X->getObjectFiles()) { - for (InputSectionBase *Sec : F->getSections()) { + for (const auto &Iter : F->getSections()) { + InputSectionBase *Sec = Iter.get(); if (!Sec || Sec == &InputSection::Discarded) continue; // .eh_frame is always marked as live now, but also it can reference to Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -680,7 +680,8 @@ std::function &, const typename ELFT::Shdr &)> Fn) { for (elf::ObjectFile *F : Symtab::X->getObjectFiles()) { - for (InputSectionBase *IS : F->getSections()) { + for (const auto &Iter : F->getSections()) { + InputSectionBase *IS = Iter.get(); if (isDiscarded(IS)) continue; // Scan all relocations. Each relocation goes through a series @@ -704,7 +705,8 @@ template void Writer::createSections() { for (elf::ObjectFile *F : Symtab::X->getObjectFiles()) { - for (InputSectionBase *IS : F->getSections()) { + for (const auto &Iter : F->getSections()) { + InputSectionBase *IS = Iter.get(); if (isDiscarded(IS)) { reportDiscarded(IS); continue;