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