diff options
-rw-r--r-- | lld/ELF/OutputSections.cpp | 14 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 11 |
2 files changed, 19 insertions, 6 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8357d6b03bb..05a58e3d200 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -99,8 +99,20 @@ template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) { template <class ELFT> 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<InputSection **> ScriptSections; + std::vector<InputSection *> Sections; + for (BaseCommand *Base : Cmd->Commands) + if (auto *ISD = dyn_cast<InputSectionDescription>(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 diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index f68e07fc69d..79ca67e7acd 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -257,11 +257,6 @@ template <class ELFT> void Writer<ELFT>::run() { if (ErrorCount) return; - if (!Script->Opt.HasSections) - Script->fabricateDefaultCommands(); - else - Script->synchronize(); - for (BaseCommand *Base : Script->Opt.Commands) if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) OutputSectionCommands.push_back(Cmd); @@ -1261,6 +1256,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { 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. |