diff options
-rw-r--r-- | lld/ELF/Writer.cpp | 15 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/at.s | 19 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/non-alloc.s | 6 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/repsection-symbol.s | 6 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/rosegment.s | 24 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/sizeofheaders.s | 4 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/symbol-conflict.s | 2 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/symbols-synthetic.s | 14 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/va.s | 6 |
9 files changed, 60 insertions, 36 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c66126ddea9..629d0e3e6be 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -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; diff --git a/lld/test/ELF/linkerscript/at.s b/lld/test/ELF/linkerscript/at.s index c26461c9d27..a6b6198710e 100644 --- a/lld/test/ELF/linkerscript/at.s +++ b/lld/test/ELF/linkerscript/at.s @@ -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: } @@ -76,20 +79,8 @@ # 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 diff --git a/lld/test/ELF/linkerscript/non-alloc.s b/lld/test/ELF/linkerscript/non-alloc.s index 0ad1a7470aa..2ab07a61e20 100644 --- a/lld/test/ELF/linkerscript/non-alloc.s +++ b/lld/test/ELF/linkerscript/non-alloc.s @@ -11,16 +11,14 @@ # 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 diff --git a/lld/test/ELF/linkerscript/repsection-symbol.s b/lld/test/ELF/linkerscript/repsection-symbol.s index 17512eb7247..f0f0d827129 100644 --- a/lld/test/ELF/linkerscript/repsection-symbol.s +++ b/lld/test/ELF/linkerscript/repsection-symbol.s @@ -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 index 00000000000..3201b8bda9f --- /dev/null +++ b/lld/test/ELF/linkerscript/rosegment.s @@ -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 diff --git a/lld/test/ELF/linkerscript/sizeofheaders.s b/lld/test/ELF/linkerscript/sizeofheaders.s index f98cd8a2763..3cc70747280 100644 --- a/lld/test/ELF/linkerscript/sizeofheaders.s +++ b/lld/test/ELF/linkerscript/sizeofheaders.s @@ -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: diff --git a/lld/test/ELF/linkerscript/symbol-conflict.s b/lld/test/ELF/linkerscript/symbol-conflict.s index 30186ed5cb8..42f3eee78d3 100644 --- a/lld/test/ELF/linkerscript/symbol-conflict.s +++ b/lld/test/ELF/linkerscript/symbol-conflict.s @@ -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: diff --git a/lld/test/ELF/linkerscript/symbols-synthetic.s b/lld/test/ELF/linkerscript/symbols-synthetic.s index fdb33309bcc..7bc7e67f130 100644 --- a/lld/test/ELF/linkerscript/symbols-synthetic.s +++ b/lld/test/ELF/linkerscript/symbols-synthetic.s @@ -40,18 +40,18 @@ # 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 diff --git a/lld/test/ELF/linkerscript/va.s b/lld/test/ELF/linkerscript/va.s index 25d0bd2268c..2e04f15a4b1 100644 --- a/lld/test/ELF/linkerscript/va.s +++ b/lld/test/ELF/linkerscript/va.s @@ -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: |