summaryrefslogtreecommitdiff
path: root/test/ELF/linkerscript
diff options
context:
space:
mode:
Diffstat (limited to 'test/ELF/linkerscript')
-rw-r--r--test/ELF/linkerscript/Inputs/common-filespec1.s2
-rw-r--r--test/ELF/linkerscript/Inputs/common-filespec2.s2
-rw-r--r--test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s5
-rw-r--r--test/ELF/linkerscript/Inputs/provide-shared.s5
-rw-r--r--test/ELF/linkerscript/Inputs/symbol-reserved.script5
-rw-r--r--test/ELF/linkerscript/absolute2.s17
-rw-r--r--test/ELF/linkerscript/align-section-offset.s11
-rw-r--r--test/ELF/linkerscript/align-section.s6
-rw-r--r--test/ELF/linkerscript/align.s45
-rw-r--r--test/ELF/linkerscript/arm-exidx-order.s19
-rw-r--r--test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s24
-rw-r--r--test/ELF/linkerscript/at-addr.s4
-rw-r--r--test/ELF/linkerscript/at.s25
-rw-r--r--test/ELF/linkerscript/common-exclude.s86
-rw-r--r--test/ELF/linkerscript/common-filespec.s105
-rw-r--r--test/ELF/linkerscript/common.s8
-rw-r--r--test/ELF/linkerscript/compress-debug-sections.s4
-rw-r--r--test/ELF/linkerscript/copy-rel-symbol-value-err.s12
-rw-r--r--test/ELF/linkerscript/copy-rel-symbol-value.s27
-rw-r--r--test/ELF/linkerscript/data-segment-relro.s4
-rw-r--r--test/ELF/linkerscript/diagnostic.s14
-rw-r--r--test/ELF/linkerscript/discard-section-err.s2
-rw-r--r--test/ELF/linkerscript/early-assign-symbol.s24
-rw-r--r--test/ELF/linkerscript/eh-frame-reloc-out-of-range.s2
-rw-r--r--test/ELF/linkerscript/emit-reloc-section-names.s22
-rw-r--r--test/ELF/linkerscript/emit-reloc.s2
-rw-r--r--test/ELF/linkerscript/emit-relocs-multiple.s2
-rw-r--r--test/ELF/linkerscript/extend-pt-load.s13
-rw-r--r--test/ELF/linkerscript/filename-spec.s47
-rw-r--r--test/ELF/linkerscript/header-addr.s22
-rw-r--r--test/ELF/linkerscript/header-phdr.s13
-rw-r--r--test/ELF/linkerscript/image-base.s18
-rw-r--r--test/ELF/linkerscript/implicit-program-header.s2
-rw-r--r--test/ELF/linkerscript/include-cycle.s15
-rw-r--r--test/ELF/linkerscript/linker-script-in-search-path.s19
-rw-r--r--test/ELF/linkerscript/linkerscript.s4
-rw-r--r--test/ELF/linkerscript/memory-at.s46
-rw-r--r--test/ELF/linkerscript/memory-err.s16
-rw-r--r--test/ELF/linkerscript/memory.s4
-rw-r--r--test/ELF/linkerscript/memory2.s14
-rw-r--r--test/ELF/linkerscript/memory3.s23
-rw-r--r--test/ELF/linkerscript/merge-sections.s2
-rw-r--r--test/ELF/linkerscript/no-space.s4
-rw-r--r--test/ELF/linkerscript/noload.s4
-rw-r--r--test/ELF/linkerscript/non-alloc.s2
-rw-r--r--test/ELF/linkerscript/operators.s2
-rw-r--r--test/ELF/linkerscript/orphan-discard.s25
-rw-r--r--test/ELF/linkerscript/orphan-end.s57
-rw-r--r--test/ELF/linkerscript/orphan-phdrs.s34
-rw-r--r--test/ELF/linkerscript/orphan-report.s54
-rw-r--r--test/ELF/linkerscript/out-of-order.s2
-rw-r--r--test/ELF/linkerscript/phdr-check.s4
-rw-r--r--test/ELF/linkerscript/phdrs.s4
-rw-r--r--test/ELF/linkerscript/provide-shared.s13
-rw-r--r--test/ELF/linkerscript/region-alias.s54
-rw-r--r--test/ELF/linkerscript/repsection-symbol.s2
-rw-r--r--test/ELF/linkerscript/sections-sort.s2
-rw-r--r--test/ELF/linkerscript/segment-headers.s26
-rw-r--r--test/ELF/linkerscript/segment-start.s2
-rw-r--r--test/ELF/linkerscript/sort-non-script.s2
-rw-r--r--test/ELF/linkerscript/subalign.s17
-rw-r--r--test/ELF/linkerscript/symbol-assignexpr.s8
-rw-r--r--test/ELF/linkerscript/symbol-only-flags.s20
-rw-r--r--test/ELF/linkerscript/symbol-only.s2
-rw-r--r--test/ELF/linkerscript/symbol-ordering-file.s23
-rw-r--r--test/ELF/linkerscript/symbol-reserved.s28
-rw-r--r--test/ELF/linkerscript/symbols.s13
-rw-r--r--test/ELF/linkerscript/thunk-gen-mips.s40
-rw-r--r--test/ELF/linkerscript/unused-synthetic.s10
-rw-r--r--test/ELF/linkerscript/version-linker-symbol.s28
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