Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -21,8 +21,6 @@ namespace lld { namespace elf { -template bool isDiscarded(InputSectionBase *S); - class SymbolBody; template class ICF; Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -28,11 +28,6 @@ using namespace lld; using namespace lld::elf; -template bool elf::isDiscarded(InputSectionBase *S) { - return !S || S == &InputSection::Discarded || !S->Live || - Script::X->isDiscarded(S); -} - template InputSectionBase::InputSectionBase(elf::ObjectFile *File, const Elf_Shdr *Header, @@ -650,11 +645,6 @@ return S->SectionKind == InputSectionBase::MipsOptions; } -template bool elf::isDiscarded(InputSectionBase *); -template bool elf::isDiscarded(InputSectionBase *); -template bool elf::isDiscarded(InputSectionBase *); -template bool elf::isDiscarded(InputSectionBase *); - template class elf::InputSectionBase; template class elf::InputSectionBase; template class elf::InputSectionBase; Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -19,6 +19,9 @@ namespace lld { namespace elf { +template class InputSectionBase; +template class OutputSectionBase; +template class OutputSectionFactory; // Parses a linker script. Calling this function updates // Config and ScriptConfig. @@ -93,6 +96,8 @@ ArrayRef getFiller(StringRef Name); bool isDiscarded(InputSectionBase *S); bool shouldKeep(InputSectionBase *S); + std::vector>> + createSections(OutputSectionFactory &Factory); void assignAddresses(ArrayRef *> S); int compareSections(StringRef A, StringRef B); void addScriptedSymbols(); Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -196,7 +196,7 @@ template bool LinkerScript::isDiscarded(InputSectionBase *S) { - return getOutputSection(S) == "/DISCARD/"; + return !S || !S->Live || getOutputSection(S) == "/DISCARD/"; } template @@ -208,6 +208,47 @@ } template +std::vector>> +LinkerScript::createSections(OutputSectionFactory &Factory) { + std::vector>> Result; + // Add input section to output section. If there is no output section yet, + // then create it and add to output section list. + auto AddInputSec = [&](InputSectionBase *C, StringRef Name) { + OutputSectionBase *Sec; + bool IsNew; + std::tie(Sec, IsNew) = Factory.create(C, Name); + if (IsNew) + Result.emplace_back(Sec); + Sec->addSection(C); + }; + + // Select input sections matching rule and add them to corresponding + // output section. Section rules are processed in order they're listed + // in script, so correct input section order is maintained by design. + for (SectionRule &R : Opt.Sections) + for (const std::unique_ptr> &F : + Symtab::X->getObjectFiles()) + for (InputSectionBase *S : F->getSections()) + if (!isDiscarded(S) && !S->OutSec && + globMatch(R.SectionPattern, S->getSectionName())) + // Add single input section to output section. + AddInputSec(S, R.Dest); + + // Add all other input sections, which are not listed in script. + for (const std::unique_ptr> &F : + Symtab::X->getObjectFiles()) + for (InputSectionBase *S : F->getSections()) + if (!isDiscarded(S)) { + if(!S->OutSec) + AddInputSec(S, getOutputSectionName(S)); + } + else + reportDiscarded(S, F); + + return Result; +} + +template void LinkerScript::assignAddresses( ArrayRef *> Sections) { // Orphan sections are sections present in the input files which Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -48,7 +48,8 @@ void copyLocalSymbols(); void addReservedSymbols(); - void createSections(); + std::vector>> createSections(); + void finalizeSections(); void addPredefinedSections(); bool needsGot(); @@ -71,6 +72,7 @@ BumpPtrAllocator Alloc; std::vector *> OutputSections; std::vector>> OwningSections; + OutputSectionFactory Factory; void addRelIpltSymbols(); void addStartEndSymbols(); @@ -216,7 +218,16 @@ if (!Config->DiscardAll) copyLocalSymbols(); addReservedSymbols(); - createSections(); + + std::vector>> OwningSections = + ScriptConfig->DoLayout ? Script::X->createSections(Factory) + : createSections(); + + std::for_each(OwningSections.begin(), OwningSections.end(), + [&](std::unique_ptr> &Sec) { + OutputSections.push_back(Sec.get()); + }); + finalizeSections(); if (HasError) return; @@ -477,6 +488,10 @@ return !Symtab::X->getSharedFiles().empty() || Config->Pic; } +template static bool isDiscarded(InputSectionBase *S) { + return !S || S == &InputSection::Discarded || !S->Live; +} + // Program header entry template PhdrEntry::PhdrEntry(unsigned Type, unsigned Flags) { @@ -623,11 +638,11 @@ reinterpret_cast *>(S)->sortCtorsDtors(); } -// Create output section objects and add them to OutputSections. -template void Writer::createSections() { - // Create output sections for input object file sections. - std::vector *> RegularSections; - OutputSectionFactory Factory; +template +std::vector>> +Writer::createSections() { + std::vector>> Result; + for (const std::unique_ptr> &F : Symtab.getObjectFiles()) { for (InputSectionBase *C : F->getSections()) { @@ -638,14 +653,19 @@ OutputSectionBase *Sec; bool IsNew; std::tie(Sec, IsNew) = Factory.create(C, getOutputSectionName(C)); - if (IsNew) { - OwningSections.emplace_back(Sec); - OutputSections.push_back(Sec); - RegularSections.push_back(Sec); - } + if (IsNew) + Result.emplace_back(Sec); + Sec->addSection(C); } } + return Result; +} + +// Create output section objects and add them to OutputSections. +template void Writer::finalizeSections() { + // Create output sections for input object file sections. + std::vector *> RegularSections = OutputSections; // If we have a .opd section (used under PPC64 for function descriptors), // store a pointer to it here so that we can use it later when processing