[PATCH] D50688: [LLD] Sort alloc/non-alloc output sections in linkerscripts

Konstantin Schwarz via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 14 01:14:45 PDT 2018


kschwarz created this revision.
kschwarz added reviewers: grimar, ruiu.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.

The program header creation logic depends on a strict separation of alloc and non-alloc output sections.
Declaring a "non-alloc" output section in linker scripts has the effect that no PT_LOAD header will be created for alloc sections coming afterwards. This patch sorts all alloc sections before non-alloc sections.

This fixes https://bugs.llvm.org/show_bug.cgi?id=37607


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D50688

Files:
  ELF/Writer.cpp
  test/ELF/linkerscript/Inputs/nonalloc.s
  test/ELF/linkerscript/nonalloc.test
  test/ELF/linkerscript/sections.s


Index: test/ELF/linkerscript/sections.s
===================================================================
--- test/ELF/linkerscript/sections.s
+++ test/ELF/linkerscript/sections.s
@@ -42,12 +42,12 @@
 #           Idx Name          Size
 # SEC-ORDER: 1 .bss          00000002 {{[0-9a-f]*}} BSS
 # SEC-ORDER: 2 other         00000003 {{[0-9a-f]*}} DATA
-# SEC-ORDER: 3 .shstrtab     0000003b {{[0-9a-f]*}}
-# SEC-ORDER: 4 .symtab       00000030 {{[0-9a-f]*}}
-# SEC-ORDER: 5 .strtab       00000008 {{[0-9a-f]*}}
-# SEC-ORDER: 6 .comment      00000008 {{[0-9a-f]*}}
-# SEC-ORDER: 7 .data         00000020 {{[0-9a-f]*}} DATA
-# SEC-ORDER: 8 .text         0000000e {{[0-9a-f]*}} TEXT
+# SEC-ORDER: 3 .data         00000020 {{[0-9a-f]*}} DATA
+# SEC-ORDER: 4 .text         0000000e {{[0-9a-f]*}} TEXT
+# SEC-ORDER: 5 .shstrtab     0000003b {{[0-9a-f]*}}
+# SEC-ORDER: 6 .symtab       00000030 {{[0-9a-f]*}}
+# SEC-ORDER: 7 .strtab       00000008 {{[0-9a-f]*}}
+# SEC-ORDER: 8 .comment      00000008 {{[0-9a-f]*}}
 
 # .text and .data have swapped names but proper sizes and types.
 # RUN: echo "SECTIONS { \
Index: test/ELF/linkerscript/nonalloc.test
===================================================================
--- /dev/null
+++ test/ELF/linkerscript/nonalloc.test
@@ -0,0 +1,29 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/nonalloc.s -o %t.o
+# RUN: ld.lld -o %t --script %s %t.o
+# RUN: llvm-objdump -all-headers %t | FileCheck %s
+
+SECTIONS {
+ .comment : { *(.comment) }
+ .data  : { *(.data)  }
+ .other : { *(.other) }
+ .text  : { *(.text*) }
+}
+
+# .comment and .other are both non-alloc sections and therefore should come after alloc
+# sections. Make sure their relative order is preserved
+
+#           Idx Name          Size
+# CHECK: 1 .data         00000020 {{[0-9a-f]*}} DATA
+# CHECK: 2 .text         0000000e {{[0-9a-f]*}} TEXT
+# CHECK: 3 .comment      00000008 {{[0-9a-f]*}}
+# CHECK: 4 .other        00000003 {{[0-9a-f]*}}
+
+# The creation of program headers depends on the strict ordering of alloc/non-alloc sections
+# Make sure both .data and .text are covered by a PT_LOAD header
+
+# Program Header:
+# CHECK: LOAD off    0x0000000000001000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
+# CHECK:      filesz 0x0000000000000020 memsz 0x0000000000000020 flags rw-
+# CHECK  LOAD off    0x0000000000001020 vaddr 0x0000000000000020 paddr 0x0000000000000020 align 2**12
+# CHECK:      filesz 0x000000000000000e memsz 0x000000000000000e flags r-x
\ No newline at end of file
Index: test/ELF/linkerscript/Inputs/nonalloc.s
===================================================================
--- /dev/null
+++ test/ELF/linkerscript/Inputs/nonalloc.s
@@ -0,0 +1,10 @@
+.globl _start
+_start:
+    mov $60, %rax
+    mov $42, %rdi
+
+.section .data,"aw"
+.quad 10, 10, 20, 20
+.section .other,""
+.short 10
+.byte 20
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -1306,6 +1306,18 @@
     return false;
   });
 
+  // In a linker script, we might have alloc and non-alloc output sections
+  // mixed, but our logic for creation of program headers requires the
+  // non-alloc sections to come after the alloc sections.
+  auto isAllocSection = [](const BaseCommand *ACmd, const BaseCommand *BCmd) {
+    if (auto *AS = dyn_cast<OutputSection>(ACmd))
+      if (auto *BS = dyn_cast<OutputSection>(BCmd))
+         return (AS->Flags & SHF_ALLOC) && !(BS->Flags & SHF_ALLOC);
+    return false;
+  };
+  std::stable_sort(I, NonScriptI, isAllocSection);
+
+
   // Sort the orphan sections.
   std::stable_sort(NonScriptI, E, compareSections);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50688.160524.patch
Type: text/x-patch
Size: 3709 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180814/c1d487d8/attachment.bin>


More information about the llvm-commits mailing list