Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -140,7 +140,7 @@ public: LinkerScript(); ~LinkerScript(); - void createSections(OutputSectionFactory &Factory); + void createSections(); std::vector> createPhdrs(); bool ignoreInterpSection(); Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -259,7 +259,34 @@ } template -void LinkerScript::createSections(OutputSectionFactory &Factory) { +static std::pair *, bool> +createOutputSection(InputSectionBase *C, StringRef Name) { + typedef typename ELFT::Shdr Elf_Shdr; + typedef typename ELFT::uint uintX_t; + + for (std::unique_ptr> &S : Out::Pool) { + if (S->getName() == Name) + return {S.get(), false}; + } + + const Elf_Shdr *H = C->getSectionHdr(); + uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED; + uintX_t Alignment = 0; + if (isa>(C)) + Alignment = std::max(H->sh_addralign, H->sh_entsize); + uint32_t Type = H->sh_type; + + bool IsNew; + OutputSectionBase *Sec = nullptr; + std::tie(Sec, IsNew) = + allocSection(C->SectionKind, Name, Flags, Alignment, Type); + if (IsNew) + Out::Pool.emplace_back(Sec); + return {Sec, IsNew}; +} + +template +void LinkerScript::createSections() { for (const std::unique_ptr &Base1 : Opt.Commands) { if (auto *Cmd = dyn_cast(Base1.get())) { if (shouldDefine(Cmd)) @@ -280,7 +307,7 @@ OutputSectionBase *OutSec; bool IsNew; - std::tie(OutSec, IsNew) = Factory.create(Head, Cmd->Name); + std::tie(OutSec, IsNew) = createOutputSection(Head, Cmd->Name); if (IsNew) OutputSections->push_back(OutSec); @@ -302,7 +329,7 @@ continue; OutputSectionBase *OutSec; bool IsNew; - std::tie(OutSec, IsNew) = Factory.create(S, getOutputSectionName(S)); + std::tie(OutSec, IsNew) = createOutputSection(S, getOutputSectionName(S)); if (IsNew) OutputSections->push_back(OutSec); OutSec->addSection(S); Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -34,11 +34,17 @@ template class MergeInputSection; template class MipsReginfoInputSection; template class OutputSection; +template class OutputSectionBase; template class ObjectFile; template class SharedFile; template class SharedSymbol; template class DefinedRegular; +template +std::pair *, bool> +allocSection(unsigned Kind, StringRef Name, typename ELFT::uint Flags, + typename ELFT::uint Alignment, uint32_t Type); + // This represents a section in an output file. // Different sub classes represent different types of sections. Some contain // input sections, others are created by the linker. Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -1790,37 +1790,41 @@ template std::pair *, bool> -OutputSectionFactory::create(InputSectionBase *C, - StringRef OutsecName) { - SectionKey Key = createKey(C, OutsecName); - OutputSectionBase *&Sec = Map[Key]; - if (Sec) - return {Sec, false}; - - switch (C->SectionKind) { +elf::allocSection(unsigned Kind, StringRef Name, typename ELFT::uint Flags, + typename ELFT::uint Alignment, uint32_t Type) { + switch (Kind) { case InputSectionBase::Regular: - Sec = new OutputSection(Key.Name, Key.Type, Key.Flags); - break; + return {new OutputSection(Name, Type, Flags), true}; case InputSectionBase::EHFrame: return {Out::EhFrame, false}; case InputSectionBase::Merge: - Sec = new MergeOutputSection(Key.Name, Key.Type, Key.Flags, - Key.Alignment); - break; + return {new MergeOutputSection(Name, Type, Flags, Alignment), true}; case InputSectionBase::MipsReginfo: - Sec = new MipsReginfoOutputSection(); - break; + return {new MipsReginfoOutputSection(), true}; case InputSectionBase::MipsOptions: - Sec = new MipsOptionsOutputSection(); - break; + return {new MipsOptionsOutputSection(), true}; case InputSectionBase::MipsAbiFlags: - Sec = new MipsAbiFlagsOutputSection(); - break; - case InputSectionBase::Layout: + return {new MipsAbiFlagsOutputSection(), true}; + default: llvm_unreachable("Invalid section type"); } - Out::Pool.emplace_back(Sec); - return {Sec, true}; +} + +template +std::pair *, bool> +OutputSectionFactory::create(InputSectionBase *C, + StringRef OutsecName) { + SectionKey Key = createKey(C, OutsecName); + OutputSectionBase *&Sec = Map[Key]; + if (Sec) + return {Sec, false}; + + bool Allocated; + std::tie(Sec, Allocated) = allocSection( + C->SectionKind, Key.Name, Key.Flags, Key.Alignment, Key.Type); + if (Allocated) + Out::Pool.emplace_back(Sec); + return {Sec, Allocated}; } template @@ -2016,3 +2020,16 @@ template class OutputSectionFactory; } } + +template std::pair *, bool> +elf::allocSection(unsigned Kind, StringRef Name, ELF32LE::uint Flags, + ELF32LE::uint Alignment, uint32_t Type); +template std::pair *, bool> +elf::allocSection(unsigned Kind, StringRef Name, ELF32BE::uint Flags, + ELF32BE::uint Alignment, uint32_t Type); +template std::pair *, bool> +elf::allocSection(unsigned Kind, StringRef Name, ELF64LE::uint Flags, + ELF64LE::uint Alignment, uint32_t Type); +template std::pair *, bool> +elf::allocSection(unsigned Kind, StringRef Name, ELF64BE::uint Flags, + ELF64BE::uint Alignment, uint32_t Type); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -252,7 +252,7 @@ Script::X->OutputSections = &OutputSections; if (ScriptConfig->HasContents) - Script::X->createSections(Factory); + Script::X->createSections(); else createSections();