[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