[lld] r313646 - Tweak orphan section placement.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 19 10:29:58 PDT 2017


Author: rafael
Date: Tue Sep 19 10:29:58 2017
New Revision: 313646

URL: http://llvm.org/viewvc/llvm-project?rev=313646&view=rev
Log:
Tweak orphan section placement.

Given a linker script that ends in

.some_sec { ...} ;
__stack_start = .;
. = . + 0x2000;
__stack_end = .;

lld would put orphan sections like .comment before __stack_end,
corrupting the intended meaning.

The reason we don't normally move orphans past assignments to . is to
avoid breaking

rx_sec : { *(rx_sec) }
. = ALIGN(0x1000);
/* The RW PT_LOAD starts here*/

but in this case, there is nothing after and it seems safer to put the
orphan section last. This seems to match bfd's behavior and is
convenient for writing linker scripts that care about the layout of
SHF_ALLOC sections, but not of any non SHF_ALLOC sections.

Added:
    lld/trunk/test/ELF/linkerscript/orphan-end.s
Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=313646&r1=313645&r2=313646&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Sep 19 10:29:58 2017
@@ -1044,6 +1044,17 @@ findOrphanPos(std::vector<BaseCommand *>
       llvm::make_reverse_iterator(I), llvm::make_reverse_iterator(B),
       [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); });
   I = J.base();
+
+  // As a special case, if the orphan section is the last section, put
+  // it at the very end, past any other commands.
+  // 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, [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); });
+  if (NextSec == E)
+    return E;
+
   while (I != E && shouldSkip(*I))
     ++I;
   return I;

Added: lld/trunk/test/ELF/linkerscript/orphan-end.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/orphan-end.s?rev=313646&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/orphan-end.s (added)
+++ lld/trunk/test/ELF/linkerscript/orphan-end.s Tue Sep 19 10:29:58 2017
@@ -0,0 +1,57 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+# Test that .orphan_rx is placed after __stack_end. This matches bfd's
+# behavior when the orphan section is the last one.
+
+# RUN: echo "SECTIONS {             \
+# RUN:        __start_text = .;     \
+# RUN:        .text : { *(.text*) } \
+# RUN:        __end_text = .;       \
+# RUN:        __stack_start = .;    \
+# RUN:        . = . + 0x1000;       \
+# RUN:        __stack_end = .;      \
+# RUN:      }" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readelf -S --symbols %t | FileCheck %s
+
+# CHECK-DAG: .text             PROGBITS        0000000000000000
+# CHECK-DAG: .orphan_rx        PROGBITS        0000000000001004
+
+# CHECK-DAG: 0000000000000000 {{.*}} __start_text
+# CHECK-DAG: 0000000000000004 {{.*}} __end_text
+# CHECK-DAG: 0000000000000004 {{.*}} __stack_start
+# CHECK-DAG: 0000000000001004 {{.*}} __stack_end
+
+# Test that .orphan_rx is now placed before __stack_end. This matches bfd's
+# behavior when the orphan section is not the last one.
+
+# RUN: echo "SECTIONS {             \
+# RUN:        __start_text = .;     \
+# RUN:        .text : { *(.text*) } \
+# RUN:        __end_text = .;       \
+# RUN:        __stack_start = .;    \
+# RUN:        . = . + 0x1000;       \
+# RUN:        __stack_end = .;      \
+# RUN:        .orphan_rw : { *(.orphan_rw*) } \
+# RUN:      }" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readelf -S --symbols %t | FileCheck --check-prefix=MIDDLE %s
+
+# MIDDLE-DAG: .text             PROGBITS        0000000000000000
+# MIDDLE-DAG: .orphan_rx        PROGBITS        0000000000000004
+
+# MIDDLE-DAG: 0000000000000000 {{.*}} __start_text
+# MIDDLE-DAG: 0000000000000004 {{.*}} __end_text
+# MIDDLE-DAG: 0000000000000004 {{.*}} __stack_start
+# MIDDLE-DAG: 0000000000001008 {{.*}} __stack_end
+
+        .global _start
+_start:
+        .zero 4
+
+        .section .orphan_rx,"ax"
+        .zero 4
+
+        .section .orphan_rw,"aw"
+        .zero 4




More information about the llvm-commits mailing list