daily update
[binutils.git] / gold / yyscript.y
bloba1f954cbfc575279017ee1622669c1d89711a39b
1 /* yyscript.y -- linker script grammer for gold. */
3 /* Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor <iant@google.com>.
6 This file is part of gold.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 /* This is a bison grammar to parse a subset of the original GNU ld
24 linker script language. */
28 #include "config.h"
30 #include <stddef.h>
31 #include <stdint.h>
33 #include "script-c.h"
37 /* We need to use a pure parser because we might be multi-threaded.
38 We pass some arguments through the parser to the lexer. */
40 %pure-parser
42 %parse-param {void* closure}
43 %lex-param {void* closure}
45 /* Since we require bison anyhow, we take advantage of it. */
47 %error-verbose
49 /* The values associated with tokens. */
51 %union {
52 /* A string. */
53 struct Parser_string string;
54 /* A number. */
55 uint64_t integer;
56 /* An expression. */
57 Expression_ptr expr;
60 /* Operators, including a precedence table for expressions. */
62 %right PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
63 %right '?' ':'
64 %left OROR
65 %left ANDAND
66 %left '|'
67 %left '^'
68 %left '&'
69 %left EQ NE
70 %left '<' '>' LE GE
71 %left LSHIFT RSHIFT
72 %left '+' '-'
73 %left '*' '/' '%'
75 /* A fake operator used to indicate unary operator precedence. */
76 %right UNARY
78 /* Constants. */
80 %token <string> STRING
81 %token <integer> INTEGER
83 /* Keywords. This list is taken from ldgram.y and ldlex.l in the old
84 GNU linker, with the keywords which only appear in MRI mode
85 removed. Not all these keywords are actually used in this grammar.
86 In most cases the keyword is recognized as the token name in upper
87 case. The comments indicate where this is not the case. */
89 %token ABSOLUTE
90 %token ADDR
91 %token ALIGN_K /* ALIGN */
92 %token ALIGNOF
93 %token ASSERT_K /* ASSERT */
94 %token AS_NEEDED
95 %token AT
96 %token BIND
97 %token BLOCK
98 %token BYTE
99 %token CONSTANT
100 %token CONSTRUCTORS
101 %token COPY
102 %token CREATE_OBJECT_SYMBOLS
103 %token DATA_SEGMENT_ALIGN
104 %token DATA_SEGMENT_END
105 %token DATA_SEGMENT_RELRO_END
106 %token DEFINED
107 %token DSECT
108 %token ENTRY
109 %token EXCLUDE_FILE
110 %token EXTERN
111 %token FILL
112 %token FLOAT
113 %token FORCE_COMMON_ALLOCATION
114 %token GLOBAL /* global */
115 %token GROUP
116 %token HLL
117 %token INCLUDE
118 %token INFO
119 %token INHIBIT_COMMON_ALLOCATION
120 %token INPUT
121 %token KEEP
122 %token LENGTH /* LENGTH, l, len */
123 %token LOADADDR
124 %token LOCAL /* local */
125 %token LONG
126 %token MAP
127 %token MAX_K /* MAX */
128 %token MEMORY
129 %token MIN_K /* MIN */
130 %token NEXT
131 %token NOCROSSREFS
132 %token NOFLOAT
133 %token NOLOAD
134 %token ONLY_IF_RO
135 %token ONLY_IF_RW
136 %token ORIGIN /* ORIGIN, o, org */
137 %token OUTPUT
138 %token OUTPUT_ARCH
139 %token OUTPUT_FORMAT
140 %token OVERLAY
141 %token PHDRS
142 %token PROVIDE
143 %token PROVIDE_HIDDEN
144 %token QUAD
145 %token SEARCH_DIR
146 %token SECTIONS
147 %token SEGMENT_START
148 %token SHORT
149 %token SIZEOF
150 %token SIZEOF_HEADERS /* SIZEOF_HEADERS, sizeof_headers */
151 %token SORT_BY_ALIGNMENT
152 %token SORT_BY_NAME
153 %token SPECIAL
154 %token SQUAD
155 %token STARTUP
156 %token SUBALIGN
157 %token SYSLIB
158 %token TARGET_K /* TARGET */
159 %token TRUNCATE
160 %token VERSIONK /* VERSION */
162 /* Keywords, part 2. These are keywords that are unique to gold,
163 and not present in the old GNU linker. As before, unless the
164 comments say otherwise, the keyword is recognized as the token
165 name in upper case. */
167 %token OPTION
169 /* Special tokens used to tell the grammar what type of tokens we are
170 parsing. The token stream always begins with one of these tokens.
171 We do this because version scripts can appear embedded within
172 linker scripts, and because --defsym uses the expression
173 parser. */
174 %token PARSING_LINKER_SCRIPT
175 %token PARSING_VERSION_SCRIPT
176 %token PARSING_DEFSYM
178 /* Non-terminal types, where needed. */
180 %type <expr> parse_exp exp
184 /* Read the special token to see what to read next. */
185 top:
186 PARSING_LINKER_SCRIPT linker_script
187 | PARSING_VERSION_SCRIPT version_script
188 | PARSING_DEFSYM defsym_expr
191 /* A file contains a list of commands. */
192 linker_script:
193 linker_script file_cmd
194 | /* empty */
197 /* A command which may appear at top level of a linker script. */
198 file_cmd:
199 GROUP
200 { script_start_group(closure); }
201 '(' input_list ')'
202 { script_end_group(closure); }
203 | OPTION '(' STRING ')'
204 { script_parse_option(closure, $3.value, $3.length); }
205 | file_or_sections_cmd
206 | ignore_cmd
209 /* Top level commands which we ignore. The GNU linker uses these to
210 select the output format, but we don't offer a choice. Ignoring
211 these is more-or-less OK since most scripts simply explicitly
212 choose the default. */
213 ignore_cmd:
214 OUTPUT_FORMAT '(' STRING ')'
215 | OUTPUT_FORMAT '(' STRING ',' STRING ',' STRING ')'
216 | OUTPUT_ARCH '(' STRING ')'
219 /* A list of input file names. */
220 input_list:
221 input_list_element
222 | input_list opt_comma input_list_element
225 /* An input file name. */
226 input_list_element:
227 STRING
228 { script_add_file(closure, $1.value, $1.length); }
229 | AS_NEEDED
230 { script_start_as_needed(closure); }
231 '(' input_list ')'
232 { script_end_as_needed(closure); }
235 /* A command which may appear at the top level of a linker script, or
236 within a SECTIONS block. */
237 file_or_sections_cmd:
238 ENTRY '(' STRING ')'
239 { script_set_entry(closure, $3.value, $3.length); }
240 | assignment end
243 /* Set a symbol to a value. */
244 assignment:
245 STRING '=' parse_exp
246 { script_set_symbol(closure, $1.value, $1.length, $3, 0, 0); }
247 | STRING PLUSEQ parse_exp
249 Expression_ptr s = script_exp_string($1.value, $1.length);
250 Expression_ptr e = script_exp_binary_add(s, $3);
251 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
253 | STRING MINUSEQ parse_exp
255 Expression_ptr s = script_exp_string($1.value, $1.length);
256 Expression_ptr e = script_exp_binary_sub(s, $3);
257 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
259 | STRING MULTEQ parse_exp
261 Expression_ptr s = script_exp_string($1.value, $1.length);
262 Expression_ptr e = script_exp_binary_mult(s, $3);
263 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
265 | STRING DIVEQ parse_exp
267 Expression_ptr s = script_exp_string($1.value, $1.length);
268 Expression_ptr e = script_exp_binary_div(s, $3);
269 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
271 | STRING LSHIFTEQ parse_exp
273 Expression_ptr s = script_exp_string($1.value, $1.length);
274 Expression_ptr e = script_exp_binary_lshift(s, $3);
275 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
277 | STRING RSHIFTEQ parse_exp
279 Expression_ptr s = script_exp_string($1.value, $1.length);
280 Expression_ptr e = script_exp_binary_rshift(s, $3);
281 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
283 | STRING ANDEQ parse_exp
285 Expression_ptr s = script_exp_string($1.value, $1.length);
286 Expression_ptr e = script_exp_binary_bitwise_and(s, $3);
287 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
289 | STRING OREQ parse_exp
291 Expression_ptr s = script_exp_string($1.value, $1.length);
292 Expression_ptr e = script_exp_binary_bitwise_or(s, $3);
293 script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
295 | PROVIDE '(' STRING '=' parse_exp ')'
296 { script_set_symbol(closure, $3.value, $3.length, $5, 1, 0); }
297 | PROVIDE_HIDDEN '(' STRING '=' parse_exp ')'
298 { script_set_symbol(closure, $3.value, $3.length, $5, 1, 1); }
301 /* Parse an expression, putting the lexer into the right mode. */
302 parse_exp:
303 { script_push_lex_into_expression_mode(closure); }
306 script_pop_lex_mode(closure);
307 $$ = $2;
311 /* An expression. */
312 exp:
313 '(' exp ')'
314 { $$ = $2; }
315 | '-' exp %prec UNARY
316 { $$ = script_exp_unary_minus($2); }
317 | '!' exp %prec UNARY
318 { $$ = script_exp_unary_logical_not($2); }
319 | '~' exp %prec UNARY
320 { $$ = script_exp_unary_bitwise_not($2); }
321 | '+' exp %prec UNARY
322 { $$ = $2; }
323 | exp '*' exp
324 { $$ = script_exp_binary_mult($1, $3); }
325 | exp '/' exp
326 { $$ = script_exp_binary_div($1, $3); }
327 | exp '%' exp
328 { $$ = script_exp_binary_mod($1, $3); }
329 | exp '+' exp
330 { $$ = script_exp_binary_add($1, $3); }
331 | exp '-' exp
332 { $$ = script_exp_binary_sub($1, $3); }
333 | exp LSHIFT exp
334 { $$ = script_exp_binary_lshift($1, $3); }
335 | exp RSHIFT exp
336 { $$ = script_exp_binary_rshift($1, $3); }
337 | exp EQ exp
338 { $$ = script_exp_binary_eq($1, $3); }
339 | exp NE exp
340 { $$ = script_exp_binary_ne($1, $3); }
341 | exp LE exp
342 { $$ = script_exp_binary_le($1, $3); }
343 | exp GE exp
344 { $$ = script_exp_binary_ge($1, $3); }
345 | exp '<' exp
346 { $$ = script_exp_binary_lt($1, $3); }
347 | exp '>' exp
348 { $$ = script_exp_binary_gt($1, $3); }
349 | exp '&' exp
350 { $$ = script_exp_binary_bitwise_and($1, $3); }
351 | exp '^' exp
352 { $$ = script_exp_binary_bitwise_xor($1, $3); }
353 | exp '|' exp
354 { $$ = script_exp_binary_bitwise_or($1, $3); }
355 | exp ANDAND exp
356 { $$ = script_exp_binary_logical_and($1, $3); }
357 | exp OROR exp
358 { $$ = script_exp_binary_logical_or($1, $3); }
359 | exp '?' exp ':' exp
360 { $$ = script_exp_trinary_cond($1, $3, $5); }
361 | INTEGER
362 { $$ = script_exp_integer($1); }
363 | STRING
364 { $$ = script_exp_string($1.value, $1.length); }
365 | MAX_K '(' exp ',' exp ')'
366 { $$ = script_exp_function_max($3, $5); }
367 | MIN_K '(' exp ',' exp ')'
368 { $$ = script_exp_function_min($3, $5); }
369 | DEFINED '(' STRING ')'
370 { $$ = script_exp_function_defined($3.value, $3.length); }
371 | SIZEOF_HEADERS
372 { $$ = script_exp_function_sizeof_headers(); }
373 | ALIGNOF '(' STRING ')'
374 { $$ = script_exp_function_alignof($3.value, $3.length); }
375 | SIZEOF '(' STRING ')'
376 { $$ = script_exp_function_sizeof($3.value, $3.length); }
377 | ADDR '(' STRING ')'
378 { $$ = script_exp_function_addr($3.value, $3.length); }
379 | LOADADDR '(' STRING ')'
380 { $$ = script_exp_function_loadaddr($3.value, $3.length); }
381 | ORIGIN '(' STRING ')'
382 { $$ = script_exp_function_origin($3.value, $3.length); }
383 | LENGTH '(' STRING ')'
384 { $$ = script_exp_function_length($3.value, $3.length); }
385 | CONSTANT '(' STRING ')'
386 { $$ = script_exp_function_constant($3.value, $3.length); }
387 | ABSOLUTE '(' exp ')'
388 { $$ = script_exp_function_absolute($3); }
389 | ALIGN_K '(' exp ')'
390 { $$ = script_exp_function_align(script_exp_string(".", 1), $3); }
391 | ALIGN_K '(' exp ',' exp ')'
392 { $$ = script_exp_function_align($3, $5); }
393 | BLOCK '(' exp ')'
394 { $$ = script_exp_function_align(script_exp_string(".", 1), $3); }
395 | DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
396 { $$ = script_exp_function_data_segment_align($3, $5); }
397 | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
398 { $$ = script_exp_function_data_segment_relro_end($3, $5); }
399 | DATA_SEGMENT_END '(' exp ')'
400 { $$ = script_exp_function_data_segment_end($3); }
401 | SEGMENT_START '(' STRING ',' exp ')'
403 $$ = script_exp_function_segment_start($3.value, $3.length, $5);
405 | ASSERT_K '(' exp ',' STRING ')'
406 { $$ = script_exp_function_assert($3, $5.value, $5.length); }
409 /* Handle the --defsym option. */
410 defsym_expr:
411 STRING '=' parse_exp
412 { script_set_symbol(closure, $1.value, $1.length, $3, 0, 0); }
415 /* A version script. Not yet implemented. */
416 version_script:
419 /* Some statements require a terminator, which may be a semicolon or a
420 comma. */
421 end:
423 | ','
426 /* An optional comma. */
427 opt_comma:
429 | /* empty */