[PATCH] D111137: [ELF] Propagate phdrs to orphan section with a smaller rank

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 11 08:31:06 PDT 2021


ikudrin updated this revision to Diff 378667.
ikudrin marked 2 inline comments as done.
ikudrin retitled this revision from "[ELF] Fix assigning segments to orphan sections" to "[ELF] Propagate phdrs to orphan section with a smaller rank".
ikudrin added a comment.

- Updated the title
- Updated the comment
- Removed `&& foundSec->hasInputSections`

In D111137#3053918 <https://reviews.llvm.org/D111137#3053918>, @MaskRay wrote:

>> Fix assigning segments to orphan sections
>
> I'd not use "Fix". It makes a case more user-friendly but does not necessarily mean we have a bug.
> I may use something like: Propagate `phdrs` to orphan section with a smaller rank.

Thanks for the suggestion!

> One practical problem is that the rule of thumb "the first output section of each segment should be specified" is not communicated among users.

A user may not be aware of all the nuances of the linker. For example, they might switch from a different linker that had different rules to place orphan sections and just continue using the same linker script that already worked for them.

> - the new logic is inconsistent when the `PHDRS` command is not used.

If no `PHDRS` is used, the new segment will start at the orphan section which is placed before the found section. From this perspective, the new logic works similarly.

> - it duplicates the `maybePropagatePhdrs` phdrs propagation logic in a different place

Right, and it also modifies its data, which is usually not expected in a `find` function.

Alternatively, we can place orphan sections after the closest-rank section, even if their sort rank is smaller. This may relieve the concerns, in the cost of slightly changing the resulting layout.


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

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. This may change the
+  // flags of that segment, for example, adding PF_W to a read-only segment.
+  auto foundSec = dyn_cast<OutputSection>(*i);
+  if (foundSec && sec->sortRank < foundSec->sortRank &&
+      script->hasPhdrsCommands())
+    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.378667.patch
Type: text/x-patch
Size: 1773 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211011/d25e74e5/attachment.bin>


More information about the llvm-commits mailing list