diff options
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 25 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 42 |
2 files changed, 43 insertions, 24 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 27a45c75402..438dfa17205 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -273,20 +273,6 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) { writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size); } -static bool compareByFilePosition(InputSection *A, InputSection *B) { - // Synthetic doesn't have link order dependecy, stable_sort will keep it last - if (A->kind() == InputSectionBase::Synthetic || - B->kind() == InputSectionBase::Synthetic) - return false; - InputSection *LA = A->getLinkOrderDep(); - InputSection *LB = B->getLinkOrderDep(); - OutputSection *AOut = LA->getParent(); - OutputSection *BOut = LB->getParent(); - if (AOut != BOut) - return AOut->SectionIndex < BOut->SectionIndex; - return LA->OutSecOff < LB->OutSecOff; -} - template <class ELFT> static void finalizeShtGroup(OutputSection *OS, ArrayRef<InputSection *> Sections) { @@ -304,26 +290,17 @@ static void finalizeShtGroup(OutputSection *OS, } template <class ELFT> void OutputSection::finalize() { - // 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 : SectionCommands) { if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) { - for (InputSection *&IS : ISD->Sections) { - ScriptSections.push_back(&IS); + for (InputSection *&IS : ISD->Sections) Sections.push_back(IS); - } } if (isa<ByteCommand>(Base) && Type == SHT_NOBITS) Type = SHT_PROGBITS; } if (Flags & SHF_LINK_ORDER) { - std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition); - 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 // need to translate the InputSection sh_link to the OutputSection sh_link, diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 043f3239fe9..0f411da4cad 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -51,6 +51,7 @@ private: void addSectionSymbols(); void forEachRelSec(std::function<void(InputSectionBase &)> Fn); void sortSections(); + void resolveShfLinkOrder(); void sortInputSections(); void finalizeSections(); void addPredefinedSections(); @@ -1146,6 +1147,43 @@ template <class ELFT> void Writer<ELFT>::sortSections() { Script->adjustSectionsAfterSorting(); } +static bool compareByFilePosition(InputSection *A, InputSection *B) { + // Synthetic doesn't have link order dependecy, stable_sort will keep it last + if (A->kind() == InputSectionBase::Synthetic || + B->kind() == InputSectionBase::Synthetic) + return false; + InputSection *LA = A->getLinkOrderDep(); + InputSection *LB = B->getLinkOrderDep(); + OutputSection *AOut = LA->getParent(); + OutputSection *BOut = LB->getParent(); + if (AOut != BOut) + return AOut->SectionIndex < BOut->SectionIndex; + return LA->OutSecOff < LB->OutSecOff; +} + +template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { + for (OutputSection *Sec : OutputSections) { + if (!(Sec->Flags & SHF_LINK_ORDER)) + continue; + + // 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 : Sec->SectionCommands) { + if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) { + for (InputSection *&IS : ISD->Sections) { + ScriptSections.push_back(&IS); + Sections.push_back(IS); + } + } + } + std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition); + for (int I = 0, N = Sections.size(); I < N; ++I) + *ScriptSections[I] = Sections[I]; + } +} + static void applySynthetic(const std::vector<SyntheticSection *> &Sections, std::function<void(SyntheticSection *)> Fn) { for (SyntheticSection *SS : Sections) @@ -1353,6 +1391,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { if (!Script->HasSectionsCommand && !Config->Relocatable) fixSectionAlignments(); + // After link order processing .ARM.exidx sections can be deduplicated, which + // needs to be resolved before any other address dependent operation. + resolveShfLinkOrder(); + // Some architectures need to generate content that depends on the address // of InputSections. For example some architectures use small displacements // for jump instructions that is is the linker's responsibility for creating |

