Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -465,9 +465,39 @@ // Add sections that didn't match any sections command. void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { + std::map> Orphanage; for (InputSectionBase *S : InputSections) - if (S->Live && !S->OutSec) + if (S->Live && !S->OutSec) { Factory.addInputSec(S, getOutputSectionName(S->Name)); + Orphanage[S->OutSec].push_back(S); + } + + // For each OutputSection that already has an OutputSectionCmd, add an + // InputSectionDescription at the end for the OrphanSections. This matches + // GNU ld behavior for scripts such as .text : { *(.text) SYM = .; } the + // orphan sections such as .text.suffix are added after the symbol assignment + for (auto &KV : Orphanage) { + OutputSection *OS = KV.first; + auto Pos = std::find_if(Opt.Commands.begin(), Opt.Commands.end(), + [&](BaseCommand *Base) { + auto *Cmd = dyn_cast(Base); + return Cmd && Cmd->Name == OS->Name; + }); + if (Pos == Opt.Commands.end()) + // A new OutputSection, we handle this case in placeOrphanSections() + continue; + auto *OSCmd = cast(*Pos); + if (KV.second.front()->Name.startswith(".ARM.exidx")) + // .ARM.exidx sections must be handled in one InputSectionDescription + // FIXME: OutputSections still sorts the OutputSection::Sections so we + // can give the wrong answer when the order of the input objects does + // not match the address assignment. + continue; + + auto *ISD = make(""); + OSCmd->Commands.push_back(ISD); + ISD->Sections = std::move(KV.second); + } } static bool isTbss(OutputSection *Sec) { @@ -828,6 +858,16 @@ auto *Cmd = make(Name); Cmd->Sec = Sec; Opt.Commands.insert(CmdIter, Cmd); + + // Create an InputSectionDescription for orphan input sections + if (!Sec->Sections.empty() && (Sec->Flags & SHF_ALLOC)) { + auto *ISD = make(""); + Cmd->Commands.push_back(ISD); + for (InputSection *ISec : Sec->Sections) { + ISD->Sections.push_back(ISec); + ISec->Assigned = true; + } + } ++CmdIndex; continue; }