Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -29,8 +29,7 @@ using namespace lld::elf; template bool elf::isDiscarded(InputSectionBase *S) { - return !S || S == &InputSection::Discarded || !S->Live || - Script::X->isDiscarded(S); + return !S || S == &InputSection::Discarded || !S->Live; } template Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -18,6 +18,12 @@ namespace lld { namespace elf { +template class InputSectionBase; +template class OutputSectionBase; +template class OutputSectionFactory; + +template +using OutputSectionList = std::vector>>; // Parses a linker script. Calling this function updates // Config and ScriptConfig. @@ -33,7 +39,6 @@ : Dest(D), SectionPattern(S) {} StringRef Dest; - StringRef SectionPattern; }; @@ -79,6 +84,7 @@ ArrayRef getFiller(StringRef Name); bool isDiscarded(InputSectionBase *S); bool shouldKeep(InputSectionBase *S); + OutputSectionList 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 @@ -23,6 +23,7 @@ #include "Symbols.h" #include "SymbolTable.h" #include "Target.h" +#include "Writer.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ELF.h" #include "llvm/Support/FileSystem.h" @@ -195,7 +196,7 @@ template bool LinkerScript::isDiscarded(InputSectionBase *S) { - return getOutputSection(S) == "/DISCARD/"; + return !S || !S->Live || S->OutSec || getOutputSection(S) == "/DISCARD/"; } template @@ -207,6 +208,46 @@ } template +static void addInputSection( + OutputSectionFactory &Factory, InputSectionBase *C, + StringRef OutSecName, + std::vector>> &OutSecList) { + + OutputSectionBase *Sec; + bool IsNew; + std::tie(Sec, IsNew) = Factory.create(C, OutSecName); + if (IsNew) + OutSecList.emplace_back(Sec); + Sec->addSection(C); +} + +template +OutputSectionList +LinkerScript::createSections(OutputSectionFactory &Factory) { + OutputSectionList Result; + typedef std::unique_ptr> ObjectFileUP; + + // 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 ObjectFileUP &F : Symtab::X->getObjectFiles()) + for (InputSectionBase *S : F->getSections()) + if (!isDiscarded(S) && + globMatch(R.SectionPattern, S->getSectionName())) + // Add single input section to output section + addInputSection(Factory, S, R.Dest, Result); + + // Add all other input sections, which are not listed in script + for (const ObjectFileUP &F : Symtab::X->getObjectFiles()) + for (InputSectionBase *C : F->getSections()) + if (!isDiscarded(C)) + addInputSection(Factory, C, getOutputSectionName(C), Result); + + 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 @@ -60,6 +60,7 @@ void copyLocalSymbols(); void addReservedSymbols(); void createSections(); + void finalizeSections(); void addPredefinedSections(); bool needsGot(); @@ -87,7 +88,8 @@ BumpPtrAllocator Alloc; std::vector *> OutputSections; - std::vector>> OwningSections; + OutputSectionList OwningSections; + OutputSectionFactory Factory; void addRelIpltSymbols(); void addStartEndSymbols(); @@ -233,7 +235,12 @@ if (!Config->DiscardAll) copyLocalSymbols(); addReservedSymbols(); - createSections(); + + if (ScriptConfig->DoLayout) + OwningSections = Script::X->createSections(Factory); + else + createSections(); + finalizeSections(); if (HasError) return; @@ -603,11 +610,7 @@ 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; for (const std::unique_ptr> &F : Symtab.getObjectFiles()) { for (InputSectionBase *C : F->getSections()) { @@ -618,14 +621,23 @@ OutputSectionBase *Sec; bool IsNew; std::tie(Sec, IsNew) = Factory.create(C, getOutputSectionName(C)); - if (IsNew) { + if (IsNew) OwningSections.emplace_back(Sec); - OutputSections.push_back(Sec); - RegularSections.push_back(Sec); - } + Sec->addSection(C); } } +} + +// Create output section objects and add them to OutputSections. +template void Writer::finalizeSections() { + // Create output sections for input object file sections. + std::vector *> RegularSections; + + for (std::unique_ptr> &OutSec : OwningSections) { + OutputSections.push_back(OutSec.get()); + RegularSections.push_back(OutSec.get()); + } // 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