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