d0196b1433dbf0472b485639495f9841fc357ee3
[deliverable/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_had_equals = false;
66 /* LOCALS */
67
68
69
70
71 %}
72 %union {
73 bfd_vma integer;
74 int voidval;
75 char *name;
76 int token;
77 union etree_union *etree;
78 asection *section;
79 struct lang_output_section_statement_struct *output_section_statement;
80 union lang_statement_union **statement_ptr;
81 int lineno;
82 struct {
83 FILE *file;
84 char *name;
85 unsigned int lineno;
86 } state;
87
88
89 }
90
91 %type <etree> exp opt_exp exp_head
92 %type <integer> fill_opt opt_block
93 %type <name> memspec_opt
94 %token <integer> INT CHAR
95 %token <name> NAME
96 %type <integer> length
97
98 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
99 %right <token> '?' ':'
100 %left <token> OROR
101 %left <token> ANDAND
102 %left <token> '|'
103 %left <token> '^'
104 %left <token> '&'
105 %left <token> EQ NE
106 %left <token> '<' '>' LE GE
107 %left <token> LSHIFT RSHIFT
108 %left <token> '+' '-'
109 %left <token> '*' '/' '%'
110 %right UNARY
111 %left <token> '('
112 %token <token> ALIGN_K BLOCK LONG SHORT BYTE
113 %token SECTIONS
114 %token '{' '}'
115 %token ALIGNMENT SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
116 %token NEXT SIZEOF ADDR SCRIPT ENDSCRIPT SIZEOF_HEADERS
117 %token MEMORY
118 %token DSECT NOLOAD COPY INFO OVERLAY
119 %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
120 %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S
121 %token OPTION_format OPTION_F OPTION_u
122
123 %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
124 %token OPTION_v OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT
125 %token OPTION_n OPTION_r OPTION_o OPTION_b OPTION_A OPTION_R
126 %token <name> OPTION_l OPTION_L OPTION_T OPTION_Aarch OPTION_Tfile OPTION_Texp
127 %token OPTION_Ur
128 %token ORIGIN FILL OPTION_g
129 %token LENGTH BIND SUBSECTION_ALIGN CREATE_OBJECT_SYMBOLS INPUT OUTPUT
130 %type <token> assign_op SIZEOF NEXT ADDR
131 %type <etree> assignment
132 %type <name> filename
133
134 %{
135 ld_config_type config;
136 %}
137
138 %%
139
140
141
142 file: command_line { lang_final(); };
143
144
145 filename:
146 NAME;
147
148 command_line:
149 command_line command_line_option
150 |
151 ;
152
153 command_line_option:
154 '{'
155 { ldgram_in_script = true; }
156 ifile_list
157 { ldgram_in_script = false; }
158 '}'
159 | OPTION_v
160 {
161 ldversion();
162 option_v = true;
163 }
164 | OPTION_t {
165 trace_files = true;
166 }
167 | OPTION_M {
168 write_map = true;
169 }
170 | OPTION_n {
171 config.magic_demand_paged = false;
172 config.make_executable = false;
173 }
174 | OPTION_s {
175 strip_symbols = STRIP_ALL;
176 }
177 | OPTION_S {
178 strip_symbols = STRIP_DEBUGGER;
179 }
180 | OPTION_u NAME {
181 ldlang_add_undef($2);
182 }
183
184 | OPTION_r {
185 config.relocateable_output = true;
186 config.build_constructors = false;
187 config.magic_demand_paged = false;
188 }
189 | OPTION_Ur {
190 config.relocateable_output = true;
191 config.build_constructors = true;
192 config.magic_demand_paged = false;
193 }
194 | OPTION_o filename
195 {
196 lang_add_output($2);
197 }
198 | OPTION_e NAME
199 { lang_add_entry($2);
200 }
201 | OPTION_X {
202 discard_locals = DISCARD_L;
203 }
204 | OPTION_x {
205 discard_locals = DISCARD_ALL;
206 }
207
208 | OPTION_noinhibit_exec
209 {
210 force_make_executable = true;
211 }
212 | OPTION_d {
213 command_line.force_common_definition = true;
214 }
215 | OPTION_dc
216 {
217 command_line.force_common_definition = true;
218 }
219 | OPTION_g
220 {
221 /* Ignored */
222 }
223 | OPTION_dp
224 {
225 command_line.force_common_definition = true;
226 }
227 | OPTION_format NAME
228 {
229 lang_add_target($2);
230 }
231 | OPTION_Texp
232 {
233 hex_mode =true;
234 }
235 INT
236 {
237 lang_section_start($1,exp_intop($3));
238 hex_mode = false;
239 }
240
241 | OPTION_Aarch
242 {
243 ldfile_add_arch($1);
244 }
245 | OPTION_b NAME
246 {
247 lang_add_target($2);
248 }
249 | OPTION_L
250 {
251 ldfile_add_library_path($1);
252 }
253 | OPTION_F
254 {
255 /* Ignore */
256 }
257 | NAME
258 { lang_add_input_file($1,lang_input_file_is_file_enum,
259 (char *)NULL); }
260 | OPTION_c filename script_file
261 { ldfile_open_command_file($2); }
262 | OPTION_Tfile
263 { ldfile_open_command_file($1); } script_file
264
265 | OPTION_T filename
266 { ldfile_open_command_file($2); } script_file
267
268 | OPTION_l
269 {
270 lang_add_input_file($1,
271 lang_input_file_is_l_enum,
272 (char *)NULL);
273 }
274 | OPTION_R filename
275 {
276 lang_add_input_file($2,
277 lang_input_file_is_symbols_only_enum,
278 (char *)NULL);
279 }
280 | OPTION_defsym
281 {
282 }
283 NAME '='
284 exp_head
285 {
286 lang_add_assignment(exp_assop($4,$3,$5));
287 }
288 | '-' NAME
289 { info("%P%F Unrecognised option -%s\n", $2); }
290
291 ;
292
293
294
295
296
297
298
299
300 script_file:
301 { ldgram_in_script = true; }
302 ifile_list '}'
303 { ldgram_in_script = false; }
304
305 ;
306
307
308 ifile_list:
309 ifile_list ifile_p1
310 |
311 ;
312
313
314
315 ifile_p1:
316 memory
317 | sections
318 | startup
319 | high_level_library
320 | low_level_library
321 | floating_point_support
322 | statement_anywhere
323 | TARGET_K '(' NAME ')'
324 { lang_add_target($3); }
325 | SEARCH_DIR '(' filename ')'
326 { ldfile_add_library_path($3); }
327 | OUTPUT '(' filename ')'
328 { lang_add_output($3); }
329 | OUTPUT_FORMAT '(' NAME ')'
330 { lang_add_output_format($3); }
331 | OUTPUT_ARCH '(' NAME ')'
332 { ldfile_set_output_arch($3); }
333 | FORCE_COMMON_ALLOCATION
334 { command_line.force_common_definition = true ; }
335 | INPUT '(' input_list ')'
336 | MAP '(' filename ')'
337 { lang_add_map($3); }
338 ;
339
340 input_list:
341 NAME
342 { lang_add_input_file($1,lang_input_file_is_file_enum,
343 (char *)NULL); }
344 | input_list ',' NAME
345 { lang_add_input_file($3,lang_input_file_is_file_enum,
346 (char *)NULL); }
347 | input_list NAME
348 { lang_add_input_file($2, lang_input_file_is_file_enum,
349 (char *)NULL); }
350 ;
351
352 sections:
353 SECTIONS '{'sec_or_group_p1 '}'
354 ;
355
356 sec_or_group_p1:
357 sec_or_group_p1 section
358 | sec_or_group_p1 statement_anywhere
359 |
360 ;
361
362 statement_anywhere:
363 ENTRY '(' NAME ')'
364 { lang_add_entry($3); }
365 | assignment end
366 ;
367
368 file_NAME_list:
369 NAME
370 { lang_add_wild($1, current_file); }
371 | file_NAME_list opt_comma NAME
372 { lang_add_wild($3, current_file); }
373 ;
374
375 input_section_spec:
376 NAME
377 {
378 lang_add_wild((char *)NULL, $1);
379 }
380 | '['
381 {
382 current_file = (char *)NULL;
383 }
384 file_NAME_list
385 ']'
386 | NAME
387 {
388 current_file =$1;
389 }
390 '(' file_NAME_list ')'
391 | '*'
392 {
393 current_file = (char *)NULL;
394 }
395 '(' file_NAME_list ')'
396 ;
397
398 statement:
399 statement assignment end
400 | statement CREATE_OBJECT_SYMBOLS
401 {
402 lang_add_attribute(lang_object_symbols_statement_enum); }
403
404 | statement input_section_spec
405 | statement length '(' exp_head ')'
406 {
407 lang_add_data($2,$4);
408 }
409
410 | statement FILL '(' exp_head ')'
411 {
412 lang_add_fill
413 (exp_get_value_int($4,
414 0,
415 "fill value",
416 lang_first_phase_enum));
417 }
418 |
419 ;
420
421 length:
422 LONG
423 { $$ = $1; }
424 | SHORT
425 { $$ = $1; }
426 | BYTE
427 { $$ = $1; }
428 ;
429
430 fill_opt:
431 '=' exp_head
432 {
433 $$ = exp_get_value_int($2,
434 0,
435 "fill value",
436 lang_first_phase_enum);
437 }
438 | { $$ = 0; }
439 ;
440
441
442
443 assign_op:
444 PLUSEQ
445 { $$ = '+'; }
446 | MINUSEQ
447 { $$ = '-'; }
448 | MULTEQ
449 { $$ = '*'; }
450 | DIVEQ
451 { $$ = '/'; }
452 | LSHIFTEQ
453 { $$ = LSHIFT; }
454 | RSHIFTEQ
455 { $$ = RSHIFT; }
456 | ANDEQ
457 { $$ = '&'; }
458 | OREQ
459 { $$ = '|'; }
460
461 ;
462
463 end: ';' | ','
464 ;
465
466
467 assignment:
468
469 NAME '=' exp_head
470 {
471 lang_add_assignment(exp_assop($2,$1,$3));
472 }
473 | NAME assign_op exp_head
474 {
475 lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
476 }
477
478 ;
479
480
481 opt_comma:
482 ',' | ;
483
484
485 memory:
486 MEMORY '{' memory_spec memory_spec_list '}'
487 ;
488
489 memory_spec_list:
490 memory_spec_list memory_spec
491 | memory_spec_list ',' memory_spec
492 |
493 ;
494
495
496 memory_spec:
497 NAME
498 { region = lang_memory_region_lookup($1); }
499 attributes_opt ':' origin_spec opt_comma length_spec
500
501 {
502
503
504 }
505 ;
506 origin_spec:
507 ORIGIN '=' exp
508 { region->current =
509 region->origin =
510 exp_get_vma($3, 0L,"origin", lang_first_phase_enum); }
511 ;
512 length_spec:
513 LENGTH '=' exp
514 { region->length = exp_get_vma($3,
515 ~((bfd_vma)0),
516 "length",
517 lang_first_phase_enum);
518 }
519
520
521 attributes_opt:
522 '(' NAME ')'
523 {
524 lang_set_flags(&region->flags, $2);
525 }
526 |
527
528 ;
529
530 startup:
531 STARTUP '(' filename ')'
532 { lang_startup($3); }
533 ;
534
535 high_level_library:
536 HLL '(' high_level_library_NAME_list ')'
537 | HLL '(' ')'
538 { ldemul_hll((char *)NULL); }
539 ;
540
541 high_level_library_NAME_list:
542 high_level_library_NAME_list opt_comma filename
543 { ldemul_hll($3); }
544 | filename
545 { ldemul_hll($1); }
546
547 ;
548
549 low_level_library:
550 SYSLIB '(' low_level_library_NAME_list ')'
551 ;
552 low_level_library_NAME_list:
553 low_level_library_NAME_list opt_comma filename
554 { ldemul_syslib($3); }
555 |
556 ;
557
558 floating_point_support:
559 FLOAT
560 { lang_float(true); }
561 | NOFLOAT
562 { lang_float(false); }
563 ;
564
565
566
567
568 exp :
569 '-' exp %prec UNARY
570 { $$ = exp_unop('-', $2); }
571 | '(' exp ')'
572 { $$ = $2; }
573 | NEXT '(' exp ')' %prec UNARY
574 { $$ = exp_unop($1,$3); }
575 | '!' exp %prec UNARY
576 { $$ = exp_unop('!', $2); }
577 | '+' exp %prec UNARY
578 { $$ = $2; }
579 | '~' exp %prec UNARY
580 { $$ = exp_unop('~', $2);}
581
582 | exp '*' exp
583 { $$ = exp_binop('*', $1, $3); }
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 LSHIFT exp
593 { $$ = exp_binop(LSHIFT , $1, $3); }
594 | exp RSHIFT exp
595 { $$ = exp_binop(RSHIFT , $1, $3); }
596 | exp EQ exp
597 { $$ = exp_binop(EQ , $1, $3); }
598 | exp NE exp
599 { $$ = exp_binop(NE , $1, $3); }
600 | exp LE exp
601 { $$ = exp_binop(LE , $1, $3); }
602 | exp GE exp
603 { $$ = exp_binop(GE , $1, $3); }
604 | exp '<' exp
605 { $$ = exp_binop('<' , $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 ':' exp
615 { $$ = exp_trinop('?' , $1, $3, $5); }
616 | exp ANDAND exp
617 { $$ = exp_binop(ANDAND , $1, $3); }
618 | exp OROR exp
619 { $$ = exp_binop(OROR , $1, $3); }
620 | DEFINED '(' NAME ')'
621 { $$ = exp_nameop(DEFINED, $3); }
622 | INT
623 { $$ = exp_intop($1); }
624 | SIZEOF_HEADERS
625 { $$ = exp_nameop(SIZEOF_HEADERS,0); }
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
This page took 0.043874 seconds and 4 git commands to generate.