Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -99,8 +99,20 @@ template void OutputSection::finalize() { if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) { + OutputSectionCommand *Cmd = Script->getCmd(this); + // Link order may be distributed across several InputSectionDescriptions + // but sort must consider them all at once. + std::vector ScriptSections; + std::vector Sections; + for (BaseCommand *Base : Cmd->Commands) + if (auto *ISD = dyn_cast(Base)) + for (InputSection *&IS : ISD->Sections) { + ScriptSections.push_back(&IS); + Sections.push_back(IS); + } std::sort(Sections.begin(), Sections.end(), compareByFilePosition); - assignOffsets(); + for (int I = 0, N = Sections.size(); I < N; ++I) + *ScriptSections[I] = Sections[I]; // We must preserve the link order dependency of sections with the // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -257,11 +257,6 @@ if (ErrorCount) return; - if (!Script->Opt.HasSections) - Script->fabricateDefaultCommands(); - else - Script->synchronize(); - for (BaseCommand *Base : Script->Opt.Commands) if (auto *Cmd = dyn_cast(Base)) OutputSectionCommands.push_back(Cmd); @@ -1261,6 +1256,12 @@ applySynthetic({InX::MipsGot}, [](SyntheticSection *SS) { SS->updateAllocSize(); }); } + + if (!Script->Opt.HasSections) + Script->fabricateDefaultCommands(); + else + Script->synchronize(); + // Fill other section headers. The dynamic table is finalized // at the end because some tags like RELSZ depend on result // of finalizing other sections.