Disable --rosegment when we have linker scripts.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 20 Sep 2016 15:22:27 +0000 (15:22 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 20 Sep 2016 15:22:27 +0000 (15:22 +0000)
Linker scripts are responsible for aliging '.'. Since they are
designed for bfd which has no --rosegment, they don't align the RO to
RX transition.

llvm-svn: 281978

lld/ELF/Writer.cpp
lld/test/ELF/linkerscript/at.s
lld/test/ELF/linkerscript/non-alloc.s
lld/test/ELF/linkerscript/repsection-symbol.s
lld/test/ELF/linkerscript/rosegment.s [new file with mode: 0644]
lld/test/ELF/linkerscript/sizeofheaders.s
lld/test/ELF/linkerscript/symbol-conflict.s
lld/test/ELF/linkerscript/symbols-synthetic.s
lld/test/ELF/linkerscript/va.s

index c66126d..629d0e3 100644 (file)
@@ -944,6 +944,17 @@ template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {
   return true;
 }
 
+// Linker scripts are responsible for aligning addresses. Unfortunately, most
+// linker scripts are designed for creating two PT_LOADs only, one RX and one
+// RW. This means that there is no alignment in the RO to RX transition and we
+// cannot create a PT_LOAD there.
+template <class ELFT>
+static typename ELFT::uint computeFlags(typename ELFT::uint F) {
+  if (ScriptConfig->HasSections && !(F & PF_W))
+    return F | PF_X;
+  return F;
+}
+
 // Decide which program headers to create and which sections to include in each
 // one.
 template <class ELFT>
@@ -966,7 +977,7 @@ std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
   }
 
   // Add the first PT_LOAD segment for regular output sections.
-  uintX_t Flags = PF_R;
+  uintX_t Flags = computeFlags<ELFT>(PF_R);
   Phdr *Load = AddHdr(PT_LOAD, Flags);
   Load->add(Out<ELFT>::ElfHeader);
   Load->add(Out<ELFT>::ProgramHeaders);
@@ -992,7 +1003,7 @@ std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
     // Therefore, we need to create a new phdr when the next section has
     // different flags or is loaded at a discontiguous address using AT linker
     // script command.
