Fixed some grammer ambiguities
[binutils-gdb.git] / ld / ldgram.y
1 %{
2 /* Copyright (C) 1991 Free Software Foundation, Inc.
3
4 This file is part of GLD, the Gnu Linker.
5
6 GLD is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
10
11 GLD is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GLD; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21 * $Id$
22 *
23 *
24 */
25
26 /*
27 This is a YACC grammer intended to parse a superset of the AT&T
28 linker scripting languaue.
29
30
31 Written by Steve Chamberlain steve@cygnus.com
32 */
33
34
35 /*SUPPRESS 166*/
36 /*SUPPRESS 112*/
37
38 #include "sysdep.h"
39 #include "bfd.h"
40
41 #include "ld.h"
42 #include "ldexp.h"
43 #include "ldversion.h"
44 #include "ldlang.h"
45 #include "ld-emul.h"
46 #include "ldfile.h"
47 #include "ldmisc.h"
48 #define YYDEBUG 1
49
50 boolean option_v;
51
52
53 extern unsigned int lineno;
54 extern boolean trace_files;
55 extern boolean write_map;
56
57 boolean hex_mode;
58
59
60
61
62 lang_memory_region_type *region;
63
64
65 lang_memory_region_type *lang_memory_region_lookup();
66 lang_output_section_statement_type *lang_output_section_statement_lookup();
67
68 #ifdef __STDC__
69
70 void lang_add_data(int type, union etree_union *exp);
71 void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, bfd_vma block_value);
72
73 #else
74
75 void lang_add_data();
76 void lang_enter_output_section_statement();
77
78 #endif /* __STDC__ */
79
80 extern args_type command_line;
81 char *current_file;
82 boolean ldgram_want_filename = true;
83 boolean had_script = false;
84 boolean force_make_executable = false;
85 boolean ldgram_has_inputfile = false;
86
87 boolean ldgram_in_expression = false;
88
89 boolean ldgram_in_defsym = false;
90 /* LOCALS */
91
92
93
94
95 %}
96 %union {
97 bfd_vma integer;
98 int voidval;
99 char *name;
100 int token;
101 union etree_union *etree;
102 asection *section;
103 struct lang_output_section_statement_struct *output_section_statement;
104 union lang_statement_union **statement_ptr;
105 int lineno;
106 struct {
107 FILE *file;
108 char *name;
109 unsigned int lineno;
110 } state;
111
112
113 }
114
115 %type <etree> exp opt_exp exp_head
116 %type <integer> fill_opt opt_block
117 %type <name> memspec_opt
118 %token <integer> INT CHAR
119 %token <name> NAME
120 %type <integer> length
121
122 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
123 %right <token> '?' ':'
124 %left <token> OROR
125 %left <token> ANDAND
126 %left <token> '|'
127 %left <token> '^'
128 %left <token> '&'
129 %left <token> EQ NE
130 %left <token> '<' '>' LE GE
131 %left <token> LSHIFT RSHIFT
132 %left <token> '+' '-'
133 %left <token> '*' '/' '%'
134 %right UNARY
135 %left <token> '('
136 %token <token> ALIGN_K BLOCK LONG SHORT BYTE
137 %token SECTIONS
138 %token '{' '}'
139 %token ALIGNMENT SIZEOF_HEADERS
140 %token NEXT SIZEOF ADDR
141 %token MEMORY
142 %token DSECT NOLOAD COPY INFO OVERLAY
143 %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
144 %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S
145 %token OPTION_format OPTION_F
146
147 %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X
148 %token OPTION_v OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT OPTION_defsym
149 %token OPTION_n OPTION_r OPTION_o OPTION_b OPTION_A
150 %token <name> OPTION_l OPTION_L OPTION_T OPTION_Aarch OPTION_Tfile OPTION_Texp
151 %token OPTION_Ur
152 %token ORIGIN FILL OPTION_g
153 %token LENGTH BIND SUBSECTION_ALIGN CREATE_OBJECT_SYMBOLS INPUT OUTPUT
154 %type <token> assign_op SIZEOF NEXT ADDR
155 %type <etree> assignment
156 %type <name> filename
157
158 %{
159 ld_config_type config;
160 %}
161
162 %%
163
164
165
166 file: command_line { lang_final(); };
167
168
169 filename:
170 NAME;
171
172 command_line:
173 command_line command_line_option
174 |
175 ;
176
177 command_line_option:
178 OPTION_v
179 {
180 ldversion();
181 option_v = true;
182 }
183 | OPTION_t {
184 trace_files = true;
185 }
186 | OPTION_M {
187 write_map = true;
188 }
189 | OPTION_n {
190 config.magic_demand_paged = false;
191 config.make_executable = false;
192 }
193 | OPTION_s {
194 strip_symbols = STRIP_ALL;
195 }
196 | OPTION_S {
197 strip_symbols = STRIP_DEBUGGER;
198 }
199
200 | OPTION_r {
201 config.relocateable_output = true;
202 config.build_constructors = false;
203 config.magic_demand_paged = false;
204 }
205 | OPTION_Ur {
206 config.relocateable_output = true;
207 config.build_constructors = true;
208 config.magic_demand_paged = false;
209 }
210 | OPTION_o filename
211 {
212 lang_add_output($2);
213 }
214 | OPTION_e NAME
215 { lang_add_entry($2);
216 }
217 | OPTION_X {
218 discard_locals = DISCARD_L;
219 }
220 | OPTION_x {
221 discard_locals = DISCARD_ALL;
222 }
223
224 | OPTION_noinhibit_exec
225 {
226 force_make_executable = true;
227 }
228 | OPTION_d {
229 command_line.force_common_definition = true;
230 }
231 | OPTION_dc
232 {
233 command_line.force_common_definition = true;
234 }
235 | OPTION_g
236 {
237 /* Ignored */
238 }
239 | OPTION_dp
240 {
241 command_line.force_common_definition = true;
242 }
243 | OPTION_format NAME
244 {
245 lang_add_target($2);
246 }
247
248 | OPTION_Texp { hex_mode =true; }
249 exp
250 { lang_section_start($1, $3);
251 hex_mode = false; }
252
253 | OPTION_Aarch
254 { ldfile_add_arch($1); }
255 | OPTION_b NAME
256 {
257 lang_add_target($2);
258 }
259 | OPTION_L
260 {
261 ldfile_add_library_path($1);
262 }
263 | OPTION_F
264 {
265 /* Ignore */
266 }
267
268 | ifile_p1
269 | input_list
270 | OPTION_c filename
271 { ldfile_open_command_file($2); }
272 | OPTION_Tfile
273 { ldfile_open_command_file($1); }
274
275 | OPTION_T filename
276 { ldfile_open_command_file($2); }
277
278 | OPTION_l
279 {
280 lang_add_input_file($1,
281 lang_input_file_is_l_enum,
282 (char *)NULL);
283 }
284 | OPTION_A filename
285 {
286 lang_add_input_file($2,
287 lang_input_file_is_symbols_only_enum,
288 (char *)NULL);
289 }
290 | OPTION_defsym
291 {
292 ldgram_in_defsym = true;
293 }
294 assignment
295 {
296 ldgram_in_defsym = false;
297 }
298
299 ;
300
301
302 input_section_spec:
303 NAME
304 {
305 lang_add_wild((char *)NULL, $1);
306 }
307 | '['
308 {
309 current_file = (char *)NULL;
310 }
311 file_NAME_list
312 ']'
313 | NAME
314 {
315 current_file =$1;
316 }
317 '(' file_NAME_list ')'
318 | '*'
319 {
320 current_file = (char *)NULL;
321 }
322 '(' file_NAME_list ')'
323 ;
324
325
326
327 file_NAME_list:
328 NAME
329 { lang_add_wild($1, current_file); }
330 | file_NAME_list opt_comma NAME
331 { lang_add_wild($3, current_file); }
332 ;
333
334
335
336 ifile_p1:
337 memory
338 | sections
339 | startup
340 | high_level_library
341 | low_level_library
342 | floating_point_support
343 | assignment end
344 | TARGET_K '(' NAME ')'
345 { lang_add_target($3); }
346 | SEARCH_DIR '(' filename ')'
347 { ldfile_add_library_path($3); }
348 | OUTPUT '(' filename ')'
349 { lang_add_output($3); }
350 | INPUT '(' input_list ')'
351 | MAP '(' filename ')'
352 { lang_add_map($3); }
353 ;
354
355 input_list:
356 NAME
357 { lang_add_input_file($1,lang_input_file_is_file_enum,
358 (char *)NULL); }
359 | input_list ',' NAME
360 { lang_add_input_file($3,lang_input_file_is_file_enum,
361 (char *)NULL); }
362 | input_list NAME
363 { lang_add_input_file($2, lang_input_file_is_file_enum,
364 (char *)NULL); }
365 ;
366
367 sections:
368 SECTIONS '{'sec_or_group_p1 '}'
369 ;
370
371 sec_or_group_p1:
372 sec_or_group_p1 section
373 | sec_or_group_p1 statement_anywhere
374 |
375 ;
376
377 statement_anywhere:
378 ENTRY '(' NAME ')'
379 { lang_add_entry($3); }
380 | assignment end
381 ;
382
383 statement:
384 statement assignment end
385 | statement CREATE_OBJECT_SYMBOLS
386 { lang_add_attribute(lang_object_symbols_statement_enum); }
387 | statement input_section_spec
388 | statement length '(' exp_head ')'
389 {
390 lang_add_data($2,$4);
391 }
392
393 | statement FILL '(' exp_head ')'
394 {
395 lang_add_fill
396 (exp_get_value_int($4,
397 0,
398 "fill value",
399 lang_first_phase_enum));
400 }
401 |
402 ;
403
404 length:
405 LONG
406 { $$ = $1; }
407 | SHORT
408 { $$ = $1; }
409 | BYTE
410 { $$ = $1; }
411 ;
412
413 fill_opt:
414 '=' exp_head
415 {
416 $$ = exp_get_value_int($2,
417 0,
418 "fill value",
419 lang_first_phase_enum);
420 }
421 | { $$ = 0; }
422 ;
423
424
425
426 assign_op:
427 PLUSEQ
428 { $$ = '+'; }
429 | MINUSEQ
430 { $$ = '-'; }
431 | MULTEQ
432 { $$ = '*'; }
433 | DIVEQ
434 { $$ = '/'; }
435 | LSHIFTEQ
436 { $$ = LSHIFT; }
437 | RSHIFTEQ
438 { $$ = RSHIFT; }
439 | ANDEQ
440 { $$ = '&'; }
441 | OREQ
442 { $$ = '|'; }
443
444 ;
445
446 end: ';' | ','
447 ;
448
449
450 assignment:
451
452 NAME '=' exp_head
453 {
454 lang_add_assignment(exp_assop($2,$1,$3));
455 }
456 | NAME assign_op exp_head
457 {
458 lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
459 }
460
461 ;
462
463
464 opt_comma:
465 ',' | ;
466
467
468 memory:
469 MEMORY '{' memory_spec memory_spec_list '}'
470 ;
471
472 memory_spec_list:
473 memory_spec_list memory_spec
474 | memory_spec_list ',' memory_spec
475 |
476 ;
477
478
479 memory_spec:
480 NAME
481 { region = lang_memory_region_lookup($1); }
482 attributes_opt ':' origin_spec opt_comma length_spec
483
484 {
485
486
487 }
488 ;
489 origin_spec:
490 ORIGIN '=' exp
491 { region->current =
492 region->origin =
493 exp_get_vma($3, 0L,"origin", lang_first_phase_enum); }
494 ;
495 length_spec:
496 LENGTH '=' exp
497 { region->length = exp_get_vma($3,
498 ~((bfd_vma)0),
499 "length",
500 lang_first_phase_enum);
501 }
502
503
504 attributes_opt:
505 '(' NAME ')'
506 {
507 lang_set_flags(&region->flags, $2);
508 }
509 |
510
511 ;
512
513 startup:
514 STARTUP '(' filename ')'
515 { lang_startup($3); }
516 ;
517
518 high_level_library:
519 HLL '(' high_level_library_NAME_list ')'
520 | HLL '(' ')'
521 { ldemul_hll((char *)NULL); }
522 ;
523
524 high_level_library_NAME_list:
525 high_level_library_NAME_list opt_comma filename
526 { ldemul_hll($3); }
527 | filename
528 { ldemul_hll($1); }
529
530 ;
531
532 low_level_library:
533 SYSLIB '(' low_level_library_NAME_list ')'
534 ;
535 low_level_library_NAME_list:
536 low_level_library_NAME_list opt_comma filename
537 { ldemul_syslib($3); }
538 |
539 ;
540
541 floating_point_support:
542 FLOAT
543 { lang_float(true); }
544 | NOFLOAT
545 { lang_float(false); }
546 ;
547
548
549
550
551 exp :
552 '-' exp %prec UNARY
553 { $$ = exp_unop('-', $2); }
554 | '(' exp ')'
555 { $$ = $2; }
556 | NEXT '(' exp ')' %prec UNARY
557 { $$ = exp_unop($1,$3); }
558 | '!' exp %prec UNARY
559 { $$ = exp_unop('!', $2); }
560 | '+' exp %prec UNARY
561 { $$ = $2; }
562 | '~' exp %prec UNARY
563 { $$ = exp_unop('~', $2);}
564
565 | exp '*' exp
566 { $$ = exp_binop('*', $1, $3); }
567 | exp '/' exp
568 { $$ = exp_binop('/', $1, $3); }
569 | exp '%' exp
570 { $$ = exp_binop('%', $1, $3); }
571 | exp '+' exp
572 { $$ = exp_binop('+', $1, $3); }
573 | exp '-' exp
574 { $$ = exp_binop('-' , $1, $3); }
575 | exp LSHIFT exp
576 { $$ = exp_binop(LSHIFT , $1, $3); }
577 | exp RSHIFT exp
578 { $$ = exp_binop(RSHIFT , $1, $3); }
579 | exp EQ exp
580 { $$ = exp_binop(EQ , $1, $3); }
581 | exp NE exp
582 { $$ = exp_binop(NE , $1, $3); }
583 | exp LE exp
584 { $$ = exp_binop(LE , $1, $3); }
585 | exp GE exp
586 { $$ = exp_binop(GE , $1, $3); }
587 | exp '<' exp
588 { $$ = exp_binop('<' , $1, $3); }
589 | exp '>' exp
590 { $$ = exp_binop('>' , $1, $3); }
591 | exp '&' exp
592 { $$ = exp_binop('&' , $1, $3); }
593 | exp '^' exp
594 { $$ = exp_binop('^' , $1, $3); }
595 | exp '|' exp
596 { $$ = exp_binop('|' , $1, $3); }
597 | exp '?' exp ':' exp
598 { $$ = exp_trinop('?' , $1, $3, $5); }
599 | exp ANDAND exp
600 { $$ = exp_binop(ANDAND , $1, $3); }
601 | exp OROR exp
602 { $$ = exp_binop(OROR , $1, $3); }
603 | DEFINED '(' NAME ')'
604 { $$ = exp_nameop(DEFINED, $3); }
605 | INT
606 { $$ = exp_intop($1); }
607
608 | SIZEOF '(' NAME ')'
609 { $$ = exp_nameop($1,$3); }
610 | ADDR '(' NAME ')'
611 { $$ = exp_nameop($1,$3); }
612 | ALIGN_K '(' exp ')'
613 { $$ = exp_unop($1,$3); }
614 | NAME
615 { $$ = exp_nameop(NAME,$1); }
616 ;
617
618
619
620
621 section: NAME opt_exp opt_block ':' opt_things'{'
622 {
623 lang_enter_output_section_statement($1,$2,$3);
624 }
625 statement '}' fill_opt memspec_opt
626 {
627 lang_leave_output_section_statement($10, $11);
628 }
629
630 ;
631
632 opt_things:
633 {
634
635 }
636 ;
637
638 exp_head:
639 {
640 ldgram_in_expression = true;
641 }
642 exp
643 {
644 ldgram_in_expression = false;
645 $$ = $2;
646 }
647 ;
648
649 opt_exp:
650 exp_head
651 { $$ = $1; }
652 | { $$= (etree_type *)NULL; }
653 ;
654
655 opt_block:
656 BLOCK '(' exp_head ')'
657 { $$ = exp_get_value_int($3,
658 1L,
659 "block",
660 lang_first_phase_enum);
661 }
662 | { $$ = 1; }
663 ;
664
665 memspec_opt:
666 '>' NAME
667 { $$ = $2; }
668 | { $$ = "*default*"; }
669 ;
670