diff options
Diffstat (limited to 'test/ELF/linkerscript')
56 files changed, 983 insertions, 403 deletions
diff --git a/test/ELF/linkerscript/Inputs/lazy-symbols.s b/test/ELF/linkerscript/Inputs/lazy-symbols.s new file mode 100644 index 000000000000..dd28fcbd5255 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/lazy-symbols.s @@ -0,0 +1,2 @@ +.globl foo +foo: diff --git a/test/ELF/linkerscript/absolute.s b/test/ELF/linkerscript/absolute.s index e4b156e2f012..54f1c7037d23 100644 --- a/test/ELF/linkerscript/absolute.s +++ b/test/ELF/linkerscript/absolute.s @@ -4,6 +4,11 @@ # RUN: ld.lld -o %t --script %t.script %t.o # RUN: llvm-readobj --symbols %t | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "PROVIDE(foo = 1 + ABSOLUTE(ADDR(.text)));" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj --symbols %t | FileCheck --check-prefix=CHECK-RHS %s + # CHECK: Name: foo # CHECK-NEXT: Value: # CHECK-NEXT: Size: @@ -13,6 +18,18 @@ # CHECK-NEXT: Section: Absolute # CHECK-NEXT: } +# CHECK-RHS: Name: foo +# CHECK-RHS-NEXT: Value: 0x201001 +# CHECK-RHS-NEXT: Size: +# CHECK-RHS-NEXT: Binding: +# CHECK-RHS-NEXT: Type: +# CHECK-RHS-NEXT: Other: +# CHECK-RHS-NEXT: Section: Absolute +# CHECK-RHS-NEXT: } + .text .globl _start _start: + nop + +.global foo diff --git a/test/ELF/linkerscript/addr-zero.s b/test/ELF/linkerscript/addr-zero.s new file mode 100644 index 000000000000..71251d3acfff --- /dev/null +++ b/test/ELF/linkerscript/addr-zero.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { foo = ADDR(.text) - ABSOLUTE(ADDR(.text)); };" > %t.script +# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: llvm-readobj --symbols %t.so | FileCheck %s + +# Test that the script creates a non absolute symbol with value +# 0 I.E., a symbol that refers to the load address. + +# CHECK: Symbol { +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } diff --git a/test/ELF/linkerscript/align.s b/test/ELF/linkerscript/align.s index 1e50fed3fa83..ffeb1acbd027 100644 --- a/test/ELF/linkerscript/align.s +++ b/test/ELF/linkerscript/align.s @@ -2,43 +2,25 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t ## Check that ALIGN command workable using location counter -# RUN: echo "SECTIONS { \ -# RUN: . = 0x10000; \ -# RUN: .aaa : \ -# RUN: { \ -# RUN: *(.aaa) \ -# RUN: } \ -# RUN: . = ALIGN(4096); \ -# RUN: .bbb : \ -# RUN: { \ -# RUN: *(.bbb) \ -# RUN: } \ +# RUN: echo "SECTIONS { \ +# RUN: . = 0x10000; \ +# RUN: .aaa : { *(.aaa) } \ +# RUN: . = ALIGN(4096); \ +# RUN: .bbb : { *(.bbb) } \ # RUN: . = ALIGN(4096 * 4); \ -# RUN: .ccc : \ -# RUN: { \ -# RUN: *(.ccc) \ -# RUN: } \ +# RUN: .ccc : { *(.ccc) } \ # RUN: }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -section-headers %t1 | FileCheck %s ## Check that the two argument version of ALIGN command works -# RUN: echo "SECTIONS { \ +# RUN: echo "SECTIONS { \ # RUN: . = ALIGN(0x1234, 0x10000); \ -# RUN: .aaa : \ -# RUN: { \ -# RUN: *(.aaa) \ -# RUN: } \ -# RUN: . = ALIGN(., 4096); \ -# RUN: .bbb : \ -# RUN: { \ -# RUN: *(.bbb) \ -# RUN: } \ -# RUN: . = ALIGN(., 4096 * 4); \ -# RUN: .ccc : \ -# RUN: { \ -# RUN: *(.ccc) \ -# RUN: } \ +# RUN: .aaa : { *(.aaa) } \ +# RUN: . = ALIGN(., 4096); \ +# RUN: .bbb : { *(.bbb) } \ +# RUN: . = ALIGN(., 4096 * 4); \ +# RUN: .ccc : { *(.ccc) } \ # RUN: }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -section-headers %t1 | FileCheck %s @@ -51,23 +33,38 @@ # CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA ## Check output sections ALIGN modificator -# RUN: echo "SECTIONS { \ -# RUN: . = 0x10000; \ -# RUN: .aaa : \ -# RUN: { \ -# RUN: *(.aaa) \ -# RUN: } \ -# RUN: .bbb : ALIGN(4096) \ -# RUN: { \ -# RUN: *(.bbb) \ -# RUN: } \ -# RUN: .ccc : ALIGN(4096 * 4) \ -# RUN: { \ -# RUN: *(.ccc) \ -# RUN: } \ +# RUN: echo "SECTIONS { \ +# RUN: . = 0x10000; \ +# RUN: .aaa : { *(.aaa) } \ +# RUN: .bbb : ALIGN(4096) { *(.bbb) } \ +# RUN: .ccc : ALIGN(4096 * 4) { *(.ccc) } \ # RUN: }" > %t2.script # RUN: ld.lld -o %t2 --script %t2.script %t -# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s + +## Check use of variables in align expressions: +# RUN: echo "VAR = 0x1000; \ +# RUN: __code_base__ = 0x10000; \ +# RUN: SECTIONS { \ +# RUN: . = __code_base__; \ +# RUN: .aaa : { *(.aaa) } \ +# RUN: .bbb : ALIGN(VAR) { *(.bbb) } \ +# RUN: . = ALIGN(., VAR * 4); \ +# RUN: .ccc : { *(.ccc) } \ +# RUN: __start_bbb = ADDR(.bbb); \ +# RUN: __end_bbb = ALIGN(__start_bbb + SIZEOF(.bbb), VAR); \ +# RUN: }" > %t3.script +# RUN: ld.lld -o %t3 --script %t3.script %t +# RUN: llvm-objdump -section-headers %t3 | FileCheck %s +# RUN: llvm-objdump -t %t3 | FileCheck -check-prefix SYMBOLS %s + +# SYMBOLS-LABEL: SYMBOL TABLE: +# SYMBOLS-NEXT: 0000000000000000 *UND* 00000000 +# SYMBOLS-NEXT: 0000000000014008 .text 00000000 _start +# SYMBOLS-NEXT: 0000000000010000 *ABS* 00000000 __code_base__ +# SYMBOLS-NEXT: 0000000000001000 *ABS* 00000000 VAR +# SYMBOLS-NEXT: 0000000000011000 .bbb 00000000 __start_bbb +# SYMBOLS-NEXT: 0000000000012000 *ABS* 00000000 __end_bbb .global _start _start: diff --git a/test/ELF/linkerscript/alternate-sections.s b/test/ELF/linkerscript/alternate-sections.s index 6d3004af9a80..fd74a8a967f3 100644 --- a/test/ELF/linkerscript/alternate-sections.s +++ b/test/ELF/linkerscript/alternate-sections.s @@ -4,25 +4,27 @@ # RUN: ld.lld -o %t --script %t.script %t.o -shared # RUN: llvm-readobj -s -section-data %t | FileCheck %s -# This test shows an oddity in lld. When a linker script alternates among -# different types of output section in the same command, the sections are -# reordered. -# In this test we go from regular, to merge and back to regular. The reason -# for the reordering is that we need two create two output sections and -# one cannot be in the middle of another. -# If this ever becomes a problem, some options would be: -# * Adding an extra layer in between input section and output sections (Chunk). -# With that this example would have 3 chunks, but only one output section. -# This would unfortunately complicate the non-script case too. -# * Just create three output sections. -# * If having three output sections causes problem, have linkerscript specific -# code to write the section table and section indexes. That way we could -# keep 3 sections internally but not expose that. - -# CHECK: Name: abc -# CHECK: 0000: 01000000 00000000 02000000 00000000 | -# CHECK: Name: abc -# CHECK: 0000: 61626331 323300 |abc123.| +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: abc +# CHECK-NEXT: Type: SHT_PROGBIT +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_MERGE +# CHECK-NEXT: SHF_STRINGS +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 01000000 00000000 61626331 32330002 |........abc123..| +# CHECK-NEXT: 0010: 00000000 000000 |.......| +# CHECK-NEXT: ) +# CHECK-NEXT: } .section foo, "a" .quad 1 diff --git a/test/ELF/linkerscript/assert.s b/test/ELF/linkerscript/assert.s index 06eeaeec3b99..73cc940669b9 100644 --- a/test/ELF/linkerscript/assert.s +++ b/test/ELF/linkerscript/assert.s @@ -5,10 +5,6 @@ # RUN: ld.lld -shared -o %t1 --script %t1.script %t1.o # RUN: llvm-readobj %t1 > /dev/null -# RUN: echo "SECTIONS { ASSERT(ASSERT(42, fail) == 42, fail) }" > %t2.script -# RUN: ld.lld -shared -o %t2 --script %t2.script %t1.o -# RUN: llvm-readobj %t2 > /dev/null - # RUN: echo "SECTIONS { ASSERT(0, fail) }" > %t3.script # RUN: not ld.lld -shared -o %t3 --script %t3.script %t1.o > %t.log 2>&1 # RUN: FileCheck %s -check-prefix=FAIL < %t.log diff --git a/test/ELF/linkerscript/at-addr.s b/test/ELF/linkerscript/at-addr.s new file mode 100644 index 000000000000..0eddf3d9e3fb --- /dev/null +++ b/test/ELF/linkerscript/at-addr.s @@ -0,0 +1,39 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { . = 0x1000; \ +# RUN: .aaa : AT(ADDR(.aaa) - 0x500) { *(.aaa) } \ +# RUN: .bbb : AT(ADDR(.bbb) - 0x500) { *(.bbb) } \ +# RUN: .ccc : AT(ADDR(.ccc) - 0x500) { *(.ccc) } \ +# RUN: }" > %t.script +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-readobj -program-headers %t2 | FileCheck %s + +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x0 +# CHECK-NEXT: PhysicalAddress: 0x0 +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0xB00 +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1008 +# CHECK-NEXT: VirtualAddress: 0x1008 +# CHECK-NEXT: PhysicalAddress: 0xB08 +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1010 +# CHECK-NEXT: VirtualAddress: 0x1010 +# CHECK-NEXT: PhysicalAddress: 0xB10 + +.global _start +_start: + nop + +.section .aaa, "a" +.quad 0 + +.section .bbb, "a" +.quad 0 + +.section .ccc, "a" +.quad 0 diff --git a/test/ELF/linkerscript/at.s b/test/ELF/linkerscript/at.s index a6b6198710ea..26441f1ffd9e 100644 --- a/test/ELF/linkerscript/at.s +++ b/test/ELF/linkerscript/at.s @@ -2,22 +2,11 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: echo "SECTIONS { \ # RUN: . = 0x1000; \ -# RUN: .aaa : AT(0x2000) \ -# RUN: { \ -# RUN: *(.aaa) \ -# RUN: } \ -# RUN: .bbb : \ -# RUN: { \ -# RUN: *(.bbb) \ -# RUN: } \ -# RUN: .ccc : AT(0x3000) \ -# RUN: { \ -# RUN: *(.ccc) \ -# RUN: } \ -# RUN: .ddd : AT(0x4000) \ -# RUN: { \ -# RUN: *(.ddd) \ -# RUN: } \ +# RUN: .aaa : AT(0x2000) { *(.aaa) } \ +# RUN: .bbb : { *(.bbb) } \ +# RUN: .ccc : AT(0x3000) { *(.ccc) } \ +# RUN: .ddd : AT(0x4000) { *(.ddd) } \ +# RUN: .eee 0x5000 : AT(0x5000) { *(.eee) } \ # RUN: }" > %t.script # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-readobj -program-headers %t2 | FileCheck %s @@ -79,6 +68,19 @@ # 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: PF_X +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: VirtualAddress: 0x5000 +# CHECK-NEXT: PhysicalAddress: 0x5000 # CHECK-NEXT: FileSize: 9 # CHECK-NEXT: MemSize: 9 # CHECK-NEXT: Flags [ @@ -117,3 +119,6 @@ _start: .section .ddd, "a" .quad 0 + +.section .eee, "a" +.quad 0 diff --git a/test/ELF/linkerscript/constructor.s b/test/ELF/linkerscript/constructor.s new file mode 100644 index 000000000000..acb86fd88e27 --- /dev/null +++ b/test/ELF/linkerscript/constructor.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { foo : { *(.foo) CONSTRUCTORS } }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t.o + +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size +# CHECK-NEXT: 0 00000000 +# CHECK-NEXT: 1 foo 00000001 + +.section foo, "a" +.byte 0 diff --git a/test/ELF/linkerscript/discard-print-gc.s b/test/ELF/linkerscript/discard-print-gc.s new file mode 100644 index 000000000000..2a230e53dc2b --- /dev/null +++ b/test/ELF/linkerscript/discard-print-gc.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -triple x86_64-pc-linux %s -o %t.o -filetype=obj +# RUN: ld.lld -o %t.so --gc-sections %t.o --print-gc-sections -shared 2>&1 | \ +# RUN: FileCheck -check-prefix=CHECK %s + +# RUN: echo "SECTIONS { /DISCARD/ : { *(.foo) } }" > %t.script +# RUN: ld.lld -o %t.so -T %t.script %t.o --print-gc-sections -shared 2>&1 | \ +# RUN: FileCheck -check-prefix=QUIET --allow-empty %s + +# RUN: echo "SECTIONS { .foo : { *(.foo) } }" > %t2.script +# RUN: ld.lld -o %t.so -T %t2.script --gc-sections %t.o --print-gc-sections -shared 2>&1 | \ +# RUN: FileCheck -check-prefix=CHECK %s + +.section .foo,"a" +.quad 0 + +# CHECK: removing unused section from '.foo' +# QUIET-NOT: removing unused section from '.foo' diff --git a/test/ELF/linkerscript/discard-section-metadata.s b/test/ELF/linkerscript/discard-section-metadata.s new file mode 100644 index 000000000000..961615d51c98 --- /dev/null +++ b/test/ELF/linkerscript/discard-section-metadata.s @@ -0,0 +1,32 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { /DISCARD/ : { *(.foo) } }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s + +# CHECK-NOT: .foo +# CHECK-NOT: .bar +# CHECK-NOT: .zed +# CHECK-NOT: .moo + +## Sections dependency tree for testcase is: +## (.foo) +## | | +## | --(.bar) +## | +## --(.zed) +## | +## --(.moo) +## + +.section .foo,"a" +.quad 0 + +.section .bar,"ao",@progbits,.foo +.quad 0 + +.section .zed,"ao",@progbits,.foo +.quad 0 + +.section .moo,"ao",@progbits,.zed +.quad 0 diff --git a/test/ELF/linkerscript/edata-etext.s b/test/ELF/linkerscript/edata-etext.s index fdf5ec1f5671..ab723ce1316e 100644 --- a/test/ELF/linkerscript/edata-etext.s +++ b/test/ELF/linkerscript/edata-etext.s @@ -2,9 +2,12 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS { }" > %t.script # RUN: not ld.lld %t.o -script %t.script -o %t 2>&1 | FileCheck %s -# CHECK: error: {{.*}}:(.text+0x0): undefined symbol '_edata' -# CHECK: error: {{.*}}:(.text+0x8): undefined symbol '_etext' -# CHECK: error: {{.*}}:(.text+0x10): undefined symbol '_end' +# CHECK: error: undefined symbol: _edata +# CHECK: >>> referenced by {{.*}}:(.text+0x0) +# CHECK: error: undefined symbol: _etext +# CHECK: >>> referenced by {{.*}}:(.text+0x8) +# CHECK: error: undefined symbol: _end +# CHECK: >>> referenced by {{.*}}:(.text+0x10) .global _start,_end,_etext,_edata .text diff --git a/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s new file mode 100644 index 000000000000..54c0cc74d394 --- /dev/null +++ b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s @@ -0,0 +1,27 @@ +## Check that error is correctly reported when .eh_frame reloc +## is out of range + +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "PHDRS { eh PT_LOAD; text PT_LOAD; } \ +# RUN: SECTIONS { . = 0x10000; \ +# RUN: .eh_frame_hdr : { *(.eh_frame_hdr*) } : eh \ +# RUN: .eh_frame : { *(.eh_frame) } : eh \ +# RUN: . = 0xF00000000; \ +# RUN: .text : { *(.text*) } : text \ +# RUN: }" > %t.script +# RUN: not ld.lld %t.o -T %t.script -o %t 2>&1 | FileCheck %s + +# CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range + + .text + .globl _start +_start: + .cfi_startproc + .cfi_lsda 0, _ex + nop + .cfi_endproc + + .data +_ex: + .word 0 diff --git a/test/ELF/linkerscript/eh-frame.s b/test/ELF/linkerscript/eh-frame.s new file mode 100644 index 000000000000..750f74eb36c6 --- /dev/null +++ b/test/ELF/linkerscript/eh-frame.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: .eh_frame : { *(.eh_frame) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -s -section=".eh_frame" %t1 | FileCheck %s + +# CHECK: 0000 14000000 00000000 017a5200 01781001 +# CHECK-NEXT: 0010 1b0c0708 90010000 + +.global _start +_start: + nop + +.section .dah,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc diff --git a/test/ELF/linkerscript/ehdr_start.s b/test/ELF/linkerscript/ehdr_start.s index 0ae4a4dcfbc9..935fa2bf3391 100644 --- a/test/ELF/linkerscript/ehdr_start.s +++ b/test/ELF/linkerscript/ehdr_start.s @@ -3,7 +3,8 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { }" > %t.script # RUN: not ld.lld %t.o -script %t.script -o %t 2>&1 | FileCheck %s -# CHECK: error: {{.*}}:(.text+0x0): undefined symbol '__ehdr_start' +# CHECK: error: undefined symbol: __ehdr_start +# CHECK: >>> referenced by {{.*}}:(.text+0x0) .text .global _start, __ehdr_start diff --git a/test/ELF/linkerscript/emit-reloc.s b/test/ELF/linkerscript/emit-reloc.s new file mode 100644 index 000000000000..725f314a9772 --- /dev/null +++ b/test/ELF/linkerscript/emit-reloc.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .rela.dyn : { *(.rela.data) } }" > %t.script +# RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t.so -shared +# RUN: llvm-readobj -r %t.so | FileCheck %s + +.data +.quad .foo + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.dyn { +# CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: Section ({{.*}}) .rela.data { +# CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] diff --git a/test/ELF/linkerscript/emit-relocs-discard.s b/test/ELF/linkerscript/emit-relocs-discard.s new file mode 100644 index 000000000000..2f1f6c6b4b0a --- /dev/null +++ b/test/ELF/linkerscript/emit-relocs-discard.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { /DISCARD/ : { *(.bbb) } }" > %t.script +# RUN: ld.lld --emit-relocs --script %t.script %t.o -o %t1 +# RUN: llvm-readobj -r %t1 | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: ] + +.section .aaa,"",@progbits +.Lfoo: + +.section .bbb,"",@progbits +.long .Lfoo diff --git a/test/ELF/linkerscript/emit-relocs-ehframe-discard.s b/test/ELF/linkerscript/emit-relocs-ehframe-discard.s new file mode 100644 index 000000000000..9df0e8ce9dcb --- /dev/null +++ b/test/ELF/linkerscript/emit-relocs-ehframe-discard.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: echo "SECTIONS { /DISCARD/ : { *(.eh_frame) } }" > %t.script +# RUN: ld.lld --emit-relocs --script %t.script %t1.o -o %t +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +# CHECK-NOT: .rela.eh_frame + +.section .foo,"ax",@progbits +.cfi_startproc +.cfi_endproc diff --git a/test/ELF/linkerscript/empty-load.s b/test/ELF/linkerscript/empty-load.s index 0a87d5727474..ea58d71402d1 100644 --- a/test/ELF/linkerscript/empty-load.s +++ b/test/ELF/linkerscript/empty-load.s @@ -5,8 +5,7 @@ # RUN: llvm-objdump -private-headers %t1 | FileCheck %s ## We expect 2 PT_LOAD segments -# CHECK: PHDR -# CHECK-NEXT: filesz {{0x[0-9a-f]+}} memsz {{0x[0-9a-f]+}} flags r-- +# CHECK: Program Header: # CHECK-NEXT: LOAD # CHECK-NEXT: filesz {{0x[0-9a-f]+}} memsz {{0x[0-9a-f]+}} flags rw- # CHECK-NEXT: LOAD diff --git a/test/ELF/linkerscript/excludefile.s b/test/ELF/linkerscript/excludefile.s index 8a154354dbc2..95b9534d9535 100644 --- a/test/ELF/linkerscript/excludefile.s +++ b/test/ELF/linkerscript/excludefile.s @@ -13,11 +13,13 @@ # CHECK: _start: # CHECK-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax # CHECK-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi -# CHECK-NEXT: : 00 00 addb %al, (%rax) +# CHECK-NEXT: : cc int3 +# CHECK-NEXT: : cc int3 # CHECK: _potato: # CHECK-NEXT: : 90 nop # CHECK-NEXT: : 90 nop -# CHECK-NEXT: : 00 00 addb %al, (%rax) +# CHECK-NEXT: : cc int3 +# CHECK-NEXT: : cc int3 # CHECK: tomato: # CHECK-NEXT: : b8 01 00 00 00 movl $1, %eax @@ -31,7 +33,8 @@ # EXCLUDE: _start: # EXCLUDE-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax # EXCLUDE-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi -# EXCLUDE-NEXT: : 00 00 addb %al, (%rax) +# EXCLUDE-NEXT: : cc int3 +# EXCLUDE-NEXT: : cc int3 # EXCLUDE: _potato: # EXCLUDE-NEXT: : 90 nop # EXCLUDE-NEXT: : 90 nop diff --git a/test/ELF/linkerscript/expr-invalid-sec.s b/test/ELF/linkerscript/expr-invalid-sec.s new file mode 100644 index 000000000000..9476be3c3b14 --- /dev/null +++ b/test/ELF/linkerscript/expr-invalid-sec.s @@ -0,0 +1,6 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { foo = ADDR(.text) + ADDR(.text); };" > %t.script +# RUN: not ld.lld -o %t.so --script %t.script %t.o -shared 2>&1 | FileCheck %s + +# CHECK: At least one side of the expression must be absolute diff --git a/test/ELF/linkerscript/expr-sections.s b/test/ELF/linkerscript/expr-sections.s new file mode 100644 index 000000000000..eb60009cd971 --- /dev/null +++ b/test/ELF/linkerscript/expr-sections.s @@ -0,0 +1,22 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: . = . + 4; \ +# RUN: .text : { \ +# RUN: *(.text) \ +# RUN: foo1 = ADDR(.text) + 1; bar1 = 1 + ADDR(.text); \ +# RUN: foo2 = ADDR(.text) & 1; bar2 = 1 & ADDR(.text); \ +# RUN: foo3 = ADDR(.text) | 1; bar3 = 1 | ADDR(.text); \ +# RUN: } \ +# RUN: };" > %t.script +# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: llvm-objdump -t -h %t.so | FileCheck %s + +# CHECK: 1 .text 00000000 0000000000000004 TEXT DATA + +# CHECK: 0000000000000005 .text 00000000 foo1 +# CHECK: 0000000000000005 .text 00000000 bar1 +# CHECK: 0000000000000000 .text 00000000 foo2 +# CHECK: 0000000000000000 .text 00000000 bar2 +# CHECK: 0000000000000005 .text 00000000 foo3 +# CHECK: 0000000000000005 .text 00000000 bar3 diff --git a/test/ELF/linkerscript/fill-exec-sections.s b/test/ELF/linkerscript/fill-exec-sections.s new file mode 100644 index 000000000000..f61d6da1db33 --- /dev/null +++ b/test/ELF/linkerscript/fill-exec-sections.s @@ -0,0 +1,40 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Check that padding of executable sections are filled with trap bytes if not +## otherwise specified in the script. +# RUN: echo "SECTIONS { .exec : { *(.exec*) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -s %t.out | FileCheck %s --check-prefix=EXEC +# EXEC: 0000 66cccccc cccccccc cccccccc cccccccc +# EXEC-NEXT: 0010 66 + +## Check that a fill expression or command overrides the default filler... +# RUN: echo "SECTIONS { .exec : { *(.exec*) }=0x11223344 }" > %t2.script +# RUN: ld.lld -o %t2.out --script %t2.script %t +# RUN: llvm-objdump -s %t2.out | FileCheck %s --check-prefix=OVERRIDE +# RUN: echo "SECTIONS { .exec : { FILL(0x11223344); *(.exec*) } }" > %t3.script +# RUN: ld.lld -o %t3.out --script %t3.script %t +# RUN: llvm-objdump -s %t3.out | FileCheck %s --check-prefix=OVERRIDE +# OVERRIDE: Contents of section .exec: +# OVERRIDE-NEXT: 0000 66112233 44112233 44112233 44112233 +# OVERRIDE-NEXT: 0010 66 + +## ...even for a value of zero. +# RUN: echo "SECTIONS { .exec : { *(.exec*) }=0x00000000 }" > %t4.script +# RUN: ld.lld -o %t4.out --script %t4.script %t +# RUN: llvm-objdump -s %t4.out | FileCheck %s --check-prefix=ZERO +# RUN: echo "SECTIONS { .exec : { FILL(0x00000000); *(.exec*) } }" > %t5.script +# RUN: ld.lld -o %t5.out --script %t5.script %t +# RUN: llvm-objdump -s %t5.out | FileCheck %s --check-prefix=ZERO +# ZERO: Contents of section .exec: +# ZERO-NEXT: 0000 66000000 00000000 00000000 00000000 +# ZERO-NEXT: 0010 66 + +.section .exec.1,"ax" +.align 16 +.byte 0x66 + +.section .exec.2,"ax" +.align 16 +.byte 0x66 diff --git a/test/ELF/linkerscript/fill.s b/test/ELF/linkerscript/fill.s index 57a19e0943d0..604506084a74 100644 --- a/test/ELF/linkerscript/fill.s +++ b/test/ELF/linkerscript/fill.s @@ -2,7 +2,8 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { \ # RUN: .out : { \ -# RUN: FILL(0x11111111); \ +# RUN: FILL(0x11111111) \ +# RUN: . += 2; \ # RUN: *(.aaa) \ # RUN: . += 4; \ # RUN: *(.bbb) \ @@ -15,7 +16,7 @@ # RUN: llvm-objdump -s %t | FileCheck %s # CHECK: Contents of section .out: -# CHECK-NEXT: aa222222 22bb2222 22222222 2222 +# CHECK-NEXT: 2222aa22 222222bb 22222222 22222222 .text .globl _start diff --git a/test/ELF/linkerscript/huge-temporary-file.s b/test/ELF/linkerscript/huge-temporary-file.s new file mode 100644 index 000000000000..d58709cf8f8d --- /dev/null +++ b/test/ELF/linkerscript/huge-temporary-file.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { .text 0x2000 : {. = 0x10 ; *(.text) } }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t1 + +## This inputs previously created a 4gb temporarily fine under 32 bit +## configuration. Issue was fixed. There is no clean way to check that from here. +## This testcase added for documentation purposes. + +.globl _start +_start: +nop diff --git a/test/ELF/linkerscript/lazy-symbols.s b/test/ELF/linkerscript/lazy-symbols.s new file mode 100644 index 000000000000..22dffeef979b --- /dev/null +++ b/test/ELF/linkerscript/lazy-symbols.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1 +# RUN: llvm-ar rcs %tar %t1 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2 +# RUN: echo "foo = 1;" > %t.script +# RUN: ld.lld %t2 %tar --script %t.script -o %tout +# RUN: llvm-readobj -symbols %tout | FileCheck %s + +# This test is to ensure a linker script can define a symbol which have the same +# name as a lazy symbol. + +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x1 diff --git a/test/ELF/linkerscript/locationcounter.s b/test/ELF/linkerscript/locationcounter.s deleted file mode 100644 index c57a17c5c9cb..000000000000 --- a/test/ELF/linkerscript/locationcounter.s +++ /dev/null @@ -1,189 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { \ -# RUN: . = 0xFFF0; \ -# RUN: . = . + 0x10; \ -# RUN: .plus : { *(.plus) } \ -# RUN: . = 0x11010 - 0x10; \ -# RUN: .minus : { *(.minus) } \ -# RUN: . = 0x24000 / 0x2; \ -# RUN: .div : { *(.div) } \ -# RUN: . = 0x11000 + 0x1000 * 0x2; \ -# RUN: .mul : { *(.mul) } \ -# RUN: . = 0x10000 + (0x1000 + 0x1000) * 0x2; \ -# RUN: .bracket : { *(.bracket) } \ -# RUN: . = 0x17000 & 0x15000; \ -# RUN: .and : { *(.and) } \ -# RUN: . = 0x1 ? 0x16000 : 0x999999; \ -# RUN: .ternary1 : { *(.ternary1) } \ -# RUN: . = 0x0 ? 0x999999 : 0x17000; \ -# RUN: .ternary2 : { *(.ternary2) } \ -# RUN: . = 0x0 < 0x1 ? 0x18000 : 0x999999; \ -# RUN: .less : { *(.less) } \ -# RUN: . = 0x1 <= 0x1 ? 0x19000 : 0x999999; \ -# RUN: .lesseq : { *(.lesseq) } \ -# RUN: . = 0x1 > 0x0 ? 0x20000 : 0x999999; \ -# RUN: .great : { *(.great) } \ -# RUN: . = 0x1 >= 0x1 ? 0x21000 : 0x999999; \ -# RUN: .greateq : { *(.greateq) } \ -# RUN: . = 0x1 == 0x1 ? 0x22000 : 0x999999; \ -# RUN: .eq : { *(.eq) } \ -# RUN: . = 0x2 != 0x1 ? 0x23000 : 0x999999; \ -# RUN: .neq : { *(.neq) } \ -# RUN: . = CONSTANT (MAXPAGESIZE) * 0x24; \ -# RUN: .maxpagesize : { *(.maxpagesize) } \ -# RUN: . = CONSTANT (COMMONPAGESIZE) * 0x25; \ -# RUN: .commonpagesize : { *(.commonpagesize) } \ -# RUN: . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \ -# RUN: .datasegmentalign : { *(.datasegmentalign) } \ -# RUN: . = DATA_SEGMENT_END (.); \ -# RUN: . = 0x27000; \ -# RUN: . += 0x1000; \ -# RUN: .plusassign : { *(.plusassign) } \ -# RUN: . = ((. + 0x1fff) & ~(0x1000 + -1)); \ -# RUN: .unary : { *(.unary) } \ -# RUN: . = 0x30000 + (1 + 1 << 5); \ -# RUN: .shiftl : { *(.shiftl) } \ -# RUN: . = 0x30000 + (1 + 1023 >> 2); \ -# RUN: .shiftr : { *(.shiftr) } \ - -# RUN: }" > %t.script -# RUN: ld.lld %t --script %t.script -o %t2 -# RUN: llvm-objdump -section-headers %t2 | FileCheck %s - -# CHECK: .plus {{.*}} 0000000000010000 -# CHECK: .minus {{.*}} 0000000000011000 -# CHECK: .div {{.*}} 0000000000012000 -# CHECK: .mul {{.*}} 0000000000013000 -# CHECK: .bracket {{.*}} 0000000000014000 -# CHECK: .and {{.*}} 0000000000015000 -# CHECK: .ternary1 {{.*}} 0000000000016000 -# CHECK: .ternary2 {{.*}} 0000000000017000 -# CHECK: .less {{.*}} 0000000000018000 -# CHECK: .lesseq {{.*}} 0000000000019000 -# CHECK: .great {{.*}} 0000000000020000 -# CHECK: .greateq {{.*}} 0000000000021000 -# CHECK: .eq {{.*}} 0000000000022000 -# CHECK: .neq {{.*}} 0000000000023000 -# CHECK: .maxpagesize {{.*}} 0000000000024000 -# CHECK: .commonpagesize {{.*}} 0000000000025000 -# CHECK: .datasegmentalign {{.*}} 0000000000026000 -# CHECK: .plusassign {{.*}} 0000000000028000 -# CHECK: .unary {{.*}} 000000000002a000 -# CHECK: .shiftl {{.*}} 0000000000030040 -# CHECK: .shiftr {{.*}} 0000000000030100 - -## Mailformed number error. -# RUN: echo "SECTIONS { \ -# RUN: . = 0x12Q41; \ -# RUN: }" > %t.script -# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=NUMERR %s -# NUMERR: malformed number: 0x12Q41 - -## Missing closing bracket. -# RUN: echo "SECTIONS { \ -# RUN: . = 0x10000 + (0x1000 + 0x1000 * 0x2; \ -# RUN: }" > %t.script -# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=BRACKETERR %s -# BRACKETERR: ) expected, but got ; - -## Missing opening bracket. -# RUN: echo "SECTIONS { \ -# RUN: . = 0x10000 + 0x1000 + 0x1000) * 0x2; \ -# RUN: }" > %t.script -# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=BRACKETERR2 %s -# BRACKETERR2: ; expected, but got ) - -## Empty expression. -# RUN: echo "SECTIONS { \ -# RUN: . = ; \ -# RUN: }" > %t.script -# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=ERREXPR %s -# ERREXPR: malformed number: ; - -## Div by zero error. -# RUN: echo "SECTIONS { \ -# RUN: . = 0x10000 / 0x0; \ -# RUN: }" > %t.script -# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=DIVZERO %s -# DIVZERO: division by zero - -## Broken ternary operator expression. -# RUN: echo "SECTIONS { \ -# RUN: . = 0x1 ? 0x2; \ -# RUN: }" > %t.script -# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=TERNERR %s -# TERNERR: : expected, but got ; - -.globl _start -_start: -nop - -.section .plus, "a" -.quad 0 - -.section .minus, "a" -.quad 0 - -.section .div, "a" -.quad 0 - -.section .mul, "a" -.quad 0 - -.section .bracket, "a" -.quad 0 - -.section .and, "a" -.quad 0 - -.section .ternary1, "a" -.quad 0 - -.section .ternary2, "a" -.quad 0 - -.section .less, "a" -.quad 0 - -.section .lesseq, "a" -.quad 0 - -.section .great, "a" -.quad 0 - -.section .greateq, "a" -.quad 0 - -.section .eq, "a" -.quad 0 - -.section .neq, "a" -.quad 0 - -.section .maxpagesize, "a" -.quad 0 - -.section .commonpagesize, "a" -.quad 0 - -.section .datasegmentalign, "a" -.quad 0 - -.section .plusassign, "a" -.quad 0 - -.section .unary, "a" -.quad 0 - -.section .shiftl, "a" -.quad 0 - -.section .shiftr, "a" -.quad 0 diff --git a/test/ELF/linkerscript/locationcountererr.s b/test/ELF/linkerscript/locationcountererr.s index 7664d8d46917..113e102d4bc2 100644 --- a/test/ELF/linkerscript/locationcountererr.s +++ b/test/ELF/linkerscript/locationcountererr.s @@ -1,8 +1,10 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { .text 0x2000 : {. = 0x10 ; *(.text) } }" > %t.script + +# RUN: echo "SECTIONS {" > %t.script +# RUN: echo ".text 0x2000 : {. = 0x10 ; *(.text) } }" >> %t.script # RUN: not ld.lld %t --script %t.script -o %t1 2>&1 | FileCheck %s -# CHECK: unable to move location counter backward for: .text +# CHECK: {{.*}}.script:2: unable to move location counter backward for: .text .globl _start _start: diff --git a/test/ELF/linkerscript/locationcountererr2.s b/test/ELF/linkerscript/locationcountererr2.s new file mode 100644 index 000000000000..e711f77a3f71 --- /dev/null +++ b/test/ELF/linkerscript/locationcountererr2.s @@ -0,0 +1,9 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS {" > %t.script +# RUN: echo ". = 0x20; . = 0x10; }" >> %t.script +# RUN: not ld.lld %t.o --script %t.script -o %t -shared 2>&1 | FileCheck %s +# CHECK: {{.*}}.script:2: unable to move location counter backward + +# RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script +# RUN: ld.lld %t.o --script %t2.script -o %t -shared diff --git a/test/ELF/linkerscript/memory.s b/test/ELF/linkerscript/memory.s new file mode 100644 index 000000000000..774a6f92ab17 --- /dev/null +++ b/test/ELF/linkerscript/memory.s @@ -0,0 +1,114 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Check simple RAM-only memory region. + +# RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0x8000, LENGTH = 256K } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text) } > ram \ +# RUN: .data : { *(.data) } > ram \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAM %s + +# RAM: 1 .text 00000001 0000000000008000 TEXT DATA +# RAM-NEXT: 2 .data 00001000 0000000000008001 DATA + +## Check RAM and ROM memory regions. + +# RUN: echo "MEMORY { \ +# RUN: ram (rwx) : ORIGIN = 0, LENGTH = 1024M \ +# RUN: rom (rx) : org = (0x80 * 0x1000 * 0x1000), len = 64M \ +# RUN: } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text) } > rom \ +# RUN: .data : { *(.data) } > ram \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAMROM %s + +# RAMROM: 1 .text 00000001 0000000080000000 TEXT DATA +# RAMROM-NEXT: 2 .data 00001000 0000000000000000 DATA + +## Check memory region placement by attributes. + +# RUN: echo "MEMORY { \ +# RUN: ram (!rx) : ORIGIN = 0, LENGTH = 1024M \ +# RUN: rom (rx) : o = 0x80000000, l = 64M \ +# RUN: } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text) } \ +# RUN: .data : { *(.data) } > ram \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=ATTRS %s + +# ATTRS: 1 .text 00000001 0000000080000000 TEXT DATA +# ATTRS: 2 .data 00001000 0000000000000000 DATA + +## Check bad `ORIGIN`. + +# RUN: echo "MEMORY { ram (rwx) : XYZ = 0x8000 } }" > %t.script +# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR1 %s +# ERR1: {{.*}}.script:1: expected one of: ORIGIN, org, or o + +## Check bad `LENGTH`. + +# RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0x8000, XYZ = 256K } }" > %t.script +# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR2 %s +# ERR2: {{.*}}.script:1: expected one of: LENGTH, len, or l + +## Check duplicate regions. + +# RUN: echo "MEMORY { ram (rwx) : o = 8, l = 256K ram (rx) : o = 0, l = 256K }" > %t.script +# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR3 %s +# ERR3: {{.*}}.script:1: region 'ram' already defined + +## Check no region available. + +# RUN: echo "MEMORY { ram (!rx) : ORIGIN = 0x8000, LENGTH = 256K } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text) } \ +# RUN: .data : { *(.data) } > ram \ +# RUN: }" > %t.script +# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR4 %s +# ERR4: {{.*}}: no memory region specified for section '.text' + +## Check undeclared region. + +# RUN: echo "SECTIONS { .text : { *(.text) } > ram }" > %t.script +# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR5 %s +# ERR5: {{.*}}: memory region 'ram' not declared + +## Check region overflow. + +# RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0, LENGTH = 2K } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text) } > ram \ +# RUN: .data : { *(.data) } > ram \ +# RUN: }" > %t.script +# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR6 %s +# ERR6: {{.*}}: section '.data' will not fit in region 'ram': overflowed by 2049 bytes + +## Check invalid region attributes. + +# RUN: echo "MEMORY { ram (abc) : ORIGIN = 8000, LENGTH = 256K } }" > %t.script +# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR7 %s +# ERR7: {{.*}}.script:1: invalid memory region attribute + +.text +.global _start +_start: + nop + +.data +b: + .long 1 + .zero 4092 diff --git a/test/ELF/linkerscript/merge-sections-syms.s b/test/ELF/linkerscript/merge-sections-syms.s new file mode 100644 index 000000000000..713d334a1a5a --- /dev/null +++ b/test/ELF/linkerscript/merge-sections-syms.s @@ -0,0 +1,49 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o + +# RUN: echo "SECTIONS { \ +# RUN: . = SIZEOF_HEADERS; \ +# RUN: .rodata : { *(.aaa) *(.bbb) A = .; *(.ccc) B = .; } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: A +# CHECK-NEXT: Value: 0x195 +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: B +# CHECK-NEXT: Value: 0x196 +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: +# CHECK-NEXT: } +# CHECK-NEXT: ] + + +.section .aaa,"a" +.byte 11 + +.section .bbb,"aMS",@progbits,1 +.asciz "foo" + +.section .ccc,"a" +.byte 33 diff --git a/test/ELF/linkerscript/merge-sections.s b/test/ELF/linkerscript/merge-sections.s index 7252fe576674..ae53ebc4d400 100644 --- a/test/ELF/linkerscript/merge-sections.s +++ b/test/ELF/linkerscript/merge-sections.s @@ -17,61 +17,19 @@ # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x[[ADDR1:.*]] # CHECK-NEXT: Offset: 0x[[ADDR1]] -# CHECK-NEXT: Size: 4 -# CHECK-NEXT: Link: 0 -# CHECK-NEXT: Info: 0 -# CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 1 -# CHECK-NEXT: } -# CHECK-NEXT: Section { -# CHECK-NEXT: Index: -# CHECK-NEXT: Name: .foo -# CHECK-NEXT: Type: SHT_PROGBITS -# CHECK-NEXT: Flags [ -# CHECK-NEXT: SHF_ALLOC -# CHECK-NEXT: SHF_MERGE -# CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x -# CHECK-NEXT: Offset: 0x -# CHECK-NEXT: Size: 1 -# CHECK-NEXT: Link: 0 -# CHECK-NEXT: Info: 0 -# CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 1 -# CHECK-NEXT: } -# CHECK-NEXT: Section { -# CHECK-NEXT: Index: -# CHECK-NEXT: Name: .foo -# CHECK-NEXT: Type: SHT_PROGBITS -# CHECK-NEXT: Flags [ -# CHECK-NEXT: SHF_ALLOC -# CHECK-NEXT: SHF_MERGE -# CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x -# CHECK-NEXT: Offset: 0x -# CHECK-NEXT: Size: 2 +# CHECK-NEXT: Size: 14 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 2 -# CHECK-NEXT: EntrySize: 2 +# CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: } -# CHECK-NEXT: Section { -# CHECK-NEXT: Index: -# CHECK-NEXT: Name: -# CHECK-NEXT: Type: -# CHECK-NEXT: Flags [ -# CHECK-NEXT: SHF_ALLOC -# CHECK-NEXT: SHF_EXECINSTR -# CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x[[ADDR2:.*]] -# CHECK-NEXT: Offset: 0x[[ADDR2]] - # CHECK: Name: begin # CHECK-NEXT: Value: 0x[[ADDR1]] # CHECK: Name: end -# CHECK-NEXT: Value: 0x[[ADDR2]] +# 0x19E = begin + sizeof(.foo) = 0x190 + 0xE +# CHECK-NEXT: Value: 0x19E .section .foo.1a,"aMS",@progbits,1 .asciz "foo" diff --git a/test/ELF/linkerscript/no-space.s b/test/ELF/linkerscript/no-space.s index a96797269e43..fc9e5b13325f 100644 --- a/test/ELF/linkerscript/no-space.s +++ b/test/ELF/linkerscript/no-space.s @@ -10,17 +10,15 @@ # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s # There is not enough address space available for the header, so just start the PT_LOAD -# after it. +# after it. Don't create a PT_PHDR as the header is not allocated. # CHECK: Program Headers: # CHECK-NEXT: Type Offset VirtAddr PhysAddr -# CHECK-NEXT: PHDR # CHECK-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 # CHECK: Section to Segment mapping: # CHECK-NEXT: Segment Sections... -# CHECK-NEXT: 00 -# CHECK-NEXT: 01 foo .text .dynsym .hash .dynstr +# CHECK-NEXT: 00 foo .text .dynsym .hash .dynstr .section foo, "a" .quad 0 diff --git a/test/ELF/linkerscript/non-absolute.s b/test/ELF/linkerscript/non-absolute.s new file mode 100644 index 000000000000..a0e9e7dc6782 --- /dev/null +++ b/test/ELF/linkerscript/non-absolute.s @@ -0,0 +1,30 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: echo "SECTIONS { A = . - 0x10; B = A + 0x1; }" > %t.script +# RUN: ld.lld -shared %t1.o --script %t.script -o %t +# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DUMP +# RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SYMBOL + +# DUMP: Disassembly of section .text: +# DUMP-NEXT: foo: +# DUMP-NEXT: 0: {{.*}} -21(%rip), %eax + +# SYMBOL: Symbol { +# SYMBOL: Name: B +# SYMBOL-NEXT: Value: 0xFFFFFFFFFFFFFFF1 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Local +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other [ +# SYMBOL-NEXT: STV_HIDDEN +# SYMBOL-NEXT: ] +# SYMBOL-NEXT: Section: .text +# SYMBOL-NEXT: } + +.text +.globl foo +.type foo, @function +foo: + movl B(%rip), %eax + +.hidden B diff --git a/test/ELF/linkerscript/non-absolute2.s b/test/ELF/linkerscript/non-absolute2.s new file mode 100644 index 000000000000..97c34d31a912 --- /dev/null +++ b/test/ELF/linkerscript/non-absolute2.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: echo "SECTIONS { A = . + 0x1; . += 0x1000; }" > %t.script +# RUN: ld.lld -shared %t1.o --script %t.script -o %t +# RUN: llvm-objdump -section-headers -t %t | FileCheck %s + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .text 00000000 0000000000001000 + +# CHECK: 0000000000000001 .text 00000000 A diff --git a/test/ELF/linkerscript/non-alloc.s b/test/ELF/linkerscript/non-alloc.s index 2060129a8020..861c74996b85 100644 --- a/test/ELF/linkerscript/non-alloc.s +++ b/test/ELF/linkerscript/non-alloc.s @@ -10,15 +10,13 @@ # CHECK: Program Headers: # CHECK-NEXT: Type -# CHECK-NEXT: PHDR # CHECK-NEXT: LOAD {{.*}} R E # CHECK-NEXT: LOAD {{.*}} RW # CHECK: Section to Segment mapping: # CHECK-NEXT: Segment Sections... -# CHECK-NEXT: 00 -# CHECK-NEXT: 01 .text .dynsym .hash .dynstr -# CHECK-NEXT: 02 .dynamic +# CHECK-NEXT: 00 .text .dynsym .hash .dynstr +# CHECK-NEXT: 01 .dynamic nop .section foo diff --git a/test/ELF/linkerscript/numbers.s b/test/ELF/linkerscript/numbers.s index 653f94bd4e6e..d4fd13fd8197 100644 --- a/test/ELF/linkerscript/numbers.s +++ b/test/ELF/linkerscript/numbers.s @@ -28,27 +28,35 @@ # CHECK-NEXT: 6 .mega2 00000008 0000000000200000 ## Mailformed number errors. -# RUN: echo "SECTIONS { \ -# RUN: . = 0x11h; \ -# RUN: }" > %t2.script +# RUN: echo "SECTIONS { . = 0x11h; }" > %t2.script # RUN: not ld.lld %t --script %t2.script -o %t3 2>&1 | \ # RUN: FileCheck --check-prefix=ERR1 %s # ERR1: malformed number: 0x11h -# RUN: echo "SECTIONS { \ -# RUN: . = 0x11k; \ -# RUN: }" > %t3.script +# RUN: echo "SECTIONS { . = 0x11k; }" > %t3.script # RUN: not ld.lld %t --script %t3.script -o %t4 2>&1 | \ # RUN: FileCheck --check-prefix=ERR2 %s # ERR2: malformed number: 0x11k -# RUN: echo "SECTIONS { \ -# RUN: . = 0x11m; \ -# RUN: }" > %t4.script +# RUN: echo "SECTIONS { . = 0x11m; }" > %t4.script # RUN: not ld.lld %t --script %t4.script -o %t5 2>&1 | \ # RUN: FileCheck --check-prefix=ERR3 %s # ERR3: malformed number: 0x11m +## Make sure that numbers can be followed by a ":" with and without a space, +## e.g. "0x100 :" or "0x100:" +# RUN: echo "SECTIONS { \ +# RUN: .hex1 0x400 : { *(.hex.1) } \ +# RUN: .hex2 0x500:{ *(.hex.2) } \ +# RUN: }" > %t5.script +# RUN: ld.lld %t --script %t5.script -o %t6 +# RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s +# SECADDR: Sections: +# SECADDR-NEXT: Idx Name Size Address +# SECADDR-NEXT: 0 00000000 0000000000000000 +# SECADDR-NEXT: 1 .hex1 00000008 0000000000000400 +# SECADDR-NEXT: 2 .hex2 00000008 0000000000000500 + .globl _start _start: nop diff --git a/test/ELF/linkerscript/obj-symbol-value.s b/test/ELF/linkerscript/obj-symbol-value.s new file mode 100644 index 000000000000..1c0b1190e815 --- /dev/null +++ b/test/ELF/linkerscript/obj-symbol-value.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { foo = bar; .bar : { *(.bar*) } }" > %t.script +# RUN: ld.lld %t.o --script %t.script -o %t.so -shared +# RUN: llvm-readobj -t %t.so | FileCheck %s + +# CHECK: Symbol { +# CHECK: Name: bar +# CHECK-NEXT: Value: 0x[[VAL:.*]] +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x[[VAL]] + +.section .bar.1, "a" +.quad 0 + +.section .bar.2, "a" +.quad 0 +.global bar +bar: diff --git a/test/ELF/linkerscript/operators.s b/test/ELF/linkerscript/operators.s new file mode 100644 index 000000000000..470558d29df1 --- /dev/null +++ b/test/ELF/linkerscript/operators.s @@ -0,0 +1,93 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: plus = 1 + 2 + 3; \ +# RUN: minus = 5 - 1; \ +# RUN: div = 6 / 2; \ +# RUN: mul = 1 + 2 * 3; \ +# RUN: nospace = 1+2*6/3; \ +# RUN: braces = 1 + (2 + 3) * 4; \ +# RUN: and = 0xbb & 0xee; \ +# RUN: ternary1 = 1 ? 1 : 2; \ +# RUN: ternary2 = 0 ? 1 : 2; \ +# RUN: less = 1 < 0 ? 1 : 2; \ +# RUN: lesseq = 1 <= 1 ? 1 : 2; \ +# RUN: greater = 0 > 1 ? 1 : 2; \ +# RUN: greatereq = 1 >= 1 ? 1 : 2; \ +# RUN: eq = 1 == 1 ? 1 : 2; \ +# RUN: neq = 1 != 1 ? 1 : 2; \ +# RUN: plusassign = 1; \ +# RUN: plusassign += 2; \ +# RUN: unary = -1 + 3; \ +# RUN: lshift = 1 << 5; \ +# RUN: rshift = 0xff >> 3; \ +# RUN: maxpagesize = CONSTANT (MAXPAGESIZE); \ +# RUN: commonpagesize = CONSTANT (COMMONPAGESIZE); \ +# RUN: . = 0xfff0; \ +# RUN: datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0); \ +# RUN: }" > %t.script +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-objdump -t %t2 | FileCheck %s + +# CHECK: 00000000000006 *ABS* 00000000 plus +# CHECK: 00000000000004 *ABS* 00000000 minus +# CHECK: 00000000000003 *ABS* 00000000 div +# CHECK: 00000000000007 *ABS* 00000000 mul +# CHECK: 00000000000005 *ABS* 00000000 nospace +# CHECK: 00000000000015 *ABS* 00000000 braces +# CHECK: 000000000000aa *ABS* 00000000 and +# CHECK: 00000000000001 *ABS* 00000000 ternary1 +# CHECK: 00000000000002 *ABS* 00000000 ternary2 +# CHECK: 00000000000002 *ABS* 00000000 less +# CHECK: 00000000000001 *ABS* 00000000 lesseq +# CHECK: 00000000000002 *ABS* 00000000 greater +# CHECK: 00000000000001 *ABS* 00000000 greatereq +# CHECK: 00000000000001 *ABS* 00000000 eq +# CHECK: 00000000000002 *ABS* 00000000 neq +# CHECK: 00000000000003 *ABS* 00000000 plusassign +# CHECK: 00000000000002 *ABS* 00000000 unary +# CHECK: 00000000000020 *ABS* 00000000 lshift +# CHECK: 0000000000001f *ABS* 00000000 rshift +# CHECK: 00000000001000 *ABS* 00000000 maxpagesize +# CHECK: 00000000001000 *ABS* 00000000 commonpagesize +# CHECK: 0000000000ffff *ABS* 00000000 datasegmentalign + +## Mailformed number error. +# RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=NUMERR %s +# NUMERR: malformed number: 0x12Q41 + +## Missing closing bracket. +# RUN: echo "SECTIONS { . = (1; }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=BRACKETERR %s +# BRACKETERR: ) expected, but got ; + +## Missing opening bracket. +# RUN: echo "SECTIONS { . = 1); }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=BRACKETERR2 %s +# BRACKETERR2: ; expected, but got ) + +## Empty expression. +# RUN: echo "SECTIONS { . = ; }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=ERREXPR %s +# ERREXPR: malformed number: ; + +## Div by zero error. +# RUN: echo "SECTIONS { . = 1 / 0; }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=DIVZERO %s +# DIVZERO: division by zero + +## Broken ternary operator expression. +# RUN: echo "SECTIONS { . = 1 ? 2; }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=TERNERR %s +# TERNERR: : expected, but got ; + +.globl _start +_start: +nop diff --git a/test/ELF/linkerscript/orphan-first-cmd.s b/test/ELF/linkerscript/orphan-first-cmd.s index 3fb3b31b9a40..263cb30d6868 100644 --- a/test/ELF/linkerscript/orphan-first-cmd.s +++ b/test/ELF/linkerscript/orphan-first-cmd.s @@ -4,7 +4,7 @@ # RUN: foo = 123; \ # RUN: . = 0x1000; \ # RUN: . = 0x2000; \ -# RUN: .bar : { . = . + 1; } \ +# RUN: .bar : { *(.bar) } \ # RUN: }" > %t.script # RUN: ld.lld -o %t -T %t.script %t.o -shared # RUN: llvm-readobj -s %t | FileCheck %s @@ -16,3 +16,5 @@ # CHECK-NEXT: SHF_EXECINSTR # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x1000 + +.section .bar, "aw" diff --git a/test/ELF/linkerscript/out-of-order.s b/test/ELF/linkerscript/out-of-order.s new file mode 100644 index 000000000000..9c6547a68643 --- /dev/null +++ b/test/ELF/linkerscript/out-of-order.s @@ -0,0 +1,10 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-linux %s -o %t.o +# RUN: echo "SECTIONS { .data 0x4000 : { *(.data) } .text 0x2000 : { *(.text) } }" > %t.script +# RUN: not ld.lld -o %t.so --script %t.script %t.o -shared 2>&1 | FileCheck %s + +# CHECK: error: {{.*}}.script:1: unable to move location counter backward + +.quad 0 +.data +.quad 0 diff --git a/test/ELF/linkerscript/output-too-large.s b/test/ELF/linkerscript/output-too-large.s new file mode 100644 index 000000000000..db021eaa99e0 --- /dev/null +++ b/test/ELF/linkerscript/output-too-large.s @@ -0,0 +1,8 @@ +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script +# RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s +# CHECK: error: output file too large + +.global _start +_start: + nop diff --git a/test/ELF/linkerscript/outputarch.s b/test/ELF/linkerscript/outputarch.s index 99089615cb17..dd3bf93611b4 100644 --- a/test/ELF/linkerscript/outputarch.s +++ b/test/ELF/linkerscript/outputarch.s @@ -1,10 +1,4 @@ # REQUIRES: x86 -# RUN: echo "OUTPUT_ARCH(x)" > %t.script +# RUN: echo "OUTPUT_ARCH(All data written here is ignored)" > %t.script # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1 # RUN: ld.lld -shared -o %t2 %t1 %t.script -# RUN: llvm-readobj %t2 > /dev/null - -# RUN: echo "OUTPUT_ARCH(x, y)" > %t.script -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1 -# RUN: not ld.lld -shared -o %t2 %t1 %t.script -# RUN: llvm-readobj %t2 > /dev/null diff --git a/test/ELF/linkerscript/outsections-addr.s b/test/ELF/linkerscript/outsections-addr.s index 003b2771c336..fda9bc994340 100644 --- a/test/ELF/linkerscript/outsections-addr.s +++ b/test/ELF/linkerscript/outsections-addr.s @@ -1,22 +1,10 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { \ -# RUN: .aaa 0x2000 : \ -# RUN: { \ -# RUN: *(.aaa) \ -# RUN: } \ -# RUN: .bbb 0x1 ? 0x3000 : 0x4000 : \ -# RUN: { \ -# RUN: *(.bbb) \ -# RUN: } \ -# RUN: .ccc ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : \ -# RUN: { \ -# RUN: *(.ccc) \ -# RUN: } \ -# RUN: .ddd 0x5001 : \ -# RUN: { \ -# RUN: *(.ddd) \ -# RUN: } \ +# RUN: echo "SECTIONS { \ +# RUN: .aaa 0x2000 : { *(.aaa) } \ +# RUN: .bbb 0x1 ? 0x3000 : 0x4000 : { *(.bbb) } \ +# RUN: .ccc ALIGN(CONSTANT(MAXPAGESIZE)) + (. & (CONSTANT(MAXPAGESIZE) - 1)) : { *(.ccc) } \ +# RUN: .ddd 0x5001 : { *(.ddd) } \ # RUN: }" > %t.script # RUN: ld.lld %t --script %t.script -o %tout # RUN: llvm-readobj -s %tout | FileCheck %s diff --git a/test/ELF/linkerscript/page-size.s b/test/ELF/linkerscript/page-size.s index 3d97816a68ee..330339d67223 100644 --- a/test/ELF/linkerscript/page-size.s +++ b/test/ELF/linkerscript/page-size.s @@ -44,9 +44,7 @@ # CHECK-NEXT: Alignment: 16384 # CHECK-NEXT: } -# RUN: echo "SECTIONS { \ -# RUN: symbol = CONSTANT(MAXPAGESIZE); \ -# RUN: }" > %t.script +# RUN: echo "SECTIONS { symbol = CONSTANT(MAXPAGESIZE); }" > %t.script # RUN: ld.lld -z max-page-size=0x4000 -o %t1 --script %t.script %t # RUN: llvm-objdump -t %t1 | FileCheck -check-prefix CHECK-SCRIPT %s diff --git a/test/ELF/linkerscript/pt_gnu_eh_frame.s b/test/ELF/linkerscript/pt_gnu_eh_frame.s new file mode 100644 index 000000000000..81b4c6307d4c --- /dev/null +++ b/test/ELF/linkerscript/pt_gnu_eh_frame.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { /DISCARD/ : { *(.eh_frame*) *(.eh_frame_hdr*) } }" > %t.script +# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t + +.global _start +_start: + nop + +.section .dah,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc diff --git a/test/ELF/linkerscript/section-align.s b/test/ELF/linkerscript/section-align.s new file mode 100644 index 000000000000..f4bdb0feac6d --- /dev/null +++ b/test/ELF/linkerscript/section-align.s @@ -0,0 +1,62 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { \ +# RUN: .aaa : ALIGN(4096) { *(.aaa) } \ +# RUN: .bbb : ALIGN(4096 * 4) { *(.bbb) } \ +# RUN: .ccc : ALIGN(4096 * 8) { *(.ccc) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-readobj -sections %t1 | FileCheck %s + +.global _start +_start: + nop + +// CHECK: Name: .aaa +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 4096 +// CHECK-NEXT: EntrySize: + +.section .aaa, "a" +.quad 0 + +// CHECK: Name: .bbb +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 16384 +// CHECK-NEXT: EntrySize: + +.section .bbb, "a" +.quad 0 + +// CHECK: Name: .ccc +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 32768 +// CHECK-NEXT: EntrySize: + +.section .ccc, "a" +.quad 0 diff --git a/test/ELF/linkerscript/sections-gc.s b/test/ELF/linkerscript/sections-gc.s new file mode 100644 index 000000000000..d71dc652511f --- /dev/null +++ b/test/ELF/linkerscript/sections-gc.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { .text : { *(.text*) } }" > %t.script +# RUN: ld.lld %t --gc-sections --script %t.script -o %t1 +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s + +# CHECK: Sections: +# CHECK-NEXT: Name Size +# CHECK: .text 00000001 + +.section .text.foo, "ax" +.global _start +_start: + nop + +.section .text.bar, "ax" +.global bar +bar: + nop diff --git a/test/ELF/linkerscript/sections-gc2.s b/test/ELF/linkerscript/sections-gc2.s new file mode 100644 index 000000000000..e2941aa57ed6 --- /dev/null +++ b/test/ELF/linkerscript/sections-gc2.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: used_in_reloc : { *(used_in_reloc) } \ +# RUN: used_in_script : { *(used_in_script) } \ +# RUN: .text : { *(.text) } \ +# RUN: }" > %t.script +# RUN: ld.lld -T %t.script -o %t.so %t.o --gc-sections +# RUN: llvm-objdump -h %t.so | FileCheck %s + +# CHECK: Idx Name Size Address Type +# CHECK-NEXT: 0 +# CHECK-NEXT: used_in_reloc +# CHECK-NEXT: .text +# CHECK-NEXT: .comment +# CHECK-NEXT: .symtab +# CHECK-NEXT: .shstrtab +# CHECK-NEXT: .strtab + + .global _start +_start: + .quad __start_used_in_reloc + + .section unused,"a" + .quad 0 + + .section used_in_script,"a" + .quad __start_used_in_script + + .section used_in_reloc,"a" + .quad 0 diff --git a/test/ELF/linkerscript/sections-padding.s b/test/ELF/linkerscript/sections-padding.s index 51d3a88fadf6..91ced2ef7a1e 100644 --- a/test/ELF/linkerscript/sections-padding.s +++ b/test/ELF/linkerscript/sections-padding.s @@ -5,13 +5,13 @@ # RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x1122 }" > %t.script # RUN: ld.lld -o %t.out --script %t.script %t # RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s -# YES: 66001122 00001122 00001122 00001122 +# YES: 66000011 22000011 22000011 22000011 ## Confirming that address was correct: # RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99887766 }" > %t.script # RUN: ld.lld -o %t.out --script %t.script %t # RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES2 %s -# YES2: 66887766 99887766 99887766 99887766 +# YES2: 66998877 66998877 66998877 66998877 ## Default padding value is 0x00: # RUN: echo "SECTIONS { .mysec : { *(.mysec*) } }" > %t.script @@ -23,7 +23,7 @@ # RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =777 }" > %t.script # RUN: ld.lld -o %t.out --script %t.script %t # RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=DEC %s -# DEC: 66000309 00000309 00000309 00000309 +# DEC: 66000003 09000003 09000003 09000003 ## Invalid hex value: # RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script @@ -36,6 +36,11 @@ # RUN: ld.lld -o %t.out --script %t.script %t # RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s +## Check case with optional comma following output section command: +# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x1122, .a : { *(.a*) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s + .section .mysec.1,"a" .align 16 .byte 0x66 diff --git a/test/ELF/linkerscript/sections-sort.s b/test/ELF/linkerscript/sections-sort.s index cf1fd3e57827..0e99851910f4 100644 --- a/test/ELF/linkerscript/sections-sort.s +++ b/test/ELF/linkerscript/sections-sort.s @@ -1,10 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: echo "SECTIONS { \ -# RUN: .text : { *(.text) } \ -# RUN: foo : { *(foo) } \ -# RUN: } " > %t.script +# RUN: echo "SECTIONS { .text : {*(.text)} foo : {*(foo)}}" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -shared # RUN: llvm-objdump --section-headers %t | FileCheck %s diff --git a/test/ELF/linkerscript/sections.s b/test/ELF/linkerscript/sections.s index 2cb9395e6692..1a2323c001dc 100644 --- a/test/ELF/linkerscript/sections.s +++ b/test/ELF/linkerscript/sections.s @@ -66,22 +66,11 @@ # SEC-SWAP-NAMES: 7 .shstrtab 0000003b {{[0-9a-f]*}} # SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}} -# .shstrtab from the input object file is discarded. -# RUN: echo "SECTIONS { \ -# RUN: /DISCARD/ : { *(.shstrtab) } }" > %t.script -# RUN: ld.lld -o %t5 --script %t.script %t -# RUN: llvm-objdump -section-headers %t5 | \ +# Attemp to discard .shstrtab section. +# RUN: echo "SECTIONS { /DISCARD/ : { *(.shstrtab) } }" > %t.script +# RUN: not ld.lld -o %t5 --script %t.script %t 2>&1 | \ # RUN: FileCheck -check-prefix=SEC-DISCARD %s - -# Idx Name Size -# SEC-DISCARD: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA -# SEC-DISCARD: 2 .data 00000020 {{[0-9a-f]*}} DATA -# SEC-DISCARD: 3 other 00000003 {{[0-9a-f]*}} DATA -# SEC-DISCARD: 4 .bss 00000002 {{[0-9a-f]*}} BSS -# SEC-DISCARD: 5 .comment 00000008 {{[0-9a-f]*}} -# SEC-DISCARD: 6 .symtab 00000030 {{[0-9a-f]*}} -# SEC-DISCARD: 7 .shstrtab 0000003b {{[0-9a-f]*}} -# SEC-DISCARD: 8 .strtab 00000008 {{[0-9a-f]*}} +# SEC-DISCARD: discarding .shstrtab section is not allowed # Multiple SECTIONS command specifying additional input section descriptions # for the same output section description - input sections are merged into @@ -104,6 +93,11 @@ # SEC-MULTI: 6 .shstrtab 00000035 {{[0-9a-f]*}} # SEC-MULTI: 7 .strtab 00000008 {{[0-9a-f]*}} +# Input section pattern contains additional semicolon. +# Case found in linux kernel script. Check we are able to parse it. +# RUN: echo "SECTIONS { .text : { ;;*(.text);;S = 0;; } }" > %t.script +# RUN: ld.lld -o /dev/null --script %t.script %t + .globl _start _start: mov $60, %rax diff --git a/test/ELF/linkerscript/symbol-assignexpr.s b/test/ELF/linkerscript/symbol-assignexpr.s index 5132ab11d821..14a1f0890ca6 100644 --- a/test/ELF/linkerscript/symbol-assignexpr.s +++ b/test/ELF/linkerscript/symbol-assignexpr.s @@ -40,9 +40,7 @@ # CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11 # CHECK-NEXT: 0000000000001235 *ABS* 00000000 symbol12 -# RUN: echo "SECTIONS { \ -# RUN: symbol2 = symbol; \ -# RUN: }" > %t2.script +# RUN: echo "SECTIONS { symbol2 = symbol; }" > %t2.script # RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \ # RUN: | FileCheck -check-prefix=ERR %s # ERR: {{.*}}.script:1: symbol not found: symbol diff --git a/test/ELF/linkerscript/symbol-only.s b/test/ELF/linkerscript/symbol-only.s index 76d54f01cdc7..2fb57260b333 100644 --- a/test/ELF/linkerscript/symbol-only.s +++ b/test/ELF/linkerscript/symbol-only.s @@ -12,7 +12,7 @@ # CHECK: Sections: # CHECK-NEXT: Idx Name Size Address # CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] BSS +# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] DATA # CHECK-NEXT: bar 00000000 0000000000001000 DATA # CHECK: SYMBOL TABLE: diff --git a/test/ELF/linkerscript/symbol-reserved.s b/test/ELF/linkerscript/symbol-reserved.s new file mode 100644 index 000000000000..ccbe761738ba --- /dev/null +++ b/test/ELF/linkerscript/symbol-reserved.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "PROVIDE_HIDDEN(newsym = __ehdr_start + 5);" > %t.script +# RUN: ld.lld -o %t1 %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck %s + +# CHECK: 0000000000200005 .text 00000000 .hidden newsym + +# RUN: ld.lld -o %t1.so %t.script %t -shared +# RUN: llvm-objdump -t %t1.so | FileCheck --check-prefix=SHARED %s + +# SHARED: 0000000000000005 .dynsym 00000000 .hidden newsym + +.global _start +_start: + lea newsym(%rip),%rax diff --git a/test/ELF/linkerscript/symbols-non-alloc.s b/test/ELF/linkerscript/symbols-non-alloc.s new file mode 100644 index 000000000000..4184487a7817 --- /dev/null +++ b/test/ELF/linkerscript/symbols-non-alloc.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ +# RUN: .text : { *(.text) } \ +# RUN: .nonalloc : { *(.nonalloc) } \ +# RUN: Sym = .; \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t2 --script %t.script %t +# RUN: llvm-objdump -section-headers -t %t2 | FileCheck %s + +# CHECK: SYMBOL TABLE: +# CHECK: 00000000000000f0 .nonalloc 00000000 Sym + +.section .nonalloc,"" + .quad 0 |