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