xref: /llvm-project/lld/test/ELF/linkerscript/operators.test (revision 8c2030b7d4c4f21270577187d6413c6b05784861)
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t.o
3# RUN: ld.lld %t.o -T %s -o %t
4# RUN: llvm-nm -p %t | FileCheck %s
5
6SECTIONS {
7  _start = .;
8  unary =!0 + !0;  # Test space can be omitted between = and !
9  negate =-1 - 1;
10  not =~0xffff + 4;
11  not_negate = -~5 + 1;
12  multiplicative = 20 / 2 % 7;
13  additive = 1 - 2 + -3 * -2;
14  shift = 2 << 5 >> 1 << 2;
15  shift2 = 2 << 69 >> 65;
16  less = 1 < 0 ? 1 : 2;
17  lesseq = 1<<0 <= 1>>0 ? 1 : 2;
18  greater = 0 > 1 ? 1 : 2;
19  greatereq = 1 >= 1 ? 1 : 2;
20  eq = 1 == 1 ? 1 : 2;
21  neq = 1 != 1 <= 1 ? 1 : 2;
22  and = 3 & 4 > 0;
23  or = 0xbb & 0xee | 1;
24  xor = 3&3^5|1;
25  logicaland = (0 && 0) + (0&&1)*2 + (1&& 0)*4 + (1 &&1) *8;
26  logicaland2 = 1 & 0 && 1 | 1;
27  logicalor = (0 || 0) + (0||1)*2 + (1|| 0)*4 + (1 ||1) *8;
28  logicalor2 = 0 && 0 || 1 && 1;
29  ternary1 = 0 ? 1 : 2 & 6;
30  ternary2 = 1 ? 2?3:4 : 5?6 :7;
31
32  mulassign =2;
33  mulassign *=2;  # Test space can be omitted after *=
34  divassign = 8;
35  divassign /=2;
36  plusassign =1;
37  plusassign += 2;
38  minusassign = 3;
39  minusassign -= 1;
40  lshiftassign = 1;
41  lshiftassign <<= 1;
42  lshiftassign <<= 65;  # arbitrarily reduced to 1
43  rshiftassign = 24;
44  rshiftassign >>= 1;
45  rshiftassign >>= 130;  # arbitrarily reduced to 2
46  andassign = 6;
47  andassign &= 4;
48  andassign&=4;
49  xorassign = 6;
50  xorassign ^= 3;
51  xorassign ^=0;
52  orassign = 4;
53  orassign |= 1;
54  orassign|=1;
55  braces = 1 + (2 + 3) * 4;
56  precedence1 = 1|0xff&1/1<<1+1*2;
57  precedence2 = (1 | (0xff & (1 << (1 + (1 * 2)))));
58  maxpagesize = CONSTANT (MAXPAGESIZE);
59  commonpagesize = CONSTANT (COMMONPAGESIZE);
60  . = 0xfff0;
61  datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0);
62  datasegmentalign2 = DATA_SEGMENT_ALIGN (0, 0);
63  _end = .;
64  minus_rel = _end - 0x10;
65  minus_abs = _end - _start;
66  max = MAX(11, 22);
67  min = MIN(11, 22);
68  log2ceil0 = LOG2CEIL(0);
69  log2ceil1 = LOG2CEIL(1);
70  log2ceil2 = LOG2CEIL(2);
71  log2ceil3 = LOG2CEIL(3);
72  log2ceil4 = LOG2CEIL(4);
73  log2ceil100000000 = LOG2CEIL(0x100000000);
74  log2ceil100000001 = LOG2CEIL(0x100000001);
75  log2ceilmax = LOG2CEIL(0xffffffffffffffff);
76  unaryadd = +3 + ++5;
77  unaryadd_and_unaryminus = 15 + +-5 + -+7;
78}
79
80# CHECK:      0000000000000002 A unary
81# CHECK-NEXT: fffffffffffffffe A negate
82# CHECK-NEXT: ffffffffffff0004 A not
83# CHECK-NEXT: 0000000000000007 A not_negate
84# CHECK-NEXT: 0000000000000003 A multiplicative
85# CHECK-NEXT: 0000000000000005 A additive
86# CHECK-NEXT: 0000000000000080 A shift
87# CHECK-NEXT: 0000000000000020 A shift
88# CHECK-NEXT: 0000000000000002 A less
89# CHECK-NEXT: 0000000000000001 A lesseq
90# CHECK-NEXT: 0000000000000002 A greater
91# CHECK-NEXT: 0000000000000001 A greatereq
92# CHECK-NEXT: 0000000000000001 A eq
93# CHECK-NEXT: 0000000000000002 A neq
94# CHECK-NEXT: 0000000000000001 A and
95# CHECK-NEXT: 00000000000000ab A or
96# CHECK-NEXT: 0000000000000007 A xor
97# CHECK-NEXT: 0000000000000008 A logicaland
98# CHECK-NEXT: 0000000000000000 A logicaland2
99# CHECK-NEXT: 000000000000000e A logicalor
100# CHECK-NEXT: 0000000000000001 A logicalor2
101# CHECK-NEXT: 0000000000000002 A ternary1
102# CHECK-NEXT: 0000000000000003 A ternary2
103# CHECK-NEXT: 0000000000000004 A mulassign
104# CHECK-NEXT: 0000000000000004 A divassign
105# CHECK-NEXT: 0000000000000003 A plusassign
106# CHECK-NEXT: 0000000000000002 A minusassign
107# CHECK-NEXT: 0000000000000004 A lshiftassign
108# CHECK-NEXT: 0000000000000003 A rshiftassign
109# CHECK-NEXT: 0000000000000004 A andassign
110# CHECK-NEXT: 0000000000000005 A xorassign
111# CHECK-NEXT: 0000000000000005 A orassign
112# CHECK-NEXT: 0000000000000015 A braces
113# CHECK-NEXT: 0000000000000009 A precedence1
114# CHECK-NEXT: 0000000000000009 A precedence2
115# CHECK-NEXT: 0000000000001000 A maxpagesize
116# CHECK-NEXT: 0000000000001000 A commonpagesize
117# CHECK-NEXT: 0000000000010000 A datasegmentalign
118# CHECK-NEXT: 000000000000fff0 A datasegmentalign2
119# CHECK-NEXT: 000000000000ffe0 T minus_rel
120# CHECK-NEXT: 000000000000fff0 A minus_abs
121# CHECK-NEXT: 0000000000000016 A max
122# CHECK-NEXT: 000000000000000b A min
123# CHECK-NEXT: 0000000000000000 A log2ceil0
124# CHECK-NEXT: 0000000000000000 A log2ceil1
125# CHECK-NEXT: 0000000000000001 A log2ceil2
126# CHECK-NEXT: 0000000000000002 A log2ceil3
127# CHECK-NEXT: 0000000000000002 A log2ceil4
128# CHECK-NEXT: 0000000000000020 A log2ceil100000000
129# CHECK-NEXT: 0000000000000021 A log2ceil100000001
130# CHECK-NEXT: 0000000000000040 A log2ceilmax
131# CHECK-NEXT: 0000000000000008 A unaryadd
132# CHECK-NEXT: 0000000000000003 A unaryadd_and_unaryminus
133
134## Mailformed number error.
135# RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script
136# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | \
137# RUN:  FileCheck --check-prefix=NUMERR %s
138# NUMERR: malformed number: 0x12Q41
139
140## Missing closing bracket.
141# RUN: echo "SECTIONS { . = (1; }" > %t.script
142# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | \
143# RUN:  FileCheck --check-prefix=BRACKETERR %s
144# BRACKETERR: ) expected, but got ;
145
146## Missing opening bracket.
147# RUN: echo "SECTIONS { . = 1); }" > %t.script
148# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | \
149# RUN:  FileCheck --check-prefix=BRACKETERR2 %s
150# BRACKETERR2: ; expected, but got )
151
152## Empty expression.
153# RUN: echo "SECTIONS { . = ; }" > %t.script
154# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | \
155# RUN:  FileCheck --check-prefix=ERREXPR %s
156# ERREXPR: malformed number: ;
157
158## Div by zero error.
159# RUN: echo "SECTIONS { . = 1 / 0; }" > %t.script
160# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | \
161# RUN:  FileCheck --check-prefix=DIVZERO %s
162# DIVZERO: {{.*}}.script:1: division by zero
163
164## Mod by zero error.
165# RUN: echo "SECTIONS { . = 1 % 0; }" > %t.script
166# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | \
167# RUN:  FileCheck --check-prefix=MODZERO %s
168# MODZERO: {{.*}}.script:1: modulo by zero
169
170## Broken ternary operator expression.
171# RUN: echo "SECTIONS { . = 1 ? 2; }" > %t.script
172# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | \
173# RUN:  FileCheck --check-prefix=TERNERR %s
174# TERNERR: : expected, but got ;
175
176## Div by zero error.
177# RUN: echo 'a = 1; a /= 0;' > %t.script
178# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | FileCheck --check-prefix=DIVZERO %s
179
180## GNU ld does not support %=.
181# RUN: echo 'a = 1; a %= 0;' > %t.script
182# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | FileCheck --check-prefix=UNKNOWN1 %s
183## For now, we don't support ^= without a preceding space.
184# RUN: echo 'a = 1; a^=0;' > %t.script
185# RUN: not ld.lld %t.o -T %t.script -o /dev/null 2>&1 | FileCheck --check-prefix=UNKNOWN2 %s
186
187# UNKNOWN1: error: {{.*}}:1: unknown directive: a{{$}}
188# UNKNOWN2: error: {{.*}}:1: unknown directive: a^=0{{$}}
189