-    uintX_t NewFlags = Sec->getPhdrFlags();
+    uintX_t NewFlags = computeFlags<ELFT>(Sec->getPhdrFlags());
     if (Script<ELFT>::X->getLma(Sec->getName()) || Flags != NewFlags) {
       Load = AddHdr(PT_LOAD, NewFlags);
       Flags = NewFlags;
index c26461c..a6b6198 100644 (file)
@@ -44,6 +44,7 @@
 # CHECK-NEXT:     MemSize:
 # CHECK-NEXT:     Flags [
 # CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_X
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Alignment:
 # CHECK-NEXT:   }
@@ -56,6 +57,7 @@
 # CHECK-NEXT:     MemSize: 16
 # CHECK-NEXT:     Flags [
 # CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_X
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Alignment:
 # CHECK-NEXT:   }
@@ -68,6 +70,7 @@
 # CHECK-NEXT:     MemSize: 8
 # CHECK-NEXT:     Flags [
 # CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_X
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Alignment: 4096
 # CHECK-NEXT:   }
 # CHECK-NEXT:     Offset: 0x1018
 # CHECK-NEXT:     VirtualAddress: 0x1018
 # CHECK-NEXT:     PhysicalAddress: 0x4000
-# CHECK-NEXT:     FileSize: 8
-# CHECK-NEXT:     MemSize: 8
-# CHECK-NEXT:     Flags [
-# CHECK-NEXT:       PF_R
-# CHECK-NEXT:     ]
-# CHECK-NEXT:     Alignment: 4096
-# CHECK-NEXT:   }
-# CHECK-NEXT:   ProgramHeader {
-# CHECK-NEXT:     Type: PT_LOAD
-# CHECK-NEXT:     Offset: 0x1020
-# CHECK-NEXT:     VirtualAddress: 0x1020
-# CHECK-NEXT:     PhysicalAddress: 0x1020
-# CHECK-NEXT:     FileSize: 1
-# CHECK-NEXT:     MemSize: 1
+# CHECK-NEXT:     FileSize: 9
+# CHECK-NEXT:     MemSize: 9
 # CHECK-NEXT:     Flags [
 # CHECK-NEXT:       PF_R
 # CHECK-NEXT:       PF_X
index 0ad1a74..2ab07a6 100644 (file)
 # CHECK: Program Headers:
 # CHECK-NEXT:  Type
 # CHECK-NEXT:  PHDR
-# CHECK-NEXT:  LOAD {{.*}} R
 # CHECK-NEXT:  LOAD {{.*}} R E
 # CHECK-NEXT:  LOAD {{.*}} RW
 
 # CHECK:      Section to Segment mapping:
 # CHECK-NEXT:  Segment Sections...
 # CHECK-NEXT:   00
-# CHECK-NEXT:   01     .dynsym .hash .dynstr
-# CHECK-NEXT:   02     .text
-# CHECK-NEXT:   03     .dynamic
+# CHECK-NEXT:   01     .dynsym .hash .dynstr .text
+# CHECK-NEXT:   02     .dynamic
 
 nop
 .section foo
index 17512eb..f0f0d82 100644 (file)
@@ -6,13 +6,13 @@
 # RUN: llvm-readobj -t %t1 | FileCheck %s
 
 # CHECK:      Name: foo1
-# CHECK-NEXT: Value: 0x238
+# CHECK-NEXT: Value: 0x200
 
 # CHECK:      Name: foo2
-# CHECK-NEXT: Value: 0x240
+# CHECK-NEXT: Value: 0x208
 
 # CHECK:      Name: foo3
-# CHECK-NEXT: Value: 0x244
+# CHECK-NEXT: Value: 0x20C
 
 .section .foo.1,"a"
  .long 1
diff --git a/lld/test/ELF/linkerscript/rosegment.s b/lld/test/ELF/linkerscript/rosegment.s
new file mode 100644 (file)
index 0000000..3201b8b
--- /dev/null
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# Test that with linker scripts we don't create a RO PT_LOAD.
+
+# RUN: echo "SECTIONS {}" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t -shared
+# RUN: llvm-readobj -l %t1 | FileCheck %s
+
+# CHECK-NOT:  Type: PT_LOAD
+
+# CHECK:      Type: PT_LOAD
+# CHECK:      Flags [
+# CHECK-NEXT:   PF_R
+# CHECK-NEXT:   PF_X
+# CHECK-NEXT: ]
+
+# CHECK:      Type: PT_LOAD
+# CHECK:      Flags [
+# CHECK-NEXT:   PF_R
+# CHECK-NEXT:   PF_W
+# CHECK-NEXT: ]
+
+# CHECK-NOT:  Type: PT_LOAD
index f98cd8a..3cc7074 100644 (file)
@@ -10,8 +10,8 @@
 
 #CHECK:      SYMBOL TABLE:
 #CHECK-NEXT:  0000000000000000 *UND* 00000000
-#CHECK-NEXT:  0000000000000120 .text 00000000 _start
-#CHECK-NEXT:  0000000000000120 *ABS* 00000000 _size
+#CHECK-NEXT:  00000000000000e8 .text 00000000 _start
+#CHECK-NEXT:  00000000000000e8 *ABS* 00000000 _size
 
 .global _start
 _start:
index 30186ed..42f3eee 100644 (file)
@@ -4,7 +4,7 @@
 # RUN: echo "SECTIONS {.text : {*(.text.*)} end = .;}" > %t.script
 # RUN: ld.lld -o %t1 --script %t.script %t
 # RUN: llvm-objdump -t %t1 | FileCheck %s
-# CHECK: 0000000000000121         *ABS*    00000000 end
+# CHECK: 00000000000000e9         *ABS*    00000000 end
 
 .global _start
 _start:
index fdb3330..7bc7e67 100644 (file)
 # RUN:         }" > %t.script
 # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
 
-# SIMPLE:      0000000000000160         .foo    00000000 .hidden _end_sec
-# SIMPLE-NEXT: 0000000000000158         .foo    00000000 _begin_sec
-# SIMPLE-NEXT: 0000000000000160         *ABS*   00000000 _end_sec_abs
+# SIMPLE:      0000000000000128         .foo    00000000 .hidden _end_sec
+# SIMPLE-NEXT: 0000000000000120         .foo    00000000 _begin_sec
+# SIMPLE-NEXT: 0000000000000128         *ABS*   00000000 _end_sec_abs
 # SIMPLE-NEXT: 0000000000001048         .text   00000000 _start
-# SIMPLE-NEXT: 0000000000000158         .foo    00000000 begin_foo
-# SIMPLE-NEXT: 0000000000000160         .foo    00000000 end_foo
+# SIMPLE-NEXT: 0000000000000120         .foo    00000000 begin_foo
+# SIMPLE-NEXT: 0000000000000128         .foo    00000000 end_foo
 # SIMPLE-NEXT: 0000000000000008         .foo    00000000 size_foo_1
 # SIMPLE-NEXT: 0000000000000008         *ABS*   00000000 size_foo_1_abs
 # SIMPLE-NEXT: 0000000000001000         .foo    00000000 begin_bar
 # SIMPLE-NEXT: 0000000000001004         .foo    00000000 end_bar
-# SIMPLE-NEXT: 0000000000000eac         .foo    00000000 size_foo_2
-# SIMPLE-NEXT: 0000000000000eac         *ABS*   00000000 size_foo_3
+# SIMPLE-NEXT: 0000000000000ee4         .foo    00000000 size_foo_2
+# SIMPLE-NEXT: 0000000000000ee4         *ABS*   00000000 size_foo_3
 # SIMPLE-NEXT: 0000000000001004         .eh_frame_hdr     00000000 __eh_frame_hdr_start
 # SIMPLE-NEXT: 0000000000001010         *ABS*             00000000 __eh_frame_hdr_start2
 # SIMPLE-NEXT: 0000000000001018         .eh_frame_hdr     00000000 __eh_frame_hdr_end
index 25d0bd2..2e04f15 100644 (file)
@@ -7,9 +7,9 @@
 # CHECK:      Sections:
 # CHECK-NEXT: Idx Name          Size      Address          Type
 # CHECK-NEXT:   0               00000000 0000000000000000
-# CHECK-NEXT:   1 .foo          00000004 0000000000000120 DATA
-# CHECK-NEXT:   2 .boo          00000004 0000000000000124 DATA
-# CHECK-NEXT:   3 .text         00000001 0000000000000128 TEXT DATA
+# CHECK-NEXT:   1 .foo          00000004 00000000000000e8 DATA
+# CHECK-NEXT:   2 .boo          00000004 00000000000000ec DATA
+# CHECK-NEXT:   3 .text         00000001 00000000000000f0 TEXT DATA
 
 .global _start
 _start: