[lld] r325887 - [ELF] - Do not remove empty output sections that are explicitly assigned to phdr in script.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 23 02:53:04 PST 2018


Author: grimar
Date: Fri Feb 23 02:53:04 2018
New Revision: 325887

URL: http://llvm.org/viewvc/llvm-project?rev=325887&view=rev
Log:
[ELF] - Do not remove empty output sections that are explicitly assigned to phdr in script.

This continues direction started in D43069.

We can keep sections that are explicitly assigned to segment in script.
It helps to simplify code.

Differential revision: https://reviews.llvm.org/D43571

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/linkerscript/implicit-program-header.s
    lld/trunk/test/ELF/linkerscript/orphan-phdrs.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=325887&r1=325886&r2=325887&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Feb 23 02:53:04 2018
@@ -752,21 +752,12 @@ void LinkerScript::assignOffsets(OutputS
   }
 }
 
-void LinkerScript::removeEmptyCommands() {
-  // It is common practice to use very generic linker scripts. So for any
-  // given run some of the output sections in the script will be empty.
-  // We could create corresponding empty output sections, but that would
-  // clutter the output.
-  // We instead remove trivially empty sections. The bfd linker seems even
-  // more aggressive at removing them.
-  llvm::erase_if(SectionCommands, [&](BaseCommand *Base) {
-    if (auto *Sec = dyn_cast<OutputSection>(Base))
-      return !Sec->Live;
+static bool isAllSectionDescription(const OutputSection &Cmd) {
+  // We do not remove empty sections that are explicitly
+  // assigned to any segment.
+  if (!Cmd.Phdrs.empty())
     return false;
-  });
-}
 
-static bool isAllSectionDescription(const OutputSection &Cmd) {
   // We do not want to remove sections that have custom address or align
   // expressions set even if them are empty. We keep them because we
   // want to be sure that any expressions can be evaluated and report
@@ -803,7 +794,7 @@ void LinkerScript::adjustSectionsBeforeS
   // the previous sections. Only a few flags are needed to keep the impact low.
   uint64_t Flags = SHF_ALLOC;
 
-  for (BaseCommand *Cmd : SectionCommands) {
+  for (BaseCommand *&Cmd : SectionCommands) {
     auto *Sec = dyn_cast<OutputSection>(Cmd);
     if (!Sec)
       continue;
@@ -812,20 +803,25 @@ void LinkerScript::adjustSectionsBeforeS
       continue;
     }
 
-    if (isAllSectionDescription(*Sec))
-      continue;
-
-    Sec->Live = true;
-    Sec->Flags = Flags;
+    if (!isAllSectionDescription(*Sec))
+      Sec->Flags = Flags;
+    else
+      Cmd = nullptr;
   }
+
+  // It is common practice to use very generic linker scripts. So for any
+  // given run some of the output sections in the script will be empty.
+  // We could create corresponding empty output sections, but that would
+  // clutter the output.
+  // We instead remove trivially empty sections. The bfd linker seems even
+  // more aggressive at removing them.
+  llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; });
 }
 
 void LinkerScript::adjustSectionsAfterSorting() {
   // Try and find an appropriate memory region to assign offsets in.
   for (BaseCommand *Base : SectionCommands) {
     if (auto *Sec = dyn_cast<OutputSection>(Base)) {
-      if (!Sec->Live)
-        continue;
       if (!Sec->LMARegionName.empty()) {
         if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName))
           Sec->LMARegion = M;

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=325887&r1=325886&r2=325887&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Feb 23 02:53:04 2018
@@ -254,7 +254,6 @@ public:
   ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
 
   void addOrphanSections();
-  void removeEmptyCommands();
   void adjustSectionsBeforeSorting();
   void adjustSectionsAfterSorting();
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=325887&r1=325886&r2=325887&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Feb 23 02:53:04 2018
@@ -937,8 +937,7 @@ static int getRankProximityAux(OutputSec
 
 static int getRankProximity(OutputSection *A, BaseCommand *B) {
   if (auto *Sec = dyn_cast<OutputSection>(B))
-    if (Sec->Live)
-      return getRankProximityAux(A, Sec);
+    return getRankProximityAux(A, Sec);
   return -1;
 }
 
@@ -984,20 +983,16 @@ findOrphanPos(std::vector<BaseCommand *>
   int Proximity = getRankProximity(Sec, *I);
   for (; I != E; ++I) {
     auto *CurSec = dyn_cast<OutputSection>(*I);
-    if (!CurSec || !CurSec->Live)
+    if (!CurSec)
       continue;
     if (getRankProximity(Sec, CurSec) != Proximity ||
         Sec->SortRank < CurSec->SortRank)
       break;
   }
 
-  auto IsLiveSection = [](BaseCommand *Cmd) {
-    auto *OS = dyn_cast<OutputSection>(Cmd);
-    return OS && OS->Live;
-  };
-
+  auto IsOutputSec = [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); };
   auto J = std::find_if(llvm::make_reverse_iterator(I),
-                        llvm::make_reverse_iterator(B), IsLiveSection);
+                        llvm::make_reverse_iterator(B), IsOutputSec);
   I = J.base();
 
   // As a special case, if the orphan section is the last section, put
@@ -1005,7 +1000,7 @@ findOrphanPos(std::vector<BaseCommand *>
   // This matches bfd's behavior and is convenient when the linker script fully
   // specifies the start of the file, but doesn't care about the end (the non
   // alloc sections for example).
-  auto NextSec = std::find_if(I, E, IsLiveSection);
+  auto NextSec = std::find_if(I, E, IsOutputSec);
   if (NextSec == E)
     return E;
 
@@ -1077,8 +1072,6 @@ static DenseMap<const InputSectionBase *
 
 static void sortSection(OutputSection *Sec,
                         const DenseMap<const InputSectionBase *, int> &Order) {
-  if (!Sec->Live)
-    return;
   StringRef Name = Sec->Name;
 
   // Sort input sections by section name suffixes for
@@ -1186,7 +1179,7 @@ template <class ELFT> void Writer<ELFT>:
   auto E = Script->SectionCommands.end();
   auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
     if (auto *Sec = dyn_cast<OutputSection>(Base))
-      return Sec->Live && Sec->SectionIndex == INT_MAX;
+      return Sec->SectionIndex == INT_MAX;
     return false;
   });
 
@@ -1498,7 +1491,6 @@ template <class ELFT> void Writer<ELFT>:
   removeUnusedSyntheticSections();
 
   sortSections();
-  Script->removeEmptyCommands();
 
   // Now that we have the final list, create a list of all the
   // OutputSections for convenience.

Modified: lld/trunk/test/ELF/linkerscript/implicit-program-header.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/implicit-program-header.s?rev=325887&r1=325886&r2=325887&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/implicit-program-header.s (original)
+++ lld/trunk/test/ELF/linkerscript/implicit-program-header.s Fri Feb 23 02:53:04 2018
@@ -15,7 +15,7 @@
 
 # CHECK:      Segment Sections...
 # CHECK-NEXT:   00     .text .dynsym .hash .dynstr .dynamic
-# CHECK-NEXT:   01     .foo
+# CHECK-NEXT:   01     .bar .foo
 
 .quad 0
 .section .foo,"ax"

Modified: lld/trunk/test/ELF/linkerscript/orphan-phdrs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/orphan-phdrs.s?rev=325887&r1=325886&r2=325887&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/orphan-phdrs.s (original)
+++ lld/trunk/test/ELF/linkerscript/orphan-phdrs.s Fri Feb 23 02:53:04 2018
@@ -18,6 +18,7 @@
 # CHECK: Section Headers
 # CHECK: .text
 # CHECK-NEXT: .orphan
+# CHECK-NEXT: .empty
 # CHECK-NEXT: .rw
 
 # CHECK: Segment Sections




More information about the llvm-commits mailing list