diff options
author | Peter Smith <peter.smith@linaro.org> | 2017-06-05 08:51:15 +0000 |
---|---|---|
committer | Peter Smith <peter.smith@linaro.org> | 2017-06-05 08:51:15 +0000 |
commit | 43e852fb79fe4a7bfca857d92b6b5d30c108cf45 (patch) | |
tree | 68fe3b061bcc0484ca3552e01459981bb54dd7b4 | |
parent | 77a12b3972a95dc620a5a6ed8b7513caebb80f35 (diff) | |
download | bcm5719-llvm-43e852fb79fe4a7bfca857d92b6b5d30c108cf45.tar.gz bcm5719-llvm-43e852fb79fe4a7bfca857d92b6b5d30c108cf45.zip |
[ELF] SHF_LINK_ORDER should sort based on InputSectionDescriptions
This change alters the sorting for OutputSections with the SHF_LINK_ORDER
flag in OutputSection::finalize() to use the InputSectionDescription
representation and not the OutputSection::Sections representation.
Differential revision: https://reviews.llvm.org/D33772
llvm-svn: 304700
-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. |