[PATCH] D111137: [ELF] Fix assigning segments to orphan sections

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 5 05:28:33 PDT 2021


ikudrin created this revision.
ikudrin added reviewers: MaskRay, jhenderson, grimar.
ikudrin added a project: lld.
Herald added subscribers: arichardson, emaste.
ikudrin requested review of this revision.
Herald added a project: LLVM.

In a case when segments are explicitly defined in a linker script, and if an orphan section is placed before the section with the closest sort rank, it may be put in the previous segment, which can affect the flags of that segment. The patch fixes the issue by assigning segments from the found section to the orphan section.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111137

Files:
  lld/ELF/Writer.cpp
  lld/test/ELF/linkerscript/orphan-phdrs2.test


Index: lld/test/ELF/linkerscript/orphan-phdrs2.test
===================================================================
--- /dev/null
+++ lld/test/ELF/linkerscript/orphan-phdrs2.test
@@ -0,0 +1,33 @@
+# REQUIRES: x86
+
+# RUN: split-file %s %ts
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %ts/s -o %t.o
+# RUN: ld.lld -pie -o %t -T %ts/t %t.o
+# RUN: llvm-readelf -l %t | FileCheck %s
+
+## Check that an orphan section '.dynamic' is added to the same segment as
+## its closest-rank section '.data', even though it is placed before '.data'.
+## Adding 'dynamic' to the first segment would make the segment writable.
+# CHECK:     LOAD {{.*}} R E
+# CHECK:     LOAD {{.*}} RW
+
+# CHECK:     Segment Sections...
+# CHECK-NOT: 00{{.*}} .dynamic
+# CHECK:     01 .dynamic .data
+
+#--- s
+  .text
+  nop
+
+  .data
+  .quad 0
+
+#--- t
+PHDRS {
+  exec PT_LOAD;
+  rw   PT_LOAD;
+}
+SECTIONS {
+  .text : { *(.text) } : exec
+  .data : { *(.data) } : rw
+}
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -1257,6 +1257,15 @@
   if (i == e)
     return e;
 
+  // If the orphan section is going to be placed before the found section,
+  // inherit explicitly specified segments from that section. Otherwise,
+  // the orphan section may be placed in the previous segment, which may
+  // corrupt its flags.
+  auto foundSec = dyn_cast<OutputSection>(*i);
+  if (script->hasPhdrsCommands() && foundSec && foundSec->hasInputSections &&
+      sec->sortRank < foundSec->sortRank)
+    sec->phdrs = foundSec->phdrs;
+
   // Consider all existing sections with the same proximity.
   int proximity = getRankProximity(sec, *i);
   for (; i != e; ++i) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111137.377160.patch
Type: text/x-patch
Size: 1740 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211005/9f6ba919/attachment.bin>


More information about the llvm-commits mailing list