Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -273,20 +273,6 @@ 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 static void finalizeShtGroup(OutputSection *OS, ArrayRef Sections) { @@ -304,26 +290,17 @@ } template void OutputSection::finalize() { - // 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 : SectionCommands) { if (auto *ISD = dyn_cast(Base)) { - for (InputSection *&IS : ISD->Sections) { - ScriptSections.push_back(&IS); + for (InputSection *&IS : ISD->Sections) Sections.push_back(IS); - } } if (isa(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, Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -51,6 +51,7 @@ void addSectionSymbols(); void forEachRelSec(std::function Fn); void sortSections(); + void resolveShfLinkOrder(); void sortInputSections(); void finalizeSections(); void addPredefinedSections(); @@ -1146,6 +1147,43 @@ 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 void Writer::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 ScriptSections; + std::vector Sections; + for (BaseCommand *Base : Sec->SectionCommands) { + if (auto *ISD = dyn_cast(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 &Sections, std::function Fn) { for (SyntheticSection *SS : Sections) @@ -1353,6 +1391,10 @@ 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