[PATCH] D66719: [ELF] Do not ICF two sections with different output sections when there is a linker script

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 25 20:07:37 PDT 2019


MaskRay updated this revision to Diff 217070.
MaskRay added a comment.

.


Repository:
  rLLD LLVM Linker

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66719/new/

https://reviews.llvm.org/D66719

Files:
  ELF/ICF.cpp
  ELF/LinkerScript.cpp


Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -378,7 +378,7 @@
     size_t sizeBefore = ret.size();
 
     for (InputSectionBase *sec : inputSections) {
-      if (!sec->isLive() || sec->assigned)
+      if (sec->assigned || (!sec->isLive() && sec->repl == sec))
         continue;
 
       // For -emit-relocs we have to ignore entries like
@@ -421,8 +421,11 @@
     if (s == mainPart->hashTab)
       mainPart->hashTab = nullptr;
 
-    s->assigned = false;
+    // Entirely discarded. s->repl != s indicates a section that can be unfolded
+    // later.
     s->markDead();
+    s->repl = s;
+
     discard(s->dependentSections);
   }
 }
@@ -521,6 +524,28 @@
         sec->flags &= ~(uint64_t)SHF_ALLOC;
     }
   }
+
+  for (BaseCommand *base : script->sectionCommands)
+    if (auto *sec = dyn_cast<OutputSection>(base))
+      for (BaseCommand *sub_base : sec->sectionCommands)
+        if (auto *isd = dyn_cast<InputSectionDescription>(sub_base)) {
+          // Do not ICF fold input sections between output sections. If the
+          // output sections of sec and the InputSection it gets folded into are
+          // different, unfold it. sec->repl may have increased alignment or be
+          // have moved to the main partition, but that does not matter.
+          for (InputSection *s : isd->sections)
+            if (s->repl != s &&
+                cast<InputSection>(s->repl)->getParent() != s->getParent()) {
+              s->repl = s;
+              s->markLive();
+              for (InputSection *dependent : s->dependentSections)
+                dependent->markLive();
+            }
+
+          llvm::erase_if(isd->sections,
+                         [](InputSection *isec) { return !isec->isLive(); });
+        }
+
   ctx = nullptr;
 }
 
Index: ELF/ICF.cpp
===================================================================
--- ELF/ICF.cpp
+++ ELF/ICF.cpp
@@ -303,10 +303,10 @@
       a->getSize() != b->getSize() || a->data() != b->data())
     return false;
 
-  // If two sections have different output sections, we cannot merge them.
-  // FIXME: This doesn't do the right thing in the case where there is a linker
-  // script. We probably need to move output section assignment before ICF to
-  // get the correct behaviour here.
+  // If two sections have different output sections, we cannot merge them. When
+  // there is a linker script, getOutputSectionName may be inaccurate, sections
+  // going into different output sections may get folded but they will be
+  // unfolded in LinkerScript::processSectionCommands.
   if (getOutputSectionName(a) != getOutputSectionName(b))
     return false;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66719.217070.patch
Type: text/x-patch
Size: 2745 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190826/04e5ae5b/attachment.bin>


More information about the llvm-commits mailing list