diff options
Diffstat (limited to 'test/ELF/linkerscript')
70 files changed, 1119 insertions, 105 deletions
diff --git a/test/ELF/linkerscript/Inputs/common-filespec1.s b/test/ELF/linkerscript/Inputs/common-filespec1.s new file mode 100644 index 0000000000000..9e25d1291354b --- /dev/null +++ b/test/ELF/linkerscript/Inputs/common-filespec1.s @@ -0,0 +1,2 @@ +.comm common_uniq_1,8,8 +.comm common_multiple,16,8 diff --git a/test/ELF/linkerscript/Inputs/common-filespec2.s b/test/ELF/linkerscript/Inputs/common-filespec2.s new file mode 100644 index 0000000000000..ceac01793599d --- /dev/null +++ b/test/ELF/linkerscript/Inputs/common-filespec2.s @@ -0,0 +1,2 @@ +.comm common_uniq_2,16,16 +.comm common_multiple,32,8 diff --git a/test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s b/test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s new file mode 100644 index 0000000000000..b10a698eac18b --- /dev/null +++ b/test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s @@ -0,0 +1,5 @@ + .global bar + .type bar, @object + .size bar, 8 +bar: + .quad 0 diff --git a/test/ELF/linkerscript/Inputs/provide-shared.s b/test/ELF/linkerscript/Inputs/provide-shared.s new file mode 100644 index 0000000000000..5ea4e952a7662 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/provide-shared.s @@ -0,0 +1,5 @@ + .global foo + .size foo, 8 + .type foo, @object +foo: + .quad 42 diff --git a/test/ELF/linkerscript/Inputs/symbol-reserved.script b/test/ELF/linkerscript/Inputs/symbol-reserved.script new file mode 100644 index 0000000000000..269bb120de95e --- /dev/null +++ b/test/ELF/linkerscript/Inputs/symbol-reserved.script @@ -0,0 +1,5 @@ +SECTIONS +{ + .text : { *(.text) } + PROVIDE_HIDDEN(_end = .); +} diff --git a/test/ELF/linkerscript/absolute2.s b/test/ELF/linkerscript/absolute2.s new file mode 100644 index 0000000000000..513468d258147 --- /dev/null +++ b/test/ELF/linkerscript/absolute2.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "SECTIONS { .text : { *(.text) } foo = ABSOLUTE(_start) + _start; };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck %s + +# RUN: echo "SECTIONS { .text : { *(.text) } foo = _start + ABSOLUTE(_start); };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck %s + +# CHECK: 0000000000000001 .text 00000000 _start +# CHECK: 0000000000000002 .text 00000000 foo + + .global _start + nop +_start: diff --git a/test/ELF/linkerscript/align-section-offset.s b/test/ELF/linkerscript/align-section-offset.s new file mode 100644 index 0000000000000..9c1603a198535 --- /dev/null +++ b/test/ELF/linkerscript/align-section-offset.s @@ -0,0 +1,11 @@ +# 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.s b/test/ELF/linkerscript/align-section.s new file mode 100644 index 0000000000000..d26f15c87329f --- /dev/null +++ b/test/ELF/linkerscript/align-section.s @@ -0,0 +1,6 @@ +# 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.s b/test/ELF/linkerscript/align.s index 357f54ce1ca5d..99e7382daa59d 100644 --- a/test/ELF/linkerscript/align.s +++ b/test/ELF/linkerscript/align.s @@ -66,6 +66,51 @@ # 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 diff --git a/test/ELF/linkerscript/arm-exidx-order.s b/test/ELF/linkerscript/arm-exidx-order.s new file mode 100644 index 0000000000000..1ff1711e60be8 --- /dev/null +++ b/test/ELF/linkerscript/arm-exidx-order.s @@ -0,0 +1,19 @@ +# 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-sentinel-and-assignment.s b/test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s new file mode 100644 index 0000000000000..8cee22f7fed26 --- /dev/null +++ b/test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s @@ -0,0 +1,24 @@ +# REQUIRES: arm +# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .ARM.exidx 0x1000 : { *(.ARM.exidx*) foo = .; } \ +# RUN: .text 0x2000 : { *(.text*) } \ +# RUN: }" > %t.script +## We used to crash if the last output section command for .ARM.exidx +## was anything but an input section description. +# RUN: ld.lld --no-merge-exidx-entries -T %t.script %t.o -shared -o %t.so +# RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s + + .syntax unified + .text + .global _start +_start: + .fnstart + .cantunwind + bx lr + .fnend + +// CHECK: Contents of section .ARM.exidx: +// 1000 + 1000 = 0x2000 = _start +// 1008 + 0ffc = 0x2004 = _start + sizeof(_start) +// CHECK-NEXT: 1000 00100000 01000000 fc0f0000 01000000 diff --git a/test/ELF/linkerscript/at-addr.s b/test/ELF/linkerscript/at-addr.s index 0eddf3d9e3fbe..f0ab989c52c7f 100644 --- a/test/ELF/linkerscript/at-addr.s +++ b/test/ELF/linkerscript/at-addr.s @@ -9,10 +9,6 @@ # RUN: llvm-readobj -program-headers %t2 | FileCheck %s # CHECK: Type: PT_LOAD -# CHECK-NEXT: Offset: 0x0 -# CHECK-NEXT: VirtualAddress: 0x0 -# CHECK-NEXT: PhysicalAddress: 0x0 -# CHECK: Type: PT_LOAD # CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: VirtualAddress: 0x1000 # CHECK-NEXT: PhysicalAddress: 0xB00 diff --git a/test/ELF/linkerscript/at.s b/test/ELF/linkerscript/at.s index 26441f1ffd9e9..430e68a53d980 100644 --- a/test/ELF/linkerscript/at.s +++ b/test/ELF/linkerscript/at.s @@ -13,31 +13,6 @@ # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { -# CHECK-NEXT: Type: PT_PHDR -# CHECK-NEXT: Offset: 0x40 -# CHECK-NEXT: VirtualAddress: 0x40 -# CHECK-NEXT: PhysicalAddress: 0x40 -# CHECK-NEXT: FileSize: -# CHECK-NEXT: MemSize: -# CHECK-NEXT: Flags [ -# CHECK-NEXT: PF_R -# CHECK-NEXT: ] -# CHECK-NEXT: Alignment: 8 -# CHECK-NEXT: } -# CHECK-NEXT: ProgramHeader { -# CHECK-NEXT: Type: PT_LOAD -# CHECK-NEXT: Offset: 0x0 -# CHECK-NEXT: VirtualAddress: 0x0 -# CHECK-NEXT: PhysicalAddress: 0x0 -# CHECK-NEXT: FileSize: -# CHECK-NEXT: MemSize: -# 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: 0x1000 # CHECK-NEXT: VirtualAddress: 0x1000 diff --git a/test/ELF/linkerscript/common-exclude.s b/test/ELF/linkerscript/common-exclude.s new file mode 100644 index 0000000000000..ef2d51b1b2295 --- /dev/null +++ b/test/ELF/linkerscript/common-exclude.s @@ -0,0 +1,86 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -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.incl : { *(EXCLUDE_FILE (*file2.o) COMMON) } .common.excl : { *(COMMON) } }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %tfile0.o %tfile1.o %tfile2.o +# RUN: llvm-readobj -s -t %t1 | FileCheck %s + +# Commons from file0 and file1 are not excluded, so they must be in .common.incl +# Commons from file2 are excluded from the first rule and should be caught by +# the second in .common.excl +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common.incl +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x8 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common.excl +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x20 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 48 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 16 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_multiple +# CHECK-NEXT: Value: 0x20 +# CHECK-NEXT: Size: 32 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.excl +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_0 +# CHECK-NEXT: Value: 0x8 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.incl +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_1 +# CHECK-NEXT: Value: 0x10 +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.incl +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_2 +# CHECK-NEXT: Value: 0x40 +# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.excl +# CHECK-NEXT: } + +.globl _start +_start: + jmp _start + +.comm common_uniq_0,4,4 +.comm common_multiple,8,8 diff --git a/test/ELF/linkerscript/common-filespec.s b/test/ELF/linkerscript/common-filespec.s new file mode 100644 index 0000000000000..25bb486ed4459 --- /dev/null +++ b/test/ELF/linkerscript/common-filespec.s @@ -0,0 +1,105 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -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: llvm-readobj -s -t %t1 | FileCheck %s + +# Make sure all 3 sections are allocated and they have sizes and alignments +# corresponding to the commons assigned to them +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common_0 +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x4 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common_1 +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x8 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common_2 +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 48 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 16 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } + +# Commons with unique name in each file must be assigned to that file's section. +# For a common with multiple definitions, the largest one wins and it must be +# assigned to the section from the file which provided the winning def +# CHECK: Symbol { +# CHECK: Name: common_multiple +# CHECK-NEXT: Value: 0x10 +# CHECK-NEXT: Size: 32 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common_2 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_0 +# CHECK-NEXT: Value: 0x4 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common_0 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_1 +# CHECK-NEXT: Value: 0x8 +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common_1 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_2 +# CHECK-NEXT: Value: 0x30 +# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# 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/common.s b/test/ELF/linkerscript/common.s index 2e5972d523794..52f0371526c40 100644 --- a/test/ELF/linkerscript/common.s +++ b/test/ELF/linkerscript/common.s @@ -4,8 +4,6 @@ # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-readobj -s -t %t1 | FileCheck %s -# q2 alignment is greater than q1, so it should have smaller offset -# because of sorting # CHECK: Section { # CHECK: Index: # CHECK: Name: .common @@ -16,7 +14,7 @@ # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x200 # CHECK-NEXT: Offset: 0x -# CHECK-NEXT: Size: 256 +# CHECK-NEXT: Size: 384 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 256 @@ -24,7 +22,7 @@ # CHECK-NEXT: } # CHECK: Symbol { # CHECK: Name: q1 -# CHECK-NEXT: Value: 0x280 +# CHECK-NEXT: Value: 0x200 # CHECK-NEXT: Size: 128 # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: Object @@ -33,7 +31,7 @@ # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: q2 -# CHECK-NEXT: Value: 0x200 +# CHECK-NEXT: Value: 0x300 # CHECK-NEXT: Size: 128 # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: Object diff --git a/test/ELF/linkerscript/compress-debug-sections.s b/test/ELF/linkerscript/compress-debug-sections.s index 6798a217b5ac7..5e8cd004068d9 100644 --- a/test/ELF/linkerscript/compress-debug-sections.s +++ b/test/ELF/linkerscript/compress-debug-sections.s @@ -10,12 +10,12 @@ # RUN: echo "SECTIONS { }" > %t.script # RUN: ld.lld -O0 %t1.o %t2.o %t.script -o %t1 --compress-debug-sections=zlib -# RUN: llvm-dwarfdump %t1 | FileCheck %s +# RUN: llvm-dwarfdump -a %t1 | FileCheck %s # RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS # RUN: echo "SECTIONS { .debug_str 0 : { *(.debug_str) } }" > %t2.script # RUN: ld.lld -O0 %t1.o %t2.o %t2.script -o %t2 --compress-debug-sections=zlib -# RUN: llvm-dwarfdump %t2 | FileCheck %s +# RUN: llvm-dwarfdump -a %t2 | FileCheck %s # RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS # CHECK: .debug_str contents: diff --git a/test/ELF/linkerscript/copy-rel-symbol-value-err.s b/test/ELF/linkerscript/copy-rel-symbol-value-err.s new file mode 100644 index 0000000000000..f134edbb1d0ca --- /dev/null +++ b/test/ELF/linkerscript/copy-rel-symbol-value-err.s @@ -0,0 +1,12 @@ +# 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/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 + +# CHECK: symbol not found: bar + +.global _start +_start: +.quad bar@got diff --git a/test/ELF/linkerscript/copy-rel-symbol-value.s b/test/ELF/linkerscript/copy-rel-symbol-value.s new file mode 100644 index 0000000000000..64627b42f8854 --- /dev/null +++ b/test/ELF/linkerscript/copy-rel-symbol-value.s @@ -0,0 +1,27 @@ +# 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/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: ld.lld %t.o %t2.so --script %t.script -o %t +# RUN: llvm-readobj -t %t | FileCheck %s + +# CHECK: Name: bar +# CHECK-NEXT: Value: 0x[[VAL:.*]] +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .bss.rel.ro + +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x[[VAL]] +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .bss.rel.ro + +.global _start +_start: +.quad bar diff --git a/test/ELF/linkerscript/data-segment-relro.s b/test/ELF/linkerscript/data-segment-relro.s index 7f69319dde7ab..e835f42e22c63 100644 --- a/test/ELF/linkerscript/data-segment-relro.s +++ b/test/ELF/linkerscript/data-segment-relro.s @@ -19,9 +19,9 @@ ## With relro or without DATA_SEGMENT_RELRO_END just aligns to ## page boundary. -# RUN: ld.lld -z norelro %t1.o %t2.so --script %t.script -o %t +# RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %t.script -o %t # RUN: llvm-readobj -s %t | FileCheck %s -# RUN: ld.lld -z relro %t1.o %t2.so --script %t.script -o %t2 +# RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %t.script -o %t2 # RUN: llvm-readobj -s %t2 | FileCheck %s # CHECK: Section { diff --git a/test/ELF/linkerscript/diagnostic.s b/test/ELF/linkerscript/diagnostic.s index bd1ebd01b5d28..af185729c430b 100644 --- a/test/ELF/linkerscript/diagnostic.s +++ b/test/ELF/linkerscript/diagnostic.s @@ -50,9 +50,9 @@ # 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: -# ERR6-NEXT: error: {{.*}}.script:1: UNKNOWN_TAG { -# ERR6-NEXT: error: {{.*}}.script:1: ^ +# 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 @@ -62,8 +62,8 @@ # 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: error: {{.*}}.script:4: boom .temp : { *(.temp) } } -# ERR7-NEXT: error: {{.*}}.script:4: ^ +# ERR7-NEXT: >>> boom .temp : { *(.temp) } } +# ERR7-NEXT: >>> ^ ## Check tokenize() error # RUN: echo "SECTIONS {}" > %t.script @@ -89,8 +89,8 @@ # 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: error: {{.*}}.script.inc:4: boom .temp : { *(.temp) } } -# ERR10-NEXT: error: {{.*}}.script.inc:4: ^ +# ERR10-NEXT: >>> boom .temp : { *(.temp) } } +# ERR10-NEXT: >>> ^ ## Check error reporting in script with INCLUDE directive. # RUN: echo "SECTIONS {" > %t.script.inc diff --git a/test/ELF/linkerscript/discard-section-err.s b/test/ELF/linkerscript/discard-section-err.s index 5d9955545d920..8ad5b486cb39a 100644 --- a/test/ELF/linkerscript/discard-section-err.s +++ b/test/ELF/linkerscript/discard-section-err.s @@ -21,3 +21,5 @@ # RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \ # RUN: FileCheck -check-prefix=DYNSTR %s # DYNSTR: discarding .dynstr section is not allowed + +.comm foo,4,4 diff --git a/test/ELF/linkerscript/early-assign-symbol.s b/test/ELF/linkerscript/early-assign-symbol.s index 0626e66e6fb62..5f61178636669 100644 --- a/test/ELF/linkerscript/early-assign-symbol.s +++ b/test/ELF/linkerscript/early-assign-symbol.s @@ -1,14 +1,28 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: echo "SECTIONS { aaa = 1 + ABSOLUTE(foo - 1); .text : { *(.text*) } }" > %t1.script -# RUN: not ld.lld -o %t --script %t1.script %t.o 2>&1 | FileCheck %s - -# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t2.script -# RUN: not ld.lld -o %t --script %t2.script %t.o 2>&1 | FileCheck %s +# RUN: echo "SECTIONS { aaa = foo | 1; .text : { *(.text*) } }" > %t3.script +# RUN: not ld.lld -o %t --script %t3.script %t.o 2>&1 | FileCheck %s # CHECK: error: {{.*}}.script:1: unable to evaluate expression: input section .text has no output section assigned +# Simple cases that we can handle. + +# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s + +# RUN: echo "SECTIONS { aaa = 1 + ABSOLUTE(foo - 1); .text : { *(.text*) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s + +# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo); .text : { *(.text*) } }" > %t4.script +# RUN: ld.lld -o %t --script %t4.script %t.o +# RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s + +# VAL: 0000000000000000 .text 00000000 foo +# VAL: 0000000000000000 *ABS* 00000000 aaa + .section .text .globl foo foo: diff --git a/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s index 54c0cc74d3946..817e458fa5ef7 100644 --- a/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s +++ b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s @@ -12,7 +12,7 @@ # 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 +# CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range: 64424443872 is not in [-2147483648, 2147483647] .text .globl _start diff --git a/test/ELF/linkerscript/emit-reloc-section-names.s b/test/ELF/linkerscript/emit-reloc-section-names.s new file mode 100644 index 0000000000000..8661ff060a79e --- /dev/null +++ b/test/ELF/linkerscript/emit-reloc-section-names.s @@ -0,0 +1,22 @@ +# 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: ld.lld -T %t.script --emit-relocs %t.o -o %t +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +## Check we name relocation sections in according to +## their target sections names. + +# CHECK: .text.zed +# CHECK: .text.qux +# CHECK: .rela.text.zed +# CHECK: .rela.text.qux + +.section .text.foo,"ax" +foo: + mov $bar, %rax + +.section .text.bar,"ax" +bar: + mov $foo, %rax diff --git a/test/ELF/linkerscript/emit-reloc.s b/test/ELF/linkerscript/emit-reloc.s index 725f314a97722..2fe127af85901 100644 --- a/test/ELF/linkerscript/emit-reloc.s +++ b/test/ELF/linkerscript/emit-reloc.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS { .rela.dyn : { *(.rela.data) } }" > %t.script -# RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t.so -shared +# RUN: ld.lld --hash-style=sysv -T %t.script --emit-relocs %t.o -o %t.so -shared # RUN: llvm-readobj -r %t.so | FileCheck %s .data diff --git a/test/ELF/linkerscript/emit-relocs-multiple.s b/test/ELF/linkerscript/emit-relocs-multiple.s index b04ca1be7a151..dcf40b3d9312f 100644 --- a/test/ELF/linkerscript/emit-relocs-multiple.s +++ b/test/ELF/linkerscript/emit-relocs-multiple.s @@ -5,7 +5,7 @@ # RUN: llvm-readobj -r %t1 | FileCheck %s # CHECK: Relocations [ -# CHECK-NEXT: Section {{.*}} .rela.foo { +# CHECK-NEXT: Section {{.*}} .rela.zed { # CHECK-NEXT: 0x1 R_X86_64_32 .zed 0x0 # CHECK-NEXT: 0x6 R_X86_64_32 .zed 0x5 # CHECK-NEXT: } diff --git a/test/ELF/linkerscript/extend-pt-load.s b/test/ELF/linkerscript/extend-pt-load.s index f9a77c8c12bf9..72740f1092eee 100644 --- a/test/ELF/linkerscript/extend-pt-load.s +++ b/test/ELF/linkerscript/extend-pt-load.s @@ -15,7 +15,7 @@ # RUN: . = ALIGN(0x1000); \ # RUN: .data.rel.ro : { *(.data.rel.ro) } \ # RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t.o -shared +# 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 @@ -33,18 +33,17 @@ # RUN: .hash : { } \ # RUN: .dynstr : { } \ # RUN: .text : { *(.text) } \ -# RUN: . = ALIGN(0x1000); \ -# RUN: bar : { HIDDEN(bar_sym = .); } \ +# RUN: bar : { . = ALIGN(0x1000); } \ # RUN: .data.rel.ro : { *(.data.rel.ro) } \ # RUN: }" > %t.script -# RUN: ld.lld -o %t2 --script %t.script %t.o -shared +# 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 PROGBITS 0000000000001000 001000 000000 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 0x001000 0x001000 R E +# 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 @@ -60,7 +59,7 @@ # RUN: HIDDEN(bar_sym = .); \ # RUN: .data.rel.ro : { *(.data.rel.ro) } \ # RUN: }" > %t.script -# RUN: ld.lld -o %t3 --script %t.script %t.o -shared +# 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 diff --git a/test/ELF/linkerscript/filename-spec.s b/test/ELF/linkerscript/filename-spec.s index d4bc495efb81c..5f075a8e50057 100644 --- a/test/ELF/linkerscript/filename-spec.s +++ b/test/ELF/linkerscript/filename-spec.s @@ -33,24 +33,63 @@ # RUN: ld.lld -o %t4 --script %t4.script %tfirst.o %tsecond.o # RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=SECONDFIRST %s -# 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 %s -o filename-spec1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -# RUN: %p/Inputs/filename-spec.s -o %T/filename-spec2.o +# RUN: %p/Inputs/filename-spec.s -o filename-spec2.o # RUN: echo "SECTIONS { .foo : { \ # RUN: filename-spec2.o(.foo) \ # RUN: filename-spec1.o(.foo) } }" > %t5.script # RUN: ld.lld -o %t5 --script %t5.script \ -# RUN: %T/filename-spec1.o %T/filename-spec2.o +# RUN: filename-spec1.o 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: ld.lld -o %t6 --script %t6.script \ -# RUN: %T/filename-spec1.o %T/filename-spec2.o +# RUN: filename-spec1.o filename-spec2.o # RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTSECOND %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 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +# RUN: %p/Inputs/filename-spec.s -o %t.testdir2/filename-spec2.o +# RUN: llvm-ar rsc %t.testdir1/lib1.a %t.testdir1/filename-spec1.o +# 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: 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: 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: 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: 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 + .global _start _start: nop diff --git a/test/ELF/linkerscript/header-addr.s b/test/ELF/linkerscript/header-addr.s index f37d319aaabee..70e6f674bafbd 100644 --- a/test/ELF/linkerscript/header-addr.s +++ b/test/ELF/linkerscript/header-addr.s @@ -2,20 +2,20 @@ # 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; \ +# RUN: . = 0x2000 + SIZEOF_HEADERS; \ # RUN: .text : {*(.text)} :all \ # RUN: }" > %t.script -# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared # RUN: llvm-readobj -program-headers %t.so | FileCheck %s # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD # CHECK-NEXT: Offset: 0x40 -# CHECK-NEXT: VirtualAddress: 0x1040 -# CHECK-NEXT: PhysicalAddress: 0x1040 -# CHECK-NEXT: FileSize: 4176 -# CHECK-NEXT: MemSize: 4176 +# CHECK-NEXT: VirtualAddress: 0x2040 +# CHECK-NEXT: PhysicalAddress: 0x2040 +# CHECK-NEXT: FileSize: 200 +# CHECK-NEXT: MemSize: 200 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_W (0x2) @@ -25,7 +25,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] -# RUN: ld.lld -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 +# RUN: ld.lld --hash-style=sysv -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 # RUN: llvm-readobj -program-headers %t2.so \ # RUN: | FileCheck --check-prefix=MAXPAGE %s @@ -33,10 +33,10 @@ # MAXPAGE-NEXT: ProgramHeader { # MAXPAGE-NEXT: Type: PT_LOAD # MAXPAGE-NEXT: Offset: 0x40 -# MAXPAGE-NEXT: VirtualAddress: 0x40 -# MAXPAGE-NEXT: PhysicalAddress: 0x40 -# MAXPAGE-NEXT: FileSize: 8272 -# MAXPAGE-NEXT: MemSize: 8272 +# MAXPAGE-NEXT: VirtualAddress: 0x2040 +# MAXPAGE-NEXT: PhysicalAddress: 0x2040 +# MAXPAGE-NEXT: FileSize: 200 +# MAXPAGE-NEXT: MemSize: 200 # MAXPAGE-NEXT: Flags [ # MAXPAGE-NEXT: PF_R # MAXPAGE-NEXT: PF_W diff --git a/test/ELF/linkerscript/header-phdr.s b/test/ELF/linkerscript/header-phdr.s new file mode 100644 index 0000000000000..8c9097d8dfa52 --- /dev/null +++ b/test/ELF/linkerscript/header-phdr.s @@ -0,0 +1,13 @@ +# 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/image-base.s b/test/ELF/linkerscript/image-base.s new file mode 100644 index 0000000000000..0ae463fce8a9e --- /dev/null +++ b/test/ELF/linkerscript/image-base.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { mysym = .; }" > %t.script + +# RUN: ld.lld %t.o -o %t-default.elf -T %t.script +# RUN: llvm-readobj --symbols %t-default.elf | FileCheck %s --check-prefix=DEFAULT +# DEFAULT: Name: mysym +# DEFAULT-NEXT: Value: 0x0 + +# RUN: ld.lld %t.o -o %t-switch.elf -T %t.script --image-base=0x100000 +# RUN: llvm-readobj --symbols %t-switch.elf | FileCheck %s --check-prefix=SWITCH +# SWITCH: Name: mysym +# SWITCH-NEXT: Value: 0x100000 + +.global _start +_start: + nop diff --git a/test/ELF/linkerscript/implicit-program-header.s b/test/ELF/linkerscript/implicit-program-header.s index 9598a6abebb04..95cdf142fe421 100644 --- a/test/ELF/linkerscript/implicit-program-header.s +++ b/test/ELF/linkerscript/implicit-program-header.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld -o %t1 --script %S/Inputs/implicit-program-header.script \ +# 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 diff --git a/test/ELF/linkerscript/include-cycle.s b/test/ELF/linkerscript/include-cycle.s new file mode 100644 index 0000000000000..e93ed904f05a3 --- /dev/null +++ b/test/ELF/linkerscript/include-cycle.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "INCLUDE \"%t1.script\"" > %t1.script +# RUN: not ld.lld %t.o %t1.script 2>&1 | FileCheck %s + +# RUN: echo "INCLUDE \"%t2.script\"" > %t1.script +# RUN: echo "INCLUDE \"%t1.script\"" > %t2.script +# RUN: not ld.lld %t.o %t1.script 2>&1 | FileCheck %s + +# CHECK: there is a cycle in linker script INCLUDEs + +.globl _start +_start: + ret diff --git a/test/ELF/linkerscript/linker-script-in-search-path.s b/test/ELF/linkerscript/linker-script-in-search-path.s new file mode 100644 index 0000000000000..be83b55b89955 --- /dev/null +++ b/test/ELF/linkerscript/linker-script-in-search-path.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# Check that we fall back to search paths if a linker script was not found +# This behaviour matches ld.bfd and various projects appear to rely on this + +# 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: 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 + +# 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: llvm-readobj %t.out | FileCheck %s diff --git a/test/ELF/linkerscript/linkerscript.s b/test/ELF/linkerscript/linkerscript.s index cac902af4270f..6a239ea57c8d0 100644 --- a/test/ELF/linkerscript/linkerscript.s +++ b/test/ELF/linkerscript/linkerscript.s @@ -37,8 +37,8 @@ # RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script # RUN: not ld.lld %t.script > %t.log 2>&1 # RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log -# INCLUDE_ERR: error: {{.+}}.script:1: cannot open foo.script -# INCLUDE_ERR-NEXT: error: {{.+}}.script:1: INCLUDE "foo.script" +# 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 diff --git a/test/ELF/linkerscript/memory-at.s b/test/ELF/linkerscript/memory-at.s new file mode 100644 index 0000000000000..9e56dbdbd6572 --- /dev/null +++ b/test/ELF/linkerscript/memory-at.s @@ -0,0 +1,46 @@ +# 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: llvm-readobj -program-headers %t2 | FileCheck %s + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# 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: 0x2000 +# CHECK-NEXT: PhysicalAddress: 0x1008 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_W +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: +# CHECK-NEXT: } + +.section .text, "ax" +.quad 0 + +.section .data, "aw" +.quad 0 diff --git a/test/ELF/linkerscript/memory-err.s b/test/ELF/linkerscript/memory-err.s new file mode 100644 index 0000000000000..19517687b78d9 --- /dev/null +++ b/test/ELF/linkerscript/memory-err.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { name : ORIGIN = DATA_SEGMENT_RELRO_END; }" > %t.script +# RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 | FileCheck %s +# CHECK: error: {{.*}}.script:1: unable to calculate page size + +# RUN: echo "MEMORY { name : ORIGIN = CONSTANT(COMMONPAGESIZE); }" > %t.script +# RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 |\ +# RUN: FileCheck %s --check-prefix=ERR2 +# ERR2: error: {{.*}}.script:1: unable to calculate page size + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { name : ORIGIN = .; }" > %t.script +# RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 |\ +# RUN: FileCheck %s --check-prefix=ERR3 +# ERR3: error: {{.*}}.script:1: unable to get location counter value diff --git a/test/ELF/linkerscript/memory.s b/test/ELF/linkerscript/memory.s index 774a6f92ab17c..172768394d30f 100644 --- a/test/ELF/linkerscript/memory.s +++ b/test/ELF/linkerscript/memory.s @@ -21,8 +21,8 @@ # RUN: rom (rx) : org = (0x80 * 0x1000 * 0x1000), len = 64M \ # RUN: } \ # RUN: SECTIONS { \ -# RUN: .text : { *(.text) } > rom \ -# RUN: .data : { *(.data) } > ram \ +# RUN: .text : { *(.text) } >rom \ +# RUN: .data : { *(.data) } >ram \ # RUN: }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAMROM %s diff --git a/test/ELF/linkerscript/memory2.s b/test/ELF/linkerscript/memory2.s new file mode 100644 index 0000000000000..2e7381fb89141 --- /dev/null +++ b/test/ELF/linkerscript/memory2.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# 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 + +.text +.global _start +_start: + .zero 1024 + +.section .text.foo,"ax",%progbits +foo: + nop diff --git a/test/ELF/linkerscript/memory3.s b/test/ELF/linkerscript/memory3.s new file mode 100644 index 0000000000000..6a24313f06210 --- /dev/null +++ b/test/ELF/linkerscript/memory3.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { ram2 (ax) : ORIGIN = 0x1000, LENGTH = 1K \ +# RUN: ram1 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \ +# RUN: SECTIONS {}" > %t1.script +# RUN: ld.lld -o %t1 --script %t1.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s + +# RUN: echo "MEMORY { ram1 (ax) : ORIGIN = 0x1000, LENGTH = 1K \ +# RUN: ram2 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \ +# RUN: SECTIONS {}" > %t2.script +# RUN: ld.lld -o %t2 --script %t2.script %t +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s + +## Check we place .text into first defined memory region with appropriate flags. +# CHECK: Sections: +# CHECK: Idx Name Size Address +# CHECK: 0 00000000 0000000000000000 +# CHECK: 1 .text 00000001 0000000000001000 + +.section .text.foo,"ax",%progbits +foo: + nop diff --git a/test/ELF/linkerscript/merge-sections.s b/test/ELF/linkerscript/merge-sections.s index 950d822ec4039..2709bdaee444f 100644 --- a/test/ELF/linkerscript/merge-sections.s +++ b/test/ELF/linkerscript/merge-sections.s @@ -36,7 +36,7 @@ # RUN: llvm-readobj -s -t %t2 | FileCheck %s --check-prefix=GC # GC: Name: .foo -# GC-NEXT: Type: SHT_PROGBITS +# GC-NEXT: Type: SHT_NOBITS # GC-NEXT: Flags [ # GC-NEXT: SHF_ALLOC # GC-NEXT: ] diff --git a/test/ELF/linkerscript/no-space.s b/test/ELF/linkerscript/no-space.s index fc9e5b13325f1..21a38e42b2a39 100644 --- a/test/ELF/linkerscript/no-space.s +++ b/test/ELF/linkerscript/no-space.s @@ -2,11 +2,11 @@ # 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 -o %t --script %t.script %t.o -shared +# 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: echo "SECTIONS {foo : {*(foo*)} }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -shared +# 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 # There is not enough address space available for the header, so just start the PT_LOAD diff --git a/test/ELF/linkerscript/noload.s b/test/ELF/linkerscript/noload.s index 9d0e085a05040..28be55df1f12a 100644 --- a/test/ELF/linkerscript/noload.s +++ b/test/ELF/linkerscript/noload.s @@ -4,10 +4,10 @@ # RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \ # RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-readobj --symbols -sections %t +# RUN: llvm-readobj --symbols -sections %t | FileCheck %s # CHECK: Section { -# CHECK-NEXT: Index: 2 +# CHECK: Index: 2 # CHECK-NEXT: Name: .data_noload_a # CHECK-NEXT: Type: SHT_NOBITS # CHECK-NEXT: Flags [ diff --git a/test/ELF/linkerscript/non-alloc.s b/test/ELF/linkerscript/non-alloc.s index 861c74996b853..3257cb9655659 100644 --- a/test/ELF/linkerscript/non-alloc.s +++ b/test/ELF/linkerscript/non-alloc.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t # RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared +# 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 # Test that we create all necessary PT_LOAD. We use to stop at the first diff --git a/test/ELF/linkerscript/operators.s b/test/ELF/linkerscript/operators.s index 470558d29df11..868805b34c2e1 100644 --- a/test/ELF/linkerscript/operators.s +++ b/test/ELF/linkerscript/operators.s @@ -25,6 +25,7 @@ # RUN: commonpagesize = CONSTANT (COMMONPAGESIZE); \ # RUN: . = 0xfff0; \ # RUN: datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0); \ +# RUN: datasegmentalign2 = DATA_SEGMENT_ALIGN (0, 0); \ # RUN: }" > %t.script # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-objdump -t %t2 | FileCheck %s @@ -51,6 +52,7 @@ # CHECK: 00000000001000 *ABS* 00000000 maxpagesize # CHECK: 00000000001000 *ABS* 00000000 commonpagesize # CHECK: 0000000000ffff *ABS* 00000000 datasegmentalign +# CHECK: 0000000000fff0 *ABS* 00000000 datasegmentalign2 ## Mailformed number error. # RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script diff --git a/test/ELF/linkerscript/orphan-discard.s b/test/ELF/linkerscript/orphan-discard.s new file mode 100644 index 0000000000000..6fd6fafcd7f4d --- /dev/null +++ b/test/ELF/linkerscript/orphan-discard.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# RUN: llvm-mc -position-independent -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: . = 0xffffffff80000000; \ +# RUN: .text : ALIGN(4096) { *(.text) } \ +# RUN: .data : ALIGN(4096) { *(.data) } \ +# RUN: .bss : ALIGN(4096) { *(.bss); } \ +# RUN: . = ALIGN(4096); \ +# RUN: _end = .; \ +# RUN: /DISCARD/ : { *(.comment) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readelf -s -symbols %t | FileCheck %s + +# CHECK: .bss NOBITS ffffffff80002000 002008 000002 00 WA 0 0 4096 +# CHECK: ffffffff80003000 0 NOTYPE GLOBAL DEFAULT 3 _end + +.section .text, "ax" + ret + +.section .data, "aw" + .quad 0 + +.section .bss, "", @nobits + .short 0 diff --git a/test/ELF/linkerscript/orphan-end.s b/test/ELF/linkerscript/orphan-end.s new file mode 100644 index 0000000000000..5f56d8f487a27 --- /dev/null +++ b/test/ELF/linkerscript/orphan-end.s @@ -0,0 +1,57 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o + +# Test that .orphan_rx is placed after __stack_end. This matches bfd's +# behavior when the orphan section is the last one. + +# RUN: echo "SECTIONS { \ +# RUN: __start_text = .; \ +# RUN: .text : { *(.text*) } \ +# RUN: __end_text = .; \ +# RUN: __stack_start = .; \ +# RUN: . = . + 0x1000; \ +# RUN: __stack_end = .; \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readelf -S --symbols %t | FileCheck %s + +# CHECK-DAG: .text PROGBITS 0000000000000000 +# CHECK-DAG: .orphan_rx PROGBITS 0000000000001004 + +# CHECK-DAG: 0000000000000000 {{.*}} __start_text +# CHECK-DAG: 0000000000000004 {{.*}} __end_text +# CHECK-DAG: 0000000000000004 {{.*}} __stack_start +# CHECK-DAG: 0000000000001004 {{.*}} __stack_end + +# Test that .orphan_rx is now placed before __stack_end. This matches bfd's +# behavior when the orphan section is not the last one. + +# RUN: echo "SECTIONS { \ +# RUN: __start_text = .; \ +# RUN: .text : { *(.text*) } \ +# RUN: __end_text = .; \ +# RUN: __stack_start = .; \ +# RUN: . = . + 0x1000; \ +# RUN: __stack_end = .; \ +# RUN: .orphan_rw : { *(.orphan_rw*) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readelf -S --symbols %t | FileCheck --check-prefix=MIDDLE %s + +# MIDDLE-DAG: .text PROGBITS 0000000000000000 +# MIDDLE-DAG: .orphan_rx PROGBITS 0000000000000004 + +# MIDDLE-DAG: 0000000000000000 {{.*}} __start_text +# MIDDLE-DAG: 0000000000000004 {{.*}} __end_text +# MIDDLE-DAG: 0000000000000004 {{.*}} __stack_start +# MIDDLE-DAG: 0000000000001008 {{.*}} __stack_end + + .global _start +_start: + .zero 4 + + .section .orphan_rx,"ax" + .zero 4 + + .section .orphan_rw,"aw" + .zero 4 diff --git a/test/ELF/linkerscript/orphan-phdrs.s b/test/ELF/linkerscript/orphan-phdrs.s new file mode 100644 index 0000000000000..648911162e973 --- /dev/null +++ b/test/ELF/linkerscript/orphan-phdrs.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "PHDRS { \ +# RUN: exec PT_LOAD FLAGS(0x4 | 0x1); \ +# RUN: rw PT_LOAD FLAGS(0x4 | 0x2); \ +# RUN: } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text) } :exec \ +# RUN: .empty : { *(.empty) } :rw \ +# 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 + +## Check that the orphan section is placed correctly and belongs to +## the correct segment. + +# CHECK: Section Headers +# CHECK: .text +# CHECK-NEXT: .orphan +# CHECK-NEXT: .rw + +# CHECK: Segment Sections +# CHECK-NEXT: .text .orphan +# CHECK-NEXT: .rw + +.section .text, "ax" + ret + +.section .rw, "aw" + .quad 0 + +.section .orphan, "ax" + ret diff --git a/test/ELF/linkerscript/orphan-report.s b/test/ELF/linkerscript/orphan-report.s new file mode 100644 index 0000000000000..241857b239c4d --- /dev/null +++ b/test/ELF/linkerscript/orphan-report.s @@ -0,0 +1,54 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { .text : { *(.text.1) } }" > %t.script + +## Check we do not report orphans by default even with -verbose. +# RUN: ld.lld -shared -o %t.out --script %t.script %t.o 2>&1 -verbose \ +# RUN: | FileCheck %s --check-prefix=DEFAULT +# DEFAULT-NOT: placed + +## Check --orphan-handling=place has the same behavior as default. +# RUN: ld.lld -shared --orphan-handling=place -o %t.out --script %t.script \ +# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=DEFAULT + +## Check --orphan-handling=error reports errors about orphans. +# RUN: not ld.lld -shared --orphan-handling=error -o %t.out --script %t.script \ +# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=REPORT +# REPORT: {{.*}}.o:(.text) is being placed in '.text' +# REPORT-NEXT: {{.*}}.o:(.text.2) is being placed in '.text' +# REPORT-NEXT: <internal>:(.comment) is being placed in '.comment' +# REPORT-NEXT: <internal>:(.bss) is being placed in '.bss' +# REPORT-NEXT: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro' +# REPORT-NEXT: <internal>:(.dynsym) is being placed in '.dynsym' +# REPORT-NEXT: <internal>:(.gnu.version) is being placed in '.gnu.version' +# REPORT-NEXT: <internal>:(.gnu.version_r) is being placed in '.gnu.version_r' +# REPORT-NEXT: <internal>:(.gnu.hash) is being placed in '.gnu.hash' +# REPORT-NEXT: <internal>:(.hash) is being placed in '.hash' +# REPORT-NEXT: <internal>:(.dynamic) is being placed in '.dynamic' +# REPORT-NEXT: <internal>:(.dynstr) is being placed in '.dynstr' +# REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn' +# REPORT-NEXT: <internal>:(.got) is being placed in '.got' +# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt' +# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt' +# REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt' +# REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt' +# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt' +# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt' +# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame' +# REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab' +# REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab' +# REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab' + +## Check --orphan-handling=warn reports warnings about orphans. +# RUN: ld.lld -shared --orphan-handling=warn -o %t.out --script %t.script \ +# RUN: %t.o 2>&1 -verbose | FileCheck %s --check-prefix=REPORT + +# RUN: not ld.lld --orphan-handling=foo -o %t.out --script %t.script %t.o 2>&1 \ +# RUN: | FileCheck %s --check-prefix=UNKNOWN +# UNKNOWN: unknown --orphan-handling mode: foo + +.section .text.1,"a" + nop + +.section .text.2,"a" + nop diff --git a/test/ELF/linkerscript/out-of-order.s b/test/ELF/linkerscript/out-of-order.s index 6cfd533c4e14f..c43df43e50020 100644 --- a/test/ELF/linkerscript/out-of-order.s +++ b/test/ELF/linkerscript/out-of-order.s @@ -1,7 +1,7 @@ # 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: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared # RUN: llvm-objdump -section-headers %t.so | FileCheck %s # CHECK: Sections: diff --git a/test/ELF/linkerscript/phdr-check.s b/test/ELF/linkerscript/phdr-check.s index c7229ed3312c6..b35256be6b71e 100644 --- a/test/ELF/linkerscript/phdr-check.s +++ b/test/ELF/linkerscript/phdr-check.s @@ -1,14 +1,14 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %t.script +# RUN: echo "SECTIONS { . = 0x10000000 + SIZEOF_HEADERS; .text : {*(.text.*)} }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-readobj -program-headers %t1 | FileCheck %s # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_PHDR (0x6) # CHECK-NEXT: Offset: 0x40 -# CHECK-NEXT: VirtualAddress: 0xFFFF040 +# CHECK-NEXT: VirtualAddress: 0x10000040 .global _start _start: diff --git a/test/ELF/linkerscript/phdrs.s b/test/ELF/linkerscript/phdrs.s index 025ced95b30ac..b650159945339 100644 --- a/test/ELF/linkerscript/phdrs.s +++ b/test/ELF/linkerscript/phdrs.s @@ -39,9 +39,9 @@ # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s -## Check that error is reported when trying to use phdr which is not listed +## Check that error is reported when trying to use phdr which is not listed ## inside PHDRS {} block -## TODO: If script doesn't contain PHDRS {} block then default phdr is always +## TODO: If script doesn't contain PHDRS {} block then default phdr is always ## created and error is not reported. # RUN: echo "PHDRS { all PT_LOAD; } \ # RUN: SECTIONS { .baz : {*(.foo.*)} :bar }" > %t.script diff --git a/test/ELF/linkerscript/provide-shared.s b/test/ELF/linkerscript/provide-shared.s new file mode 100644 index 0000000000000..e3f1bdb2ea3df --- /dev/null +++ b/test/ELF/linkerscript/provide-shared.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-shared.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-objdump -t %t | FileCheck %s + +# CHECK: 000000000000002a *ABS* 00000000 foo + +.global _start +_start: +.quad foo diff --git a/test/ELF/linkerscript/region-alias.s b/test/ELF/linkerscript/region-alias.s new file mode 100644 index 0000000000000..8a88f6f5ad9f5 --- /dev/null +++ b/test/ELF/linkerscript/region-alias.s @@ -0,0 +1,54 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { \ +# RUN: ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100 \ +# RUN: RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100 \ +# RUN: } \ +# RUN: INCLUDE \"%t.script.inc\" \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text*) } > ALIAS_TEXT \ +# RUN: .data : { *(.data*) } > ALIAS_DATA \ +# RUN: }" > %t.script + +## .text to ROM, .data to RAM. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc +# 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: .data 00000008 0000000000002000 DATA + +## All to ROM. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc +# 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: .data 00000008 0000000000001001 DATA + +## Redefinition of region. +# RUN: echo "REGION_ALIAS (\"ROM\", ROM);" > %t.script.inc +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR1 +# ERR1: {{.*}}script.inc:1: redefinition of memory region 'ROM' + +## Redefinition of alias. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" >> %t.script.inc +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR2 +# ERR2: {{.*}}script.inc:2: redefinition of memory region 'ALIAS_TEXT' + +## Attemp to create an alias for undefined region. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", FOO);" > %t.script.inc +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR3 +# ERR3: {{.*}}script.inc:1: memory region 'FOO' is not defined + +.text +.global _start +_start: + nop + +.section .data,"aw" +.quad 0 diff --git a/test/ELF/linkerscript/repsection-symbol.s b/test/ELF/linkerscript/repsection-symbol.s index d2d8c9dd56ef0..195380be9ff85 100644 --- a/test/ELF/linkerscript/repsection-symbol.s +++ b/test/ELF/linkerscript/repsection-symbol.s @@ -6,7 +6,7 @@ # RUN: .text : { *(.text) } \ # RUN: .foo : {foo1 = .; *(.foo.*) foo2 = .; *(.bar) foo3 = .;} \ # RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared +# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared # RUN: llvm-readobj -t %t1 | FileCheck %s # CHECK: Name: foo1 diff --git a/test/ELF/linkerscript/sections-sort.s b/test/ELF/linkerscript/sections-sort.s index 0e99851910f44..99bbbead925c0 100644 --- a/test/ELF/linkerscript/sections-sort.s +++ b/test/ELF/linkerscript/sections-sort.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { .text : {*(.text)} foo : {*(foo)}}" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared # RUN: llvm-objdump --section-headers %t | FileCheck %s # Test the section order. This is a case where at least with libstdc++'s diff --git a/test/ELF/linkerscript/segment-headers.s b/test/ELF/linkerscript/segment-headers.s new file mode 100644 index 0000000000000..b3bdad9ea08b3 --- /dev/null +++ b/test/ELF/linkerscript/segment-headers.s @@ -0,0 +1,26 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { . = 0x2000; .text : AT(0x100000) { *(.text) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -l %t | FileCheck %s + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x2000 +# CHECK-NEXT: PhysicalAddress: 0x100000 +# 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 +.global _start + +_start: + ret diff --git a/test/ELF/linkerscript/segment-start.s b/test/ELF/linkerscript/segment-start.s index e46c398f63f95..69897d604b3b3 100644 --- a/test/ELF/linkerscript/segment-start.s +++ b/test/ELF/linkerscript/segment-start.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: ld.lld %t.o %S/Inputs/segment-start.script -shared -o %t.so +// RUN: ld.lld --hash-style=sysv %t.o %S/Inputs/segment-start.script -shared -o %t.so // RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s // CHECK: Name: foobar1 diff --git a/test/ELF/linkerscript/sort-non-script.s b/test/ELF/linkerscript/sort-non-script.s index b0517608d51b5..4611b18d55ef9 100644 --- a/test/ELF/linkerscript/sort-non-script.s +++ b/test/ELF/linkerscript/sort-non-script.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t # RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared +# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s # CHECK: .text {{.*}} AX diff --git a/test/ELF/linkerscript/subalign.s b/test/ELF/linkerscript/subalign.s index 8b441d440b0ef..1396798c82f6a 100644 --- a/test/ELF/linkerscript/subalign.s +++ b/test/ELF/linkerscript/subalign.s @@ -22,6 +22,23 @@ # SUBALIGN: 01000000 00000000 02000000 00000000 # SUBALIGN: 03000000 00000000 04000000 00000000 +## Test we do not assert or crash when dot(.) is used inside SUBALIGN. +## ld.bfd does not allow to use dot in such expressions, our behavior is +## different for simplicity of implementation. Value of dot is undefined. +# RUN: echo "SECTIONS { . = 0x32; .aaa : SUBALIGN(.) { *(.aaa*) } }" > %t3.script +# RUN: ld.lld %t1.o --script %t3.script -o %t3 +# RUN: llvm-objdump -s %t3 > /dev/null + +## Test we are able to link with zero alignment, this is consistent with bfd 2.26.1. +# RUN: echo "SECTIONS { .aaa : SUBALIGN(0) { *(.aaa*) } }" > %t4.script +# RUN: ld.lld %t1.o --script %t4.script -o %t4 +# RUN: llvm-objdump -s %t4 | FileCheck -check-prefix=SUBALIGN %s + +## 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 +# ERR: {{.*}}.script:1: alignment must be power of 2 + .global _start _start: nop diff --git a/test/ELF/linkerscript/symbol-assignexpr.s b/test/ELF/linkerscript/symbol-assignexpr.s index 14a1f0890ca67..9ab03a173f1c8 100644 --- a/test/ELF/linkerscript/symbol-assignexpr.s +++ b/test/ELF/linkerscript/symbol-assignexpr.s @@ -6,7 +6,7 @@ # RUN: symbol2 = symbol + 0x1234; \ # RUN: symbol3 = symbol2; \ # RUN: symbol4 = symbol + -4; \ -# RUN: symbol5 = symbol - ~ 0xfffb; \ +# RUN: symbol5 = symbol - ~0xfffb; \ # RUN: symbol6 = symbol - ~(0xfff0 + 0xb); \ # RUN: symbol7 = symbol - ~ 0xfffb + 4; \ # RUN: symbol8 = ~ 0xffff + 4; \ @@ -15,6 +15,9 @@ # RUN: symbol11 = ((0x28000 + 0x1fff) & ~(0x1000 + -1)); \ # RUN: symbol12 = 0x1234; \ # RUN: symbol12 += 1; \ +# RUN: symbol13 = !1; \ +# RUN: symbol14 = !0; \ +# RUN: symbol15 = 0!=1; \ # RUN: bar = 0x5678; \ # RUN: baz = 0x9abc; \ # RUN: }" > %t.script @@ -39,6 +42,9 @@ # CHECK-NEXT: fedcba9876543210 *ABS* 00000000 symbol10 # CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11 # CHECK-NEXT: 0000000000001235 *ABS* 00000000 symbol12 +# CHECK-NEXT: 0000000000000000 *ABS* 00000000 symbol13 +# CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol14 +# 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 \ diff --git a/test/ELF/linkerscript/symbol-only-flags.s b/test/ELF/linkerscript/symbol-only-flags.s new file mode 100644 index 0000000000000..300d8d88da973 --- /dev/null +++ b/test/ELF/linkerscript/symbol-only-flags.s @@ -0,0 +1,20 @@ +# 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: llvm-readobj -s %t | FileCheck %s + +## Check .foo does not get SHF_TLS flag. +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# 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 index 2fb57260b333e..76d54f01cdc75 100644 --- a/test/ELF/linkerscript/symbol-only.s +++ b/test/ELF/linkerscript/symbol-only.s @@ -12,7 +12,7 @@ # CHECK: Sections: # CHECK-NEXT: Idx Name Size Address # CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] DATA +# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] BSS # CHECK-NEXT: bar 00000000 0000000000001000 DATA # CHECK: SYMBOL TABLE: diff --git a/test/ELF/linkerscript/symbol-ordering-file.s b/test/ELF/linkerscript/symbol-ordering-file.s new file mode 100644 index 0000000000000..be686c4208875 --- /dev/null +++ b/test/ELF/linkerscript/symbol-ordering-file.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .foo : { *(.foo) } }" > %t.script + +# RUN: ld.lld %t.o --script %t.script -o %t.out +# RUN: llvm-objdump -s %t.out| FileCheck %s --check-prefix=BEFORE +# BEFORE: Contents of section .foo: +# BEFORE-NEXT: 1122 + +# RUN: echo "_foo2" > %t.ord +# RUN: echo "_foo1" >> %t.ord +# RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t.script -o %t2.out +# RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER +# AFTER: Contents of section .foo: +# AFTER-NEXT: 2211 + +.section .foo,"ax",@progbits,unique,1 +_foo1: + .byte 0x11 + +.section .foo,"ax",@progbits,unique,2 +_foo2: + .byte 0x22 diff --git a/test/ELF/linkerscript/symbol-reserved.s b/test/ELF/linkerscript/symbol-reserved.s index e0b2595973810..8ae9d0cd661a6 100644 --- a/test/ELF/linkerscript/symbol-reserved.s +++ b/test/ELF/linkerscript/symbol-reserved.s @@ -17,6 +17,34 @@ # ALIGNED: 0000000000200005 .text 00000000 .hidden newsym +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(3, 8) + 10);" > %t.script +# RUN: ld.lld -o %t1 %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGN-ADD %s +# ALIGN-ADD: 0000000000000012 *ABS* 00000000 .hidden newsym + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(11, 8) - 10);" > %t.script +# RUN: ld.lld -o %t1 %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGN-SUB %s +# ALIGN-SUB: 0000000000000006 *ABS* 00000000 .hidden newsym + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script +# RUN: ld.lld -o %t1 %t %t.script +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE %s +# RELATIVE: 0000000000202005 .text 00000000 .hidden newsym +# RELATIVE: 0000000000201007 .text 00000000 _end + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script +# RUN: ld.lld -o %t1 --script %p/Inputs/symbol-reserved.script %t %t.script +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE-ADD %s +# RELATIVE-ADD: 0000000000001005 .text 00000000 .hidden newsym +# RELATIVE-ADD: 0000000000000007 .text 00000000 .hidden _end + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) - 5);" > %t.script +# RUN: ld.lld -o %t1 --script %p/Inputs/symbol-reserved.script %t %t.script +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE-SUB %s +# RELATIVE-SUB: 0000000000000ffb .text 00000000 .hidden newsym +# RELATIVE-SUB: 0000000000000007 .text 00000000 .hidden _end + .global _start _start: lea newsym(%rip),%rax diff --git a/test/ELF/linkerscript/symbols.s b/test/ELF/linkerscript/symbols.s index 4656635171c88..a6d797584417b 100644 --- a/test/ELF/linkerscript/symbols.s +++ b/test/ELF/linkerscript/symbols.s @@ -12,14 +12,13 @@ # The symbol is not referenced. Don't provide it. # RUN: echo "SECTIONS { PROVIDE(newsym = 1);}" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE1 %s -# PROVIDE1-NOT: 0000000000000001 *ABS* 00000000 newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s +# DONTPROVIDE-NOT: newsym # The symbol is not referenced. Don't provide it. # RUN: echo "SECTIONS { PROVIDE_HIDDEN(newsym = 1);}" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN1 %s -# HIDDEN1-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s # Provide existing symbol. The value should be 0, even though we # have value of 1 in PROVIDE() @@ -44,14 +43,12 @@ # The symbol is not referenced. Don't provide it. # RUN: echo "PROVIDE(newsym = 1);" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE4 %s -# PROVIDE4-NOT: 0000000000000001 *ABS* 00000000 newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s # The symbol is not referenced. Don't provide it. # RUN: echo "PROVIDE_HIDDEN(newsym = 1);" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN4 %s -# HIDDEN4-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s # Provide existing symbol. The value should be 0, even though we # have value of 1 in PROVIDE() diff --git a/test/ELF/linkerscript/thunk-gen-mips.s b/test/ELF/linkerscript/thunk-gen-mips.s new file mode 100644 index 0000000000000..97d06d0ee6542 --- /dev/null +++ b/test/ELF/linkerscript/thunk-gen-mips.s @@ -0,0 +1,40 @@ +# REQUIRES: mips +# RUN: llvm-mc -filetype=obj -defsym=MAIN=1 -triple=mips-unknown-freebsd %s -o %t +# RUN: llvm-mc -filetype=obj -defsym=TARGET=1 -triple=mips-unknown-freebsd %s -o %t1 + +# SECTIONS command with the first pattern that does not match. +# Linking a PIC and non-PIC object files triggers the LA25 thunk generation. +# RUN: echo "SECTIONS { \ +# RUN: .text : { \ +# RUN: *(.nomatch) \ +# RUN: %t(.text) \ +# RUN: . = . + 0x100000 ; \ +# RUN: %t1(.text) \ +# RUN: } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t.exe --script %t.script %t %t1 +# RUN: llvm-objdump -t %t.exe | FileCheck %s +# CHECK: SYMBOL TABLE: +# CHECK-ANY: 00000000 .text 00000000 _start +# CHECK-ANY: 0010000c l F .text 00000010 __LA25Thunk_too_far +# CHECK-ANY: 00100020 g F .text 00000024 too_far + +.ifdef MAIN +.global _start +_start: + j too_far + nop +.endif + +.ifdef TARGET + .text + .abicalls + .set noreorder + .globl too_far + .ent too_far +too_far: + nop + jr $ra + nop + .end too_far +.endif diff --git a/test/ELF/linkerscript/unused-synthetic.s b/test/ELF/linkerscript/unused-synthetic.s index c9295fff7b59d..b7cedbc8e09cb 100644 --- a/test/ELF/linkerscript/unused-synthetic.s +++ b/test/ELF/linkerscript/unused-synthetic.s @@ -13,6 +13,16 @@ # 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 +# the output section, but does not cause the section size to be recomputed. +# RUN: echo "SECTIONS { \ +# RUN: .got.plt : { a_sym = .; *(.got.plt) } \ +# RUN: }" > %t2.script +# RUN: ld.lld -shared -o %t2.so --script %t2.script %t.o +# RUN: llvm-objdump -section-headers %t2.so | FileCheck %s --check-prefix=CHECK2 +# CHECK2: .got.plt 00000000 + .global _start _start: nop diff --git a/test/ELF/linkerscript/version-linker-symbol.s b/test/ELF/linkerscript/version-linker-symbol.s new file mode 100644 index 0000000000000..de30cf5c2ed5f --- /dev/null +++ b/test/ELF/linkerscript/version-linker-symbol.s @@ -0,0 +1,28 @@ +# REQUIRES: x86 + +# RUN: echo "VER1 { global: _end; foo ; local: * ; } ;" > %t.script +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s + +# CHECK: Name: _end@@VER1 +# CHECK-NEXT: Value: 0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .dynamic + +# CHECK: Name: foo@@VER1 +# CHECK-NEXT: Value: 0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text + +.global foo +foo: + .data + .quad _end + .quad foo |