diff options
Diffstat (limited to 'test/ELF/linkerscript')
211 files changed, 2810 insertions, 1336 deletions
diff --git a/test/ELF/linkerscript/Inputs/addr.s b/test/ELF/linkerscript/Inputs/addr.s new file mode 100644 index 000000000000..65d99dcf99cd --- /dev/null +++ b/test/ELF/linkerscript/Inputs/addr.s @@ -0,0 +1,12 @@ +.text +.globl _start +_start: + +.section .foo.1,"a" +.quad 1 + +.section .foo.2,"a" +.quad 2 + +.section .foo.3,"a" +.quad 3 diff --git a/test/ELF/linkerscript/Inputs/align.s b/test/ELF/linkerscript/Inputs/align.s new file mode 100644 index 000000000000..c804536aa543 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/align.s @@ -0,0 +1,13 @@ +.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/Inputs/alignof.s b/test/ELF/linkerscript/Inputs/alignof.s new file mode 100644 index 000000000000..b288f94a12c9 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/alignof.s @@ -0,0 +1,15 @@ +.global _start +_start: + nop + +.section .aaa,"a" + .align 8 + .quad 0 + +.section .bbb,"a" + .align 16 + .quad 0 + +.section .ccc,"a" + .align 32 + .quad 0 diff --git a/test/ELF/linkerscript/Inputs/at2.s b/test/ELF/linkerscript/Inputs/at2.s new file mode 100644 index 000000000000..8c6548b53f69 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/at2.s @@ -0,0 +1,14 @@ +.section .foo1, "ax" +.quad 0 + +.section .foo2, "ax" +.quad 0 + +.section .bar1, "aw" +.quad 0 + +.section .bar2, "aw" +.quad 0 + +.section .bar3, "aw" +.quad 0 diff --git a/test/ELF/linkerscript/Inputs/at3.s b/test/ELF/linkerscript/Inputs/at3.s new file mode 100644 index 000000000000..8005c75723dd --- /dev/null +++ b/test/ELF/linkerscript/Inputs/at3.s @@ -0,0 +1,8 @@ +.section .foo1, "a" +.quad 0 + +.section .foo2, "ax" +.quad 0 + +.section .foo3, "ax" +.quad 0 diff --git a/test/ELF/linkerscript/Inputs/data-commands.s b/test/ELF/linkerscript/Inputs/data-commands.s new file mode 100644 index 000000000000..d5d78cfd9beb --- /dev/null +++ b/test/ELF/linkerscript/Inputs/data-commands.s @@ -0,0 +1,35 @@ +.global a +a = 0x11 + +.global b +b = 0x1122 + +.global c +c = 0x11223344 + +.global d +d = 0x1122334455667788 + +.section .foo.1, "a" + .byte 0xFF + +.section .foo.2, "a" + .byte 0xFF + +.section .foo.3, "a" + .byte 0xFF + +.section .foo.4, "a" + .byte 0xFF + +.section .bar.1, "a" + .byte 0xFF + +.section .bar.2, "a" + .byte 0xFF + +.section .bar.3, "a" + .byte 0xFF + +.section .bar.4, "a" + .byte 0xFF diff --git a/test/ELF/linkerscript/Inputs/data-segment-relro.s b/test/ELF/linkerscript/Inputs/data-segment-relro.s new file mode 100644 index 000000000000..668a2e2ca2a4 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/data-segment-relro.s @@ -0,0 +1,11 @@ +.global _start +_start: + .long bar + jmp *bar2@GOTPCREL(%rip) + +.section .data,"aw" +.quad 0 + +.zero 4 +.section .foo,"aw" +.section .bss,"",@nobits diff --git a/test/ELF/linkerscript/Inputs/define.s b/test/ELF/linkerscript/Inputs/define.s new file mode 100644 index 000000000000..bc60a233dcb4 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/define.s @@ -0,0 +1,8 @@ +.global defined +defined = 0 + +.section .foo,"a" +.quad 1 + +.section .bar,"a" +.quad 1 diff --git a/test/ELF/linkerscript/Inputs/eh-frame-reloc-out-of-range.s b/test/ELF/linkerscript/Inputs/eh-frame-reloc-out-of-range.s new file mode 100644 index 000000000000..19e50488050e --- /dev/null +++ b/test/ELF/linkerscript/Inputs/eh-frame-reloc-out-of-range.s @@ -0,0 +1,11 @@ +.text +.globl _start +_start: + .cfi_startproc + .cfi_lsda 0, _ex + nop + .cfi_endproc + +.data +_ex: + .word 0 diff --git a/test/ELF/linkerscript/Inputs/extend-pt-load.s b/test/ELF/linkerscript/Inputs/extend-pt-load.s new file mode 100644 index 000000000000..8993fb163346 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/extend-pt-load.s @@ -0,0 +1,3 @@ +nop +.section .data.rel.ro, "aw" +.byte 0 diff --git a/test/ELF/linkerscript/Inputs/fill.s b/test/ELF/linkerscript/Inputs/fill.s new file mode 100644 index 000000000000..b8eed890601b --- /dev/null +++ b/test/ELF/linkerscript/Inputs/fill.s @@ -0,0 +1,11 @@ +.text +.globl _start +_start: + +.section .aaa, "a" +.align 1 +.byte 0xAA + +.section .bbb, "a" +.align 1 +.byte 0xBB diff --git a/test/ELF/linkerscript/Inputs/implicit-program-header.script b/test/ELF/linkerscript/Inputs/implicit-program-header.script deleted file mode 100644 index 27dbea84c4e4..000000000000 --- a/test/ELF/linkerscript/Inputs/implicit-program-header.script +++ /dev/null @@ -1,12 +0,0 @@ -PHDRS -{ - ph_write PT_LOAD FLAGS(2); - ph_exec PT_LOAD FLAGS(1); -} - -SECTIONS -{ - .bar : { *(.bar) } : ph_exec - .foo : { *(.foo) } - .text : { *(.text) } : ph_write -} diff --git a/test/ELF/linkerscript/Inputs/insert-after.s b/test/ELF/linkerscript/Inputs/insert-after.s new file mode 100644 index 000000000000..88a6044cc968 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/insert-after.s @@ -0,0 +1,11 @@ +.section .foo.text,"ax" +.quad 0 + +.section .foo.data,"aw" +.quad 0 + +.section .text.1,"ax" +.quad 0 + +.section .data.1,"aw" +.quad 0 diff --git a/test/ELF/linkerscript/Inputs/insert-after.script b/test/ELF/linkerscript/Inputs/insert-after.script new file mode 100644 index 000000000000..cb95878bc5cf --- /dev/null +++ b/test/ELF/linkerscript/Inputs/insert-after.script @@ -0,0 +1,4 @@ +SECTIONS { + .text : { *(.text.*) } + .data : { *(.data.*) } +} diff --git a/test/ELF/linkerscript/Inputs/map-file2.s b/test/ELF/linkerscript/Inputs/map-file2.s new file mode 100644 index 000000000000..daf994eca172 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/map-file2.s @@ -0,0 +1,19 @@ +.global _start +_start: +.global _Z1fi +_Z1fi: +.cfi_startproc +nop +.cfi_endproc + +.section .aaa, "a"; +.quad 1; + +.section .bbb, "a"; +.quad 2; + +.section .ccc, "a"; +.quad 3; + +.section .ddd, "a"; +.quad 4 diff --git a/test/ELF/linkerscript/Inputs/provide-shared2.s b/test/ELF/linkerscript/Inputs/provide-shared2.s new file mode 100644 index 000000000000..f02fd650106a --- /dev/null +++ b/test/ELF/linkerscript/Inputs/provide-shared2.s @@ -0,0 +1,3 @@ +.global foo +.data +.dc.a foo diff --git a/test/ELF/linkerscript/Inputs/sections-va-overflow.s b/test/ELF/linkerscript/Inputs/sections-va-overflow.s new file mode 100644 index 000000000000..6bb049031c7d --- /dev/null +++ b/test/ELF/linkerscript/Inputs/sections-va-overflow.s @@ -0,0 +1,6 @@ +.global _start +_start: + retq + +.bss +.space 0x2000 diff --git a/test/ELF/linkerscript/Inputs/synthetic-symbols.s b/test/ELF/linkerscript/Inputs/synthetic-symbols.s new file mode 100644 index 000000000000..670e65cb80f4 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/synthetic-symbols.s @@ -0,0 +1,16 @@ +.global _start +_start: + nop + +.section .foo,"a" + .quad 0 + +.section .bar,"a" + .long 0 + +.section .dah,"ax",@progbits + .cfi_startproc + nop + .cfi_endproc + +.global _begin_sec, _end_sec, _end_sec_abs diff --git a/test/ELF/linkerscript/absolute-expr.s b/test/ELF/linkerscript/absolute-expr.test index a9a674b859f4..9e8f517d0ac4 100644 --- a/test/ELF/linkerscript/absolute-expr.s +++ b/test/ELF/linkerscript/absolute-expr.test @@ -1,21 +1,19 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { \ -# RUN: .text : { \ -# RUN: bar1 = ALIGNOF(.text); \ -# RUN: bar2 = CONSTANT (MAXPAGESIZE); \ -# RUN: bar3 = SIZEOF (.text); \ -# RUN: bar4 = SIZEOF_HEADERS; \ -# RUN: bar5 = 0x42; \ -# RUN: bar6 = foo + 1; \ -# RUN: *(.text) \ -# RUN: } \ -# RUN: };" > %t.script -# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: echo ".global foo; foo = 0x123" | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o +# RUN: ld.lld -o %t.so --script %s %t.o -shared # RUN: llvm-readobj -t %t.so | FileCheck %s -.global foo -foo = 0x123 +SECTIONS { + .text : { + bar1 = ALIGNOF(.text); + bar2 = CONSTANT (MAXPAGESIZE); + bar3 = SIZEOF (.text); + bar4 = SIZEOF_HEADERS; + bar5 = 0x42; + bar6 = foo + 1; + *(.text) + } +} # CHECK: Symbol { # CHECK: Name: foo diff --git a/test/ELF/linkerscript/addr-zero.s b/test/ELF/linkerscript/addr-zero.test index 71251d3acfff..6253f619381b 100644 --- a/test/ELF/linkerscript/addr-zero.s +++ b/test/ELF/linkerscript/addr-zero.test @@ -1,7 +1,6 @@ # 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-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: ld.lld -o %t.so --script %s %t.o -shared # RUN: llvm-readobj --symbols %t.so | FileCheck %s # Test that the script creates a non absolute symbol with value @@ -9,10 +8,14 @@ # CHECK: Symbol { # CHECK: Name: foo -# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Value: 0x70 # CHECK-NEXT: Size: 0 # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: None # CHECK-NEXT: Other: 0 # CHECK-NEXT: Section: .text # CHECK-NEXT: } + +SECTIONS { + foo = ADDR(.text) - ABSOLUTE(ADDR(.text)); +}; diff --git a/test/ELF/linkerscript/addr.s b/test/ELF/linkerscript/addr.s deleted file mode 100644 index 2d3a7ab35767..000000000000 --- a/test/ELF/linkerscript/addr.s +++ /dev/null @@ -1,32 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { \ -# RUN: . = 0x1000; \ -# RUN: .text : { *(.text*) } \ -# RUN: .foo.1 : { *(.foo.1) } \ -# RUN: .foo.2 ADDR(.foo.1) + 0x100 : { *(.foo.2) } \ -# RUN: .foo.3 : { *(.foo.3) } \ -# RUN: }" > %t.script -# RUN: ld.lld %t --script %t.script -o %t1 -# RUN: llvm-objdump -section-headers %t1 | FileCheck %s - -# CHECK: Sections: -# CHECK-NEXT: Idx Name Size Address Type -# CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 .text 00000000 0000000000001000 TEXT DATA -# CHECK-NEXT: 2 .foo.1 00000008 0000000000001000 DATA -# CHECK-NEXT: 3 .foo.2 00000008 0000000000001100 DATA -# CHECK-NEXT: 4 .foo.3 00000008 0000000000001108 DATA - -.text -.globl _start -_start: - -.section .foo.1,"a" - .quad 1 - -.section .foo.2,"a" - .quad 2 - -.section .foo.3,"a" - .quad 3 diff --git a/test/ELF/linkerscript/addr.test b/test/ELF/linkerscript/addr.test new file mode 100644 index 000000000000..db0568e56c76 --- /dev/null +++ b/test/ELF/linkerscript/addr.test @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/addr.s -o %t +# RUN: ld.lld %t --script %s -o %t1 +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .text 00000000 0000000000001000 TEXT +# CHECK-NEXT: 2 .foo.1 00000008 0000000000001000 DATA +# CHECK-NEXT: 3 .foo.2 00000008 0000000000001100 DATA +# CHECK-NEXT: 4 .foo.3 00000008 0000000000001108 DATA + +SECTIONS { + . = 0x1000; + .text : { *(.text*) } + .foo.1 : { *(.foo.1) } + .foo.2 ADDR(.foo.1) + 0x100 : { *(.foo.2) } + .foo.3 : { *(.foo.3) } +} diff --git a/test/ELF/linkerscript/address-expr-symbols.s b/test/ELF/linkerscript/address-expr-symbols.s new file mode 100644 index 000000000000..0b76c91a5c8b --- /dev/null +++ b/test/ELF/linkerscript/address-expr-symbols.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "SECTIONS { .bar (foo) : { } };" > %t.script +# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s +# CHECK: symbol not found: foo + +# RUN: echo "SECTIONS { .bar : AT(foo) { } };" > %t.script +# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s + +# RUN: echo "SECTIONS { .bar : ALIGN(foo) { } };" > %t.script +# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s + +# RUN: echo "SECTIONS { .bar : SUBALIGN(foo) { } };" > %t.script +# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s diff --git a/test/ELF/linkerscript/align-empty.s b/test/ELF/linkerscript/align-empty.s deleted file mode 100644 index 3ff71578410a..000000000000 --- a/test/ELF/linkerscript/align-empty.s +++ /dev/null @@ -1,18 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: abc : { } \ -# RUN: . = ALIGN(0x1000); \ -# RUN: foo : { *(foo) } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared -# RUN: llvm-objdump -section-headers %t1 | FileCheck %s -# CHECK: Sections: -# CHECK-NEXT: Idx Name Size Address -# CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 foo 00000001 0000000000001000 - - .section foo, "a" - .byte 0 diff --git a/test/ELF/linkerscript/align-empty.test b/test/ELF/linkerscript/align-empty.test new file mode 100644 index 000000000000..63fe32882c0b --- /dev/null +++ b/test/ELF/linkerscript/align-empty.test @@ -0,0 +1,22 @@ +# REQUIRES: x86 +# RUN: echo '.section foo, "a"; .byte 0' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o + +# RUN: ld.lld -o %t1 --script %s %t.o -shared +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s + +SECTIONS { + . = SIZEOF_HEADERS; + abc : {} + . = ALIGN(0x1000); + foo : { *(foo) } +} + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .dynsym 00000018 0000000000000190 +# CHECK-NEXT: 2 .gnu.hash 0000001c 00000000000001a8 +# CHECK-NEXT: 3 .hash 00000010 00000000000001c4 +# CHECK-NEXT: 4 .dynstr 00000001 00000000000001d4 +# CHECK-NEXT: 5 foo 00000001 0000000000001000 diff --git a/test/ELF/linkerscript/align-r.test b/test/ELF/linkerscript/align-r.test new file mode 100644 index 000000000000..684ac1e92328 --- /dev/null +++ b/test/ELF/linkerscript/align-r.test @@ -0,0 +1,21 @@ +# REQUIRES: x86 + +## Check output section ALIGN modifier with -r + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t1.o +# RUN: ld.lld -r -o %t2.o --script %s %t1.o +# RUN: llvm-readelf -s %t2.o | FileCheck %s + +# CHECK: Section Headers: +# CHECK-NEXT: Name Type Address Off Size ES Flg Lk Inf Al +# CHECK-NEXT: NULL 0000000000000000 000000 000000 00 +# CHECK-NEXT: .aaa PROGBITS 0000000000000000 000040 000008 00 A 0 0 1 +# CHECK-NEXT: .bbb PROGBITS 0000000000000000 001000 000008 00 A 0 0 4096 +# CHECK-NEXT: .ccc PROGBITS 0000000000000000 004000 000008 00 A 0 0 16384 + +SECTIONS { + . = 0x10000; + .aaa : { *(.aaa) } + .bbb : ALIGN(4096) { *(.bbb) } + .ccc : ALIGN(4096 * 4) { *(.ccc) } +} diff --git a/test/ELF/linkerscript/align-section-offset.s b/test/ELF/linkerscript/align-section-offset.s deleted file mode 100644 index 9c1603a19853..000000000000 --- a/test/ELF/linkerscript/align-section-offset.s +++ /dev/null @@ -1,11 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { .foo : ALIGN(2M) { *(.foo) } }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -shared -# RUN: llvm-readelf -S -l %t | FileCheck %s - -# CHECK: .foo PROGBITS 0000000000200000 200000 000008 00 WA 0 0 2097152 -# CHECK: LOAD 0x200000 0x0000000000200000 0x0000000000200000 {{.*}} RW 0x200000 - - .section .foo, "aw" - .quad 42 diff --git a/test/ELF/linkerscript/align-section-offset.test b/test/ELF/linkerscript/align-section-offset.test new file mode 100644 index 000000000000..66508c472e94 --- /dev/null +++ b/test/ELF/linkerscript/align-section-offset.test @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: echo '.section .foo, "aw"; .quad 42' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o +# RUN: ld.lld -o %t --script %s %t.o -shared +# RUN: llvm-readelf -S -l %t | FileCheck %s + +SECTIONS { + .foo : ALIGN(2M) { *(.foo) } +} + +# CHECK: .foo PROGBITS 0000000000200000 200000 000008 00 WA 0 0 2097152 +# CHECK: LOAD 0x200000 0x0000000000200000 0x0000000000200000 {{.*}} RW 0x200000 diff --git a/test/ELF/linkerscript/align-section.s b/test/ELF/linkerscript/align-section.s deleted file mode 100644 index d26f15c87329..000000000000 --- a/test/ELF/linkerscript/align-section.s +++ /dev/null @@ -1,6 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { .foo : ALIGN(2M) { } }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -shared - -# We would crash if an empty section had an ALIGN. diff --git a/test/ELF/linkerscript/align-section.test b/test/ELF/linkerscript/align-section.test new file mode 100644 index 000000000000..7a28fef2076e --- /dev/null +++ b/test/ELF/linkerscript/align-section.test @@ -0,0 +1,7 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -o %t --script %s %t.o -shared + +# lld shouldn't crash. + +SECTIONS { .foo : ALIGN(2M) {} } diff --git a/test/ELF/linkerscript/align.s b/test/ELF/linkerscript/align.s deleted file mode 100644 index 99e7382daa59..000000000000 --- a/test/ELF/linkerscript/align.s +++ /dev/null @@ -1,125 +0,0 @@ -# REQUIRES: x86 -# 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 : { *(.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 - -## Check that the two argument version of ALIGN command works -# RUN: echo "SECTIONS { \ -# RUN: . = ALIGN(0x1234, 0x10000); \ -# 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 - -# CHECK: Sections: -# CHECK-NEXT: Idx Name Size Address Type -# CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA -# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA -# CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA - -## Check output sections ALIGN modificator -# 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 %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 .bbb 00000000 __end_bbb - -## Check that ALIGN zero do nothing and does not crash #1. -# RUN: echo "SECTIONS { . = ALIGN(0x123, 0); .aaa : { *(.aaa) } }" > %t.script -# RUN: ld.lld -o %t4 --script %t.script %t -# RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO - -# ZERO: Sections: -# ZERO-NEXT: Idx Name Size Address Type -# ZERO-NEXT: 0 00000000 0000000000000000 -# ZERO-NEXT: 1 .aaa 00000008 0000000000000123 DATA - -## Check that ALIGN zero do nothing and does not crash #2. -# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0); .aaa : { *(.aaa) } }" > %t.script -# RUN: ld.lld -o %t5 --script %t.script %t -# RUN: llvm-objdump -section-headers %t5 | FileCheck %s -check-prefix=ZERO - -## Test we fail gracefuly when alignment value is not a power of 2 (#1). -# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0x123, 3); .aaa : { *(.aaa) } }" > %t.script -# RUN: not ld.lld -o %t6 --script %t.script %t 2>&1 | FileCheck -check-prefix=ERR %s -# ERR: {{.*}}.script:1: alignment must be power of 2 - -## Test we fail gracefuly when alignment value is not a power of 2 (#2). -# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(3); .aaa : { *(.aaa) } }" > %t.script -# RUN: not ld.lld -o %t7 --script %t.script %t 2>&1 | FileCheck -check-prefix=ERR %s - -# RUN: echo "SECTIONS { \ -# RUN: . = 0xff8; \ -# RUN: .aaa : { \ -# RUN: *(.aaa) \ -# RUN: foo = ALIGN(., 0x100); \ -# RUN: bar = .; \ -# RUN: zed1 = ALIGN(., 0x100) + 1; \ -# RUN: zed2 = ALIGN(., 0x100) - 1; \ -# RUN: } \ -# RUN: .bbb : { *(.bbb); } \ -# RUN: .ccc : { *(.ccc); } \ -# RUN: .text : { *(.text); } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=OFFSET %s - -# OFFSET: 0000000000001000 .aaa 00000000 foo -# OFFSET: 0000000000001000 .aaa 00000000 bar -# OFFSET: 0000000000001001 .aaa 00000000 zed1 -# OFFSET: 0000000000000fff .aaa 00000000 zed2 - -.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/align1.test b/test/ELF/linkerscript/align1.test new file mode 100644 index 000000000000..5804bf933740 --- /dev/null +++ b/test/ELF/linkerscript/align1.test @@ -0,0 +1,44 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o +# RUN: ld.lld -o %t --script %s %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +SECTIONS { + . = 0x10000; + .aaa : { *(.aaa) } + . = ALIGN(4096); + .bbb : { *(.bbb) } + . = ALIGN(4096 * 4); + .ccc : { *(.ccc) } +} + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA +# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA +# CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA + +## Check that ALIGN zero do nothing and does not crash #1. +# RUN: echo "SECTIONS { . = ALIGN(0x123, 0); .aaa : { *(.aaa) } }" > %t.script +# RUN: ld.lld -o %t4 --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO + +# ZERO: Sections: +# ZERO-NEXT: Idx Name Size Address Type +# ZERO-NEXT: 0 00000000 0000000000000000 +# ZERO-NEXT: 1 .aaa 00000008 0000000000000123 DATA + +## Check that ALIGN zero do nothing and does not crash #2. +# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0); .aaa : { *(.aaa) } }" > %t.script +# RUN: ld.lld -o %t5 --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t5 | FileCheck %s -check-prefix=ZERO + +## Test we fail gracefuly when alignment value is not a power of 2 (#1). +# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0x123, 3); .aaa : { *(.aaa) } }" > %t.script +# RUN: not ld.lld -o %t6 --script %t.script %t.o 2>&1 | FileCheck -check-prefix=ERR %s + +# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(3); .aaa : { *(.aaa) } }" > %t.script +# RUN: not ld.lld -o %t7 --script %t.script %t.o 2>&1 | FileCheck -check-prefix=ERR %s + +# ERR: {{.*}}.script:1: alignment must be power of 2 diff --git a/test/ELF/linkerscript/align2.test b/test/ELF/linkerscript/align2.test new file mode 100644 index 000000000000..a9003a403d75 --- /dev/null +++ b/test/ELF/linkerscript/align2.test @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o +# RUN: ld.lld -o %t --script %s %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +SECTIONS { + . = ALIGN(0x1234, 0x10000); + .aaa : { *(.aaa) } + . = ALIGN(., 4096); + .bbb : { *(.bbb) } + . = ALIGN(., 4096 * 4); + .ccc : { *(.ccc) } +} + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA +# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA +# CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA diff --git a/test/ELF/linkerscript/align3.test b/test/ELF/linkerscript/align3.test new file mode 100644 index 000000000000..2a091fcbd6bd --- /dev/null +++ b/test/ELF/linkerscript/align3.test @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o +# RUN: ld.lld -o %t --script %s %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +SECTIONS { + . = 0x10000; + .aaa : { *(.aaa) } + .bbb : ALIGN(4096) { *(.bbb) } + .ccc : ALIGN(4096 * 4) { *(.ccc) } +} + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA +# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA +# CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA diff --git a/test/ELF/linkerscript/align4.test b/test/ELF/linkerscript/align4.test new file mode 100644 index 000000000000..9440d60f6385 --- /dev/null +++ b/test/ELF/linkerscript/align4.test @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o +# RUN: ld.lld -o %t --script %s %t.o +# RUN: llvm-objdump -t %t | FileCheck %s + +# CHECK-LABEL: SYMBOL TABLE: +# CHECK-NEXT: 0000000000000000 *UND* 00000000 +# CHECK-NEXT: 0000000000014008 .text 00000000 _start +# CHECK-NEXT: 0000000000010000 *ABS* 00000000 __code_base__ +# CHECK-NEXT: 0000000000001000 *ABS* 00000000 VAR +# CHECK-NEXT: 0000000000011000 .bbb 00000000 __start_bbb +# CHECK-NEXT: 0000000000012000 .bbb 00000000 __end_bbb + +VAR = 0x1000; +__code_base__ = 0x10000; + +SECTIONS { + . = __code_base__; + .aaa : { *(.aaa) } + .bbb : ALIGN(VAR) { *(.bbb) } + . = ALIGN(., VAR * 4); + .ccc : { *(.ccc) } + __start_bbb = ADDR(.bbb); + __end_bbb = ALIGN(__start_bbb + SIZEOF(.bbb), VAR); +} diff --git a/test/ELF/linkerscript/align5.test b/test/ELF/linkerscript/align5.test new file mode 100644 index 000000000000..47b5c8c03490 --- /dev/null +++ b/test/ELF/linkerscript/align5.test @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o +# RUN: ld.lld -o %t --script %s %t.o +# RUN: llvm-objdump -t %t | FileCheck %s + +SECTIONS { + . = 0xff8; + .aaa : { + *(.aaa) + foo = ALIGN(., 0x100); + bar = .; + zed1 = ALIGN(., 0x100) + 1; + zed2 = ALIGN(., 0x100) - 1; + } + .bbb : { *(.bbb); } + .ccc : { *(.ccc); } + .text : { *(.text); } +} + +# CHECK: 0000000000001000 .aaa 00000000 foo +# CHECK: 0000000000001000 .aaa 00000000 bar +# CHECK: 0000000000001001 .aaa 00000000 zed1 +# CHECK: 0000000000000fff .aaa 00000000 zed2 diff --git a/test/ELF/linkerscript/alignof.s b/test/ELF/linkerscript/alignof.s deleted file mode 100644 index 8880634df243..000000000000 --- a/test/ELF/linkerscript/alignof.s +++ /dev/null @@ -1,41 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -# RUN: echo "SECTIONS { \ -# RUN: .aaa : { *(.aaa) } \ -# RUN: .bbb : { *(.bbb) } \ -# RUN: .ccc : { *(.ccc) } \ -# RUN: _aaa = ALIGNOF(.aaa); \ -# RUN: _bbb = ALIGNOF(.bbb); \ -# RUN: _ccc = ALIGNOF(.ccc); \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck %s -# CHECK: SYMBOL TABLE: -# CHECK: 0000000000000008 *ABS* 00000000 _aaa -# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb -# CHECK-NEXT: 0000000000000020 *ABS* 00000000 _ccc - -## Check that we error out if trying to get alignment of -## section that does not exist. -# RUN: echo "SECTIONS { \ -# RUN: _aaa = ALIGNOF(.foo); \ -# RUN: }" > %t.script -# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \ -# RUN: | FileCheck -check-prefix=ERR %s -# ERR: {{.*}}.script:1: undefined section .foo -.global _start -_start: - nop - -.section .aaa,"a" - .align 8 - .quad 0 - -.section .bbb,"a" - .align 16 - .quad 0 - -.section .ccc,"a" - .align 32 - .quad 0 diff --git a/test/ELF/linkerscript/alignof.test b/test/ELF/linkerscript/alignof.test new file mode 100644 index 000000000000..0e3abf6133c9 --- /dev/null +++ b/test/ELF/linkerscript/alignof.test @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/alignof.s -o %t +# RUN: ld.lld -o %t1 --script %s %t +# RUN: llvm-objdump -t %t1 | FileCheck %s +# CHECK: SYMBOL TABLE: +# CHECK: 0000000000000008 *ABS* 00000000 _aaa +# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb +# CHECK-NEXT: 0000000000000020 *ABS* 00000000 _ccc + +SECTIONS { + .aaa : { *(.aaa) } + .bbb : { *(.bbb) } + .ccc : { *(.ccc) } + _aaa = ALIGNOF(.aaa); + _bbb = ALIGNOF(.bbb); + _ccc = ALIGNOF(.ccc); +} + +## Check that we error out if trying to get alignment of +## section that does not exist. +# RUN: echo "SECTIONS { _aaa = ALIGNOF(.foo); }" > %t.script +# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR %s +# ERR: {{.*}}.script:1: undefined section .foo diff --git a/test/ELF/linkerscript/arm-exidx-order.s b/test/ELF/linkerscript/arm-exidx-order.s deleted file mode 100644 index 1ff1711e60be..000000000000 --- a/test/ELF/linkerscript/arm-exidx-order.s +++ /dev/null @@ -1,19 +0,0 @@ -# REQUIRES: arm -# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o -# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ -# RUN: .ARM.exidx : { *(.ARM.exidx*) } \ -# RUN: .foo : { _foo = 0; } }" > %t.script -# RUN: ld.lld -T %t.script %t.o -shared -o %t.so -# RUN: llvm-readobj -s %t.so | FileCheck %s - -# CHECK: Section { -# CHECK: Index: -# CHECK: Name: .foo -# CHECK-NEXT: Type: SHT_NOBITS -# CHECK-NEXT: Flags [ -# CHECK-NEXT: SHF_ALLOC -# CHECK-NEXT: ] - -.fnstart -.cantunwind -.fnend diff --git a/test/ELF/linkerscript/arm-exidx-order.test b/test/ELF/linkerscript/arm-exidx-order.test new file mode 100644 index 000000000000..60abddfd77da --- /dev/null +++ b/test/ELF/linkerscript/arm-exidx-order.test @@ -0,0 +1,19 @@ +# REQUIRES: arm +# RUN: echo ".fnstart; .cantunwind; .fnend" \ +# RUN: | llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi - -o %t.o +# RUN: ld.lld -T %s %t.o -shared -o %t.so +# RUN: llvm-readobj -s %t.so | FileCheck %s + +SECTIONS { + . = SIZEOF_HEADERS; + .ARM.exidx : { *(.ARM.exidx*) } + .foo : { _foo = 0; } +} + +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] diff --git a/test/ELF/linkerscript/arm-exidx-phdrs.s b/test/ELF/linkerscript/arm-exidx-phdrs.s deleted file mode 100644 index 971702f55d7b..000000000000 --- a/test/ELF/linkerscript/arm-exidx-phdrs.s +++ /dev/null @@ -1,16 +0,0 @@ -// REQUIRES: arm -// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o -// RUN: echo "PHDRS { ph_text PT_LOAD; } \ -// RUN: SECTIONS { \ -// RUN: . = SIZEOF_HEADERS; \ -// RUN: .text : { *(.text) } : ph_text \ -// RUN: }" > %t.script -// RUN: ld.lld -T %t.script %t.o -shared -o %t.so -// RUN: llvm-readobj --program-headers %t.so | FileCheck %s - -// CHECK: Type: PT_ARM_EXIDX - -.fnstart -bx lr -.cantunwind -.fnend diff --git a/test/ELF/linkerscript/arm-exidx-phdrs.test b/test/ELF/linkerscript/arm-exidx-phdrs.test new file mode 100644 index 000000000000..208d4d72ad43 --- /dev/null +++ b/test/ELF/linkerscript/arm-exidx-phdrs.test @@ -0,0 +1,13 @@ +# REQUIRES: arm +# RUN: echo ".fnstart; bx lr; .cantunwind; .fnend" \ +# RUN: | llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi - -o %t.o +# RUN: ld.lld -T %s %t.o -shared -o %t.so +# RUN: llvm-readobj --program-headers %t.so | FileCheck %s + +# CHECK: Type: PT_ARM_EXIDX + +PHDRS { ph_text PT_LOAD; } +SECTIONS { + . = SIZEOF_HEADERS; + .text : { *(.text) } : ph_text +} diff --git a/test/ELF/linkerscript/arm-lscript.s b/test/ELF/linkerscript/arm-lscript.s deleted file mode 100644 index c377764e9776..000000000000 --- a/test/ELF/linkerscript/arm-lscript.s +++ /dev/null @@ -1,9 +0,0 @@ -// REQUIRES: arm -// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o -// RUN: echo "SECTIONS { \ -// RUN: .rel.dyn : { } \ -// RUN: .zed : { PROVIDE_HIDDEN (foobar = .); } \ -// RUN: }" > %t.script -// This is a test case for PR33029. Making sure that linker can digest -// the above script without dumping core. -// RUN: ld.lld -emit-relocs -T %t.script %t.o -shared -o %t.so diff --git a/test/ELF/linkerscript/arm-lscript.test b/test/ELF/linkerscript/arm-lscript.test new file mode 100644 index 000000000000..af2e6316ea43 --- /dev/null +++ b/test/ELF/linkerscript/arm-lscript.test @@ -0,0 +1,11 @@ +# REQUIRES: arm +# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi /dev/null -o %t.o + +# This is a test case for PR33029. Making sure that linker can digest +# the above script without dumping core. +# RUN: ld.lld -emit-relocs -T %s %t.o -shared -o %t.so + +SECTIONS { + .rel.dyn : {} + .zed : { PROVIDE_HIDDEN (foobar = .); } +} diff --git a/test/ELF/linkerscript/assert.s b/test/ELF/linkerscript/assert.s index 73cc940669b9..f7113e5b25f0 100644 --- a/test/ELF/linkerscript/assert.s +++ b/test/ELF/linkerscript/assert.s @@ -6,7 +6,7 @@ # RUN: llvm-readobj %t1 > /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: not ld.lld -shared -o /dev/null --script %t3.script %t1.o > %t.log 2>&1 # RUN: FileCheck %s -check-prefix=FAIL < %t.log # FAIL: fail @@ -30,10 +30,11 @@ # RUN: ld.lld -shared -o %t6 --script %t6.script %t1.o # RUN: llvm-readobj %t6 > /dev/null +## Unlike the GNU ld, we accept the ASSERT without the semicolon. +## It is consistent with how ASSERT can be written outside of the +## output section declaration. # RUN: echo "SECTIONS { .foo : { ASSERT(1, \"true\") } }" > %t7.script -# RUN: not ld.lld -shared -o %t7 --script %t7.script %t1.o > %t.log 2>&1 -# RUN: FileCheck %s -check-prefix=CHECK-SEMI < %t.log -# CHECK-SEMI: error: {{.*}}.script:1: ; expected, but got } +# RUN: ld.lld -shared -o /dev/null --script %t7.script %t1.o .section .foo, "a" .quad 0 diff --git a/test/ELF/linkerscript/at-self-reference.s b/test/ELF/linkerscript/at-self-reference.s new file mode 100644 index 000000000000..7208a4b9fcd4 --- /dev/null +++ b/test/ELF/linkerscript/at-self-reference.s @@ -0,0 +1,63 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: . = 0x1000; \ +# RUN: .aaa : AT(ADDR(.aaa)) { *(.aaa) } \ +# RUN: .bbb : AT(ADDR(.bbb)) { *(.bbb) } \ +# RUN: }" > %t.script +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-readobj -program-headers %t2 | FileCheck %s + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 3 +# CHECK-NEXT: MemSize: 3 +# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1008 +# CHECK-NEXT: VirtualAddress: 0x1008 +# CHECK-NEXT: PhysicalAddress: 0x1008 +# CHECK-NEXT: FileSize: 9 +# CHECK-NEXT: MemSize: 9 +# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x0 +# CHECK-NEXT: PhysicalAddress: 0x0 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: Flags [ (0x6) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_W (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: } +# CHECK-NEXT:] + +.global _start +_start: + nop + + +.section .aaa, "a" +.asciz "aa" + +.section .bbb, "a" +.align 8 +.quad 0 diff --git a/test/ELF/linkerscript/at2.test b/test/ELF/linkerscript/at2.test new file mode 100644 index 000000000000..82c9ae1d2252 --- /dev/null +++ b/test/ELF/linkerscript/at2.test @@ -0,0 +1,58 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/at2.s -o %t.o +# RUN: ld.lld -o %t.exe %t.o --script %s +# RUN: llvm-readobj -program-headers %t.exe | FileCheck %s +# RUN: llvm-objdump -section-headers %t.exe | FileCheck %s --check-prefix=SECTIONS + +MEMORY { + AX (ax) : ORIGIN = 0x2000, LENGTH = 0x100 + AW (aw) : ORIGIN = 0x3000, LENGTH = 0x100 + FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x100 + RAM (aw) : ORIGIN = 0x7000, LENGTH = 0x100 +} + +SECTIONS { + .foo1 : { *(.foo1) } > AX AT>FLASH + .foo2 : { *(.foo2) } > AX + .bar1 : { *(.bar1) } > AW AT> RAM + .bar2 : { *(.bar2) } > AW AT > RAM + .bar3 : { *(.bar3) } > AW AT >RAM +} + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x2000 +# CHECK-NEXT: PhysicalAddress: 0x6000 +# CHECK-NEXT: FileSize: 16 +# CHECK-NEXT: MemSize: 16 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_X +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: VirtualAddress: 0x3000 +# CHECK-NEXT: PhysicalAddress: 0x7000 +# CHECK-NEXT: FileSize: 24 +# CHECK-NEXT: MemSize: 24 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_W +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } + +# SECTIONS: Sections: +# SECTIONS-NEXT: Idx Name Size Address +# SECTIONS-NEXT: 0 00000000 0000000000000000 +# SECTIONS-NEXT: 1 .foo1 00000008 0000000000002000 +# SECTIONS-NEXT: 2 .foo2 00000008 0000000000002008 +# SECTIONS-NEXT: 3 .text 00000000 0000000000002010 +# SECTIONS-NEXT: 4 .bar1 00000008 0000000000003000 +# SECTIONS-NEXT: 5 .bar2 00000008 0000000000003008 +# SECTIONS-NEXT: 6 .bar3 00000008 0000000000003010 diff --git a/test/ELF/linkerscript/at3.test b/test/ELF/linkerscript/at3.test new file mode 100644 index 000000000000..6344f38b304d --- /dev/null +++ b/test/ELF/linkerscript/at3.test @@ -0,0 +1,31 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at3.s -o %t.o +# RUN: ld.lld %t.o --script %s -o %t +# RUN: llvm-readelf -sections -program-headers %t | FileCheck %s + +MEMORY { + FOO (ax) : ORIGIN = 0x1000, LENGTH = 0x100 + BAR (ax) : ORIGIN = 0x2000, LENGTH = 0x100 + ZED (ax) : ORIGIN = 0x3000, LENGTH = 0x100 + FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x200 +} + +SECTIONS { + .foo1 : { *(.foo1) } > FOO AT>FLASH + .foo2 : { *(.foo2) BYTE(0x42) } > BAR AT>FLASH + .foo3 : { *(.foo3) } > ZED AT>FLASH +} + +# CHECK: .foo1 PROGBITS 0000000000001000 001000 +# CHECK: .foo2 PROGBITS 0000000000002000 002000 +# CHECK: .foo3 PROGBITS 0000000000003000 003000 + +# CHECK: Program Headers: +# CHECK-NOT: LOAD + +# CHECK: Type Offset VirtAddr PhysAddr +# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000006000 +# CHECK-NEXT: LOAD 0x002000 0x0000000000002000 0x0000000000006008 +# CHECK-NEXT: LOAD 0x003000 0x0000000000003000 0x0000000000006011 + +# CHECK-NOT: LOAD diff --git a/test/ELF/linkerscript/at4.s b/test/ELF/linkerscript/at4.s new file mode 100644 index 000000000000..a6fa50820376 --- /dev/null +++ b/test/ELF/linkerscript/at4.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: . = 0x1000; \ +# RUN: .aaa : { *(.aaa) } \ +# RUN: .bbb : AT(0x2008) { *(.bbb) } \ +# RUN: .ccc : { *(.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: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1008 +# CHECK-NEXT: VirtualAddress: 0x1008 +# CHECK-NEXT: PhysicalAddress: 0x2008 +# CHECK-NEXT: FileSize: 17 +# CHECK-NEXT: MemSize: 17 + +.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/at5.test b/test/ELF/linkerscript/at5.test new file mode 100644 index 000000000000..8e1ed93bcad9 --- /dev/null +++ b/test/ELF/linkerscript/at5.test @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld -o %t.exe %t.o --script %s 2>&1 | FileCheck %s + +MEMORY { + FLASH (ax) : ORIGIN = 0x2000, LENGTH = 0x100 + RAM (aw) : ORIGIN = 0x5000, LENGTH = 0x100 +} + +SECTIONS { + .foo1 : AT(0x500) { *(.foo1) } > FLASH AT>FLASH +} + +# CHECK: error: section can't have both LMA and a load region diff --git a/test/ELF/linkerscript/broken-memory-declaration.s b/test/ELF/linkerscript/broken-memory-declaration.s new file mode 100644 index 000000000000..197c9cd22b6d --- /dev/null +++ b/test/ELF/linkerscript/broken-memory-declaration.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 + +## Check we do not crash. + +# RUN: echo "MEMORY { FLASH (rx) : ORIGIN = 0x1000< LENGTH" > %t.script +# RUN: not ld.lld -o %t --script %t.script 2>&1 | FileCheck %s +# CHECK: unexpected EOF + +# RUN: echo "MEMORY { FLASH (rx) : ORIGIN = 0x1000< ORIGIN" > %t.script +# RUN: not ld.lld -o %t --script %t.script 2>&1 | FileCheck %s + +# RUN: echo "MEMORY { FLASH (rx) : ORIGIN = 0x1000, LENGTH = CONSTANT" > %t.script +# RUN: not ld.lld -o %t --script %t.script 2>&1 | FileCheck %s diff --git a/test/ELF/linkerscript/bss-fill.s b/test/ELF/linkerscript/bss-fill.s deleted file mode 100644 index 92f9fdf56190..000000000000 --- a/test/ELF/linkerscript/bss-fill.s +++ /dev/null @@ -1,7 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: echo "SECTIONS { .bss : { . += 0x10000; *(.bss) } =0xFF };" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o - -.section .bss,"",@nobits -.short 0 diff --git a/test/ELF/linkerscript/bss-fill.test b/test/ELF/linkerscript/bss-fill.test new file mode 100644 index 000000000000..b7ed47656172 --- /dev/null +++ b/test/ELF/linkerscript/bss-fill.test @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: echo '.section .bss,"",@nobits; .short 0' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: ld.lld -o %t --script %s %t.o + +## Check we do not crash. + +SECTIONS { + .bss : { + . += 0x10000; + *(.bss) + } =0xFF +} diff --git a/test/ELF/linkerscript/common-filespec.s b/test/ELF/linkerscript/common-filespec.test index 25bb486ed445..2afd91d3d5b7 100644 --- a/test/ELF/linkerscript/common-filespec.s +++ b/test/ELF/linkerscript/common-filespec.test @@ -1,11 +1,17 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile0.o +# RUN: echo '.long 0; .comm common_uniq_0,4,4; .comm common_multiple,8,8' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tfile0.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec1.s -o %tfile1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec2.s -o %tfile2.o -# RUN: echo "SECTIONS { .common_0 : { *file0.o(COMMON) } .common_1 : { *file1.o(COMMON) } .common_2 : { *file2.o(COMMON) } }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %tfile0.o %tfile1.o %tfile2.o +# RUN: ld.lld -o %t1 --script %s %tfile0.o %tfile1.o %tfile2.o # RUN: llvm-readobj -s -t %t1 | FileCheck %s +SECTIONS { + .common_0 : { *file0.o(COMMON) } + .common_1 : { *file1.o(COMMON) } + .common_2 : { *file2.o(COMMON) } +} + # Make sure all 3 sections are allocated and they have sizes and alignments # corresponding to the commons assigned to them # CHECK: Section { @@ -96,10 +102,3 @@ # CHECK-NEXT: Other: 0 # CHECK-NEXT: Section: .common_2 # CHECK-NEXT: } - -.globl _start -_start: - jmp _start - -.comm common_uniq_0,4,4 -.comm common_multiple,8,8 diff --git a/test/ELF/linkerscript/compress-debug-sections-custom.s b/test/ELF/linkerscript/compress-debug-sections-custom.s new file mode 100644 index 000000000000..31fdd56381b0 --- /dev/null +++ b/test/ELF/linkerscript/compress-debug-sections-custom.s @@ -0,0 +1,35 @@ +# REQUIRES: x86, zlib + +# RUN: echo "SECTIONS { \ +# RUN: .text : { . += 0x10; *(.text) } \ +# RUN: .debug_str : { . += 0x10; *(.debug_str) } \ +# RUN: .debug_info : { . += 0x10; *(.debug_info) } \ +# RUN: }" > %t.script + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/../Inputs/compress-debug.s -o %t2.o +# RUN: ld.lld %t2.o %t.o -o %t1 --compress-debug-sections=zlib -T %t.script +# RUN: llvm-dwarfdump %t1 -debug-str | FileCheck %s +# These two checks correspond to the patched values of a_sym and a_debug_sym. +# T = 0x54 - address of .text input section for this file (the start address of +# .text is 0 by default, the size of the preceding .text in the other input +# file is 0x44, and the linker script adds an additional 0x10). +# S = 0x53 - offset of .debug_info section for this file (the size of +# the preceding .debug_info from the other input file is 0x43, and the +# linker script adds an additional 0x10). +# Also note that the .debug_str offsets are also offset by 0x10, as directed by +# the linker script. +# CHECK: 0x00000010: "T" +# CHECK: 0x00000014: "S" + +.text +a_sym: +nop + +.section .debug_str,"",@progbits +.long a_sym +.long a_debug_sym + +.section .debug_info,"",@progbits +a_debug_sym: +.long 0x88776655 diff --git a/test/ELF/linkerscript/constructor.s b/test/ELF/linkerscript/constructor.test index acb86fd88e27..edd2cd297997 100644 --- a/test/ELF/linkerscript/constructor.s +++ b/test/ELF/linkerscript/constructor.test @@ -1,7 +1,7 @@ # 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: echo '.section foo, "a"; .byte 0' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: ld.lld -o %t1 --script %s %t.o # RUN: llvm-objdump -section-headers %t1 | FileCheck %s # CHECK: Sections: @@ -9,5 +9,9 @@ # CHECK-NEXT: 0 00000000 # CHECK-NEXT: 1 foo 00000001 -.section foo, "a" -.byte 0 +SECTIONS { + foo : { + *(.foo) + CONSTRUCTORS + } +} diff --git a/test/ELF/linkerscript/copy-rel-symbol-value-err.s b/test/ELF/linkerscript/copy-rel-symbol-value-err.s index f134edbb1d0c..cd5262b142f5 100644 --- a/test/ELF/linkerscript/copy-rel-symbol-value-err.s +++ b/test/ELF/linkerscript/copy-rel-symbol-value-err.s @@ -3,7 +3,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-symbol-value.s -o %t2.o # RUN: ld.lld %t2.o -o %t2.so -shared # RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; foo = bar; }" > %t.script -# RUN: not ld.lld %t.o %t2.so --script %t.script -o %t 2>&1 | FileCheck %s +# RUN: not ld.lld %t.o %t2.so --script %t.script -o /dev/null 2>&1 | FileCheck %s # CHECK: symbol not found: bar diff --git a/test/ELF/linkerscript/data-commands-gc.s b/test/ELF/linkerscript/data-commands-gc.s index 1afcc9a3bb81..6d5ae8c9ef9d 100644 --- a/test/ELF/linkerscript/data-commands-gc.s +++ b/test/ELF/linkerscript/data-commands-gc.s @@ -4,7 +4,7 @@ # RUN: ld.lld --gc-sections -o %t %t.o --script %t.script # RUN: llvm-objdump -t %t | FileCheck %s -# CHECK: 0000000000000011 .rodata 00000000 bar +# CHECK: 0000000000000008 .rodata 00000000 bar .section .rodata.bar .quad 0x1122334455667788 diff --git a/test/ELF/linkerscript/data-commands.s b/test/ELF/linkerscript/data-commands.s deleted file mode 100644 index 5a5655620dd9..000000000000 --- a/test/ELF/linkerscript/data-commands.s +++ /dev/null @@ -1,117 +0,0 @@ -# REQUIRES: x86,mips -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: echo "SECTIONS \ -# RUN: { \ -# RUN: .foo : { \ -# RUN: *(.foo.1) \ -# RUN: BYTE(0x11) \ -# RUN: *(.foo.2) \ -# RUN: SHORT(0x1122) \ -# RUN: *(.foo.3) \ -# RUN: LONG(0x11223344) \ -# RUN: *(.foo.4) \ -# RUN: QUAD(0x1122334455667788) \ -# RUN: } \ -# RUN: .bar : { \ -# RUN: *(.bar.1) \ -# RUN: BYTE(a + 1) \ -# RUN: *(.bar.2) \ -# RUN: SHORT(b) \ -# RUN: *(.bar.3) \ -# RUN: LONG(c + 2) \ -# RUN: *(.bar.4) \ -# RUN: QUAD(d) \ -# RUN: } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t %t.o --script %t.script -# RUN: llvm-objdump -s %t | FileCheck %s - -# CHECK: Contents of section .foo: -# CHECK-NEXT: ff11ff22 11ff4433 2211ff88 77665544 -# CHECK-NEXT: 332211 - -# CHECK: Contents of section .bar: -# CHECK-NEXT: ff12ff22 11ff4633 2211ff88 77665544 -# CHECK-NEXT: 332211 - -# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %tmips64be -# RUN: ld.lld --script %t.script %tmips64be -o %t2 -# RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=BE -# BE: Contents of section .foo: -# BE-NEXT: ff11ff11 22ff1122 3344ff11 22334455 -# BE-NEXT: 667788 -# BE-NEXT: Contents of section .bar: -# BE-NEXT: ff12ff11 22ff1122 3346ff11 22334455 -# BE-NEXT: 667788 - -# RUN: echo "MEMORY { \ -# RUN: rom (rwx) : ORIGIN = 0x00, LENGTH = 2K \ -# RUN: } \ -# RUN: SECTIONS { \ -# RUN: .foo : { \ -# RUN: *(.foo.1) \ -# RUN: BYTE(0x11) \ -# RUN: *(.foo.2) \ -# RUN: SHORT(0x1122) \ -# RUN: *(.foo.3) \ -# RUN: LONG(0x11223344) \ -# RUN: *(.foo.4) \ -# RUN: QUAD(0x1122334455667788) \ -# RUN: } > rom \ -# RUN: .bar : { \ -# RUN: *(.bar.1) \ -# RUN: BYTE(a + 1) \ -# RUN: *(.bar.2) \ -# RUN: SHORT(b) \ -# RUN: *(.bar.3) \ -# RUN: LONG(c + 2) \ -# RUN: *(.bar.4) \ -# RUN: QUAD(d) \ -# RUN: } > rom \ -# RUN: }" > %t-memory.script -# RUN: ld.lld -o %t-memory %t.o --script %t-memory.script -# RUN: llvm-objdump -s %t-memory | FileCheck %s --check-prefix=MEM - -# MEM: Contents of section .foo: -# MEM-NEXT: 0000 ff11ff22 11ff4433 2211ff88 77665544 -# MEM-NEXT: 0010 332211 - -# MEM: Contents of section .bar: -# MEM-NEXT: 0013 ff12ff22 11ff4633 2211ff88 77665544 -# MEM-NEXT: 0023 332211 - -.global a -a = 0x11 - -.global b -b = 0x1122 - -.global c -c = 0x11223344 - -.global d -d = 0x1122334455667788 - -.section .foo.1, "a" - .byte 0xFF - -.section .foo.2, "a" - .byte 0xFF - -.section .foo.3, "a" - .byte 0xFF - -.section .foo.4, "a" - .byte 0xFF - -.section .bar.1, "a" - .byte 0xFF - -.section .bar.2, "a" - .byte 0xFF - -.section .bar.3, "a" - .byte 0xFF - -.section .bar.4, "a" - .byte 0xFF diff --git a/test/ELF/linkerscript/data-commands1.test b/test/ELF/linkerscript/data-commands1.test new file mode 100644 index 000000000000..32c5978c30a8 --- /dev/null +++ b/test/ELF/linkerscript/data-commands1.test @@ -0,0 +1,45 @@ +# REQUIRES: x86,mips +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/data-commands.s -o %t.o +# RUN: ld.lld -o %t %t.o --script %s +# RUN: llvm-objdump -s %t | FileCheck %s + +SECTIONS { + .foo : { + *(.foo.1) + BYTE(0x11) + *(.foo.2) + SHORT(0x1122) + *(.foo.3) + LONG(0x11223344) + *(.foo.4) + QUAD(0x1122334455667788) + } + .bar : { + *(.bar.1) + BYTE(a + 1) + *(.bar.2) + SHORT(b) + *(.bar.3) + LONG(c + 2) + *(.bar.4) + QUAD(d) + } +} + +# CHECK: Contents of section .foo: +# CHECK-NEXT: ff11ff22 11ff4433 2211ff88 77665544 +# CHECK-NEXT: 332211 + +# CHECK: Contents of section .bar: +# CHECK-NEXT: ff12ff22 11ff4633 2211ff88 77665544 +# CHECK-NEXT: 332211 + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %p/Inputs/data-commands.s -o %t2.o +# RUN: ld.lld --script %s %t2.o -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=BIGENDIAN %s +# BIGENDIAN: Contents of section .foo: +# BIGENDIAN-NEXT: ff11ff11 22ff1122 3344ff11 22334455 +# BIGENDIAN-NEXT: 667788 +# BIGENDIAN-NEXT: Contents of section .bar: +# BIGENDIAN-NEXT: ff12ff11 22ff1122 3346ff11 22334455 +# BIGENDIAN-NEXT: 667788 diff --git a/test/ELF/linkerscript/data-commands2.test b/test/ELF/linkerscript/data-commands2.test new file mode 100644 index 000000000000..e1efa35965cb --- /dev/null +++ b/test/ELF/linkerscript/data-commands2.test @@ -0,0 +1,40 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/data-commands.s -o %t.o +# RUN: ld.lld -o %t %t.o --script %s +# RUN: llvm-objdump -s %t | FileCheck %s + +MEMORY { + rom (rwx) : ORIGIN = 0x00, LENGTH = 2K +} + +SECTIONS { + .foo : { + *(.foo.1) + BYTE(0x11) + *(.foo.2) + SHORT(0x1122) + *(.foo.3) + LONG(0x11223344) + *(.foo.4) + QUAD(0x1122334455667788) + } > rom + + .bar : { + *(.bar.1) + BYTE(a + 1) + *(.bar.2) + SHORT(b) + *(.bar.3) + LONG(c + 2) + *(.bar.4) + QUAD(d) + } > rom +} + +# CHECK: Contents of section .foo: +# CHECK-NEXT: 0000 ff11ff22 11ff4433 2211ff88 77665544 +# CHECK-NEXT: 0010 332211 + +# CHECK: Contents of section .bar: +# CHECK-NEXT: 0013 ff12ff22 11ff4633 2211ff88 77665544 +# CHECK-NEXT: 0023 332211 diff --git a/test/ELF/linkerscript/data-segment-relro.s b/test/ELF/linkerscript/data-segment-relro.test index e835f42e22c6..aeaf08540871 100644 --- a/test/ELF/linkerscript/data-segment-relro.s +++ b/test/ELF/linkerscript/data-segment-relro.test @@ -1,29 +1,37 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/data-segment-relro.s -o %t1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o # RUN: ld.lld -shared %t2.o -o %t2.so -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: .plt : { *(.plt) } \ -# RUN: .text : { *(.text) } \ -# RUN: . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \ -# RUN: .dynamic : { *(.dynamic) } \ -# RUN: .got : { *(.got) } \ -# RUN: . = DATA_SEGMENT_RELRO_END (1 ? 24 : 0, .); \ -# RUN: .got.plt : { *(.got.plt) } \ -# RUN: .data : { *(.data) } \ -# RUN: .bss : { *(.bss) } \ -# RUN: . = DATA_SEGMENT_END (.); \ -# RUN: }" > %t.script - ## With relro or without DATA_SEGMENT_RELRO_END just aligns to ## page boundary. -# RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %t.script -o %t + +# RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %s -o %t # RUN: llvm-readobj -s %t | FileCheck %s -# RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %t.script -o %t2 + +# RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %s -o %t2 # RUN: llvm-readobj -s %t2 | FileCheck %s +SECTIONS { + . = SIZEOF_HEADERS; + + .plt : { *(.plt) } + .text : { *(.text) } + + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + + .dynamic : { *(.dynamic) } + .got : { *(.got) } + + . = DATA_SEGMENT_RELRO_END (1 ? 24 : 0, .); + + .got.plt : { *(.got.plt) } + .data : { *(.data) } + .bss : { *(.bss) } + + . = DATA_SEGMENT_END (.); +} + # CHECK: Section { # CHECK: Index: # CHECK: Name: .got @@ -56,15 +64,3 @@ # CHECK-NEXT: AddressAlignment: # CHECK-NEXT: EntrySize: # CHECK-NEXT: } - -.global _start -_start: - .long bar - jmp *bar2@GOTPCREL(%rip) - -.section .data,"aw" -.quad 0 - -.zero 4 -.section .foo,"aw" -.section .bss,"",@nobits diff --git a/test/ELF/linkerscript/define.s b/test/ELF/linkerscript/define.s deleted file mode 100644 index b5f0b76e9e6b..000000000000 --- a/test/ELF/linkerscript/define.s +++ /dev/null @@ -1,25 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -# RUN: echo "SECTIONS \ -# RUN: { \ -# RUN: . = DEFINED(defined) ? 0x11000 : .; \ -# RUN: .foo : { *(.foo*) } \ -# RUN: . = DEFINED(notdefined) ? 0x12000 : 0x13000; \ -# RUN: .bar : { *(.bar*) } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -section-headers %t1 | FileCheck %s - -# CHECK: 1 .foo 00000008 0000000000011000 DATA -# CHECK: 2 .bar 00000008 0000000000013000 DATA -# CHECK: 3 .text 00000000 0000000000013008 TEXT DATA - -.global defined -defined = 0 - -.section .foo,"a" -.quad 1 - -.section .bar,"a" -.quad 1 diff --git a/test/ELF/linkerscript/define.test b/test/ELF/linkerscript/define.test new file mode 100644 index 000000000000..3a2e242e015c --- /dev/null +++ b/test/ELF/linkerscript/define.test @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/define.s -o %t.o +# RUN: ld.lld -o %t --script %s %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +SECTIONS { + . = DEFINED(defined) ? 0x11000 : .; + .foo : { *(.foo*) } + . = DEFINED(notdefined) ? 0x12000 : 0x13000; + .bar : { *(.bar*) } +} + +# CHECK: 1 .foo 00000008 0000000000011000 DATA +# CHECK: 2 .bar 00000008 0000000000013000 DATA +# CHECK: 3 .text 00000000 0000000000013008 TEXT diff --git a/test/ELF/linkerscript/defsym.s b/test/ELF/linkerscript/defsym.s new file mode 100644 index 000000000000..467adaeea2f8 --- /dev/null +++ b/test/ELF/linkerscript/defsym.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "foo = 0x22;" > %t.script + +## This testcase checks that we apply -defsym and linker script +## in the same order are they specified in a command line. + +## Check that linker script can override -defsym assignments. +# RUN: ld.lld %t.o -defsym=foo=0x11 -script %t.script -o %t +# RUN: llvm-readobj -t %t | FileCheck %s +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x22 + +## Check that -defsym can override linker script. Check that multiple +## -defsym commands for the same symbol are allowed. +# RUN: ld.lld %t.o -script %t.script -defsym=foo=0x11 -defsym=foo=0x33 -o %t +# RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=REORDER +# REORDER: Name: foo +# REORDER-NEXT: Value: 0x33 diff --git a/test/ELF/linkerscript/diag1.test b/test/ELF/linkerscript/diag1.test new file mode 100644 index 000000000000..73a627ff4ef5 --- /dev/null +++ b/test/ELF/linkerscript/diag1.test @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck -strict-whitespace %s + +SECTIONS { + .text + { *(.text) } + .keep : { *(.keep) } /* + comment line 1 + comment line 2 */ + .temp : { *(.temp) } +} + +CHECK: 6: malformed number: + +CHECK-NEXT: >>> .text + { *(.text) } +CHECK-NEXT: >>> ^ diff --git a/test/ELF/linkerscript/diag2.test b/test/ELF/linkerscript/diag2.test new file mode 100644 index 000000000000..05cd4c3a752a --- /dev/null +++ b/test/ELF/linkerscript/diag2.test @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck -strict-whitespace %s + +UNKNOWN_TAG { + .text : { *(.text) } + .keep : { *(.keep) } + .temp : { *(.temp) } +} + +CHECK: 5: unknown directive: UNKNOWN_TAG +CHECK-NEXT: >>> UNKNOWN_TAG { +CHECK-NEXT: >>> ^ diff --git a/test/ELF/linkerscript/diag3.test b/test/ELF/linkerscript/diag3.test new file mode 100644 index 000000000000..8ffc9d4d864c --- /dev/null +++ b/test/ELF/linkerscript/diag3.test @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck -strict-whitespace %s + +SECTIONS { + .text : { *(.text) } + .keep : { *(.keep) } + boom .temp : { *(.temp) } +} + +# CHECK: 8: malformed number: .temp +# CHECK-NEXT: >>> boom .temp : { *(.temp) } +# CHECK-NEXT: >>> ^ diff --git a/test/ELF/linkerscript/diag4.test b/test/ELF/linkerscript/diag4.test new file mode 100644 index 000000000000..484bdf26fe72 --- /dev/null +++ b/test/ELF/linkerscript/diag4.test @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: echo "INCLUDE \"%s\"" > %t.script +# RUN: not ld.lld -shared %t.o -o %t --script %t.script 2>&1 | FileCheck -strict-whitespace %s + +SECTIONS { + .text : { *(.text) } + .keep : { *(.keep) } + boom .temp : { *(.temp) } +} + +# CHECK: 9: malformed number: .temp +# CHECK-NEXT: >>> boom .temp : { *(.temp) } +# CHECK-NEXT: >>> ^
\ No newline at end of file diff --git a/test/ELF/linkerscript/diag5.test b/test/ELF/linkerscript/diag5.test new file mode 100644 index 000000000000..38a774e747ab --- /dev/null +++ b/test/ELF/linkerscript/diag5.test @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: echo "INCLUDE \"%s\"" > %t.script +# RUN: not ld.lld -shared %t.o -o %t --script %t.script 2>&1 | FileCheck -strict-whitespace %s + +SECTIONS { + .text : { *(.text) } + .keep : { *(.keep) } + boom .temp : { *(.temp) } +} + +# CHECK: 9: malformed number: .temp +# CHECK-NEXT: >>> boom .temp : { *(.temp) } +# CHECK-NEXT: >>> ^ diff --git a/test/ELF/linkerscript/diag6.test b/test/ELF/linkerscript/diag6.test new file mode 100644 index 000000000000..e4ad4d96d1dd --- /dev/null +++ b/test/ELF/linkerscript/diag6.test @@ -0,0 +1,7 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck %s + +SECTIONS /* + +CHECK: error: unclosed comment in a linker script diff --git a/test/ELF/linkerscript/diagnostic.s b/test/ELF/linkerscript/diagnostic.s deleted file mode 100644 index af185729c430..000000000000 --- a/test/ELF/linkerscript/diagnostic.s +++ /dev/null @@ -1,106 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -## Take some valid script with multiline comments -## and check it actually works: -# RUN: echo "SECTIONS {" > %t.script -# RUN: echo ".text : { *(.text) }" >> %t.script -# RUN: echo ".keep : { *(.keep) } /*" >> %t.script -# RUN: echo "comment line 1" >> %t.script -# RUN: echo "comment line 2 */" >> %t.script -# RUN: echo ".temp : { *(.temp) } }" >> %t.script -# RUN: ld.lld -shared %t -o %t1 --script %t.script - -## Change ":" to "+" at line 2, check that error -## message starts from correct line number: -# RUN: echo "SECTIONS {" > %t.script -# RUN: echo ".text + { *(.text) }" >> %t.script -# RUN: echo ".keep : { *(.keep) } /*" >> %t.script -# RUN: echo "comment line 1" >> %t.script -# RUN: echo "comment line 2 */" >> %t.script -# RUN: echo ".temp : { *(.temp) } }" >> %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR1 %s -# ERR1: {{.*}}.script:2: - -## Change ":" to "+" at line 3 now, check correct error line number: -# RUN: echo "SECTIONS {" > %t.script -# RUN: echo ".text : { *(.text) }" >> %t.script -# RUN: echo ".keep + { *(.keep) } /*" >> %t.script -# RUN: echo "comment line 1" >> %t.script -# RUN: echo "comment line 2 */" >> %t.script -# RUN: echo ".temp : { *(.temp) } }" >> %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR2 %s -# ERR2: {{.*}}.script:3: - -## Change ":" to "+" at line 6, after multiline comment, -## check correct error line number: -# RUN: echo "SECTIONS {" > %t.script -# RUN: echo ".text : { *(.text) }" >> %t.script -# RUN: echo ".keep : { *(.keep) } /*" >> %t.script -# RUN: echo "comment line 1" >> %t.script -# RUN: echo "comment line 2 */" >> %t.script -# RUN: echo ".temp + { *(.temp) } }" >> %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR5 %s -# ERR5: {{.*}}.script:6: - -## Check that text of lines and pointer to 'bad' token are working ok. -# RUN: echo "UNKNOWN_TAG {" > %t.script -# RUN: echo ".text : { *(.text) }" >> %t.script -# RUN: echo ".keep : { *(.keep) }" >> %t.script -# RUN: echo ".temp : { *(.temp) } }" >> %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ -# RUN: FileCheck -check-prefix=ERR6 -strict-whitespace %s -# ERR6: error: {{.*}}.script:1: unknown directive: UNKNOWN_TAG -# ERR6-NEXT: >>> UNKNOWN_TAG { -# ERR6-NEXT: >>> ^ - -## One more check that text of lines and pointer to 'bad' token are working ok. -# RUN: echo "SECTIONS {" > %t.script -# RUN: echo ".text : { *(.text) }" >> %t.script -# RUN: echo ".keep : { *(.keep) }" >> %t.script -# RUN: echo "boom .temp : { *(.temp) } }" >> %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ -# RUN: FileCheck -check-prefix=ERR7 -strict-whitespace %s -# ERR7: error: {{.*}}.script:4: malformed number: .temp -# ERR7-NEXT: >>> boom .temp : { *(.temp) } } -# ERR7-NEXT: >>> ^ - -## Check tokenize() error -# RUN: echo "SECTIONS {}" > %t.script -# RUN: echo "\"" >> %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ -# RUN: FileCheck -check-prefix=ERR8 -strict-whitespace %s -# ERR8: {{.*}}.script:2: unclosed quote - -## Check tokenize() error in included script file -# RUN: echo "SECTIONS {}" > %t.script.inc -# RUN: echo "\"" >> %t.script.inc -# RUN: echo "INCLUDE \"%t.script.inc\"" > %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ -# RUN: FileCheck -check-prefix=ERR9 -strict-whitespace %s -# ERR9: {{.*}}.script.inc:2: unclosed quote - -## Check error reporting correctness for included files. -# RUN: echo "SECTIONS {" > %t.script.inc -# RUN: echo ".text : { *(.text) }" >> %t.script.inc -# RUN: echo ".keep : { *(.keep) }" >> %t.script.inc -# RUN: echo "boom .temp : { *(.temp) } }" >> %t.script.inc -# RUN: echo "INCLUDE \"%t.script.inc\"" > %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ -# RUN: FileCheck -check-prefix=ERR10 -strict-whitespace %s -# ERR10: error: {{.*}}.script.inc:4: malformed number: .temp -# ERR10-NEXT: >>> boom .temp : { *(.temp) } } -# ERR10-NEXT: >>> ^ - -## Check error reporting in script with INCLUDE directive. -# RUN: echo "SECTIONS {" > %t.script.inc -# RUN: echo ".text : { *(.text) }" >> %t.script.inc -# RUN: echo ".keep : { *(.keep) }" >> %t.script.inc -# RUN: echo ".temp : { *(.temp) } }" >> %t.script.inc -# RUN: echo "/* One line before INCLUDE */" > %t.script -# RUN: echo "INCLUDE \"%t.script.inc\"" >> %t.script -# RUN: echo "/* One line ater INCLUDE */" >> %t.script -# RUN: echo "Error" >> %t.script -# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ -# RUN: FileCheck -check-prefix=ERR11 -strict-whitespace %s -# ERR11: error: {{.*}}.script:4: unexpected EOF diff --git a/test/ELF/linkerscript/discard-gnu-hash.s b/test/ELF/linkerscript/discard-gnu-hash.s new file mode 100644 index 000000000000..77f168de9caf --- /dev/null +++ b/test/ELF/linkerscript/discard-gnu-hash.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: ld.lld --hash-style both -shared -o %t1 %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: .gnu.hash +# CHECK: .hash + +# RUN: echo "SECTIONS { /DISCARD/ : { *(.hash) } }" > %t.script +# RUN: ld.lld --hash-style both -shared -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 \ +# RUN: | FileCheck %s --check-prefix=HASH +# HASH-NOT: .hash +# HASH: .gnu.hash +# HASH-NOT: .hash + +# RUN: echo "SECTIONS { /DISCARD/ : { *(.gnu.hash) } }" > %t.script +# RUN: ld.lld --hash-style both -shared -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 \ +# RUN: | FileCheck %s --check-prefix=GNUHASH +# GNUHASH-NOT: .gnu.hash +# GNUHASH: .hash +# GNUHASH-NOT: .gnu.hash diff --git a/test/ELF/linkerscript/discard-interp.s b/test/ELF/linkerscript/discard-interp.s deleted file mode 100644 index 261509e2e76b..000000000000 --- a/test/ELF/linkerscript/discard-interp.s +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o -// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/../Inputs/shared.s -o %t2.o -// RUN: ld.lld -shared %t2.o -o %t2.so -// RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; } \ -// RUN: SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } : text }" > %t.script -// RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --script %t.script --export-dynamic %t.o %t2.so -o %t -// RUN: llvm-readobj -s %t | FileCheck %s - -// CHECK-NOT: Name: .interp - -.global _start -_start: diff --git a/test/ELF/linkerscript/discard-interp.test b/test/ELF/linkerscript/discard-interp.test new file mode 100644 index 000000000000..02e97b99958c --- /dev/null +++ b/test/ELF/linkerscript/discard-interp.test @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux /dev/null -o %t.o +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/../Inputs/shared.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: ld.lld -dynamic-linker foo -rpath bar -rpath baz --script %s --export-dynamic %t.o %t2.so -o %t +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK-NOT: Name: .interp + +PHDRS { text PT_LOAD FILEHDR PHDRS; } +SECTIONS { + . = SIZEOF_HEADERS; + .text : { *(.text) } : text +} diff --git a/test/ELF/linkerscript/discard-print-gc.s b/test/ELF/linkerscript/discard-print-gc.s index 2a230e53dc2b..c9233ce7b0eb 100644 --- a/test/ELF/linkerscript/discard-print-gc.s +++ b/test/ELF/linkerscript/discard-print-gc.s @@ -15,5 +15,5 @@ .section .foo,"a" .quad 0 -# CHECK: removing unused section from '.foo' -# QUIET-NOT: removing unused section from '.foo' +# CHECK: removing unused section {{.*}}:(.foo) +# QUIET-NOT: removing unused section {{.*}}:(.foo) diff --git a/test/ELF/linkerscript/discard-section-err.s b/test/ELF/linkerscript/discard-section-err.s index 8ad5b486cb39..f1d3b96691ba 100644 --- a/test/ELF/linkerscript/discard-section-err.s +++ b/test/ELF/linkerscript/discard-section-err.s @@ -22,4 +22,14 @@ # RUN: FileCheck -check-prefix=DYNSTR %s # DYNSTR: discarding .dynstr section is not allowed +# RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.plt) } }" > %t.script +# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \ +# RUN: FileCheck -check-prefix=RELAPLT %s +# RELAPLT: discarding .rela.plt section is not allowed + +# RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.dyn) } }" > %t.script +# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \ +# RUN: FileCheck -check-prefix=RELADYN %s +# RELADYN: discarding .rela.dyn section is not allowed + .comm foo,4,4 diff --git a/test/ELF/linkerscript/dot-is-not-abs.s b/test/ELF/linkerscript/dot-is-not-abs.s index 4532cd59f2a1..a93d1c8b4344 100644 --- a/test/ELF/linkerscript/dot-is-not-abs.s +++ b/test/ELF/linkerscript/dot-is-not-abs.s @@ -1,9 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { .text : { *(.text) } \ -# RUN: foo = .; \ -# RUN: .bar : { *(.bar) } }" > %t1.script +# RUN: echo "SECTIONS { .text : { *(.text) } foo = .; .bar : { *(.bar) } }" > %t1.script # RUN: ld.lld -o %t1 --script %t1.script %t.o -shared # RUN: llvm-readobj -t -s -section-data %t1 | FileCheck %s diff --git a/test/ELF/linkerscript/double-bss.s b/test/ELF/linkerscript/double-bss.s deleted file mode 100644 index c24332f5e5a6..000000000000 --- a/test/ELF/linkerscript/double-bss.s +++ /dev/null @@ -1,21 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; " > %t.script -# RUN: echo ".text : { *(.text*) }" >> %t.script -# RUN: echo ".bss1 : { *(.bss) }" >> %t.script -# RUN: echo ".bss2 : { *(COMMON) }" >> %t.script -# RUN: echo "}" >> %t.script - -# RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -section-headers %t1 | FileCheck %s -# CHECK: .bss1 00000004 0000000000000122 BSS -# CHECK-NEXT: .bss2 00000080 0000000000000128 BSS - -.globl _start -_start: - jmp _start - -.bss -.zero 4 - -.comm q,128,8 diff --git a/test/ELF/linkerscript/double-bss.test b/test/ELF/linkerscript/double-bss.test new file mode 100644 index 000000000000..32b796d01c2e --- /dev/null +++ b/test/ELF/linkerscript/double-bss.test @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: echo '.short 0; .bss; .zero 4; .comm q,128,8' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t +# RUN: ld.lld -o %t1 --script %s %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: .bss1 00000004 0000000000000122 BSS +# CHECK-NEXT: .bss2 00000080 0000000000000128 BSS + +SECTIONS { + . = SIZEOF_HEADERS; + .text : { *(.text*) } + .bss1 : { *(.bss) } + .bss2 : { *(COMMON) } +} diff --git a/test/ELF/linkerscript/edata-etext.s b/test/ELF/linkerscript/edata-etext.s index ab723ce1316e..c15cf4c865c0 100644 --- a/test/ELF/linkerscript/edata-etext.s +++ b/test/ELF/linkerscript/edata-etext.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # 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 +# RUN: not ld.lld %t.o -script %t.script -o /dev/null 2>&1 | FileCheck %s # CHECK: error: undefined symbol: _edata # CHECK: >>> referenced by {{.*}}:(.text+0x0) # CHECK: error: undefined symbol: _etext diff --git a/test/ELF/linkerscript/eh-frame-emit-relocs.s b/test/ELF/linkerscript/eh-frame-emit-relocs.s new file mode 100644 index 000000000000..d951cbc261b9 --- /dev/null +++ b/test/ELF/linkerscript/eh-frame-emit-relocs.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: echo "SECTIONS { .foo : { *(.eh_frame) } }" > %t.script +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld --emit-relocs %t.o -T %t.script -o %t +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +# CHECK-NOT: eh_frame +# CHECK: .rela.foo +# CHECK-NOT: eh_frame + +.text + .cfi_startproc + .cfi_endproc diff --git a/test/ELF/linkerscript/eh-frame-hdr.s b/test/ELF/linkerscript/eh-frame-hdr.s index d1545be632a3..a7892b2259e0 100644 --- a/test/ELF/linkerscript/eh-frame-hdr.s +++ b/test/ELF/linkerscript/eh-frame-hdr.s @@ -1,13 +1,10 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { \ -# RUN: .eh_frame_hdr : {} \ -# RUN: .eh_frame : {} \ -# RUN: }" > %t.script +# RUN: echo "SECTIONS { .eh_frame_hdr : {} .eh_frame : {} }" > %t.script # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t # RUN: llvm-objdump -s -section=".eh_frame_hdr" %t1 | FileCheck %s -# CHECK: 011b033b 14000000 01000000 49000000 +# CHECK: 011b033b 14000000 01000000 4d000000 # CHECK-NEXT: 30000000 .global _start diff --git a/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s deleted file mode 100644 index 817e458fa5ef..000000000000 --- a/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s +++ /dev/null @@ -1,27 +0,0 @@ -## 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: 64424443872 is not in [-2147483648, 2147483647] - - .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-reloc-out-of-range.test b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.test new file mode 100644 index 000000000000..7f4df21fd4c4 --- /dev/null +++ b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.test @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/eh-frame-reloc-out-of-range.s -o %t.o +# RUN: not ld.lld %t.o -T %s -o %t 2>&1 | FileCheck %s + +PHDRS { eh PT_LOAD; text PT_LOAD; } +SECTIONS { . = 0x10000; + .eh_frame_hdr : { *(.eh_frame_hdr*) } : eh + .eh_frame : { *(.eh_frame) } : eh + . = 0xF00000000; + .text : { *(.text*) } : text +} + +# CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range: 64424443872 is not in [-2147483648, 2147483647] diff --git a/test/ELF/linkerscript/eh-frame.s b/test/ELF/linkerscript/eh-frame.s index 750f74eb36c6..5e43ec738f7b 100644 --- a/test/ELF/linkerscript/eh-frame.s +++ b/test/ELF/linkerscript/eh-frame.s @@ -1,8 +1,6 @@ # 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: echo "SECTIONS { .eh_frame : { *(.eh_frame) } }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -s -section=".eh_frame" %t1 | FileCheck %s diff --git a/test/ELF/linkerscript/emit-reloc-section-names.s b/test/ELF/linkerscript/emit-reloc-section-names.s index 8661ff060a79..7f76057322e8 100644 --- a/test/ELF/linkerscript/emit-reloc-section-names.s +++ b/test/ELF/linkerscript/emit-reloc-section-names.s @@ -1,7 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { .text.zed : { *(.text.foo) } \ -# RUN: .text.qux : { *(.text.bar) } }" > %t.script +# RUN: echo "SECTIONS { .text.zed : { *(.text.foo) } .text.qux : { *(.text.bar) } }" > %t.script # RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t # RUN: llvm-objdump -section-headers %t | FileCheck %s diff --git a/test/ELF/linkerscript/emit-reloc.s b/test/ELF/linkerscript/emit-reloc.s index 2fe127af8590..43ab4e8e47d8 100644 --- a/test/ELF/linkerscript/emit-reloc.s +++ b/test/ELF/linkerscript/emit-reloc.s @@ -9,9 +9,9 @@ # CHECK: Relocations [ # CHECK-NEXT: Section ({{.*}}) .rela.dyn { -# CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0 +# CHECK-NEXT: 0x68 R_X86_64_64 .foo 0x0 # CHECK-NEXT: } # CHECK-NEXT: Section ({{.*}}) .rela.data { -# CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0 +# CHECK-NEXT: 0x68 R_X86_64_64 .foo 0x0 # CHECK-NEXT: } # CHECK-NEXT: ] diff --git a/test/ELF/linkerscript/empty-link-order.test b/test/ELF/linkerscript/empty-link-order.test new file mode 100644 index 000000000000..b63b60ca8c15 --- /dev/null +++ b/test/ELF/linkerscript/empty-link-order.test @@ -0,0 +1,21 @@ +# REQUIRES: arm +# RUN: llvm-mc -filetype=obj -triple=arm-arm-none-eabi -o %t.o < /dev/null + +SECTIONS { + .foo : { + bar = .; + *(.ARM.exidx*) + } +} + +# RUN: ld.lld %t.o -o %t --script %s + +## Check we do not crash and do not set SHF_LINK_ORDER flag for .foo +# RUN: llvm-readobj -s %t | FileCheck %s +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_ARM_EXIDX +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] diff --git a/test/ELF/linkerscript/empty-load.s b/test/ELF/linkerscript/empty-load.s index ea58d71402d1..a2b7d8227f60 100644 --- a/test/ELF/linkerscript/empty-load.s +++ b/test/ELF/linkerscript/empty-load.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { .rw : { *(.rw) } .text : { *(.text) } }" > %t.script +# RUN: echo "SECTIONS { .rw : { *(.rw) } .text : { *(.text) } }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -private-headers %t1 | FileCheck %s diff --git a/test/ELF/linkerscript/empty-section-size.test b/test/ELF/linkerscript/empty-section-size.test new file mode 100644 index 000000000000..665ddf1ddf01 --- /dev/null +++ b/test/ELF/linkerscript/empty-section-size.test @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: ld.lld %t.o --script %s -o %t1 +# RUN: llvm-readobj -symbols %t1 | FileCheck %s + +## We had a bug when LLD increased the size of the output section even +## if it was empty. That happened because of empty synthetic sections included. +## Here we check that size of empty output section is zero. + +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x0 + +SECTIONS { + . = 0x1000; + .bss : { *(.bss*) *(COMMON) } + foo = SIZEOF(.bss); +} diff --git a/test/ELF/linkerscript/empty-sections-expressions.s b/test/ELF/linkerscript/empty-sections-expressions.s new file mode 100644 index 000000000000..3c9a9edf5786 --- /dev/null +++ b/test/ELF/linkerscript/empty-sections-expressions.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +## We remove empty sections that do not reference symbols in address, +## LMA, align and subalign expressions. Here we check that. + +# RUN: echo "SECTIONS { .debug_info 0 : { *(.debug_info) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck %s +# CHECK-NOT: .debug_info + +# RUN: echo "SECTIONS { .debug_info foo : { *(.debug_info) } }" > %t2.script +# RUN: ld.lld -o %t2 --script %t2.script %t.o +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=SEC +# SEC: .debug_info + +.globl foo +foo: diff --git a/test/ELF/linkerscript/empty-synthetic-removed-flags.s b/test/ELF/linkerscript/empty-synthetic-removed-flags.s new file mode 100644 index 000000000000..54a8baba3bec --- /dev/null +++ b/test/ELF/linkerscript/empty-synthetic-removed-flags.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { .foo : { *(.foo) } .bar : { *(.got.plt) BYTE(0x11) }}" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -s %t | FileCheck %s + +## We have ".got.plt" synthetic section with SHF_ALLOC|SHF_WRITE flags. +## It is empty, so linker removes it, but it has to keep ".got.plt" output +## section because of the BYTE command. Here we check that the output section +## still remembers what the flags of .got.plt are. + +# CHECK: Section { +# CHECK: Index: 2 +# CHECK: Name: .bar +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] + +## Check flags are not the same if we omit empty synthetic section in script. +# RUN: echo "SECTIONS { .foo : { *(.foo) } .bar : { BYTE(0x11) }}" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -s %t | FileCheck --check-prefix=EMPTY %s + +# EMPTY: Section { +# EMPTY: Index: 2 +# EMPTY: Name: .bar +# EMPTY-NEXT: Type: SHT_PROGBITS +# EMPTY-NEXT: Flags [ +# EMPTY-NEXT: SHF_ALLOC +# EMPTY-NEXT: SHF_EXECINSTR +# EMPTY-NEXT: ] + +.section .foo,"ax" +.quad 0 diff --git a/test/ELF/linkerscript/empty-tls.s b/test/ELF/linkerscript/empty-tls.s deleted file mode 100644 index 919ccbffbe43..000000000000 --- a/test/ELF/linkerscript/empty-tls.s +++ /dev/null @@ -1,14 +0,0 @@ -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: echo "PHDRS { ph_tls PT_TLS; }" > %t.script -// RUN: ld.lld -o %t.so -T %t.script %t.o -shared -// RUN: llvm-readobj -l %t.so | FileCheck %s - -// test that we don't crash with an empty PT_TLS - -// CHECK: Type: PT_TLS -// CHECK-NEXT: Offset: 0x0 -// CHECK-NEXT: VirtualAddress: 0x0 -// CHECK-NEXT: PhysicalAddress: 0x0 -// CHECK-NEXT: FileSize: 0 -// CHECK-NEXT: MemSize: 0 diff --git a/test/ELF/linkerscript/empty-tls.test b/test/ELF/linkerscript/empty-tls.test new file mode 100644 index 000000000000..2f473cb55f8c --- /dev/null +++ b/test/ELF/linkerscript/empty-tls.test @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -o %t.so -T %s %t.o -shared +# RUN: llvm-readobj -l %t.so | FileCheck %s + +PHDRS { + ph_tls PT_TLS; +} + +# Test that we don't crash with an empty PT_TLS + +# CHECK: Type: PT_TLS +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x0 +# CHECK-NEXT: PhysicalAddress: 0x0 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 diff --git a/test/ELF/linkerscript/exidx-crash.s b/test/ELF/linkerscript/exidx-crash.s deleted file mode 100644 index c29d0135414d..000000000000 --- a/test/ELF/linkerscript/exidx-crash.s +++ /dev/null @@ -1,7 +0,0 @@ -# REQUIRES: aarch64 - -# We used to crash on this. - -# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux -# RUN: echo "SECTIONS { .ARM.exidx : { *(.foo) } }" > %t.script -# RUN: ld.lld -T %t.script %t.o -o %t diff --git a/test/ELF/linkerscript/exidx-crash.test b/test/ELF/linkerscript/exidx-crash.test new file mode 100644 index 000000000000..4d765f4d3380 --- /dev/null +++ b/test/ELF/linkerscript/exidx-crash.test @@ -0,0 +1,10 @@ +# REQUIRES: aarch64 + +# We used to crash on this. + +# RUN: llvm-mc /dev/null -o %t.o -filetype=obj -triple=aarch64-pc-linux +# RUN: ld.lld -T %s %t.o -o %t + +SECTIONS { + .ARM.exidx : { *(.foo) } +} diff --git a/test/ELF/linkerscript/expr-invalid-sec.s b/test/ELF/linkerscript/expr-invalid-sec.s deleted file mode 100644 index 5687751b6806..000000000000 --- a/test/ELF/linkerscript/expr-invalid-sec.s +++ /dev/null @@ -1,6 +0,0 @@ -# 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: error: {{.*}}.script:1: at least one side of the expression must be absolute diff --git a/test/ELF/linkerscript/expr-invalid-sec.test b/test/ELF/linkerscript/expr-invalid-sec.test new file mode 100644 index 000000000000..946062a0c575 --- /dev/null +++ b/test/ELF/linkerscript/expr-invalid-sec.test @@ -0,0 +1,9 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld -o %t.so --script %s %t.o -shared 2>&1 | FileCheck %s + +# CHECK: error: {{.*}}.test:8: at least one side of the expression must be absolute + +SECTIONS { + foo = ADDR(.text) + ADDR(.text); +}; diff --git a/test/ELF/linkerscript/expr-sections.s b/test/ELF/linkerscript/expr-sections.s deleted file mode 100644 index eb60009cd971..000000000000 --- a/test/ELF/linkerscript/expr-sections.s +++ /dev/null @@ -1,22 +0,0 @@ -# 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/expr-sections.test b/test/ELF/linkerscript/expr-sections.test new file mode 100644 index 000000000000..1d16cc2239e9 --- /dev/null +++ b/test/ELF/linkerscript/expr-sections.test @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: ld.lld -o %t.so --script %s %t.o -shared +# RUN: llvm-objdump -t -h %t.so | FileCheck %s + +SECTIONS { + . = . + 4; + .text : { + *(.text) + foo1 = ADDR(.text) + 1; bar1 = 1 + ADDR(.text); + foo2 = ADDR(.text) & 1; bar2 = 1 & ADDR(.text); + foo3 = ADDR(.text) | 1; bar3 = 1 | ADDR(.text); + } +}; + +# CHECK: 5 .text 00000000 000000000000014c + +# CHECK: 000000000000014d .text 00000000 foo1 +# CHECK: 000000000000014d .text 00000000 bar1 +# CHECK: 0000000000000000 .text 00000000 foo2 +# CHECK: 0000000000000000 .text 00000000 bar2 +# CHECK: 000000000000014d .text 00000000 foo3 +# CHECK: 000000000000014d .text 00000000 bar3 diff --git a/test/ELF/linkerscript/extend-pt-load.s b/test/ELF/linkerscript/extend-pt-load.s deleted file mode 100644 index 72740f1092ee..000000000000 --- a/test/ELF/linkerscript/extend-pt-load.s +++ /dev/null @@ -1,68 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o - -# This test demonstrates an odd consequence of the way we handle sections with just symbol -# assignments. - -# First, run a test with no such section. - -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: .dynsym : { } \ -# RUN: .hash : { } \ -# RUN: .dynstr : { } \ -# RUN: .text : { *(.text) } \ -# RUN: . = ALIGN(0x1000); \ -# RUN: .data.rel.ro : { *(.data.rel.ro) } \ -# RUN: }" > %t.script -# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t.o -shared -# RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck --check-prefix=CHECK1 %s - -# CHECK1: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX -# CHECK1-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA - -# CHECK1: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x0001bd R E -# CHECK1-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW - -# Then add the section bar. Note how bar is given AX flags, which causes the PT_LOAD to now -# cover the padding bits created by ALIGN. - -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: .dynsym : { } \ -# RUN: .hash : { } \ -# RUN: .dynstr : { } \ -# RUN: .text : { *(.text) } \ -# RUN: bar : { . = ALIGN(0x1000); } \ -# RUN: .data.rel.ro : { *(.data.rel.ro) } \ -# RUN: }" > %t.script -# RUN: ld.lld --hash-style=sysv -o %t2 --script %t.script %t.o -shared -# RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck --check-prefix=CHECK2 %s - -# CHECK2: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX -# CHECK2-NEXT: bar NOBITS 00000000000001bd 0001bd 000e43 00 AX -# CHECK2-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA - -# CHECK2: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x001000 R E -# CHECK2-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW - -# If the current behavior becomes a problem we should consider just moving the commands out -# of the section. That is, handle the above like the following test. - -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: .dynsym : { } \ -# RUN: .hash : { } \ -# RUN: .dynstr : { } \ -# RUN: .text : { *(.text) } \ -# RUN: . = ALIGN(0x1000); \ -# RUN: HIDDEN(bar_sym = .); \ -# RUN: .data.rel.ro : { *(.data.rel.ro) } \ -# RUN: }" > %t.script -# RUN: ld.lld --hash-style=sysv -o %t3 --script %t.script %t.o -shared -# RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck --check-prefix=CHECK1 %s - -nop - -.section .data.rel.ro, "aw" -.byte 0 diff --git a/test/ELF/linkerscript/extend-pt-load1.test b/test/ELF/linkerscript/extend-pt-load1.test new file mode 100644 index 000000000000..a1359eace186 --- /dev/null +++ b/test/ELF/linkerscript/extend-pt-load1.test @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o +# RUN: ld.lld --hash-style=sysv -o %t1 --script %s %t.o -shared +# RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck %s + +# This test demonstrates an odd consequence of the way we handle sections with just symbol +# assignments. + +SECTIONS { + . = SIZEOF_HEADERS; + .dynsym : {} + .hash : {} + .dynstr : {} + .text : { *(.text) } + . = ALIGN(0x1000); + .data.rel.ro : { *(.data.rel.ro) } +} + +# CHECK: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX +# CHECK-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA + +# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x0001bd R E +# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW diff --git a/test/ELF/linkerscript/extend-pt-load2.test b/test/ELF/linkerscript/extend-pt-load2.test new file mode 100644 index 000000000000..1aa943703f27 --- /dev/null +++ b/test/ELF/linkerscript/extend-pt-load2.test @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o +# RUN: ld.lld --hash-style=sysv -o %t2 --script %s %t.o -shared +# RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck %s + +# Then add the section bar. Note how bar is given AX flags, which causes the PT_LOAD to now +# cover the padding bits created by ALIGN. + +SECTIONS { + . = SIZEOF_HEADERS; + .dynsym : {} + .hash : {} + .dynstr : {} + .text : { *(.text) } + bar : { . = ALIGN(0x1000); } + .data.rel.ro : { *(.data.rel.ro) } +} + +# CHECK: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX +# CHECK-NEXT: bar NOBITS 00000000000001bd 0001bd 000e43 00 AX +# CHECK-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA + +# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x001000 R E +# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW diff --git a/test/ELF/linkerscript/extend-pt-load3.test b/test/ELF/linkerscript/extend-pt-load3.test new file mode 100644 index 000000000000..1b7ef6fdbf94 --- /dev/null +++ b/test/ELF/linkerscript/extend-pt-load3.test @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o +# RUN: ld.lld --hash-style=sysv -o %t3 --script %s %t.o -shared +# RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck --check-prefix=CHECK %s + +# If the current behavior becomes a problem we should consider just moving the commands out +# of the section. That is, handle the above like the following test. + +SECTIONS { + . = SIZEOF_HEADERS; + .dynsym : {} + .hash : {} + .dynstr : {} + .text : { *(.text) } + . = ALIGN(0x1000); + HIDDEN(bar_sym = .); + .data.rel.ro : { *(.data.rel.ro) } +} + +# CHECK: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX +# CHECK-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA + +# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x0001bd R E +# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW
\ No newline at end of file diff --git a/test/ELF/linkerscript/filename-spec.s b/test/ELF/linkerscript/filename-spec.s index 5f075a8e5005..66fd4178387c 100644 --- a/test/ELF/linkerscript/filename-spec.s +++ b/test/ELF/linkerscript/filename-spec.s @@ -1,55 +1,43 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfirst.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tx.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -# RUN: %p/Inputs/filename-spec.s -o %tsecond.o +# RUN: %p/Inputs/filename-spec.s -o %ty.o -# RUN: echo "SECTIONS { .foo : { \ -# RUN: KEEP(*first.o(.foo)) \ -# RUN: KEEP(*second.o(.foo)) } }" > %t1.script -# RUN: ld.lld -o %t1 --script %t1.script %tfirst.o %tsecond.o -# RUN: llvm-objdump -s %t1 | FileCheck --check-prefix=FIRSTSECOND %s -# FIRSTSECOND: Contents of section .foo: -# FIRSTSECOND-NEXT: 01000000 00000000 11000000 00000000 +# RUN: echo "SECTIONS{.foo :{ KEEP(*x.o(.foo)) KEEP(*y.o(.foo)) }}" > %t1.script +# RUN: ld.lld -o %t1 --script %t1.script %tx.o %ty.o +# RUN: llvm-objdump -s %t1 | FileCheck --check-prefix=FIRSTY %s +# FIRSTY: Contents of section .foo: +# FIRSTY-NEXT: 01000000 00000000 11000000 00000000 -# RUN: echo "SECTIONS { .foo : { \ -# RUN: KEEP(*second.o(.foo)) \ -# RUN: KEEP(*first.o(.foo)) } }" > %t2.script -# RUN: ld.lld -o %t2 --script %t2.script %tfirst.o %tsecond.o +# RUN: echo "SECTIONS{.foo :{ KEEP(*y.o(.foo)) KEEP(*x.o(.foo)) }}" > %t2.script +# RUN: ld.lld -o %t2 --script %t2.script %tx.o %ty.o # RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SECONDFIRST %s # SECONDFIRST: Contents of section .foo: # SECONDFIRST-NEXT: 11000000 00000000 01000000 00000000 ## Now the same tests but without KEEP. Checking that file name inside ## KEEP is parsed fine. -# RUN: echo "SECTIONS { .foo : { \ -# RUN: *first.o(.foo) \ -# RUN: *second.o(.foo) } }" > %t3.script -# RUN: ld.lld -o %t3 --script %t3.script %tfirst.o %tsecond.o -# RUN: llvm-objdump -s %t3 | FileCheck --check-prefix=FIRSTSECOND %s +# RUN: echo "SECTIONS{.foo :{ *x.o(.foo) *y.o(.foo) }}" > %t3.script +# RUN: ld.lld -o %t3 --script %t3.script %tx.o %ty.o +# RUN: llvm-objdump -s %t3 | FileCheck --check-prefix=FIRSTY %s -# RUN: echo "SECTIONS { .foo : { \ -# RUN: *second.o(.foo) \ -# RUN: *first.o(.foo) } }" > %t4.script -# RUN: ld.lld -o %t4 --script %t4.script %tfirst.o %tsecond.o +# RUN: echo "SECTIONS{.foo :{ *y.o(.foo) *x.o(.foo) }}" > %t4.script +# RUN: ld.lld -o %t4 --script %t4.script %tx.o %ty.o # RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=SECONDFIRST %s -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o filename-spec1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %T/filename-spec1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -# RUN: %p/Inputs/filename-spec.s -o filename-spec2.o +# RUN: %p/Inputs/filename-spec.s -o %T/filename-spec2.o -# RUN: echo "SECTIONS { .foo : { \ -# RUN: filename-spec2.o(.foo) \ -# RUN: filename-spec1.o(.foo) } }" > %t5.script +# RUN: echo "SECTIONS{.foo :{ %T/filename-spec2.o(.foo) %T/filename-spec1.o(.foo) }}" > %t5.script # RUN: ld.lld -o %t5 --script %t5.script \ -# RUN: filename-spec1.o filename-spec2.o +# RUN: %T/filename-spec1.o %T/filename-spec2.o # RUN: llvm-objdump -s %t5 | FileCheck --check-prefix=SECONDFIRST %s -# RUN: echo "SECTIONS { .foo : { \ -# RUN: filename-spec1.o(.foo) \ -# RUN: filename-spec2.o(.foo) } }" > %t6.script +# RUN: echo "SECTIONS{.foo :{ %T/filename-spec1.o(.foo) %T/filename-spec2.o(.foo) }}" > %t6.script # RUN: ld.lld -o %t6 --script %t6.script \ -# RUN: filename-spec1.o filename-spec2.o -# RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTSECOND %s +# RUN: %T/filename-spec1.o %T/filename-spec2.o +# RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTY %s # RUN: mkdir -p %t.testdir1 %t.testdir2 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.testdir1/filename-spec1.o @@ -59,33 +47,25 @@ # RUN: llvm-ar rsc %t.testdir2/lib2.a %t.testdir2/filename-spec2.o # Verify matching of archive library names. -# RUN: echo "SECTIONS { .foo : { \ -# RUN: *lib2*(.foo) \ -# RUN: *lib1*(.foo) } }" > %t7.script +# RUN: echo "SECTIONS{.foo :{ *lib2*(.foo) *lib1*(.foo) }}" > %t7.script # RUN: ld.lld -o %t7 --script %t7.script --whole-archive \ # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a # RUN: llvm-objdump -s %t7 | FileCheck --check-prefix=SECONDFIRST %s # Verify matching directories. -# RUN: echo "SECTIONS { .foo : { \ -# RUN: *testdir2*(.foo) \ -# RUN: *testdir1*(.foo) } }" > %t8.script +# RUN: echo "SECTIONS{.foo :{ *testdir2*(.foo) *testdir1*(.foo) }}" > %t8.script # RUN: ld.lld -o %t8 --script %t8.script --whole-archive \ # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a # RUN: llvm-objdump -s %t8 | FileCheck --check-prefix=SECONDFIRST %s # Verify matching of archive library names in KEEP. -# RUN: echo "SECTIONS { .foo : { \ -# RUN: KEEP(*lib2*(.foo)) \ -# RUN: KEEP(*lib1*(.foo)) } }" > %t9.script +# RUN: echo "SECTIONS{.foo :{ KEEP(*lib2*(.foo)) KEEP(*lib1*(.foo)) }}" > %t9.script # RUN: ld.lld -o %t9 --script %t9.script --whole-archive \ # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a # RUN: llvm-objdump -s %t9 | FileCheck --check-prefix=SECONDFIRST %s # Verify matching directories in KEEP. -# RUN: echo "SECTIONS { .foo : { \ -# RUN: KEEP(*testdir2*(.foo)) \ -# RUN: KEEP(*testdir1*(.foo)) } }" > %t10.script +# RUN: echo "SECTIONS{.foo :{ KEEP(*testdir2*(.foo)) KEEP(*testdir1*(.foo)) }}" > %t10.script # RUN: ld.lld -o %t10 --script %t10.script --whole-archive \ # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a # RUN: llvm-objdump -s %t10 | FileCheck --check-prefix=SECONDFIRST %s diff --git a/test/ELF/linkerscript/fill.s b/test/ELF/linkerscript/fill.s deleted file mode 100644 index 604506084a74..000000000000 --- a/test/ELF/linkerscript/fill.s +++ /dev/null @@ -1,31 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: echo "SECTIONS { \ -# RUN: .out : { \ -# RUN: FILL(0x11111111) \ -# RUN: . += 2; \ -# RUN: *(.aaa) \ -# RUN: . += 4; \ -# RUN: *(.bbb) \ -# RUN: . += 4; \ -# RUN: FILL(0x22222222); \ -# RUN: . += 4; \ -# RUN: } \ -# RUN: }; " > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-objdump -s %t | FileCheck %s - -# CHECK: Contents of section .out: -# CHECK-NEXT: 2222aa22 222222bb 22222222 22222222 - -.text -.globl _start -_start: - -.section .aaa, "a" -.align 1 -.byte 0xAA - -.section .bbb, "a" -.align 1 -.byte 0xBB diff --git a/test/ELF/linkerscript/fill.test b/test/ELF/linkerscript/fill.test new file mode 100644 index 000000000000..5bf295ec9c14 --- /dev/null +++ b/test/ELF/linkerscript/fill.test @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/fill.s -o %t.o +# RUN: ld.lld -o %t --script %s %t.o +# RUN: llvm-objdump -s %t | FileCheck %s + +SECTIONS { + .out : { + FILL(0x11111111) + . += 2; + *(.aaa) + . += 4; + *(.bbb) + . += 4; + FILL(0x22222222); + . += 4; + } +} + +# CHECK: Contents of section .out: +# CHECK-NEXT: 2222aa22 222222bb 22222222 22222222 diff --git a/test/ELF/linkerscript/header-addr.s b/test/ELF/linkerscript/header-addr.test index 70e6f674bafb..7994c0fc9653 100644 --- a/test/ELF/linkerscript/header-addr.s +++ b/test/ELF/linkerscript/header-addr.test @@ -1,13 +1,15 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "PHDRS {all PT_LOAD PHDRS;} \ -# RUN: SECTIONS { \ -# RUN: . = 0x2000 + SIZEOF_HEADERS; \ -# RUN: .text : {*(.text)} :all \ -# RUN: }" > %t.script -# RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld --hash-style=sysv -o %t.so --script %s %t.o -shared # RUN: llvm-readobj -program-headers %t.so | FileCheck %s +PHDRS { all PT_LOAD PHDRS; } + +SECTIONS { + . = 0x2000 + SIZEOF_HEADERS; + .text : {*(.text)} :all +} + # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD @@ -25,7 +27,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] -# RUN: ld.lld --hash-style=sysv -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 +# RUN: ld.lld --hash-style=sysv -o %t2.so --script %s %t.o -shared -z max-page-size=0x2000 # RUN: llvm-readobj -program-headers %t2.so \ # RUN: | FileCheck --check-prefix=MAXPAGE %s diff --git a/test/ELF/linkerscript/header-phdr.s b/test/ELF/linkerscript/header-phdr.s deleted file mode 100644 index 8c9097d8dfa5..000000000000 --- a/test/ELF/linkerscript/header-phdr.s +++ /dev/null @@ -1,13 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "PHDRS { foobar PT_LOAD FILEHDR PHDRS; } \ -# RUN: SECTIONS { . = 0x1000; .abc : { *(.zed) } : foobar }" > %t.script -# RUN: ld.lld --script %t.script %t.o -o %t -# RUN: llvm-readelf -l -S -W %t | FileCheck %s - -.section .zed, "a" -.zero 4 - - -# CHECK: [ 1] .abc PROGBITS 0000000000001000 001000 000004 00 A 0 0 1 -# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001004 0x001004 R E 0x1000 diff --git a/test/ELF/linkerscript/header-phdr.test b/test/ELF/linkerscript/header-phdr.test new file mode 100644 index 000000000000..72be15b88a94 --- /dev/null +++ b/test/ELF/linkerscript/header-phdr.test @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: echo '.section .zed, "a"; .zero 4' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: ld.lld --script %s %t.o -o %t +# RUN: llvm-readelf -l -S -W %t | FileCheck %s + +# CHECK: [ 1] .abc PROGBITS 0000000000001000 001000 000004 00 A 0 0 1 +# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001004 0x001004 R E 0x1000 + +PHDRS { foobar PT_LOAD FILEHDR PHDRS; } + +SECTIONS { + . = 0x1000; + .abc : { *(.zed) } : foobar +} diff --git a/test/ELF/linkerscript/header-phdr2.s b/test/ELF/linkerscript/header-phdr2.s new file mode 100644 index 000000000000..fbcd03ff6056 --- /dev/null +++ b/test/ELF/linkerscript/header-phdr2.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "PHDRS { foobar PT_LOAD FILEHDR PHDRS; }" > %t.script +# RUN: echo "SECTIONS { .text : { *(.text) } : foobar }" >> %t.script +# RUN: not ld.lld --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s + +# CHECK: could not allocate headers + + .global _start +_start: + retq diff --git a/test/ELF/linkerscript/huge-temporary-file.s b/test/ELF/linkerscript/huge-temporary-file.s index d58709cf8f8d..e30153c28857 100644 --- a/test/ELF/linkerscript/huge-temporary-file.s +++ b/test/ELF/linkerscript/huge-temporary-file.s @@ -3,7 +3,7 @@ # 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 +## This inputs previously created a 4gb temporarily file under 32 bit ## configuration. Issue was fixed. There is no clean way to check that from here. ## This testcase added for documentation purposes. diff --git a/test/ELF/linkerscript/i386-sections-max-va-overflow.s b/test/ELF/linkerscript/i386-sections-max-va-overflow.s new file mode 100644 index 000000000000..d424112a1ce4 --- /dev/null +++ b/test/ELF/linkerscript/i386-sections-max-va-overflow.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o + +# RUN: echo "SECTIONS { . = 0xfffffff1;" > %t.script +# RUN: echo " .bar : { *(.bar*) } }" >> %t.script +# RUN: not ld.lld -o /dev/null --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR + +## .bar section has data in [0xfffffff1, 0xfffffff1 + 0x10] == [0xffffff1, 0x1]. +## Check we can catch this overflow. +# ERR: error: section .bar at 0xFFFFFFF1 of size 0x10 exceeds available address space + +.section .bar,"ax",@progbits +.zero 0x10 diff --git a/test/ELF/linkerscript/implicit-program-header.s b/test/ELF/linkerscript/implicit-program-header.s deleted file mode 100644 index 95cdf142fe42..000000000000 --- a/test/ELF/linkerscript/implicit-program-header.s +++ /dev/null @@ -1,13 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld --hash-style=sysv -o %t1 --script %S/Inputs/implicit-program-header.script \ -# RUN: %t.o -shared -# RUN: llvm-readobj -elf-output-style=GNU -l %t1 | FileCheck %s - -# CHECK: Segment Sections... -# CHECK-NEXT: 00 .text .dynsym .hash .dynstr .dynamic -# CHECK-NEXT: 01 .foo - -.quad 0 -.section .foo,"ax" -.quad 0 diff --git a/test/ELF/linkerscript/implicit-program-header.test b/test/ELF/linkerscript/implicit-program-header.test new file mode 100644 index 000000000000..8a3a4c6684af --- /dev/null +++ b/test/ELF/linkerscript/implicit-program-header.test @@ -0,0 +1,22 @@ +# REQUIRES: x86 + +# RUN: echo '.section .text,"ax"; .quad 0' > %t.s +# RUN: echo '.section .foo,"ax"; .quad 0' >> %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t.o +# RUN: ld.lld --hash-style=sysv -o %t1 --script %s %t.o -shared +# RUN: llvm-readelf -l %t1 | FileCheck %s + +# CHECK: Segment Sections... +# CHECK-NEXT: 00 .dynsym .hash .dynstr .bar .foo .text .dynamic +# CHECK-NEXT: 01 .bar .foo + +PHDRS { + ph_write PT_LOAD FLAGS(2); + ph_exec PT_LOAD FLAGS(1); +} + +SECTIONS { + .bar : { *(.bar) } : ph_exec + .foo : { *(.foo) } + .text : { *(.text) } : ph_write +} diff --git a/test/ELF/linkerscript/info-section-type.s b/test/ELF/linkerscript/info-section-type.s new file mode 100644 index 000000000000..b718e828ab7d --- /dev/null +++ b/test/ELF/linkerscript/info-section-type.s @@ -0,0 +1,33 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +## In this test we check that output section types such as +## COPY, INFO and OVERLAY marks output section as non-allocatable. + +# RUN: echo "SECTIONS { .bar : { *(.foo) } };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=DEFAULT +# DEFAULT: Name: .bar +# DEFAULT: Type: SHT_PROGBITS +# DEFAULT-NEXT: Flags [ +# DEFAULT-NEXT: SHF_ALLOC +# DEFAULT-NEXT: ] + +# RUN: echo "SECTIONS { .bar (COPY) : { *(.foo) } };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC +# NONALLOC: Name: .bar +# NONALLOC: Type: SHT_PROGBITS +# NONALLOC-NEXT: Flags [ +# NONALLOC-NEXT: ] + +# RUN: echo "SECTIONS { .bar (INFO) : { *(.foo) } };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC + +# RUN: echo "SECTIONS { .bar (OVERLAY) : { *(.foo) } };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC + +.section .foo,"a",@progbits +.zero 1 diff --git a/test/ELF/linkerscript/insert-after.test b/test/ELF/linkerscript/insert-after.test new file mode 100644 index 000000000000..4260cd77f553 --- /dev/null +++ b/test/ELF/linkerscript/insert-after.test @@ -0,0 +1,29 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/insert-after.s -o %t1.o + +## Main linker script contains .text and .data sections. Here +## we check that can use INSERT AFTER to insert sections .foo.data +## and .foo.text at the right places. + +SECTIONS { + .foo.data : { *(.foo.data) } +} INSERT AFTER .data; + +SECTIONS { + .foo.text : { *(.foo.text) } +} INSERT AFTER .text; + +# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .text 00000008 0000000000000000 TEXT +# CHECK-NEXT: 2 .foo.text 00000008 0000000000000008 TEXT +# CHECK-NEXT: 3 .data 00000008 0000000000000010 DATA +# CHECK-NEXT: 4 .foo.data 00000008 0000000000000018 DATA + +# RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=ERR +# ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined +# ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined diff --git a/test/ELF/linkerscript/insert-before.test b/test/ELF/linkerscript/insert-before.test new file mode 100644 index 000000000000..52317bef6ac0 --- /dev/null +++ b/test/ELF/linkerscript/insert-before.test @@ -0,0 +1,29 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/insert-after.s -o %t1.o + +## Main linker script contains .text and .data sections. Here +## we check that can use INSERT BEFORE to insert sections .foo.data +## and .foo.text at the right places. + +SECTIONS { + .foo.data : { *(.foo.data) } +} INSERT BEFORE .data; + +SECTIONS { + .foo.text : { *(.foo.text) } +} INSERT BEFORE .text; + +# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .foo.text 00000008 0000000000000000 TEXT +# CHECK-NEXT: 2 .text 00000008 0000000000000008 TEXT +# CHECK-NEXT: 3 .foo.data 00000008 0000000000000010 DATA +# CHECK-NEXT: 4 .data 00000008 0000000000000018 DATA + +# RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=ERR +# ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined +# ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined diff --git a/test/ELF/linkerscript/insert-broken.test b/test/ELF/linkerscript/insert-broken.test new file mode 100644 index 000000000000..9a295623a2ca --- /dev/null +++ b/test/ELF/linkerscript/insert-broken.test @@ -0,0 +1,6 @@ +SECTIONS { + .foo : { *(.bar) } +} INSERT .data; + +# RUN: not ld.lld -o %t1 --script %s 2>&1 | FileCheck %s +# CHECK: {{.*}}:3: expected AFTER/BEFORE, but got '.data' diff --git a/test/ELF/linkerscript/lazy-symbols.s b/test/ELF/linkerscript/lazy-symbols.test index 22dffeef979b..579df9323865 100644 --- a/test/ELF/linkerscript/lazy-symbols.s +++ b/test/ELF/linkerscript/lazy-symbols.test @@ -1,11 +1,12 @@ # 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-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t2 +# RUN: ld.lld %t2 %tar --script %s -o %tout # RUN: llvm-readobj -symbols %tout | FileCheck %s +foo = 1; + # This test is to ensure a linker script can define a symbol which have the same # name as a lazy symbol. diff --git a/test/ELF/linkerscript/linker-script-in-search-path.s b/test/ELF/linkerscript/linker-script-in-search-path.s index be83b55b8995..8f1802299de5 100644 --- a/test/ELF/linkerscript/linker-script-in-search-path.s +++ b/test/ELF/linkerscript/linker-script-in-search-path.s @@ -4,16 +4,16 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: mkdir -p %T/searchpath -# RUN: echo "OUTPUT(\"%t.out\")" > %T/searchpath/foo.script -# RUN: ld.lld -T%T/searchpath/foo.script %t.o +# RUN: echo 'OUTPUT("%t.out")' > %T/searchpath/%basename_t.script +# RUN: ld.lld -T%T/searchpath/%basename_t.script %t.o # RUN: llvm-readobj %t.out | FileCheck %s # CHECK: Format: ELF64-x86-64 # If the linker script specified with -T is missing we should emit an error -# RUN: not ld.lld -Tfoo.script %t.o 2>&1 | FileCheck %s -check-prefix ERROR -# ERROR: error: cannot find linker script foo.script +# RUN: not ld.lld -T%basename_t.script %t.o 2>&1 | FileCheck %s -check-prefix ERROR +# ERROR: error: cannot find linker script {{.*}}.script # But if it exists in the search path we should fall back to that instead: # RUN: rm %t.out -# RUN: ld.lld -L %T/searchpath -Tfoo.script %t.o +# RUN: ld.lld -L %T/searchpath -T%basename_t.script %t.o # RUN: llvm-readobj %t.out | FileCheck %s diff --git a/test/ELF/linkerscript/linkerscript.s b/test/ELF/linkerscript/linkerscript.s index 6a239ea57c8d..39d2d4620a4f 100644 --- a/test/ELF/linkerscript/linkerscript.s +++ b/test/ELF/linkerscript/linkerscript.s @@ -17,32 +17,32 @@ # RUN: llvm-readobj %t.out > /dev/null # RUN: echo "SEARCH_DIR(/lib/foo/blah)" > %t.script -# RUN: ld.lld %t.script %t +# RUN: ld.lld %t.script %t -o %t.out # RUN: llvm-readobj %t.out > /dev/null # RUN: echo ";SEARCH_DIR(x);SEARCH_DIR(y);" > %t.script -# RUN: ld.lld %t.script %t +# RUN: ld.lld %t.script %t -o %t.out # RUN: llvm-readobj %t.out > /dev/null # RUN: echo ";" > %t.script -# RUN: ld.lld %t.script %t +# RUN: ld.lld %t.script %t -o %t.out # RUN: llvm-readobj %t.out > /dev/null # RUN: echo "INCLUDE \"%t.script2\" OUTPUT(\"%t.out\")" > %t.script1 # RUN: echo "GROUP(\"%t\")" > %t.script2 -# RUN: ld.lld %t.script1 +# RUN: ld.lld %t.script1 -o %t.out # RUN: llvm-readobj %t2 > /dev/null # RUN: echo "INCLUDE \"foo.script\"" > %t.script # RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script -# RUN: not ld.lld %t.script > %t.log 2>&1 +# RUN: not ld.lld %t.script -o %t.out > %t.log 2>&1 # RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log # INCLUDE_ERR: error: {{.+}}.script:1: cannot find linker script foo.script # INCLUDE_ERR-NEXT: INCLUDE "foo.script" # RUN: ld.lld -L %T %t.script %t # RUN: echo "FOO(BAR)" > %t.script -# RUN: not ld.lld -o foo %t.script > %t.log 2>&1 +# RUN: not ld.lld -o %t.out %t.script > %t.log 2>&1 # RUN: FileCheck -check-prefix=ERR1 %s < %t.log # ERR1: unknown directive: FOO diff --git a/test/ELF/linkerscript/lma-overflow.test b/test/ELF/linkerscript/lma-overflow.test new file mode 100644 index 000000000000..e572c05af344 --- /dev/null +++ b/test/ELF/linkerscript/lma-overflow.test @@ -0,0 +1,16 @@ +# REQUIRES: x86 + +# RUN: echo '.section .foo,"a"; .quad 1' | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: not ld.lld -o %t %t.o --script %s 2>&1 | FileCheck %s +# CHECK: error: section '.foo' will not fit in region 'flash': overflowed by 264 bytes + +MEMORY { + ram (rwx) : org = 0x1000, len = 0x300 + flash (rwx) : org = 0x1000, len = 0x100 +} +SECTIONS { + .foo : { + *(.foo) + . += 0x200; + } > ram AT>flash +} diff --git a/test/ELF/linkerscript/locationcountererr.s b/test/ELF/linkerscript/locationcountererr.s deleted file mode 100644 index 113e102d4bc2..000000000000 --- a/test/ELF/linkerscript/locationcountererr.s +++ /dev/null @@ -1,11 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -# 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: {{.*}}.script:2: unable to move location counter backward for: .text - -.globl _start -_start: -nop diff --git a/test/ELF/linkerscript/locationcountererr.test b/test/ELF/linkerscript/locationcountererr.test new file mode 100644 index 000000000000..6a1b21319c5b --- /dev/null +++ b/test/ELF/linkerscript/locationcountererr.test @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t +# RUN: not ld.lld %t --script %s -o %t1 2>&1 | FileCheck %s +# CHECK: {{.*}}.test:8: unable to move location counter backward for: .text + +SECTIONS { + .text 0x2000 : { + . = 0x10; + *(.text) + } +} diff --git a/test/ELF/linkerscript/locationcountererr2.s b/test/ELF/linkerscript/locationcountererr2.s index 8968f6740ee4..9efe86a7283b 100644 --- a/test/ELF/linkerscript/locationcountererr2.s +++ b/test/ELF/linkerscript/locationcountererr2.s @@ -1,11 +1,11 @@ # 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; .text : {} }" >> %t.script +# RUN: echo ". = 0x150; . = 0x10; .text : {} }" >> %t.script # RUN: ld.lld %t.o --script %t.script -o %t -shared # RUN: llvm-objdump -section-headers %t | FileCheck %s -# CHECK: Idx Name Size Address -# CHECK: 1 .text 00000000 0000000000000010 +# CHECK: Name Size Address +# CHECK: .text 00000000 0000000000000010 # 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/map-file.test b/test/ELF/linkerscript/map-file.test new file mode 100644 index 000000000000..540b8d494887 --- /dev/null +++ b/test/ELF/linkerscript/map-file.test @@ -0,0 +1,60 @@ +# REQUIRES: x86 + +# RUN: echo '.quad sym3; .quad sym4; .section .foo.1, "a"; .quad 1' > %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o + +# RUN: ld.lld -o %t %t.o -Map=%t.map --script %s +# RUN: FileCheck -strict-whitespace %s < %t.map + +SECTIONS { + . = 0x1000; + .foo : { + BYTE(0x11) + SHORT(0x1122) + LONG(0x11223344) + QUAD(0x1122334455667788) + PROVIDE_HIDDEN(sym4 = .); + . += 0x1000; + *(.foo.1) + PROVIDE(unused1 = 0xff); + HIDDEN(sym6 = .); + . += 0x123 * + (1 + 1); + foo = .; + bar = 0x42 - 0x26; + } + sym1 = .; + . += 0x500; + sym2 = .; + PROVIDE(unused2 = 0xff); + PROVIDE(sym3 = 42); +} + +# CHECK: VMA LMA Size Align Out In Symbol +# CHECK-NEXT: 0 0 1000 1 . = 0x1000 +# CHECK-NEXT: 1000 1000 125d 1 .foo +# CHECK-NEXT: 1000 1000 1 1 BYTE ( 0x11 ) +# CHECK-NEXT: 1001 1001 2 1 SHORT ( 0x1122 ) +# CHECK-NEXT: 1003 1003 4 1 LONG ( 0x11223344 ) +# CHECK-NEXT: 1007 1007 8 1 QUAD ( 0x1122334455667788 ) +# CHECK-NEXT: 100f 100f 0 1 PROVIDE_HIDDEN ( sym4 = . ) +# CHECK-NEXT: 100f 100f 1000 1 . += 0x1000 +# CHECK-NEXT: 200f 200f 8 1 {{.*}}{{/|\\}}map-file.test.tmp.o:(.foo.1) +# CHECK-NEXT: 2017 2017 0 1 HIDDEN ( sym6 = . ) +# CHECK-NEXT: 2017 2017 246 1 . += 0x123 * ( 1 + 1 ) +# CHECK-NEXT: 225d 225d 0 1 foo = . +# CHECK-NEXT: 225d 225d 0 1 bar = 0x42 - 0x26 +# CHECK-NEXT: 225d 0 0 1 sym1 = . +# CHECK-NEXT: 225d 0 500 1 . += 0x500 +# CHECK-NEXT: 275d 0 0 1 sym2 = . +# CHECK-NEXT: 275d 0 0 1 PROVIDE ( sym3 = 42 ) +# CHECK-NEXT: 2760 2760 10 4 .text +# CHECK-NEXT: 2760 2760 10 4 {{.*}}{{/|\\}}map-file.test.tmp.o:(.text) +# CHECK-NEXT: 0 0 8 1 .comment +# CHECK-NEXT: 0 0 8 1 <internal>:(.comment) +# CHECK-NEXT: 0 0 c0 8 .symtab +# CHECK-NEXT: 0 0 c0 8 <internal>:(.symtab) +# CHECK-NEXT: 0 0 2f 1 .shstrtab +# CHECK-NEXT: 0 0 2f 1 <internal>:(.shstrtab) +# CHECK-NEXT: 0 0 22 1 .strtab +# CHECK-NEXT: 0 0 22 1 <internal>:(.strtab) diff --git a/test/ELF/linkerscript/map-file2.test b/test/ELF/linkerscript/map-file2.test new file mode 100644 index 000000000000..d9ed339e228d --- /dev/null +++ b/test/ELF/linkerscript/map-file2.test @@ -0,0 +1,44 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file2.s -o %t.o +# RUN: ld.lld -o %t %t.o -Map=%t.map --script %s +# RUN: FileCheck -strict-whitespace %s < %t.map + +SECTIONS { + . = 0x1000; + .aaa : { *(.aaa.*) } + .bbb : AT(0x2000) { *(.bbb.*) } + .ccc : AT(0x3000) { *(.ccc.*) } + .ddd : { + BYTE(0x11) + . += 0x100; + *(.ddd.*) + } + .text : { *(.text.*) } +} + +# CHECK: VMA LMA Size Align Out In Symbol +# CHECK-NEXT: 0 0 1000 1 . = 0x1000 +# CHECK-NEXT: 1000 1000 8 1 .aaa +# CHECK-NEXT: 1000 1000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.aaa) +# CHECK-NEXT: 1008 2000 8 1 .bbb +# CHECK-NEXT: 1008 2000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.bbb) +# CHECK-NEXT: 1010 3000 8 1 .ccc +# CHECK-NEXT: 1010 3000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ccc) +# CHECK-NEXT: 1018 3008 109 1 .ddd +# CHECK-NEXT: 1018 3008 1 1 BYTE ( 0x11 ) +# CHECK-NEXT: 1019 3009 100 1 . += 0x100 +# CHECK-NEXT: 1119 3109 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ddd) +# CHECK-NEXT: 1128 3118 34 8 .eh_frame +# CHECK-NEXT: 1128 3118 30 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.eh_frame+0x0) +# CHECK-NEXT: 115c 314c 1 4 .text +# CHECK-NEXT: 115c 314c 1 4 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.text) +# CHECK-NEXT: 115c 314c 0 1 f(int) +# CHECK-NEXT: 115c 314c 0 1 _start +# CHECK-NEXT: 0 0 8 1 .comment +# CHECK-NEXT: 0 0 8 1 <internal>:(.comment) +# CHECK-NEXT: 0 0 48 8 .symtab +# CHECK-NEXT: 0 0 48 8 <internal>:(.symtab) +# CHECK-NEXT: 0 0 48 1 .shstrtab +# CHECK-NEXT: 0 0 48 1 <internal>:(.shstrtab) +# CHECK-NEXT: 0 0 e 1 .strtab +# CHECK-NEXT: 0 0 e 1 <internal>:(.strtab) diff --git a/test/ELF/linkerscript/memory-at.s b/test/ELF/linkerscript/memory-at.test index 9e56dbdbd657..0f06a6620a79 100644 --- a/test/ELF/linkerscript/memory-at.s +++ b/test/ELF/linkerscript/memory-at.test @@ -1,16 +1,21 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "MEMORY { \ -# RUN: FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0x100 \ -# RUN: RAM (rwx) : ORIGIN = 0x2000, LENGTH = 0x100 } \ -# RUN: SECTIONS { \ -# RUN: .text : { *(.text*) } > FLASH \ -# RUN: __etext = .; \ -# RUN: .data : AT (__etext) { *(.data*) } > RAM \ -# RUN: }" > %t.script -# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: echo '.section .text,"ax"; .quad 0' > %t.s +# RUN: echo '.section .data,"aw"; .quad 0' >> %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t +# RUN: ld.lld %t --script %s -o %t2 # RUN: llvm-readobj -program-headers %t2 | FileCheck %s +MEMORY { + FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0x100 + RAM (rwx) : ORIGIN = 0x2000, LENGTH = 0x100 +} + +SECTIONS { + .text : { *(.text*) } > FLASH + __etext = .; + .data : AT (__etext) { *(.data*) } > RAM +} + # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD @@ -38,9 +43,3 @@ # CHECK-NEXT: ] # CHECK-NEXT: Alignment: # CHECK-NEXT: } - -.section .text, "ax" -.quad 0 - -.section .data, "aw" -.quad 0 diff --git a/test/ELF/linkerscript/memory-data-commands.test b/test/ELF/linkerscript/memory-data-commands.test new file mode 100644 index 000000000000..2762ec9e985f --- /dev/null +++ b/test/ELF/linkerscript/memory-data-commands.test @@ -0,0 +1,22 @@ +# REQUIRES: x86 + +# RUN: echo ".section .foo,\"a\"" > %t.s +# RUN: echo ".quad 1" >> %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o + +# RUN: not ld.lld -o %t %t.o --script %s 2>&1 | FileCheck %s + +# Check we are able to catch 'ram' overflow caused by BYTE command. +# CHECK: error: section '.foo' will not fit in region 'ram': overflowed by 1 bytes + +MEMORY { + text (rwx): org = 0x0, len = 0x1000 + ram (rwx): org = 0x1000, len = 8 +} +SECTIONS { + .text : { *(.text) } > text + .foo : { + *(.foo) + BYTE(0x1) + } > ram +} diff --git a/test/ELF/linkerscript/memory-loc-counter.test b/test/ELF/linkerscript/memory-loc-counter.test new file mode 100644 index 000000000000..3ca9a2cf6caa --- /dev/null +++ b/test/ELF/linkerscript/memory-loc-counter.test @@ -0,0 +1,37 @@ +# REQUIRES: x86 + +# RUN: echo ".section .foo,\"a\"" > %t.s +# RUN: echo ".quad 1" >> %t.s +# RUN: echo ".section .bar,\"a\"" >> %t.s +# RUN: echo ".quad 1" >> %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o + +# RUN: ld.lld -o %t %t.o --script %s +# RUN: llvm-readelf -sections -program-headers %t | FileCheck %s + +## Check that we can produce output without errors, +## and .foo section has proper size. +# CHECK: Section Headers: +# CHECK-NEXT: [Nr] Name Type Address Off Size +# CHECK-NEXT: [ 0] NULL 0000000000000000 000000 000000 +# CHECK-NEXT: [ 1] .foo PROGBITS 0000000000001000 001000 000108 +# CHECK-NEXT: [ 2] .bar PROGBITS 0000000000001108 001108 000008 + +## Check that load address is correct. +# CHECK: Program Headers: +# CHECK-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz +# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000002000 0x000110 0x000110 + +MEMORY { + ram (rwx) : org = 0x1000, len = 0x200 + flash (rwx) : org = 0x2000, len = 0x200 +} +SECTIONS { + .foo : { + *(.foo) + . += 0x100; + } > ram AT>flash + .bar : { + *(.bar) + } > ram AT>flash +} diff --git a/test/ELF/linkerscript/memory-region-alignment.test b/test/ELF/linkerscript/memory-region-alignment.test new file mode 100644 index 000000000000..ba9d4e3bab3f --- /dev/null +++ b/test/ELF/linkerscript/memory-region-alignment.test @@ -0,0 +1,58 @@ +# REQUIRES: x86 +# RUN: echo '.section .foo,"a"; .quad 0; .section .zed,"M",@progbits,1; .byte 0' > %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o + +MEMORY { + ram (rwx): org = 0x1, len = 96K +} + +SECTIONS { + .foo : ALIGN(8) { + *(.foo) + } > ram + + .zed : { + *(.zed) + } > ram +} + +# RUN: ld.lld %t.o -o %t --script %s +# RUN: llvm-readobj -sections %t | FileCheck %s + +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x8 +# CHECK-NEXT: Offset: 0x1008 +# CHECK-NEXT: Size: 8 + +# CHECK: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10 +# CHECK-NEXT: Offset: 0x1010 +# CHECK-NEXT: Size: 0 + +# CHECK: Name: .zed +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_MERGE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10 +# CHECK-NEXT: Offset: 0x1010 +# CHECK-NEXT: Size: 1 + +# CHECK: Name: .comment +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_MERGE +# CHECK-NEXT: SHF_STRINGS +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x1011 +# CHECK-NEXT: Size: 8 diff --git a/test/ELF/linkerscript/memory.s b/test/ELF/linkerscript/memory.s index 172768394d30..0c171425b20a 100644 --- a/test/ELF/linkerscript/memory.s +++ b/test/ELF/linkerscript/memory.s @@ -11,7 +11,7 @@ # 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: 1 .text 00000001 0000000000008000 TEXT # RAM-NEXT: 2 .data 00001000 0000000000008001 DATA ## Check RAM and ROM memory regions. @@ -27,7 +27,7 @@ # 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: 1 .text 00000001 0000000080000000 TEXT # RAMROM-NEXT: 2 .data 00001000 0000000000000000 DATA ## Check memory region placement by attributes. @@ -43,7 +43,7 @@ # 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: 1 .text 00000001 0000000080000000 TEXT # ATTRS: 2 .data 00001000 0000000000000000 DATA ## Check bad `ORIGIN`. diff --git a/test/ELF/linkerscript/memory2.s b/test/ELF/linkerscript/memory2.s index 2e7381fb8914..7f86ecec29b7 100644 --- a/test/ELF/linkerscript/memory2.s +++ b/test/ELF/linkerscript/memory2.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0, LENGTH = 2K } \ # RUN: SECTIONS { .text : { *(.text*) } > ram }" > %t.script -# RUN: ld.lld -o %t2 --script %t.script %t +# RUN: ld.lld -o /dev/null --script %t.script %t .text .global _start diff --git a/test/ELF/linkerscript/memory4.test b/test/ELF/linkerscript/memory4.test new file mode 100644 index 000000000000..e73d36085562 --- /dev/null +++ b/test/ELF/linkerscript/memory4.test @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: echo ".section .text,\"ax\"; nop; .section .data,\"aw\"; nop;" \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o +# RUN: ld.lld -o %t.so --script %s %t.o +# RUN: llvm-objdump -section-headers %t.so | FileCheck %s + +# CHECK: 1 .text 00000001 0000000000042000 +# CHECK-NEXT: 2 .data 00000001 0000000000042400 + +## Test that address expressions changes the position in a memory region. + +MEMORY { + ram (wxa) : ORIGIN = 0x42000, LENGTH = 0x100000 +} +SECTIONS { + .text : { *(.text*) } + data_addr = ALIGN(1024); + .data data_addr : { *(.data*) } +} diff --git a/test/ELF/linkerscript/memory5.test b/test/ELF/linkerscript/memory5.test new file mode 100644 index 000000000000..150ddf0e833c --- /dev/null +++ b/test/ELF/linkerscript/memory5.test @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: echo ".section .text,\"ax\"; nop; .section .data,\"aw\"; nop;" \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o +# RUN: ld.lld -o %t.so --script %s %t.o +# RUN: llvm-objdump -section-headers %t.so | FileCheck %s + +# CHECK: 1 .text 00000001 0000000000042000 +# CHECK-NEXT: 2 .data 00000001 0000000000044001 + +## Test that assign to Dot changes the position in a memory region. + +MEMORY { + ram (wxa) : ORIGIN = 0x42000, LENGTH = 0x100000 +} +SECTIONS { + .text : { *(.text*) } + . += 0x2000; + .data : { *(.data*) } +} diff --git a/test/ELF/linkerscript/merge-header-load.s b/test/ELF/linkerscript/merge-header-load.s new file mode 100644 index 000000000000..5fb866abef85 --- /dev/null +++ b/test/ELF/linkerscript/merge-header-load.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: . = 0xffffffff80000200; \ +# RUN: .text : AT (0x4200) { *(.text) } \ +# RUN: }" > %t.script +# RUN: ld.lld %t.o --script %t.script -o %t +# RUN: llvm-readelf -program-headers %t | FileCheck %s + +# Test that we put the header in the first PT_LOAD. We used to create a PT_LOAD +# just for it and it would have a different virtual to physical address delta. + +# CHECK: Program Headers: +# CHECK: Type Offset VirtAddr PhysAddr +# CHECK-NEXT: PHDR 0x000040 0xffffffff80000040 0x0000000000004040 +# CHECK-NEXT: LOAD 0x000000 0xffffffff80000000 0x0000000000004000 +# CHECK-NOT: LOAD + +.global _start +_start: +nop diff --git a/test/ELF/linkerscript/merge-sections-syms.s b/test/ELF/linkerscript/merge-sections-syms.s index 713d334a1a5a..421749b6f1b9 100644 --- a/test/ELF/linkerscript/merge-sections-syms.s +++ b/test/ELF/linkerscript/merge-sections-syms.s @@ -20,7 +20,7 @@ # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: A -# CHECK-NEXT: Value: 0x195 +# CHECK-NEXT: Value: 0x226 # CHECK-NEXT: Size: # CHECK-NEXT: Binding: # CHECK-NEXT: Type: @@ -29,7 +29,7 @@ # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: B -# CHECK-NEXT: Value: 0x196 +# CHECK-NEXT: Value: 0x227 # CHECK-NEXT: Size: # CHECK-NEXT: Binding: # CHECK-NEXT: Type: diff --git a/test/ELF/linkerscript/merge-sections.s b/test/ELF/linkerscript/merge-sections.s index 2709bdaee444..8fb9e87d616a 100644 --- a/test/ELF/linkerscript/merge-sections.s +++ b/test/ELF/linkerscript/merge-sections.s @@ -28,8 +28,7 @@ # CHECK-NEXT: Value: 0x[[ADDR1]] # CHECK: Name: end -# 0x19E = begin + sizeof(.foo) = 0x190 + 0xE -# CHECK-NEXT: Value: 0x19E +# CHECK-NEXT: Value: 0x236 # Check that we don't crash with --gc-sections # RUN: ld.lld --gc-sections -o %t2 --script %t.script %t -shared diff --git a/test/ELF/linkerscript/no-pt-load.s b/test/ELF/linkerscript/no-pt-load.s deleted file mode 100644 index c70402501391..000000000000 --- a/test/ELF/linkerscript/no-pt-load.s +++ /dev/null @@ -1,5 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "PHDRS {foo PT_DYNAMIC ;} " \ -# RUN: "SECTIONS { .text : { *(.text) } : foo }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t.o diff --git a/test/ELF/linkerscript/no-pt-load.test b/test/ELF/linkerscript/no-pt-load.test new file mode 100644 index 000000000000..16f7f4409984 --- /dev/null +++ b/test/ELF/linkerscript/no-pt-load.test @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -o %t1 --script %s %t.o + +## Check we do not crash. + +PHDRS { foo PT_DYNAMIC; } + +SECTIONS { + .text : { *(.text) } : foo +} diff --git a/test/ELF/linkerscript/no-space.s b/test/ELF/linkerscript/no-space.s index 21a38e42b2a3..7232495a3fd4 100644 --- a/test/ELF/linkerscript/no-space.s +++ b/test/ELF/linkerscript/no-space.s @@ -1,13 +1,13 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS {foo 0 : {*(foo*)} }" > %t.script +# RUN: echo "SECTIONS {foo 0 : {*(foo*)} .dynsym : {*(.dynsym)} .dynstr : {*(.dynstr)} }" > %t.script # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared -# RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s +# RUN: llvm-readelf -l %t | FileCheck %s -# RUN: echo "SECTIONS {foo : {*(foo*)} }" > %t.script +# RUN: echo "SECTIONS {foo : {*(foo*)} .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } }" > %t.script # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared -# RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s +# RUN: llvm-readelf -l %t | FileCheck %s # There is not enough address space available for the header, so just start the PT_LOAD # after it. Don't create a PT_PHDR as the header is not allocated. @@ -18,7 +18,7 @@ # CHECK: Section to Segment mapping: # CHECK-NEXT: Segment Sections... -# CHECK-NEXT: 00 foo .text .dynsym .hash .dynstr +# CHECK-NEXT: 00 foo .dynsym .dynstr .hash .section foo, "a" .quad 0 diff --git a/test/ELF/linkerscript/nobits-offset.s b/test/ELF/linkerscript/nobits-offset.s new file mode 100644 index 000000000000..c4141487630b --- /dev/null +++ b/test/ELF/linkerscript/nobits-offset.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .sec1 (NOLOAD) : { . += 1; } \ +# RUN: .text : { *(.text) } \ +# RUN: };" > %t.script +# RUN: ld.lld %t.o -T %t.script -o %t +# RUN: llvm-readelf --sections %t | FileCheck %s + +# We used to misalign section offsets if the first section in a +# PT_LOAD was SHT_NOBITS. + +# CHECK: [ 2] .text PROGBITS 0000000000000010 001010 000010 00 AX 0 0 16 + +.global _start +_start: + nop +.p2align 4 diff --git a/test/ELF/linkerscript/noload.s b/test/ELF/linkerscript/noload.s index 28be55df1f12..bd49160d80bd 100644 --- a/test/ELF/linkerscript/noload.s +++ b/test/ELF/linkerscript/noload.s @@ -2,12 +2,13 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { \ # RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \ -# RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script +# RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } \ +# RUN: .text (0x20000) : { *(.text) } };" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-readobj --symbols -sections %t | FileCheck %s +# RUN: llvm-readobj -sections -program-headers %t | FileCheck %s # CHECK: Section { -# CHECK: Index: 2 +# CHECK: Index: 1 # CHECK-NEXT: Name: .data_noload_a # CHECK-NEXT: Type: SHT_NOBITS # CHECK-NEXT: Flags [ @@ -15,7 +16,7 @@ # CHECK-NEXT: SHF_WRITE # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Offset: 0xE8 # CHECK-NEXT: Size: 4096 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -23,7 +24,7 @@ # CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Index: 2 # CHECK-NEXT: Name: .data_noload_b # CHECK-NEXT: Type: SHT_NOBITS # CHECK-NEXT: Flags [ @@ -31,13 +32,29 @@ # CHECK-NEXT: SHF_WRITE # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x10000 -# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Offset: 0xE8 # CHECK-NEXT: Size: 4096 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 # CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: } +# CHECK: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x20000 +# CHECK-NEXT: PhysicalAddress: 0x20000 +# CHECK-NEXT: FileSize: 1 +# CHECK-NEXT: MemSize: 1 +# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } + +.section .text,"ax",@progbits + nop .section .data_noload_a,"aw",@progbits .zero 4096 diff --git a/test/ELF/linkerscript/non-absolute.s b/test/ELF/linkerscript/non-absolute.s index a0e9e7dc6782..b4b25a7bbf84 100644 --- a/test/ELF/linkerscript/non-absolute.s +++ b/test/ELF/linkerscript/non-absolute.s @@ -5,9 +5,11 @@ # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DUMP # RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SYMBOL +# B = A + 0x1 = -0x10 + 0x1 = -0xf -> 0xFFFFFFFFFFFFFFF1 +# B - (0x94+6) = -0xf - (0x94+6) = -169 # DUMP: Disassembly of section .text: # DUMP-NEXT: foo: -# DUMP-NEXT: 0: {{.*}} -21(%rip), %eax +# DUMP-NEXT: 94: {{.*}} -169(%rip), %eax # SYMBOL: Symbol { # SYMBOL: Name: B @@ -18,7 +20,7 @@ # SYMBOL-NEXT: Other [ # SYMBOL-NEXT: STV_HIDDEN # SYMBOL-NEXT: ] -# SYMBOL-NEXT: Section: .text +# SYMBOL-NEXT: Section: .dynsym # SYMBOL-NEXT: } .text diff --git a/test/ELF/linkerscript/non-absolute2.s b/test/ELF/linkerscript/non-absolute2.s deleted file mode 100644 index 97c34d31a912..000000000000 --- a/test/ELF/linkerscript/non-absolute2.s +++ /dev/null @@ -1,12 +0,0 @@ -# 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-absolute2.test b/test/ELF/linkerscript/non-absolute2.test new file mode 100644 index 000000000000..b60666412b8a --- /dev/null +++ b/test/ELF/linkerscript/non-absolute2.test @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t1.o +# RUN: ld.lld -shared %t1.o --script %s -o %t +# RUN: llvm-objdump -section-headers -t %t | FileCheck %s + +SECTIONS { + A = . + 0x1; + . += 0x1000; +} + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .dynsym 00000030 0000000000001000 +# CHECK: 5 .text 00000000 000000000000106c + +# CHECK: 0000000000000001 .dynsym 00000000 A diff --git a/test/ELF/linkerscript/non-alloc-segment.s b/test/ELF/linkerscript/non-alloc-segment.s index 229f028a16b2..d9984b3867d4 100644 --- a/test/ELF/linkerscript/non-alloc-segment.s +++ b/test/ELF/linkerscript/non-alloc-segment.s @@ -16,7 +16,7 @@ # RUN: .foo : {*(.foo)} :foo \ # RUN: }" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s +# RUN: llvm-readelf -s -l %t | FileCheck %s # RUN: llvm-readobj -l %t | FileCheck --check-prefix=PHDR %s # CHECK: Program Headers: diff --git a/test/ELF/linkerscript/non-alloc.s b/test/ELF/linkerscript/non-alloc.s index 3257cb965565..87f9afff8091 100644 --- a/test/ELF/linkerscript/non-alloc.s +++ b/test/ELF/linkerscript/non-alloc.s @@ -1,9 +1,9 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script -# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared -# RUN: llvm-readobj -elf-output-style=GNU -s -l %t1 | FileCheck %s +# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared +# RUN: llvm-readelf -s -l %t | FileCheck %s # Test that we create all necessary PT_LOAD. We use to stop at the first # non-alloc, causing us to not create PT_LOAD for linker generated sections. @@ -15,7 +15,7 @@ # CHECK: Section to Segment mapping: # CHECK-NEXT: Segment Sections... -# CHECK-NEXT: 00 .text .dynsym .hash .dynstr +# CHECK-NEXT: 00 .dynsym .hash .dynstr .text # CHECK-NEXT: 01 .dynamic nop diff --git a/test/ELF/linkerscript/numbers.s b/test/ELF/linkerscript/numbers.s index d4fd13fd8197..98d7e3361343 100644 --- a/test/ELF/linkerscript/numbers.s +++ b/test/ELF/linkerscript/numbers.s @@ -29,12 +29,12 @@ ## Mailformed number errors. # RUN: echo "SECTIONS { . = 0x11h; }" > %t2.script -# RUN: not ld.lld %t --script %t2.script -o %t3 2>&1 | \ +# RUN: not ld.lld %t --script %t2.script -o /dev/null 2>&1 | \ # RUN: FileCheck --check-prefix=ERR1 %s # ERR1: malformed number: 0x11h # RUN: echo "SECTIONS { . = 0x11k; }" > %t3.script -# RUN: not ld.lld %t --script %t3.script -o %t4 2>&1 | \ +# RUN: not ld.lld %t --script %t3.script -o /dev/null 2>&1 | \ # RUN: FileCheck --check-prefix=ERR2 %s # ERR2: malformed number: 0x11k @@ -43,13 +43,28 @@ # RUN: FileCheck --check-prefix=ERR3 %s # ERR3: malformed number: 0x11m +# RUN: echo "SECTIONS { . = 1zh; }" > %t5.script +# RUN: not ld.lld %t --script %t5.script -o %t5 2>&1 | \ +# RUN: FileCheck --check-prefix=ERR4 %s +# ERR4: malformed number: 1zh + +# RUN: echo "SECTIONS { . = 1zk; }" > %t6.script +# RUN: not ld.lld %t --script %t6.script -o %t6 2>&1 | \ +# RUN: FileCheck --check-prefix=ERR5 %s +# ERR5: malformed number: 1zk + +# RUN: echo "SECTIONS { . = 1zm; }" > %t7.script +# RUN: not ld.lld %t --script %t7.script -o /dev/null 2>&1 | \ +# RUN: FileCheck --check-prefix=ERR6 %s +# ERR6: malformed number: 1zm + ## 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: }" > %t8.script +# RUN: ld.lld %t --script %t8.script -o %t6 # RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s # SECADDR: Sections: # SECADDR-NEXT: Idx Name Size Address diff --git a/test/ELF/linkerscript/openbsd-bootdata.s b/test/ELF/linkerscript/openbsd-bootdata.s deleted file mode 100644 index 3e90574bb3a3..000000000000 --- a/test/ELF/linkerscript/openbsd-bootdata.s +++ /dev/null @@ -1,7 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o -# RUN: echo "PHDRS { boot PT_OPENBSD_BOOTDATA; }" > %t.script -# RUN: ld.lld --script %t.script %t.o -o %t -# RUN: llvm-readobj --program-headers -s %t | FileCheck %s - -# CHECK: ProgramHeader { -# CHECK: Type: PT_OPENBSD_BOOTDATA (0x65A41BE6) diff --git a/test/ELF/linkerscript/openbsd-bootdata.test b/test/ELF/linkerscript/openbsd-bootdata.test new file mode 100644 index 000000000000..6846c7f22f86 --- /dev/null +++ b/test/ELF/linkerscript/openbsd-bootdata.test @@ -0,0 +1,9 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux /dev/null -o %t.o +# RUN: ld.lld --script %s %t.o -o %t +# RUN: llvm-readobj --program-headers -s %t | FileCheck %s + +PHDRS { boot PT_OPENBSD_BOOTDATA; } + +# CHECK: ProgramHeader { +# CHECK: Type: PT_OPENBSD_BOOTDATA (0x65A41BE6) diff --git a/test/ELF/linkerscript/openbsd-randomize.s b/test/ELF/linkerscript/openbsd-randomize.s index bf885f423b02..575a6b25be78 100644 --- a/test/ELF/linkerscript/openbsd-randomize.s +++ b/test/ELF/linkerscript/openbsd-randomize.s @@ -1,3 +1,4 @@ +# REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o # RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; rand PT_OPENBSD_RANDOMIZE; } \ # RUN: SECTIONS { . = SIZEOF_HEADERS; \ diff --git a/test/ELF/linkerscript/openbsd-wxneeded.s b/test/ELF/linkerscript/openbsd-wxneeded.test index d371da9d8645..1868c0e08802 100644 --- a/test/ELF/linkerscript/openbsd-wxneeded.s +++ b/test/ELF/linkerscript/openbsd-wxneeded.test @@ -1,8 +1,10 @@ -# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o -# RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; wxneeded PT_OPENBSD_WXNEEDED; }" > %t.script -# RUN: ld.lld -z wxneeded --script %t.script %t.o -o %t +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux /dev/null -o %t.o +# RUN: ld.lld -z wxneeded --script %s %t.o -o %t # RUN: llvm-readobj --program-headers %t | FileCheck %s +PHDRS { text PT_LOAD FILEHDR PHDRS; wxneeded PT_OPENBSD_WXNEEDED; } + # CHECK: ProgramHeader { # CHECK: Type: PT_OPENBSD_WXNEEDED (0x65A3DBE7) # CHECK-NEXT: Offset: 0x0 diff --git a/test/ELF/linkerscript/operators.s b/test/ELF/linkerscript/operators.test index 494fc08c0f99..2be24dfc2fe3 100644 --- a/test/ELF/linkerscript/operators.s +++ b/test/ELF/linkerscript/operators.test @@ -1,42 +1,57 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { \ -# RUN: _start = .; \ -# 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: datasegmentalign2 = DATA_SEGMENT_ALIGN (0, 0); \ -# RUN: _end = .; \ -# RUN: minus_rel = _end - 0x10; \ -# RUN: minus_abs = _end - _start; \ -# RUN: }" > %t.script -# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t +# RUN: ld.lld %t --script %s -o %t2 # RUN: llvm-objdump -t %t2 | FileCheck %s +SECTIONS { + _start = .; + plus = 1 + 2 + 3; + minus = 5 - 1; + div = 6 / 2; + mod = 20 % 7; + mul = 1 + 2 * 3; + nospace = 1+2*6/3; + braces = 1 + (2 + 3) * 4; + and = 0xbb & 0xee; + ternary1 = 1 ? 1 : 2; + ternary2 = 0 ? 1 : 2; + less = 1 < 0 ? 1 : 2; + lesseq = 1 <= 1 ? 1 : 2; + greater = 0 > 1 ? 1 : 2; + greatereq = 1 >= 1 ? 1 : 2; + eq = 1 == 1 ? 1 : 2; + neq = 1 != 1 ? 1 : 2; + plusassign = 1; + plusassign += 2; + unary = -1 + 3; + lshift = 1 << 5; + rshift = 0xff >> 3; + precedence1 = 1 | 0xff & 1 << 1 + 1 * 2; + precedence2 = (1 | (0xff & (1 << (1 + (1 * 2))))); + maxpagesize = CONSTANT (MAXPAGESIZE); + commonpagesize = CONSTANT (COMMONPAGESIZE); + . = 0xfff0; + datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0); + datasegmentalign2 = DATA_SEGMENT_ALIGN (0, 0); + _end = .; + minus_rel = _end - 0x10; + minus_abs = _end - _start; + max = MAX(11, 22); + min = MIN(11, 22); + logicaland1 = 0 && 0; + logicaland2 = 0 && 1; + logicaland3 = 1 && 0; + logicaland4 = 1 && 1; + logicalor1 = 0 || 0; + logicalor2 = 0 || 1; + logicalor3 = 1 || 0; + logicalor4 = 1 || 1; +} + # CHECK: 00000000000006 *ABS* 00000000 plus # CHECK: 00000000000004 *ABS* 00000000 minus # CHECK: 00000000000003 *ABS* 00000000 div +# CHECK: 00000000000006 *ABS* 00000000 mod # CHECK: 00000000000007 *ABS* 00000000 mul # CHECK: 00000000000005 *ABS* 00000000 nospace # CHECK: 00000000000015 *ABS* 00000000 braces @@ -53,12 +68,24 @@ # CHECK: 00000000000002 *ABS* 00000000 unary # CHECK: 00000000000020 *ABS* 00000000 lshift # CHECK: 0000000000001f *ABS* 00000000 rshift +# CHECK: 00000000000009 *ABS* 00000000 precedence1 +# CHECK: 00000000000009 *ABS* 00000000 precedence2 # CHECK: 00000000001000 *ABS* 00000000 maxpagesize # CHECK: 00000000001000 *ABS* 00000000 commonpagesize # CHECK: 0000000000ffff *ABS* 00000000 datasegmentalign # CHECK: 0000000000fff0 *ABS* 00000000 datasegmentalign2 # CHECK: 0000000000ffe0 .text 00000000 minus_rel # CHECK: 0000000000fff0 *ABS* 00000000 minus_abs +# CHECK: 00000000000016 *ABS* 00000000 max +# CHECK: 0000000000000b *ABS* 00000000 min +# CHECK: 00000000000000 *ABS* 00000000 logicaland1 +# CHECK: 00000000000000 *ABS* 00000000 logicaland2 +# CHECK: 00000000000000 *ABS* 00000000 logicaland3 +# CHECK: 00000000000001 *ABS* 00000000 logicaland4 +# CHECK: 00000000000000 *ABS* 00000000 logicalor1 +# CHECK: 00000000000001 *ABS* 00000000 logicalor2 +# CHECK: 00000000000001 *ABS* 00000000 logicalor3 +# CHECK: 00000000000001 *ABS* 00000000 logicalor4 ## Mailformed number error. # RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script @@ -88,14 +115,16 @@ # 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 +# DIVZERO: {{.*}}.script:1: division by zero + +## Mod 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=MODZERO %s +# MODZERO: {{.*}}.script:1: modulo 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 deleted file mode 100644 index 263cb30d6868..000000000000 --- a/test/ELF/linkerscript/orphan-first-cmd.s +++ /dev/null @@ -1,20 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { \ -# RUN: foo = 123; \ -# RUN: . = 0x1000; \ -# RUN: . = 0x2000; \ -# RUN: .bar : { *(.bar) } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t -T %t.script %t.o -shared -# RUN: llvm-readobj -s %t | FileCheck %s - -# CHECK: Name: .text -# CHECK-NEXT: Type: SHT_PROGBITS -# CHECK-NEXT: Flags [ -# CHECK-NEXT: SHF_ALLOC -# CHECK-NEXT: SHF_EXECINSTR -# CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x1000 - -.section .bar, "aw" diff --git a/test/ELF/linkerscript/orphan-first-cmd.test b/test/ELF/linkerscript/orphan-first-cmd.test new file mode 100644 index 000000000000..84b183f96efb --- /dev/null +++ b/test/ELF/linkerscript/orphan-first-cmd.test @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: echo '.section .bar, "aw"' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: ld.lld -o %t -T %s %t.o -shared +# RUN: llvm-readobj -s %t | FileCheck %s + +SECTIONS { + foo = 123; + . = 0x1000; + . = 0x2000; + .bar : { *(.bar) } +} + +# CHECK: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x1070 diff --git a/test/ELF/linkerscript/orphan-phdrs.s b/test/ELF/linkerscript/orphan-phdrs.s index 648911162e97..f9d1467b532a 100644 --- a/test/ELF/linkerscript/orphan-phdrs.s +++ b/test/ELF/linkerscript/orphan-phdrs.s @@ -10,7 +10,7 @@ # RUN: .rw : { *(.rw) } \ # RUN: }" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s +# RUN: llvm-readelf -s -l %t | FileCheck %s ## Check that the orphan section is placed correctly and belongs to ## the correct segment. @@ -18,6 +18,7 @@ # CHECK: Section Headers # CHECK: .text # CHECK-NEXT: .orphan +# CHECK-NEXT: .empty # CHECK-NEXT: .rw # CHECK: Segment Sections diff --git a/test/ELF/linkerscript/orphan.s b/test/ELF/linkerscript/orphan.s index f51085383a9e..4dbaf37c687e 100644 --- a/test/ELF/linkerscript/orphan.s +++ b/test/ELF/linkerscript/orphan.s @@ -13,7 +13,7 @@ ## .bss is SHT_NOBITS section and should be last RW section, so some space ## in ELF file could be saved. # CHECK: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 .text 00000000 0000000000000000 TEXT DATA +# CHECK-NEXT: 1 .text 00000000 0000000000000000 TEXT # CHECK-NEXT: 2 .rw1 00000008 0000000000000000 DATA # CHECK-NEXT: 3 .rw2 00000008 0000000000000008 DATA # CHECK-NEXT: 4 .rw3 00000008 0000000000000010 DATA diff --git a/test/ELF/linkerscript/out-of-order.s b/test/ELF/linkerscript/out-of-order.s index c43df43e5002..da8c103bb47f 100644 --- a/test/ELF/linkerscript/out-of-order.s +++ b/test/ELF/linkerscript/out-of-order.s @@ -1,19 +1,37 @@ # 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: echo "SECTIONS { .data 0x4000 : {*(.data)} .dynsym 0x2000 : {*(.dynsym)} .dynstr : {*(.dynstr)} }" > %t.script # RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared # RUN: llvm-objdump -section-headers %t.so | FileCheck %s +# Note: how the layout is done: +# we need to layout 2 segments, each contains sections: +# seg1: .data .dynamic +# seg2: .dynsym .dynstr .text .hash +# for each segment, we start from the first section, regardless +# whether it is an orphan or not (sections that are not listed in the +# linkerscript are orphans): +# for seg1, we assign address: .data(0x4000), .dynamic(0x4008) +# for seg2, we assign address: .dynsym(0x2000), .dynstr(0x2018) ... +# .dynsym is not an orphan, so we take address from script, we assign +# .dynstr current address cursor, which is the end # of .dynsym and so +# on for later sections. + +# Also note, it is absolutely *illegal* to have section addresses of +# the same segment in none-increasing order, authors of linker scripts +# must take responsibility to make sure this does not happen. + # CHECK: Sections: # CHECK-NEXT: Idx Name Size Address Type # CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 .data 00000008 0000000000004000 DATA +# CHECK-NEXT: 1 .data 00000008 0000000000004000 # CHECK-NEXT: 2 .dynamic 00000060 0000000000004008 -# CHECK-NEXT: 3 .text 00000008 0000000000002000 TEXT DATA -# CHECK-NEXT: 4 .dynsym 00000018 0000000000002008 -# CHECK-NEXT: 5 .hash 00000010 0000000000002020 -# CHECK-NEXT: 6 .dynstr 00000001 0000000000002030 +# CHECK-NEXT: 3 .dynsym 00000018 0000000000002000 +# CHECK-NEXT: 4 .dynstr 00000001 0000000000002018 +# CHECK-NEXT: 5 .hash 00000010 000000000000201c +# CHECK-NEXT: 6 .text 00000008 000000000000202c .quad 0 .data .quad 0 + diff --git a/test/ELF/linkerscript/output-too-large.s b/test/ELF/linkerscript/output-too-large.s index c892a88a947e..ca85465036fe 100644 --- a/test/ELF/linkerscript/output-too-large.s +++ b/test/ELF/linkerscript/output-too-large.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # 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 +# RUN: not ld.lld --no-check-sections --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s # CHECK: error: output file too large .global _start diff --git a/test/ELF/linkerscript/outputarch.s b/test/ELF/linkerscript/outputarch.s deleted file mode 100644 index dd3bf93611b4..000000000000 --- a/test/ELF/linkerscript/outputarch.s +++ /dev/null @@ -1,4 +0,0 @@ -# REQUIRES: x86 -# 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 diff --git a/test/ELF/linkerscript/outputarch.test b/test/ELF/linkerscript/outputarch.test new file mode 100644 index 000000000000..4819a983cfce --- /dev/null +++ b/test/ELF/linkerscript/outputarch.test @@ -0,0 +1,5 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd /dev/null -o %t1 +# RUN: ld.lld -shared -o %t2 %t1 %s + +OUTPUT_ARCH(All data written here is ignored) diff --git a/test/ELF/linkerscript/overlapping-sections.s b/test/ELF/linkerscript/overlapping-sections.s new file mode 100644 index 000000000000..818301fd2b0e --- /dev/null +++ b/test/ELF/linkerscript/overlapping-sections.s @@ -0,0 +1,113 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "SECTIONS { \ +# RUN: .sec1 0x8000 : AT(0x8000) { sec1_start = .; *(.first_sec) sec1_end = .;} \ +# RUN: .sec2 0x8800 : AT(0x8080) { sec2_start = .; *(.second_sec) sec2_end = .;} \ +# RUN: }" > %t-lma.script +# RUN: not ld.lld -o %t.so --script %t-lma.script %t.o -shared 2>&1 | FileCheck %s -check-prefix LMA-OVERLAP-ERR +# LMA-OVERLAP-ERR: error: section .sec1 load address range overlaps with .sec2 +# LMA-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] +# LMA-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8080, 0x817F] + +# Check that we create the expected binary with --noinhibit-exec or --no-check-sections: +# RUN: ld.lld -o %t.so --script %t-lma.script %t.o -shared --noinhibit-exec +# RUN: ld.lld -o %t.so --script %t-lma.script %t.o -shared --no-check-sections -fatal-warnings +# RUN: ld.lld -o %t.so --script %t-lma.script %t.o -shared --check-sections --no-check-sections -fatal-warnings + +# Verify that the .sec2 was indeed placed in a PT_LOAD where the PhysAddr +# overlaps with where .sec1 is loaded: +# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-LMA +# BAD-LMA-LABEL: Section Headers: +# BAD-LMA: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1 +# BAD-LMA: .sec2 PROGBITS 0000000000008800 002800 000100 00 WA 0 0 1 +# BAD-LMA-LABEL: Program Headers: +# BAD-LMA-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# BAD-LMA-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000 +# BAD-LMA-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW 0x1000 +# BAD-LMA-NEXT: LOAD 0x002800 0x0000000000008800 0x0000000000008080 0x000170 0x000170 RW 0x1000 +# BAD-LMA-LABEL: Section to Segment mapping: +# BAD-LMA: 01 .sec1 +# BAD-LMA: 02 .sec2 .dynamic + +# Now try a script where the virtual memory addresses overlap but ensure that the +# load addresses don't: +# RUN: echo "SECTIONS { \ +# RUN: .sec1 0x8000 : AT(0x8000) { sec1_start = .; *(.first_sec) sec1_end = .;} \ +# RUN: .sec2 0x8020 : AT(0x8800) { sec2_start = .; *(.second_sec) sec2_end = .;} \ +# RUN: }" > %t-vaddr.script +# RUN: not ld.lld -o %t.so --script %t-vaddr.script %t.o -shared 2>&1 | FileCheck %s -check-prefix VADDR-OVERLAP-ERR +# VADDR-OVERLAP-ERR: error: section .sec1 virtual address range overlaps with .sec2 +# VADDR-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] +# VADDR-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8020, 0x811F] + +# Check that the expected binary was created with --noinhibit-exec: +# RUN: ld.lld -o %t.so --script %t-vaddr.script %t.o -shared --noinhibit-exec +# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-VADDR +# BAD-VADDR-LABEL: Section Headers: +# BAD-VADDR: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1 +# BAD-VADDR: .sec2 PROGBITS 0000000000008020 003020 000100 00 WA 0 0 1 +# BAD-VADDR-LABEL: Program Headers: +# BAD-VADDR-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# BAD-VADDR-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000 +# BAD-VADDR-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW 0x1000 +# BAD-VADDR-NEXT: LOAD 0x003020 0x0000000000008020 0x0000000000008800 0x000170 0x000170 RW 0x1000 +# BAD-VADDR-LABEL: Section to Segment mapping: +# BAD-VADDR: 01 .sec1 +# BAD-VADDR: 02 .sec2 .dynamic + +# Finally check the case where both LMA and vaddr overlap + +# RUN: echo "SECTIONS { \ +# RUN: .sec1 0x8000 : { sec1_start = .; *(.first_sec) sec1_end = .;} \ +# RUN: .sec2 0x8040 : { sec2_start = .; *(.second_sec) sec2_end = .;} \ +# RUN: }" > %t-both-overlap.script + +# RUN: not ld.lld -o %t.so --script %t-both-overlap.script %t.o -shared 2>&1 | FileCheck %s -check-prefix BOTH-OVERLAP-ERR + +# BOTH-OVERLAP-ERR: error: section .sec1 file range overlaps with .sec2 +# BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x2000, 0x20FF] +# BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x2040, 0x213F] +# BOTH-OVERLAP-ERR: error: section .sec1 virtual address range overlaps with .sec2 +# BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] +# BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8040, 0x813F] +# BOTH-OVERLAP-ERR: error: section .sec1 load address range overlaps with .sec2 +# BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] +# BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8040, 0x813F] + +# RUN: ld.lld -o %t.so --script %t-both-overlap.script %t.o -shared --noinhibit-exec +# Note: In case everything overlaps we create a binary with overlapping file +# offsets. ld.bfd seems to place .sec1 to file offset 18000 and .sec2 +# at 18100 so that only virtual addr and LMA overlap +# However, in order to create such a broken binary the user has to ignore a +# fatal error by passing --noinhibit-exec, so this behaviour is fine. + +# RUN: llvm-objdump -s %t.so | FileCheck %s -check-prefix BROKEN-OUTPUT-FILE +# BROKEN-OUTPUT-FILE-LABEL: Contents of section .sec1: +# BROKEN-OUTPUT-FILE-NEXT: 8000 01010101 01010101 01010101 01010101 +# BROKEN-OUTPUT-FILE-NEXT: 8010 01010101 01010101 01010101 01010101 +# BROKEN-OUTPUT-FILE-NEXT: 8020 01010101 01010101 01010101 01010101 +# BROKEN-OUTPUT-FILE-NEXT: 8030 01010101 01010101 01010101 01010101 +# Starting here the contents of .sec2 overwrites .sec1: +# BROKEN-OUTPUT-FILE-NEXT: 8040 02020202 02020202 02020202 02020202 + +# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-BOTH +# BAD-BOTH-LABEL: Section Headers: +# BAD-BOTH: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1 +# BAD-BOTH: .sec2 PROGBITS 0000000000008040 002040 000100 00 WA 0 0 1 +# BAD-BOTH-LABEL: Program Headers: +# BAD-BOTH-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# BAD-BOTH-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000 +# BAD-BOTH-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x0001b0 0x0001b0 RW 0x1000 +# BAD-BOTH-LABEL: Section to Segment mapping: +# BAD-BOTH: 01 .sec1 .sec2 .dynamic + +.section .first_sec,"aw",@progbits +.rept 0x100 +.byte 1 +.endr + +.section .second_sec,"aw",@progbits +.rept 0x100 +.byte 2 +.endr diff --git a/test/ELF/linkerscript/overlay-reject.test b/test/ELF/linkerscript/overlay-reject.test new file mode 100644 index 000000000000..fcb82b6df4b5 --- /dev/null +++ b/test/ELF/linkerscript/overlay-reject.test @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld %t.o --script %s -o %t 2>&1 | FileCheck %s + +# CHECK: {{.*}}.test:{{.*}}: { expected, but got 0x3000 +# CHECK-NEXT: >>> .out.aaa 0x3000 : { *(.aaa) } +# CHECK-NEXT: >>> ^ + +SECTIONS { + OVERLAY 0x1000 : AT ( 0x2000 ) { + .out.aaa 0x3000 : { *(.aaa) } + } +} diff --git a/test/ELF/linkerscript/overlay-reject2.test b/test/ELF/linkerscript/overlay-reject2.test new file mode 100644 index 000000000000..490533c5fa5e --- /dev/null +++ b/test/ELF/linkerscript/overlay-reject2.test @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o +# RUN: not ld.lld %t.o --script %s -o %t 2>&1 | FileCheck %s + +# CHECK: {{.*}}.test:{{.*}}: { expected, but got AX +# CHECK-NEXT: >>> .out.aaa { *(.aaa) } > AX AT>FLASH +# CHECK-NEXT: >>> ^ + +MEMORY { + AX (ax) : ORIGIN = 0x3000, LENGTH = 0x4000 +} + +SECTIONS { + OVERLAY 0x1000 : AT ( 0x2000 ) { + .out.aaa { *(.aaa) } > AX AT>FLASH + } +} diff --git a/test/ELF/linkerscript/overlay.test b/test/ELF/linkerscript/overlay.test new file mode 100644 index 000000000000..a28ab610ec09 --- /dev/null +++ b/test/ELF/linkerscript/overlay.test @@ -0,0 +1,30 @@ +# REQUIRES: x86 +# RUN: echo 'nop; .section .small, "a"; .long 0; .section .big, "a"; .quad 1;' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: ld.lld %t.o --script %s -o %t + +SECTIONS { + OVERLAY 0x1000 : AT ( 0x4000 ) { + .out.big { *(.big) } + .out.small { *(.small) } + } +} + +## Here we check that can handle OVERLAY which will produce sections +## .out.big and .out.small with the same starting VAs, but different LMAs. +## Section .big is larger than .small, we check that placing of section +## .text does not cause overlapping error and that +## .text's VA is 0x1000 + max(sizeof(.out.big), sizeof(.out.small)). + +# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t | FileCheck %s + +# CHECK: Section Headers: +# CHECK: Name Type Address Off Size +# CHECK: .out.big PROGBITS 0000000000001000 001000 000008 +# CHECK: .out.small PROGBITS 0000000000001000 002000 000004 +# CHECK: .text PROGBITS 0000000000001008 002008 000001 + +# CHECK: Program Headers: +# CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000004000 0x000008 0x000008 R E 0x1000 +# CHECK-NEXT: LOAD 0x002000 0x0000000000001000 0x0000000000004008 0x000009 0x000009 R E 0x1000 diff --git a/test/ELF/linkerscript/page-size-align.s b/test/ELF/linkerscript/page-size-align.s deleted file mode 100644 index 771bb13a8e6d..000000000000 --- a/test/ELF/linkerscript/page-size-align.s +++ /dev/null @@ -1,22 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o - -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: .text : { *(.text) } \ -# RUN: . = ALIGN(CONSTANT(MAXPAGESIZE)); \ -# RUN: . = . + 0x3000; \ -# RUN: .dynamic : { *(.dynamic) } \ -# RUN: }" > %t.script - -# RUN: ld.lld -T %t.script -z max-page-size=0x4000 %t.o -o %t.so -shared -# RUN: llvm-readobj -s %t.so | FileCheck %s - -# CHECK: Name: .dynamic -# CHECK-NEXT: Type: SHT_DYNAMIC -# CHECK-NEXT: Flags [ -# CHECK-NEXT: SHF_ALLOC -# CHECK-NEXT: SHF_WRITE -# CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x7000 -# CHECK-NEXT: Offset: 0x3000 diff --git a/test/ELF/linkerscript/page-size-align.test b/test/ELF/linkerscript/page-size-align.test new file mode 100644 index 000000000000..f69413157426 --- /dev/null +++ b/test/ELF/linkerscript/page-size-align.test @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -T %s -z max-page-size=0x4000 %t.o -o %t.so -shared +# RUN: llvm-readobj -s %t.so | FileCheck %s + +SECTIONS { + . = SIZEOF_HEADERS; + .text : { *(.text) } + . = ALIGN(CONSTANT(MAXPAGESIZE)); + . = . + 0x3000; + .dynamic : { *(.dynamic) } +} + +# CHECK: Name: .dynamic +# CHECK-NEXT: Type: SHT_DYNAMIC +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x7000 +# CHECK-NEXT: Offset: 0x3000 diff --git a/test/ELF/linkerscript/parse-section-in-addr.test b/test/ELF/linkerscript/parse-section-in-addr.test new file mode 100644 index 000000000000..6f42a6fe2788 --- /dev/null +++ b/test/ELF/linkerscript/parse-section-in-addr.test @@ -0,0 +1,10 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -o %t.so --script %s %t.o -shared +# RUN: llvm-readelf -S %t.so | FileCheck %s + +SECTIONS { + .foo-bar : AT(ADDR(.foo-bar)) { *(.text) } +} + +# CHECK: .foo-bar diff --git a/test/ELF/linkerscript/provide-empty-section.s b/test/ELF/linkerscript/provide-empty-section.s new file mode 100644 index 000000000000..56cb6aca1e3b --- /dev/null +++ b/test/ELF/linkerscript/provide-empty-section.s @@ -0,0 +1,30 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tundefined.o +# RUN: echo "foo=42" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tdefined.o +# RUN: echo "call foo" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %treference.o + +# RUN: echo "SECTIONS { .bar : { PROVIDE(foo = .); } }" > %t.script + +# Case 1: Provided symbol is undefined and not referenced - empty section should be removed. +# RUN: ld.lld %tundefined.o -T %t.script -o %t1.elf +# RUN: llvm-readobj -sections %t1.elf | FileCheck %s --check-prefix=NOSECTION + +# Case 2: Provided symbol is undefined and referenced - empty section should not be removed. +# RUN: ld.lld %tundefined.o %treference.o -T %t.script -o %t2.elf +# RUN: llvm-readobj -sections %t2.elf | FileCheck %s --check-prefix=SECTION + +# Case 3: Provided symbol is defined and not referenced - empty section should be removed. +# RUN: ld.lld %tdefined.o -T %t.script -o %t3.elf +# RUN: llvm-readobj -sections %t3.elf | FileCheck %s --check-prefix=NOSECTION + +# Case 4: Provided symbol is defined and referenced - empty section should not be removed. +# RUN: ld.lld %tdefined.o %treference.o -T %t.script -o %t4.elf +# RUN: llvm-readobj -sections %t4.elf | FileCheck %s --check-prefix=SECTION + +.global _start +_start: + ret + +# SECTION: .bar +# NOSECTION-NOT: .bar diff --git a/test/ELF/linkerscript/provide-shared2.s b/test/ELF/linkerscript/provide-shared2.s new file mode 100644 index 000000000000..8a3200b6f545 --- /dev/null +++ b/test/ELF/linkerscript/provide-shared2.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/provide-shared2.s -o %t2.o +# RUN: ld.lld %t2.o -o %t2.so -shared +# RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; PROVIDE(foo = 42); }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o %t2.so +# RUN: llvm-readelf --dyn-symbols %t | FileCheck %s + +# CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo@ + +.global _start +_start: + nop diff --git a/test/ELF/linkerscript/pt-interp.test b/test/ELF/linkerscript/pt-interp.test new file mode 100644 index 000000000000..0441817aea6d --- /dev/null +++ b/test/ELF/linkerscript/pt-interp.test @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o +# RUN: ld.lld -o %t.so -shared %t.o + +## Check we create PT_INTERP program header when it is specified in PHDRS. +# RUN: echo "PHDRS { interp PT_INTERP; }" > %t1.script +# RUN: ld.lld -o %t1 --script %t1.script %t.o %t.so --dynamic-linker foo +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s +# CHECK: PT_INTERP + +## Check we do not create it if it is not specified, +## but only if PHDRS is not empty by itself. +# RUN: echo "PHDRS { ph_text PT_LOAD; }" > %t2.script +# RUN: ld.lld -o %t1 --script %t2.script %t.o %t.so --dynamic-linker foo +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s --check-prefix=NOINTERP +# NOINTERP-NOT: PT_INTERP + +## Otherwise, if PHDRS is empty, we create PT_INTERP header. +# RUN: echo "PHDRS {}" > %t3.script +# RUN: ld.lld -o %t1 --script %t3.script %t.o %t.so --dynamic-linker foo +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s diff --git a/test/ELF/linkerscript/pt_gnu_eh_frame.s b/test/ELF/linkerscript/pt_gnu_eh_frame.s index 81b4c6307d4c..7f9ebaa8d8d1 100644 --- a/test/ELF/linkerscript/pt_gnu_eh_frame.s +++ b/test/ELF/linkerscript/pt_gnu_eh_frame.s @@ -1,7 +1,7 @@ # 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 +# RUN: ld.lld -o /dev/null --eh-frame-hdr --script %t.script %t .global _start _start: diff --git a/test/ELF/linkerscript/region-alias.s b/test/ELF/linkerscript/region-alias.s index 8a88f6f5ad9f..af4a0f377ddd 100644 --- a/test/ELF/linkerscript/region-alias.s +++ b/test/ELF/linkerscript/region-alias.s @@ -15,7 +15,7 @@ # RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", RAM);" >> %t.script.inc # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-objdump -section-headers %t2 | FileCheck %s -# CHECK: .text 00000001 0000000000001000 TEXT DATA +# CHECK: .text 00000001 0000000000001000 TEXT # CHECK: .data 00000008 0000000000002000 DATA ## All to ROM. @@ -23,7 +23,7 @@ # RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", ROM);" >> %t.script.inc # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=RAM -# RAM: .text 00000001 0000000000001000 TEXT DATA +# RAM: .text 00000001 0000000000001000 TEXT # RAM: .data 00000008 0000000000001001 DATA ## Redefinition of region. diff --git a/test/ELF/linkerscript/rosegment.s b/test/ELF/linkerscript/rosegment.test index 3201b8bda9fb..41479e609d24 100644 --- a/test/ELF/linkerscript/rosegment.s +++ b/test/ELF/linkerscript/rosegment.test @@ -1,12 +1,14 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -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: ld.lld -o %t1 --script %s %t -shared # RUN: llvm-readobj -l %t1 | FileCheck %s +SECTIONS { +} + # CHECK-NOT: Type: PT_LOAD # CHECK: Type: PT_LOAD diff --git a/test/ELF/linkerscript/section-metadata.s b/test/ELF/linkerscript/section-metadata.s index f447240ac3a9..44547b8ab002 100644 --- a/test/ELF/linkerscript/section-metadata.s +++ b/test/ELF/linkerscript/section-metadata.s @@ -10,15 +10,15 @@ # RUN: llvm-objdump -s %t | FileCheck --check-prefix=INV %s -# CHECK: Contents of section .text: -# CHECK-NEXT: 02000000 00000000 01000000 00000000 # CHECK: Contents of section .rodata: # CHECK-NEXT: 02000000 00000000 01000000 00000000 +# CHECK: Contents of section .text: +# CHECK-NEXT: 02000000 00000000 01000000 00000000 -# INV: Contents of section .text: -# INV-NEXT: 01000000 00000000 02000000 00000000 # INV: Contents of section .rodata: # INV-NEXT: 01000000 00000000 02000000 00000000 +# INV: Contents of section .text: +# INV-NEXT: 01000000 00000000 02000000 00000000 .global _start _start: diff --git a/test/ELF/linkerscript/section-metadata2.s b/test/ELF/linkerscript/section-metadata2.s new file mode 100644 index 000000000000..4a538b6190e7 --- /dev/null +++ b/test/ELF/linkerscript/section-metadata2.s @@ -0,0 +1,37 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .text : { *(.text.*) } }" > %t.script + +# RUN: echo "_bar" > %t.ord +# RUN: echo "_foo" >> %t.ord +# RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o +# RUN: llvm-objdump -s %t | FileCheck %s + +# CHECK: Contents of section .rodata: +# CHECK-NEXT: 02000000 00000000 01000000 00000000 +# CHECK: Contents of section .text: +# CHECK-NEXT: 02000000 00000000 01000000 00000000 + +# RUN: echo "_foo" > %t.ord +# RUN: echo "_bar" >> %t.ord +# RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o +# RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=INV + +# INV: Contents of section .rodata: +# INV-NEXT: 01000000 00000000 02000000 00000000 +# INV: Contents of section .text: +# INV-NEXT: 01000000 00000000 02000000 00000000 + +.section .text.foo,"a",@progbits +_foo: +.quad 1 + +.section .text.bar,"a",@progbits +_bar: +.quad 2 + +.section .rodata.foo,"ao",@progbits,.text.foo +.quad 1 + +.section .rodata.bar,"ao",@progbits,.text.bar +.quad 2 diff --git a/test/ELF/linkerscript/sections-keep.s b/test/ELF/linkerscript/sections-keep.s index feb0baca9c3d..2c778e3e936b 100644 --- a/test/ELF/linkerscript/sections-keep.s +++ b/test/ELF/linkerscript/sections-keep.s @@ -1,14 +1,14 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/keep.s -o %t2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/keep.s -o %t1.o ## First check that section "keep" is garbage collected without using KEEP # RUN: echo "SECTIONS { \ # RUN: .text : { *(.text) } \ # RUN: .keep : { *(.keep) } \ # RUN: .temp : { *(.temp) }}" > %t.script -# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t -# RUN: llvm-objdump -section-headers %t1 | \ +# RUN: ld.lld --gc-sections -o %t --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t | \ # RUN: FileCheck -check-prefix=SECGC %s # SECGC: Sections: # SECGC-NEXT: Idx Name Size @@ -21,8 +21,8 @@ # RUN: .text : { *(.text) } \ # RUN: .keep : { KEEP(*(.keep)) } \ # RUN: .temp : { *(.temp) }}" > %t.script -# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t -# RUN: llvm-objdump -section-headers %t1 | \ +# RUN: ld.lld --gc-sections -o %t --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t | \ # RUN: FileCheck -check-prefix=SECNOGC %s # SECNOGC: Sections: # SECNOGC-NEXT: Idx Name Size @@ -38,14 +38,14 @@ # RUN: . = SIZEOF_HEADERS; \ # RUN: .keep : { KEEP(*(.keep)) } \ # RUN: .nokeep : { *(.keep) }}" > %t.script -# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t -# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED1 %s +# RUN: ld.lld --gc-sections -o %t --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=MIXED1 %s # MIXED1: Sections: # MIXED1-NEXT: Idx Name Size # MIXED1-NEXT: 0 00000000 # MIXED1-NEXT: 1 .keep 00000004 -# MIXED1-NEXT: 2 .text 00000007 00000000000000ec TEXT DATA -# MIXED1-NEXT: 3 .temp 00000004 00000000000000f3 DATA +# MIXED1-NEXT: 2 .temp 00000004 00000000000000ec +# MIXED1-NEXT: 3 .text 00000007 00000000000000f0 # MIXED1-NEXT: 4 .comment 00000008 0000000000000000 # MIXED1-NEXT: 5 .symtab 00000060 0000000000000000 # MIXED1-NEXT: 6 .shstrtab 00000036 0000000000000000 @@ -59,14 +59,14 @@ # RUN: . = SIZEOF_HEADERS; \ # RUN: .nokeep : { *(.keep) } \ # RUN: .keep : { KEEP(*(.keep)) }}" > %t.script -# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t -# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED2 %s +# RUN: ld.lld --gc-sections -o %t --script %t.script %t.o +# RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=MIXED2 %s # MIXED2: Sections: # MIXED2-NEXT: Idx Name Size # MIXED2-NEXT: 0 00000000 -# MIXED2-NEXT: 1 .nokeep 00000004 00000000000000e8 DATA -# MIXED2-NEXT: 2 .text 00000007 00000000000000ec TEXT DATA -# MIXED2-NEXT: 3 .temp 00000004 00000000000000f3 DATA +# MIXED2-NEXT: 1 .nokeep 00000004 00000000000000e8 +# MIXED2-NEXT: 2 .temp 00000004 00000000000000ec +# MIXED2-NEXT: 3 .text 00000007 00000000000000f0 # MIXED2-NEXT: 4 .comment 00000008 0000000000000000 # MIXED2-NEXT: 5 .symtab 00000060 0000000000000000 # MIXED2-NEXT: 6 .shstrtab 00000038 0000000000000000 @@ -75,10 +75,10 @@ # Check file pattern for kept sections. # RUN: echo "SECTIONS { \ # RUN: . = SIZEOF_HEADERS; \ -# RUN: .keep : { KEEP(*2.o(.keep)) } \ +# RUN: .keep : { KEEP(*1.o(.keep)) } \ # RUN: }" > %t.script -# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t2.o %t -# RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=FILEMATCH %s +# RUN: ld.lld --gc-sections -o %t --script %t.script %t1.o %t.o +# RUN: llvm-objdump -s %t | FileCheck -check-prefix=FILEMATCH %s # FILEMATCH: Contents of section .keep: # FILEMATCH-NEXT: 00e8 41414141 AAAA diff --git a/test/ELF/linkerscript/sections-max-va-overflow.s b/test/ELF/linkerscript/sections-max-va-overflow.s new file mode 100644 index 000000000000..ce771b4784c4 --- /dev/null +++ b/test/ELF/linkerscript/sections-max-va-overflow.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "SECTIONS { . = 0xfffffffffffffff1;" > %t.script +# RUN: echo " .bar : { *(.bar*) } }" >> %t.script +# RUN: not ld.lld -o /dev/null --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR + +## .bar section has data in [0xfffffffffffffff1, 0xfffffffffffffff1 + 0x10] == +## [0xfffffffffffffff1, 0x1]. Check we can catch this overflow. +# ERR: error: section .bar at 0xFFFFFFFFFFFFFFF1 of size 0x10 exceeds available address space + +.section .bar,"ax",@progbits +.zero 0x10 diff --git a/test/ELF/linkerscript/sections-sort.s b/test/ELF/linkerscript/sections-sort.s index 99bbbead925c..e665c9aaa74a 100644 --- a/test/ELF/linkerscript/sections-sort.s +++ b/test/ELF/linkerscript/sections-sort.s @@ -13,13 +13,13 @@ nop .section foo, "a" .byte 0 -# CHECK: Id +# CHECK: Idx # CHECK-NEXT: 0 # CHECK-NEXT: 1 .text -# CHECK-NEXT: 2 foo -# CHECK-NEXT: 3 .dynsym -# CHECK-NEXT: 4 .hash -# CHECK-NEXT: 5 .dynstr +# CHECK-NEXT: 2 .dynsym +# CHECK-NEXT: 3 .hash +# CHECK-NEXT: 4 .dynstr +# CHECK-NEXT: 5 foo # CHECK-NEXT: 6 .dynamic # CHECK-NEXT: 7 .comment # CHECK-NEXT: 8 .symtab diff --git a/test/ELF/linkerscript/sections-va-overflow.test b/test/ELF/linkerscript/sections-va-overflow.test new file mode 100644 index 000000000000..7ede6ecc3de8 --- /dev/null +++ b/test/ELF/linkerscript/sections-va-overflow.test @@ -0,0 +1,22 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/sections-va-overflow.s -o %t.o +# RUN: not ld.lld -o /dev/null --script %s %t.o 2>&1 | FileCheck %s -check-prefix=ERR + +PHDRS { + ph_headers PT_PHDR PHDRS; + ph_text PT_LOAD FILEHDR PHDRS FLAGS (0x1 | 0x4); +} + +SECTIONS { + . = 0xffffffff20000000; + .text : { *(.text*) } : ph_text + .test 0x1000 : { BYTE(0) } + .bss : { *(.bss*) } +} + +## Section .test has VA 0x1000 and placed in the same segment as section .text +## with VA 0xffffffff20000000. That might be technically correct, but most probably +## is a result of a broken script file and causes file offset calculation overflow. +## It seems we do not have to support it, so we don't and we report an error in this case. +# ERR: error: unable to place section .text at file offset [0xFFFFFFFF20000000, 0xFFFFFFFE40000000]; check your linker script for overflows +# ERR-NOT: unable to place section .bss diff --git a/test/ELF/linkerscript/sections.s b/test/ELF/linkerscript/sections.s index dd4b12f42b89..b1e8fb5e9a12 100644 --- a/test/ELF/linkerscript/sections.s +++ b/test/ELF/linkerscript/sections.s @@ -16,7 +16,7 @@ # RUN: FileCheck -check-prefix=SEC-DEFAULT %s # Idx Name Size -# SEC-DEFAULT: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA +# SEC-DEFAULT: 1 .text 0000000e {{[0-9a-f]*}} TEXT # SEC-DEFAULT: 2 .data 00000020 {{[0-9a-f]*}} DATA # SEC-DEFAULT: 3 other 00000003 {{[0-9a-f]*}} DATA # SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS @@ -47,7 +47,7 @@ # 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 DATA +# SEC-ORDER: 8 .text 0000000e {{[0-9a-f]*}} TEXT # .text and .data have swapped names but proper sizes and types. # RUN: echo "SECTIONS { \ @@ -58,7 +58,7 @@ # RUN: FileCheck -check-prefix=SEC-SWAP-NAMES %s # Idx Name Size -# SEC-SWAP-NAMES: 1 .data 0000000e {{[0-9a-f]*}} TEXT DATA +# SEC-SWAP-NAMES: 1 .data 0000000e {{[0-9a-f]*}} TEXT # SEC-SWAP-NAMES: 2 .text 00000020 {{[0-9a-f]*}} DATA # SEC-SWAP-NAMES: 3 other 00000003 {{[0-9a-f]*}} DATA # SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS @@ -80,7 +80,7 @@ # RUN: FileCheck -check-prefix=SEC-MULTI %s # Idx Name Size -# SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA +# SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT # SEC-MULTI-NEXT: .data 00000020 {{[0-9a-f]*}} DATA # SEC-MULTI-NEXT: .data 00000003 {{[0-9a-f]*}} DATA # SEC-MULTI-NEXT: .bss 00000002 {{[0-9a-f]*}} BSS diff --git a/test/ELF/linkerscript/segment-none.s b/test/ELF/linkerscript/segment-none.s index d54e835a0c22..06566525caf7 100644 --- a/test/ELF/linkerscript/segment-none.s +++ b/test/ELF/linkerscript/segment-none.s @@ -9,7 +9,7 @@ # RUN: .foo : {*(.foo)} :NONE \ # RUN: }" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s +# RUN: llvm-readelf -s -l %t | FileCheck %s ## Test that section .foo is placed in segment NONE when assigned to segment ## NONE in the linker script and segment NONE is defined. @@ -19,7 +19,7 @@ # RUN: .foo : {*(.foo)} :NONE \ # RUN: }" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s +# RUN: llvm-readelf -s -l %t | FileCheck --check-prefix=DEFINED %s # CHECK: Section to Segment mapping: # CHECK-NEXT: Segment Sections... diff --git a/test/ELF/linkerscript/segment-start.s b/test/ELF/linkerscript/segment-start.s index 69897d604b3b..cb47cb6cd471 100644 --- a/test/ELF/linkerscript/segment-start.s +++ b/test/ELF/linkerscript/segment-start.s @@ -22,6 +22,6 @@ .quad foobar4 // RUN: echo "SECTIONS { . = SEGMENT_START(\"foobar\", foo); }" > %t.script -// RUN: not ld.lld %t.o %t.script -shared -o %t2.so 2>&1 \ +// RUN: not ld.lld %t.o %t.script -shared -o /dev/null 2>&1 \ // RUN: | FileCheck --check-prefix=ERR %s // ERR: {{.*}}.script:1: symbol not found: foo diff --git a/test/ELF/linkerscript/sort-constructors.s b/test/ELF/linkerscript/sort-constructors.s deleted file mode 100644 index a0c23af6de79..000000000000 --- a/test/ELF/linkerscript/sort-constructors.s +++ /dev/null @@ -1,5 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o -# RUN: echo "SECTIONS { .aaa : { SORT(CONSTRUCTORS) } }" > %t1.script -# RUN: ld.lld -shared -o %t1 --script %t1.script %t1.o -# RUN: llvm-readobj %t1 > /dev/null diff --git a/test/ELF/linkerscript/sort-constructors.test b/test/ELF/linkerscript/sort-constructors.test new file mode 100644 index 000000000000..698208afd54e --- /dev/null +++ b/test/ELF/linkerscript/sort-constructors.test @@ -0,0 +1,8 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t1.o +# RUN: ld.lld -shared -o %t1 --script %s %t1.o +# RUN: llvm-readobj %t1 > /dev/null + +SECTIONS { + .aaa : { SORT(CONSTRUCTORS) } +} diff --git a/test/ELF/linkerscript/sort-non-script.s b/test/ELF/linkerscript/sort-non-script.s index 4611b18d55ef..2477c835e134 100644 --- a/test/ELF/linkerscript/sort-non-script.s +++ b/test/ELF/linkerscript/sort-non-script.s @@ -1,14 +1,14 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script -# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared -# RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s +# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared +# RUN: llvm-readelf -s %t | FileCheck %s -# CHECK: .text {{.*}} AX -# CHECK-NEXT: .dynsym {{.*}} A +# CHECK: .dynsym {{.*}} A # CHECK-NEXT: .hash {{.*}} A # CHECK-NEXT: .dynstr {{.*}} A +# CHECK-NEXT: .text {{.*}} AX # CHECK-NEXT: foo {{.*}} WA # CHECK-NEXT: .dynamic {{.*}} WA diff --git a/test/ELF/linkerscript/start-end.s b/test/ELF/linkerscript/start-end.s deleted file mode 100644 index b68606abc181..000000000000 --- a/test/ELF/linkerscript/start-end.s +++ /dev/null @@ -1,16 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { \ -# RUN: .init_array : { \ -# RUN: __init_array_start = .; \ -# RUN: *(.init_array) \ -# RUN: __init_array_end = .; } }" > %t.script -# RUN: ld.lld %t.o -script %t.script -o %t 2>&1 - -.globl _start -.text -_start: - nop - -.section .init_array, "aw" - .quad 0 diff --git a/test/ELF/linkerscript/start-end.test b/test/ELF/linkerscript/start-end.test new file mode 100644 index 000000000000..ab7504dac2d4 --- /dev/null +++ b/test/ELF/linkerscript/start-end.test @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: echo '.section .init_array, "aw"; .quad 0' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: ld.lld %t.o -script %s -o %t 2>&1 + +SECTIONS { + .init_array : { + __init_array_start = .; + *(.init_array) + __init_array_end = .; + } +} diff --git a/test/ELF/linkerscript/subalign.s b/test/ELF/linkerscript/subalign.s index 1396798c82f6..99cb3f19a999 100644 --- a/test/ELF/linkerscript/subalign.s +++ b/test/ELF/linkerscript/subalign.s @@ -36,7 +36,7 @@ ## Test we fail gracefuly when alignment value is not a power of 2. # RUN: echo "SECTIONS { .aaa : SUBALIGN(3) { *(.aaa*) } }" > %t5.script -# RUN: not ld.lld %t1.o --script %t5.script -o %t5 2>&1 | FileCheck -check-prefix=ERR %s +# RUN: not ld.lld %t1.o --script %t5.script -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s # ERR: {{.*}}.script:1: alignment must be power of 2 .global _start diff --git a/test/ELF/linkerscript/symbol-assignexpr.s b/test/ELF/linkerscript/symbol-assignexpr.s index 9ab03a173f1c..3be7d05931fe 100644 --- a/test/ELF/linkerscript/symbol-assignexpr.s +++ b/test/ELF/linkerscript/symbol-assignexpr.s @@ -47,7 +47,7 @@ # CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol15 # RUN: echo "SECTIONS { symbol2 = symbol; }" > %t2.script -# RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \ +# RUN: not ld.lld -o /dev/null --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-memoryexpr.s b/test/ELF/linkerscript/symbol-memoryexpr.s index 9c75274e1644..cdd821dc585a 100644 --- a/test/ELF/linkerscript/symbol-memoryexpr.s +++ b/test/ELF/linkerscript/symbol-memoryexpr.s @@ -23,7 +23,7 @@ # RUN: no_exist_origin = ORIGIN(ram); \ # RUN: no_exist_length = LENGTH(ram); \ # RUN: }" > %t2.script -# RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \ +# RUN: not ld.lld -o /dev/null --script %t2.script %t 2>&1 \ # RUN: | FileCheck -check-prefix=ERR %s # ERR: {{.*}}.script:1: memory region not defined: ram diff --git a/test/ELF/linkerscript/symbol-only-flags.s b/test/ELF/linkerscript/symbol-only-flags.test index 300d8d88da97..cea2539cd6ba 100644 --- a/test/ELF/linkerscript/symbol-only-flags.s +++ b/test/ELF/linkerscript/symbol-only-flags.test @@ -1,11 +1,15 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ -# RUN: .tbss : { *(.tbss) } \ -# RUN: .foo : { bar = .; } }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: echo '.section .tbss,"awT",@nobits; .quad 0' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o +# RUN: ld.lld -o %t --script %s %t.o # RUN: llvm-readobj -s %t | FileCheck %s +SECTIONS { + . = SIZEOF_HEADERS; + .tbss : { *(.tbss) } + .foo : { bar = .; } +} + ## Check .foo does not get SHF_TLS flag. # CHECK: Section { # CHECK: Index: @@ -15,6 +19,3 @@ # CHECK-NEXT: SHF_ALLOC # CHECK-NEXT: SHF_WRITE # CHECK-NEXT: ] - -.section .tbss,"awT",@nobits -.quad 0 diff --git a/test/ELF/linkerscript/symbol-only.s b/test/ELF/linkerscript/symbol-only.s deleted file mode 100644 index 76d54f01cdc7..000000000000 --- a/test/ELF/linkerscript/symbol-only.s +++ /dev/null @@ -1,21 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: abc : { foo = .; } \ -# RUN: . = ALIGN(0x1000); \ -# RUN: bar : { *(bar) } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared -# RUN: llvm-objdump -section-headers -t %t1 | FileCheck %s -# CHECK: Sections: -# CHECK-NEXT: Idx Name Size Address -# CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] BSS -# CHECK-NEXT: bar 00000000 0000000000001000 DATA - -# CHECK: SYMBOL TABLE: -# CHECK: [[ADDR]] abc 00000000 foo - -.section bar, "a" diff --git a/test/ELF/linkerscript/symbol-only.test b/test/ELF/linkerscript/symbol-only.test new file mode 100644 index 000000000000..f2fefdc049b9 --- /dev/null +++ b/test/ELF/linkerscript/symbol-only.test @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: echo '.section bar, "a"' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t +# RUN: ld.lld -o %t1 --script %s %t -shared +# RUN: llvm-objdump -section-headers -t %t1 | FileCheck %s + +SECTIONS { + . = SIZEOF_HEADERS; + abc : { foo = .; } + . = ALIGN(0x1000); + bar : { *(bar) } +} + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] +# CHECK: bar 00000000 0000000000001000 + +# CHECK: SYMBOL TABLE: +# CHECK: [[ADDR]] abc 00000000 foo diff --git a/test/ELF/linkerscript/symbol-ordering-file.s b/test/ELF/linkerscript/symbol-ordering-file.s index be686c420887..dd5e0a152ae9 100644 --- a/test/ELF/linkerscript/symbol-ordering-file.s +++ b/test/ELF/linkerscript/symbol-ordering-file.s @@ -14,6 +14,16 @@ # AFTER: Contents of section .foo: # AFTER-NEXT: 2211 +# RUN: echo "SECTIONS { .text : { *(.text) } }" > %t2.script +# RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t2.script -o %t3.out +# RUN: llvm-objdump -s %t3.out| FileCheck %s --check-prefix=AFTER + +# RUN: echo "SECTIONS { .foo : { BYTE(0x33); *(.foo); BYTE(0x44) } }" > %t3.script +# RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t3.script -o %t4.out +# RUN: llvm-objdump -s %t4.out| FileCheck %s --check-prefix=COMMANDS +# COMMANDS: Contents of section .foo: +# COMMANDS-NEXT: 33221144 + .section .foo,"ax",@progbits,unique,1 _foo1: .byte 0x11 diff --git a/test/ELF/linkerscript/symbol-ordering-file2.s b/test/ELF/linkerscript/symbol-ordering-file2.s new file mode 100644 index 000000000000..31746ae0a333 --- /dev/null +++ b/test/ELF/linkerscript/symbol-ordering-file2.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o + +## Check we do not crash when trying to order linker script symbol. + +# RUN: echo "bar" > %t.ord +# RUN: echo "SECTIONS { bar = 1; }" > %t.script +# RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t.script \ +# RUN: -o %t.out 2>&1 | FileCheck %s +# CHECK: warning: <internal>: unable to order absolute symbol: bar + +## Check we do not crash when trying to order --defsym symbol. + +# RUN: echo "bar" > %t.ord +# RUN: ld.lld --symbol-ordering-file %t.ord %t.o -defsym=bar=1 \ +# RUN: -o %t.out 2>&1 | FileCheck %s diff --git a/test/ELF/linkerscript/symbols-non-alloc.s b/test/ELF/linkerscript/symbols-non-alloc.s deleted file mode 100644 index e51a39ee5d29..000000000000 --- a/test/ELF/linkerscript/symbols-non-alloc.s +++ /dev/null @@ -1,19 +0,0 @@ -# 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: Sections: -# CHECK: .nonalloc 00000008 0000000000000000 - -# CHECK: SYMBOL TABLE: -# CHECK: 0000000000000008 .nonalloc 00000000 Sym - -.section .nonalloc,"" - .quad 0 diff --git a/test/ELF/linkerscript/symbols-non-alloc.test b/test/ELF/linkerscript/symbols-non-alloc.test new file mode 100644 index 000000000000..6d7580affc26 --- /dev/null +++ b/test/ELF/linkerscript/symbols-non-alloc.test @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: echo '.section .nonalloc,""; .quad 0' \ +# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t +# RUN: ld.lld -o %t2 --script %s %t +# RUN: llvm-objdump -section-headers -t %t2 | FileCheck %s + +# CHECK: Sections: +# CHECK: .nonalloc 00000008 0000000000000000 + +# CHECK: SYMBOL TABLE: +# CHECK: 0000000000000008 .nonalloc 00000000 Sym + +SECTIONS { + . = SIZEOF_HEADERS; + .text : { *(.text) } + .nonalloc : { *(.nonalloc) } + Sym = .; +} diff --git a/test/ELF/linkerscript/symbols-synthetic.s b/test/ELF/linkerscript/symbols-synthetic.s deleted file mode 100644 index 95cdae9a929e..000000000000 --- a/test/ELF/linkerscript/symbols-synthetic.s +++ /dev/null @@ -1,98 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# Simple symbol assignment within input section list. The '.' symbol -# is not location counter but offset from the beginning of output -# section .foo -# RUN: echo "SECTIONS { \ -# RUN: . = SIZEOF_HEADERS; \ -# RUN: .foo : { \ -# RUN: begin_foo = .; \ -# RUN: PROVIDE(_begin_sec = .); \ -# RUN: *(.foo) \ -# RUN: end_foo = .; \ -# RUN: PROVIDE_HIDDEN(_end_sec = .); \ -# RUN: PROVIDE(_end_sec_abs = ABSOLUTE(.)); \ -# RUN: size_foo_1 = SIZEOF(.foo); \ -# RUN: size_foo_1_abs = ABSOLUTE(SIZEOF(.foo)); \ -# RUN: . = ALIGN(0x1000); \ -# RUN: begin_bar = .; \ -# RUN: *(.bar) \ -# RUN: end_bar = .; \ -# RUN: size_foo_2 = SIZEOF(.foo); } \ -# RUN: size_foo_3 = SIZEOF(.foo); \ -# RUN: .eh_frame_hdr : { \ -# RUN: __eh_frame_hdr_start = .; \ -# RUN: __eh_frame_hdr_start2 = ABSOLUTE(ALIGN(0x10)); \ -# RUN: *(.eh_frame_hdr) \ -# RUN: __eh_frame_hdr_end = .; \ -# RUN: __eh_frame_hdr_end2 = ABSOLUTE(ALIGN(0x10)); } \ -# RUN: .eh_frame : { } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE %s - -# Check that the following script is processed without errors -# RUN: echo "SECTIONS { \ -# RUN: .eh_frame_hdr : { \ -# RUN: PROVIDE_HIDDEN(_begin_sec = .); \ -# RUN: *(.eh_frame_hdr) \ -# RUN: *(.eh_frame_hdr) \ -# RUN: PROVIDE_HIDDEN(_end_sec_abs = ABSOLUTE(.)); \ -# RUN: PROVIDE_HIDDEN(_end_sec = .); } \ -# RUN: }" > %t.script -# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t - -# Check that we can specify synthetic symbols without defining SECTIONS. -# RUN: echo "PROVIDE_HIDDEN(_begin_sec = _start); \ -# RUN: PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text));" > %t.script -# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=NO-SEC %s - -# Check that we can do the same as above inside SECTIONS block. -# RUN: echo "SECTIONS { \ -# RUN: . = 0x201000; \ -# RUN: .text : { *(.text) } \ -# RUN: PROVIDE_HIDDEN(_begin_sec = ADDR(.text)); \ -# RUN: PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text)); }" > %t.script -# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=IN-SEC %s - -# 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: 0000000000000120 .foo 00000000 begin_foo -# SIMPLE-NEXT: 0000000000000128 .foo 00000000 end_foo -# SIMPLE-NEXT: 0000000000000008 *ABS* 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: 0000000000000ee4 *ABS* 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 -# SIMPLE-NEXT: 0000000000001020 *ABS* 00000000 __eh_frame_hdr_end2 - -# NO-SEC: 0000000000201000 .text 00000000 .hidden _begin_sec -# NO-SEC-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec - -# IN-SEC: 0000000000201000 .text 00000000 .hidden _begin_sec -# IN-SEC-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec - -.global _start -_start: - nop - -.section .foo,"a" - .quad 0 - -.section .bar,"a" - .long 0 - -.section .dah,"ax",@progbits - .cfi_startproc - nop - .cfi_endproc - -.global _begin_sec, _end_sec, _end_sec_abs diff --git a/test/ELF/linkerscript/synthetic-relsec-layout.s b/test/ELF/linkerscript/synthetic-relsec-layout.s new file mode 100644 index 000000000000..efaa946cbaa9 --- /dev/null +++ b/test/ELF/linkerscript/synthetic-relsec-layout.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .foo : { *(.rela.dyn) } }" > %t.script +# RUN: ld.lld -T %t.script %t.o -o %t.so -shared +# RUN: llvm-readobj -r %t.so | FileCheck %s + +# Check we are able to do custom layout for synthetic sections. +# (here we check we can place synthetic .rela.dyn into .foo). + +# CHECK: Relocations [ +# CHECK: Section ({{.*}}) .foo { +# CHECK: R_X86_64_64 .foo 0x0 +# CHECK: } + +.data +.quad .foo diff --git a/test/ELF/linkerscript/synthetic-symbols1.test b/test/ELF/linkerscript/synthetic-symbols1.test new file mode 100644 index 000000000000..908a05f49588 --- /dev/null +++ b/test/ELF/linkerscript/synthetic-symbols1.test @@ -0,0 +1,56 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t +# RUN: ld.lld -o %t.exe --eh-frame-hdr --script %s %t +# RUN: llvm-objdump -t %t.exe | FileCheck %s + +# Simple symbol assignment within input section list. The '.' symbol +# is not location counter but offset from the beginning of output +# section .foo + +SECTIONS { + . = SIZEOF_HEADERS; + .foo : { + begin_foo = .; + PROVIDE(_begin_sec = .); + *(.foo) + end_foo = .; + PROVIDE_HIDDEN(_end_sec = .); + PROVIDE(_end_sec_abs = ABSOLUTE(.)); + size_foo_1 = SIZEOF(.foo); + size_foo_1_abs = ABSOLUTE(SIZEOF(.foo)); + . = ALIGN(0x1000); + begin_bar = .; + *(.bar) + end_bar = .; + size_foo_2 = SIZEOF(.foo); + } + + size_foo_3 = SIZEOF(.foo); + + .eh_frame_hdr : { + __eh_frame_hdr_start = .; + __eh_frame_hdr_start2 = ABSOLUTE(ALIGN(0x10)); + *(.eh_frame_hdr) + __eh_frame_hdr_end = .; + __eh_frame_hdr_end2 = ABSOLUTE(ALIGN(0x10)); + } + + .eh_frame : {} +} + +# CHECK: 0000000000000128 .foo 00000000 .hidden _end_sec +# CHECK-NEXT: 0000000000000120 .foo 00000000 _begin_sec +# CHECK-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs +# CHECK-NEXT: 000000000000104c .text 00000000 _start +# CHECK-NEXT: 0000000000000120 .foo 00000000 begin_foo +# CHECK-NEXT: 0000000000000128 .foo 00000000 end_foo +# CHECK-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1 +# CHECK-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1_abs +# CHECK-NEXT: 0000000000001000 .foo 00000000 begin_bar +# CHECK-NEXT: 0000000000001004 .foo 00000000 end_bar +# CHECK-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_2 +# CHECK-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_3 +# CHECK-NEXT: 0000000000001004 .eh_frame_hdr 00000000 __eh_frame_hdr_start +# CHECK-NEXT: 0000000000001010 *ABS* 00000000 __eh_frame_hdr_start2 +# CHECK-NEXT: 0000000000001018 .eh_frame_hdr 00000000 __eh_frame_hdr_end +# CHECK-NEXT: 0000000000001020 *ABS* 00000000 __eh_frame_hdr_end2 diff --git a/test/ELF/linkerscript/synthetic-symbols2.test b/test/ELF/linkerscript/synthetic-symbols2.test new file mode 100644 index 000000000000..5304c1e28f01 --- /dev/null +++ b/test/ELF/linkerscript/synthetic-symbols2.test @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t +# RUN: ld.lld -o %t.exe --eh-frame-hdr --script %s %t + +SECTIONS { + .eh_frame_hdr : { + PROVIDE_HIDDEN(_begin_sec = .); + *(.eh_frame_hdr) + *(.eh_frame_hdr) + PROVIDE_HIDDEN(_end_sec_abs = ABSOLUTE(.)); + PROVIDE_HIDDEN(_end_sec = .); + } +} diff --git a/test/ELF/linkerscript/synthetic-symbols3.test b/test/ELF/linkerscript/synthetic-symbols3.test new file mode 100644 index 000000000000..a24ecccedf0b --- /dev/null +++ b/test/ELF/linkerscript/synthetic-symbols3.test @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t +# RUN: ld.lld -o %t.exe --eh-frame-hdr --script %s %t +# RUN: llvm-objdump -t %t.exe | FileCheck %s + +# Check that we can specify synthetic symbols without defining SECTIONS. +PROVIDE_HIDDEN(_begin_sec = _start); +PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text)); + +# CHECK: 0000000000201000 .text 00000000 .hidden _begin_sec +# CHECK-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec diff --git a/test/ELF/linkerscript/synthetic-symbols4.test b/test/ELF/linkerscript/synthetic-symbols4.test new file mode 100644 index 000000000000..fde06e3f3a44 --- /dev/null +++ b/test/ELF/linkerscript/synthetic-symbols4.test @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t.o +# RUN: ld.lld -o %t --eh-frame-hdr --script %s %t.o +# RUN: llvm-objdump -t %t | FileCheck %s + +SECTIONS { + . = 0x201000; + .text : { *(.text) } + PROVIDE_HIDDEN(_begin_sec = ADDR(.text)); + PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text)); +} + +# CHECK: 0000000000201054 .text 00000000 .hidden _begin_sec +# CHECK-NEXT: 0000000000201055 .text 00000000 .hidden _end_sec diff --git a/test/ELF/linkerscript/unused-synthetic.s b/test/ELF/linkerscript/unused-synthetic.s index b7cedbc8e09c..6ddbf505ccbb 100644 --- a/test/ELF/linkerscript/unused-synthetic.s +++ b/test/ELF/linkerscript/unused-synthetic.s @@ -1,17 +1,17 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { \ -# RUN: .got : { *(.got) } \ +# RUN: .got : { *(.got) *(.got) } \ # RUN: .plt : { *(.plt) } \ # RUN: .text : { *(.text) } \ # RUN: }" > %t.script # RUN: ld.lld -shared -o %t.so --script %t.script %t.o -# RUN: llvm-objdump -section-headers %t.so | FileCheck %s +# RUN: llvm-readelf -s %t.so | FileCheck %s # CHECK-NOT: .got # CHECK-NOT: .plt +# CHECK: .dynsym # CHECK: .text -# CHECK-NEXT: .dynsym # Test that the size of a removed unused synthetic input section is not added # to the output section size. Adding a symbol assignment prevents removal of diff --git a/test/ELF/linkerscript/unused-synthetic2.test b/test/ELF/linkerscript/unused-synthetic2.test new file mode 100644 index 000000000000..755d1af00be0 --- /dev/null +++ b/test/ELF/linkerscript/unused-synthetic2.test @@ -0,0 +1,12 @@ +# REQUIRES: arm +# RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux-gnueabi /dev/null -o %t.o + +## We incorrectly removed unused synthetic sections and crashed before. +## Check we do not crash and do not produce .trap output section. +# RUN: ld.lld -shared -o %t.so --script %s %t.o +# RUN: llvm-objdump -section-headers %t.so | FileCheck %s +# CHECK-NOT: .trap + +SECTIONS { + .trap : { *(.ARM.exidx) *(.dummy) } +} diff --git a/test/ELF/linkerscript/va.s b/test/ELF/linkerscript/va.s index 854ebcef0146..c305f0689e11 100644 --- a/test/ELF/linkerscript/va.s +++ b/test/ELF/linkerscript/va.s @@ -5,11 +5,11 @@ # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -section-headers %t1 | FileCheck %s # CHECK: Sections: -# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: Idx Name Size Address # CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 .text 00000001 0000000000000000 TEXT DATA -# CHECK-NEXT: 2 .foo 00000004 0000000000000001 DATA -# CHECK-NEXT: 3 .boo 00000004 0000000000000005 DATA +# CHECK-NEXT: 1 .foo 00000004 0000000000000000 +# CHECK-NEXT: 2 .boo 00000004 0000000000000004 +# CHECK-NEXT: 3 .text 00000001 0000000000000008 .global _start _start: diff --git a/test/ELF/linkerscript/version-script.s b/test/ELF/linkerscript/version-script.s new file mode 100644 index 000000000000..df666e1b39ea --- /dev/null +++ b/test/ELF/linkerscript/version-script.s @@ -0,0 +1,57 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "bar = foo; VERSION { V { global: foo; bar; local: *; }; }" > %t.script +# RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so +# RUN: llvm-readobj -V %t.so | FileCheck %s + +# RUN: echo "SECTIONS { .text : { bar = foo; *(.text) } }" > %t.script +# RUN: echo "VERSION { V { global: foo; bar; local: *; }; }" >> %t.script +# RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so +# RUN: llvm-readobj -V %t.so | FileCheck %s + +## Check that we are able to version symbols defined in script. +# CHECK: Symbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 0 +# CHECK-NEXT: Name: @ +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 0 +# CHECK-NEXT: Name: und@ +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 2 +# CHECK-NEXT: Name: foo@@V +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 2 +# CHECK-NEXT: Name: bar@@V +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# RUN: echo "bar = und; VERSION { V { global: foo; bar; local: *; }; }" > %t.script +# RUN: not ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so \ +# RUN: 2>&1 | FileCheck --check-prefix=ERR %s +# ERR: symbol not found: und + +# RUN: echo "und = 0x1; VERSION { V { global: und; local: *; }; }" > %t.script +# RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so +# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=UNDEF +# UNDEF: Symbols [ +# UNDEF-NEXT: Symbol { +# UNDEF-NEXT: Version: 0 +# UNDEF-NEXT: Name: @ +# UNDEF-NEXT: } +# UNDEF-NEXT: Symbol { +# UNDEF-NEXT: Version: 2 +# UNDEF-NEXT: Name: und@@V +# UNDEF-NEXT: } +# UNDEF-NEXT: ] + +.global und + +.text +.globl foo +.type foo,@function +foo: |
