summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/OutputSections.cpp25
-rw-r--r--lld/ELF/Writer.cpp42
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
OpenPOWER on IntegriCloud