Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -459,7 +459,13 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { unsigned End = SectionCommands.size(); + std::vector V; for (InputSectionBase *S : InputSections) { + // We should report discarded sections for case when no SECTIONS command + // is present. For other case we already reported it during processing + // layout commands when computed input sections lists. + if (!S->Live && !HasSectionsCommand) + reportDiscarded(S); if (!S->Live || S->Parent) continue; @@ -473,9 +479,17 @@ } if (OutputSection *OS = Factory.addInputSec(S, Name)) - SectionCommands.push_back(OS); + V.push_back(OS); assert(S->getOutputSection()->SectionIndex == INT_MAX); } + + // If no SECTIONS command was given, we should insert sections commands + // before any others, so that we can handle scripts which refers them, + // for example: "foo = ABSOLUTE(ADDR(.text)));". + // When SECTIONS command is present we just add all orphans to the end. + auto InsertPoint = + HasSectionsCommand ? SectionCommands.end() : SectionCommands.begin(); + SectionCommands.insert(InsertPoint, V.begin(), V.end()); } uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) { Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -89,11 +89,7 @@ } void OutputSection::addSection(InputSection *IS) { - if (!IS->Live) { - reportDiscarded(IS); - return; - } - + assert(IS->Live); if (!Live) { // If IS is the first section to be added to this section, // initialize Type by IS->Type. @@ -235,11 +231,7 @@ OutputSection *OutputSectionFactory::addInputSec(InputSectionBase *IS, StringRef OutsecName) { - if (!IS->Live) { - reportDiscarded(IS); - return nullptr; - } - + assert(IS->Live); // Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r // option is given. A section with SHT_GROUP defines a "section group", and // its members have SHF_GROUP attribute. Usually these flags have already been Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -49,7 +49,6 @@ void copyLocalSymbols(); void addSectionSymbols(); void addReservedSymbols(); - void createSections(); void forEachRelSec(std::function Fn); void sortSections(); void finalizeSections(); @@ -160,21 +159,27 @@ if (!Config->Relocatable) addReservedSymbols(); - // Create output sections. - if (Script->HasSectionsCommand) { - // If linker script contains SECTIONS commands, let it create sections. - Script->processSectionCommands(Factory); - - // Linker scripts may have left some input sections unassigned. - // Assign such sections using the default rule. - Script->addOrphanSections(Factory); - } else { - // If linker script does not contain SECTIONS commands, create - // output sections by default rules. We still need to give the - // linker script a chance to run, because it might contain - // non-SECTIONS commands such as ASSERT. - Script->processSectionCommands(Factory); - createSections(); + // We want to process linker script commands. When SECTIONS command given + // we let it create sections, otherwise we still need to give the linker + // script a chance to run, because it might contain non-SECTIONS commands + // such as ASSERT or symbols assignments. + Script->processSectionCommands(Factory); + + // When script does not have SECTIONS command or have sections not listed in + // layout, such sections called "orphans". Here we create output sections and + // assign orphan sections using the default rule. + Script->addOrphanSections(Factory); + + // When no SEECTIONS command is present, we want to apply default sorting and + // fabricate minimum default commands, like if trivial SECTIONS command would + // be given. + if (!Script->HasSectionsCommand) { + Script->fabricateDefaultCommands(); + sortBySymbolsOrder(); + sortInitFini(findSection(".init_array")); + sortInitFini(findSection(".fini_array")); + sortCtorsDtors(findSection(".ctors")); + sortCtorsDtors(findSection(".dtors")); } if (Config->Discard != DiscardPolicy::All) @@ -859,25 +864,6 @@ Fn(*ES); } -template void Writer::createSections() { - std::vector Vec; - for (InputSectionBase *IS : InputSections) - if (IS) - if (OutputSection *Sec = - Factory.addInputSec(IS, getOutputSectionName(IS->Name))) - Vec.push_back(Sec); - - Script->SectionCommands.insert(Script->SectionCommands.begin(), Vec.begin(), - Vec.end()); - - Script->fabricateDefaultCommands(); - sortBySymbolsOrder(); - sortInitFini(findSection(".init_array")); - sortInitFini(findSection(".fini_array")); - sortCtorsDtors(findSection(".ctors")); - sortCtorsDtors(findSection(".dtors")); -} - // This function generates assignments for predefined symbols (e.g. _end or // _etext) and inserts them into the commands sequence to be processed at the // appropriate time. This ensures that the value is going to be correct by the