[PATCH] D60273: [ELF] Change findOrphanPos to only consider live sections

Andrew Ng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 4 08:51:23 PDT 2019


andrewng created this revision.
andrewng added reviewers: ruiu, grimar.
Herald added subscribers: MaskRay, arichardson, emaste.
Herald added a reviewer: espindola.

This patch changes the behaviour of findOrphanPos to only consider live
sections when placing orphan sections. This used to be how it behaved in
the past.


https://reviews.llvm.org/D60273

Files:
  ELF/Writer.cpp
  test/ELF/linkerscript/orphan-phdrs.s


Index: test/ELF/linkerscript/orphan-phdrs.s
===================================================================
--- test/ELF/linkerscript/orphan-phdrs.s
+++ test/ELF/linkerscript/orphan-phdrs.s
@@ -1,15 +1,3 @@
-# XFAIL: *
-
-# This test fails because empty sections that are explicitly assigned to a
-# segment are kept. The flags of such empty sections are derived from preceding
-# live sections. This unfortunately means that orphan sections can then end up
-# in the wrong segment, in this test .orphan ends up in the rw segment rather
-# than the intended exec segment.
-#
-# This test was previously working because empty sections happened to be
-# SHT_NOBITS, which changes the ranking such that it no longer affects the
-# orphan section.
-
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: echo "PHDRS { \
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -1086,16 +1086,19 @@
   int Proximity = getRankProximity(Sec, *I);
   for (; I != E; ++I) {
     auto *CurSec = dyn_cast<OutputSection>(*I);
-    if (!CurSec)
+    if (!CurSec || !CurSec->Live)
       continue;
     if (getRankProximity(Sec, CurSec) != Proximity ||
         Sec->SortRank < CurSec->SortRank)
       break;
   }
 
-  auto IsOutputSec = [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); };
+  auto IsLiveOutputSec = [](BaseCommand *Cmd) {
+    auto *OS = dyn_cast<OutputSection>(Cmd);
+    return OS && OS->Live;
+  };
   auto J = std::find_if(llvm::make_reverse_iterator(I),
-                        llvm::make_reverse_iterator(B), IsOutputSec);
+                        llvm::make_reverse_iterator(B), IsLiveOutputSec);
   I = J.base();
 
   // As a special case, if the orphan section is the last section, put
@@ -1103,7 +1106,7 @@
   // 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, IsOutputSec);
+  auto NextSec = std::find_if(I, E, IsLiveOutputSec);
   if (NextSec == E)
     return E;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60273.193734.patch
Type: text/x-patch
Size: 2186 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190404/14b7f3d3/attachment.bin>


More information about the llvm-commits mailing list