[lld] r320477 - [ELF] Move SHF_LINK_ORDER processing earlier in Writer.cpp [NFC]
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 12 05:30:44 PST 2017
Author: psmith
Date: Tue Dec 12 05:30:44 2017
New Revision: 320477
URL: http://llvm.org/viewvc/llvm-project?rev=320477&view=rev
Log:
[ELF] Move SHF_LINK_ORDER processing earlier in Writer.cpp [NFC]
By moving this step before thunk creation and other processing that depends
on the size of sections, we permit removal of duplicates in the .ARM.exidx
section.
Differential Revision: https://reviews.llvm.org/D40964
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=320477&r1=320476&r2=320477&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Dec 12 05:30:44 2017
@@ -273,20 +273,6 @@ template <class ELFT> void OutputSection
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(OutputSecti
}
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,
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=320477&r1=320476&r2=320477&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Dec 12 05:30:44 2017
@@ -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>:
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>:
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
More information about the llvm-commits
mailing list