ld/
[deliverable/binutils-gdb.git] / ld / ldgram.y
1 /* A YACC grammar to parse a superset of the AT&T linker scripting language.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
5
6 This file is part of GNU ld.
7
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 2 of the License, or
11 (at your option) any later version.
12
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.
17
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 %{
23 /*
24
25 */
26
27 #define DONTDECLARE_MALLOC
28
29 #include "bfd.h"
30 #include "sysdep.h"
31 #include "bfdlink.h"
32 #include "ld.h"
33 #include "ldexp.h"
34 #include "ldver.h"
35 #include "ldlang.h"
36 #include "ldfile.h"
37 #include "ldemul.h"
38 #include "ldmisc.h"
39 #include "ldmain.h"
40 #include "mri.h"
41 #include "ldctor.h"
42 #include "ldlex.h"
43
44 #ifndef YYDEBUG
45 #define YYDEBUG 1
46 #endif
47
48 static enum section_type sectype;
49
50 lang_memory_region_type *region;
51
52 bfd_boolean ldgram_want_filename = TRUE;
53 FILE *saved_script_handle = NULL;
54 bfd_boolean force_make_executable = FALSE;
55
56 bfd_boolean ldgram_in_script = FALSE;
57 bfd_boolean ldgram_had_equals = FALSE;
58 bfd_boolean ldgram_had_keep = FALSE;
59 char *ldgram_vers_current_lang = NULL;
60
61 #define ERROR_NAME_MAX 20
62 static char *error_names[ERROR_NAME_MAX];
63 static int error_index;
64 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
65 #define POP_ERROR() error_index--;
66 %}
67 %union {
68 bfd_vma integer;
69 struct big_int
70 {
71 bfd_vma integer;
72 char *str;
73 } bigint;
74 fill_type *fill;
75 char *name;
76 const char *cname;
77 struct wildcard_spec wildcard;
78 struct wildcard_list *wildcard_list;
79 struct name_list *name_list;
80 int token;
81 union etree_union *etree;
82 struct phdr_info
83 {
84 bfd_boolean filehdr;
85 bfd_boolean phdrs;
86 union etree_union *at;
87 union etree_union *flags;
88 } phdr;
89 struct lang_nocrossref *nocrossref;
90 struct lang_output_section_phdr_list *section_phdr;
91 struct bfd_elf_version_deps *deflist;
92 struct bfd_elf_version_expr *versyms;
93 struct bfd_elf_version_tree *versnode;
94 }
95
96 %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
97 %type <etree> opt_exp_without_type opt_subalign
98 %type <fill> fill_opt fill_exp
99 %type <name_list> exclude_name_list
100 %type <wildcard_list> file_NAME_list
101 %type <name> memspec_opt casesymlist
102 %type <name> memspec_at_opt
103 %type <cname> wildcard_name
104 %type <wildcard> wildcard_spec
105 %token <bigint> INT
106 %token <name> NAME LNAME
107 %type <integer> length
108 %type <phdr> phdr_qualifiers
109 %type <nocrossref> nocrossref_list
110 %type <section_phdr> phdr_opt
111 %type <integer> opt_nocrossrefs
112
113 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
114 %right <token> '?' ':'
115 %left <token> OROR
116 %left <token> ANDAND
117 %left <token> '|'
118 %left <token> '^'
119 %left <token> '&'
120 %left <token> EQ NE
121 %left <token> '<' '>' LE GE
122 %left <token> LSHIFT RSHIFT
123
124 %left <token> '+' '-'
125 %left <token> '*' '/' '%'
126
127 %right UNARY
128 %token END
129 %left <token> '('
130 %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
131 %token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
132 %token SORT_BY_NAME SORT_BY_ALIGNMENT
133 %token '{' '}'
134 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
135 %token INHIBIT_COMMON_ALLOCATION
136 %token SIZEOF_HEADERS
137 %token INCLUDE
138 %token MEMORY DEFSYMEND
139 %token NOLOAD DSECT COPY INFO OVERLAY
140 %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
141 %token <integer> NEXT
142 %token SIZEOF ADDR LOADADDR MAX_K MIN_K
143 %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
144 %token ORIGIN FILL
145 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
146 %token ALIGNMOD AT SUBALIGN PROVIDE
147 %type <token> assign_op atype attributes_opt sect_constraint
148 %type <name> filename
149 %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
150 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
151 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
152 %token <name> VERS_TAG VERS_IDENTIFIER
153 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
154 %token KEEP ONLY_IF_RO ONLY_IF_RW
155 %token EXCLUDE_FILE
156 %type <versyms> vers_defns
157 %type <versnode> vers_tag
158 %type <deflist> verdep
159
160 %%
161
162 file:
163 INPUT_SCRIPT script_file
164 | INPUT_MRI_SCRIPT mri_script_file
165 | INPUT_VERSION_SCRIPT version_script_file
166 | INPUT_DEFSYM defsym_expr
167 ;
168
169
170 filename: NAME;
171
172
173 defsym_expr:
174 { ldlex_defsym(); }
175 NAME '=' exp
176 {
177 ldlex_popstate();
178 lang_add_assignment(exp_assop($3,$2,$4));
179 }
180 ;
181
182 /* SYNTAX WITHIN AN MRI SCRIPT FILE */
183 mri_script_file:
184 {
185 ldlex_mri_script ();
186 PUSH_ERROR (_("MRI style script"));
187 }
188 mri_script_lines
189 {
190 ldlex_popstate ();
191 mri_draw_tree ();
192 POP_ERROR ();
193 }
194 ;
195
196 mri_script_lines:
197 mri_script_lines mri_script_command NEWLINE
198 |
199 ;
200
201 mri_script_command:
202 CHIP exp
203 | CHIP exp ',' exp
204 | NAME {
205 einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
206 }
207 | LIST {
208 config.map_filename = "-";
209 }
210 | ORDER ordernamelist
211 | ENDWORD
212 | PUBLIC NAME '=' exp
213 { mri_public($2, $4); }
214 | PUBLIC NAME ',' exp
215 { mri_public($2, $4); }
216 | PUBLIC NAME exp
217 { mri_public($2, $3); }
218 | FORMAT NAME
219 { mri_format($2); }
220 | SECT NAME ',' exp
221 { mri_output_section($2, $4);}
222 | SECT NAME exp
223 { mri_output_section($2, $3);}
224 | SECT NAME '=' exp
225 { mri_output_section($2, $4);}
226 | ALIGN_K NAME '=' exp
227 { mri_align($2,$4); }
228 | ALIGN_K NAME ',' exp
229 { mri_align($2,$4); }
230 | ALIGNMOD NAME '=' exp
231 { mri_alignmod($2,$4); }
232 | ALIGNMOD NAME ',' exp
233 { mri_alignmod($2,$4); }
234 | ABSOLUTE mri_abs_name_list
235 | LOAD mri_load_name_list
236 | NAMEWORD NAME
237 { mri_name($2); }
238 | ALIAS NAME ',' NAME
239 { mri_alias($2,$4,0);}
240 | ALIAS NAME ',' INT
241 { mri_alias ($2, 0, (int) $4.integer); }
242 | BASE exp
243 { mri_base($2); }
244 | TRUNCATE INT
245 { mri_truncate ((unsigned int) $2.integer); }
246 | CASE casesymlist
247 | EXTERN extern_name_list
248 | INCLUDE filename
249 { ldlex_script (); ldfile_open_command_file($2); }
250 mri_script_lines END
251 { ldlex_popstate (); }
252 | START NAME
253 { lang_add_entry ($2, FALSE); }
254 |
255 ;
256
257 ordernamelist:
258 ordernamelist ',' NAME { mri_order($3); }
259 | ordernamelist NAME { mri_order($2); }
260 |
261 ;
262
263 mri_load_name_list:
264 NAME
265 { mri_load($1); }
266 | mri_load_name_list ',' NAME { mri_load($3); }
267 ;
268
269 mri_abs_name_list:
270 NAME
271 { mri_only_load($1); }
272 | mri_abs_name_list ',' NAME
273 { mri_only_load($3); }
274 ;
275
276 casesymlist:
277 /* empty */ { $$ = NULL; }
278 | NAME
279 | casesymlist ',' NAME
280 ;
281
282 extern_name_list:
283 NAME
284 { ldlang_add_undef ($1); }
285 | extern_name_list NAME
286 { ldlang_add_undef ($2); }
287 | extern_name_list ',' NAME
288 { ldlang_add_undef ($3); }
289 ;
290
291 script_file:
292 {
293 ldlex_both();
294 }
295 ifile_list
296 {
297 ldlex_popstate();
298 }
299 ;
300
301
302 ifile_list:
303 ifile_list ifile_p1
304 |
305 ;
306
307
308
309 ifile_p1:
310 memory
311 | sections
312 | phdrs
313 | startup
314 | high_level_library
315 | low_level_library
316 | floating_point_support
317 | statement_anywhere
318 | version
319 | ';'
320 | TARGET_K '(' NAME ')'
321 { lang_add_target($3); }
322 | SEARCH_DIR '(' filename ')'
323 { ldfile_add_library_path ($3, FALSE); }
324 | OUTPUT '(' filename ')'
325 { lang_add_output($3, 1); }
326 | OUTPUT_FORMAT '(' NAME ')'
327 { lang_add_output_format ($3, (char *) NULL,
328 (char *) NULL, 1); }
329 | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
330 { lang_add_output_format ($3, $5, $7, 1); }
331 | OUTPUT_ARCH '(' NAME ')'
332 { ldfile_set_output_arch ($3, bfd_arch_unknown); }
333 | FORCE_COMMON_ALLOCATION
334 { command_line.force_common_definition = TRUE ; }
335 | INHIBIT_COMMON_ALLOCATION
336 { command_line.inhibit_common_definition = TRUE ; }
337 | INPUT '(' input_list ')'
338 | GROUP
339 { lang_enter_group (); }
340 '(' input_list ')'
341 { lang_leave_group (); }
342 | MAP '(' filename ')'
343 { lang_add_map($3); }
344 | INCLUDE filename
345 { ldlex_script (); ldfile_open_command_file($2); }
346 ifile_list END
347 { ldlex_popstate (); }
348 | NOCROSSREFS '(' nocrossref_list ')'
349 {
350 lang_add_nocrossref ($3);
351 }
352 | EXTERN '(' extern_name_list ')'
353 ;
354
355 input_list:
356 NAME
357 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
358 (char *)NULL); }
359 | input_list ',' NAME
360 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
361 (char *)NULL); }
362 | input_list NAME
363 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
364 (char *)NULL); }
365 | LNAME
366 { lang_add_input_file($1,lang_input_file_is_l_enum,
367 (char *)NULL); }
368 | input_list ',' LNAME
369 { lang_add_input_file($3,lang_input_file_is_l_enum,
370 (char *)NULL); }
371 | input_list LNAME
372 { lang_add_input_file($2,lang_input_file_is_l_enum,
373 (char *)NULL); }
374 ;
375
376 sections:
377 SECTIONS '{' sec_or_group_p1 '}'
378 ;
379
380 sec_or_group_p1:
381 sec_or_group_p1 section
382 | sec_or_group_p1 statement_anywhere
383 |
384 ;
385
386 statement_anywhere:
387 ENTRY '(' NAME ')'
388 { lang_add_entry ($3, FALSE); }
389 | assignment end
390 | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')'
391 { ldlex_popstate ();
392 lang_add_assignment (exp_assert ($4, $6)); }
393 ;
394
395 /* The '*' and '?' cases are there because the lexer returns them as
396 separate tokens rather than as NAME. */
397 wildcard_name:
398 NAME
399 {
400 $$ = $1;
401 }
402 | '*'
403 {
404 $$ = "*";
405 }
406 | '?'
407 {
408 $$ = "?";
409 }
410 ;
411
412 wildcard_spec:
413 wildcard_name
414 {
415 $$.name = $1;
416 $$.sorted = none;
417 $$.exclude_name_list = NULL;
418 }
419 | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name
420 {
421 $$.name = $5;
422 $$.sorted = none;
423 $$.exclude_name_list = $3;
424 }
425 | SORT_BY_NAME '(' wildcard_name ')'
426 {
427 $$.name = $3;
428 $$.sorted = by_name;
429 $$.exclude_name_list = NULL;
430 }
431 | SORT_BY_ALIGNMENT '(' wildcard_name ')'
432 {
433 $$.name = $3;
434 $$.sorted = by_alignment;
435 $$.exclude_name_list = NULL;
436 }
437 | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
438 {
439 $$.name = $5;
440 $$.sorted = by_name_alignment;
441 $$.exclude_name_list = NULL;
442 }
443 | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')'
444 {
445 $$.name = $5;
446 $$.sorted = by_name;
447 $$.exclude_name_list = NULL;
448 }
449 | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')'
450 {
451 $$.name = $5;
452 $$.sorted = by_alignment_name;
453 $$.exclude_name_list = NULL;
454 }
455 | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
456 {
457 $$.name = $5;
458 $$.sorted = by_alignment;
459 $$.exclude_name_list = NULL;
460 }
461 | SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
462 {
463 $$.name = $7;
464 $$.sorted = by_name;
465 $$.exclude_name_list = $5;
466 }
467 ;
468
469 exclude_name_list:
470 exclude_name_list wildcard_name
471 {
472 struct name_list *tmp;
473 tmp = (struct name_list *) xmalloc (sizeof *tmp);
474 tmp->name = $2;
475 tmp->next = $1;
476 $$ = tmp;
477 }
478 |
479 wildcard_name
480 {
481 struct name_list *tmp;
482 tmp = (struct name_list *) xmalloc (sizeof *tmp);
483 tmp->name = $1;
484 tmp->next = NULL;
485 $$ = tmp;
486 }
487 ;
488
489 file_NAME_list:
490 file_NAME_list opt_comma wildcard_spec
491 {
492 struct wildcard_list *tmp;
493 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
494 tmp->next = $1;
495 tmp->spec = $3;
496 $$ = tmp;
497 }
498 |
499 wildcard_spec
500 {
501 struct wildcard_list *tmp;
502 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
503 tmp->next = NULL;
504 tmp->spec = $1;
505 $$ = tmp;
506 }
507 ;
508
509 input_section_spec_no_keep:
510 NAME
511 {
512 struct wildcard_spec tmp;
513 tmp.name = $1;
514 tmp.exclude_name_list = NULL;
515 tmp.sorted = none;
516 lang_add_wild (&tmp, NULL, ldgram_had_keep);
517 }
518 | '[' file_NAME_list ']'
519 {
520 lang_add_wild (NULL, $2, ldgram_had_keep);
521 }
522 | wildcard_spec '(' file_NAME_list ')'
523 {
524 lang_add_wild (&$1, $3, ldgram_had_keep);
525 }
526 ;
527
528 input_section_spec:
529 input_section_spec_no_keep
530 | KEEP '('
531 { ldgram_had_keep = TRUE; }
532 input_section_spec_no_keep ')'
533 { ldgram_had_keep = FALSE; }
534 ;
535
536 statement:
537 assignment end
538 | CREATE_OBJECT_SYMBOLS
539 {
540 lang_add_attribute(lang_object_symbols_statement_enum);
541 }
542 | ';'
543 | CONSTRUCTORS
544 {
545
546 lang_add_attribute(lang_constructors_statement_enum);
547 }
548 | SORT_BY_NAME '(' CONSTRUCTORS ')'
549 {
550 constructors_sorted = TRUE;
551 lang_add_attribute (lang_constructors_statement_enum);
552 }
553 | input_section_spec
554 | length '(' mustbe_exp ')'
555 {
556 lang_add_data ((int) $1, $3);
557 }
558
559 | FILL '(' fill_exp ')'
560 {
561 lang_add_fill ($3);
562 }
563 ;
564
565 statement_list:
566 statement_list statement
567 | statement
568 ;
569
570 statement_list_opt:
571 /* empty */
572 | statement_list
573 ;
574
575 length:
576 QUAD
577 { $$ = $1; }
578 | SQUAD
579 { $$ = $1; }
580 | LONG
581 { $$ = $1; }
582 | SHORT
583 { $$ = $1; }
584 | BYTE
585 { $$ = $1; }
586 ;
587
588 fill_exp:
589 mustbe_exp
590 {
591 $$ = exp_get_fill ($1,
592 0,
593 "fill value",
594 lang_first_phase_enum);
595 }
596 ;
597
598 fill_opt:
599 '=' fill_exp
600 { $$ = $2; }
601 | { $$ = (fill_type *) 0; }
602 ;
603
604 assign_op:
605 PLUSEQ
606 { $$ = '+'; }
607 | MINUSEQ
608 { $$ = '-'; }
609 | MULTEQ
610 { $$ = '*'; }
611 | DIVEQ
612 { $$ = '/'; }
613 | LSHIFTEQ
614 { $$ = LSHIFT; }
615 | RSHIFTEQ
616 { $$ = RSHIFT; }
617 | ANDEQ
618 { $$ = '&'; }
619 | OREQ
620 { $$ = '|'; }
621
622 ;
623
624 end: ';' | ','
625 ;
626
627
628 assignment:
629 NAME '=' mustbe_exp
630 {
631 lang_add_assignment (exp_assop ($2, $1, $3));
632 }
633 | NAME assign_op mustbe_exp
634 {
635 lang_add_assignment (exp_assop ('=', $1,
636 exp_binop ($2,
637 exp_nameop (NAME,
638 $1),
639 $3)));
640 }
641 | PROVIDE '(' NAME '=' mustbe_exp ')'
642 {
643 lang_add_assignment (exp_provide ($3, $5));
644 }
645 ;
646
647
648 opt_comma:
649 ',' | ;
650
651
652 memory:
653 MEMORY '{' memory_spec memory_spec_list '}'
654 ;
655
656 memory_spec_list:
657 memory_spec_list memory_spec
658 | memory_spec_list ',' memory_spec
659 |
660 ;
661
662
663 memory_spec: NAME
664 { region = lang_memory_region_lookup ($1, TRUE); }
665 attributes_opt ':'
666 origin_spec opt_comma length_spec
667 {}
668 ;
669
670 origin_spec:
671 ORIGIN '=' mustbe_exp
672 { region->current =
673 region->origin =
674 exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
675 }
676 ;
677
678 length_spec:
679 LENGTH '=' mustbe_exp
680 { region->length = exp_get_vma($3,
681 ~((bfd_vma)0),
682 "length",
683 lang_first_phase_enum);
684 }
685 ;
686
687 attributes_opt:
688 /* empty */
689 { /* dummy action to avoid bison 1.25 error message */ }
690 | '(' attributes_list ')'
691 ;
692
693 attributes_list:
694 attributes_string
695 | attributes_list attributes_string
696 ;
697
698 attributes_string:
699 NAME
700 { lang_set_flags (region, $1, 0); }
701 | '!' NAME
702 { lang_set_flags (region, $2, 1); }
703 ;
704
705 startup:
706 STARTUP '(' filename ')'
707 { lang_startup($3); }
708 ;
709
710 high_level_library:
711 HLL '(' high_level_library_NAME_list ')'
712 | HLL '(' ')'
713 { ldemul_hll((char *)NULL); }
714 ;
715
716 high_level_library_NAME_list:
717 high_level_library_NAME_list opt_comma filename
718 { ldemul_hll($3); }
719 | filename
720 { ldemul_hll($1); }
721
722 ;
723
724 low_level_library:
725 SYSLIB '(' low_level_library_NAME_list ')'
726 ; low_level_library_NAME_list:
727 low_level_library_NAME_list opt_comma filename
728 { ldemul_syslib($3); }
729 |
730 ;
731
732 floating_point_support:
733 FLOAT
734 { lang_float(TRUE); }
735 | NOFLOAT
736 { lang_float(FALSE); }
737 ;
738
739 nocrossref_list:
740 /* empty */
741 {
742 $$ = NULL;
743 }
744 | NAME nocrossref_list
745 {
746 struct lang_nocrossref *n;
747
748 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
749 n->name = $1;
750 n->next = $2;
751 $$ = n;
752 }
753 | NAME ',' nocrossref_list
754 {
755 struct lang_nocrossref *n;
756
757 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
758 n->name = $1;
759 n->next = $3;
760 $$ = n;
761 }
762 ;
763
764 mustbe_exp: { ldlex_expression(); }
765 exp
766 { ldlex_popstate(); $$=$2;}
767 ;
768
769 exp :
770 '-' exp %prec UNARY
771 { $$ = exp_unop('-', $2); }
772 | '(' exp ')'
773 { $$ = $2; }
774 | NEXT '(' exp ')' %prec UNARY
775 { $$ = exp_unop((int) $1,$3); }
776 | '!' exp %prec UNARY
777 { $$ = exp_unop('!', $2); }
778 | '+' exp %prec UNARY
779 { $$ = $2; }
780 | '~' exp %prec UNARY
781 { $$ = exp_unop('~', $2);}
782
783 | exp '*' exp
784 { $$ = exp_binop('*', $1, $3); }
785 | exp '/' exp
786 { $$ = exp_binop('/', $1, $3); }
787 | exp '%' exp
788 { $$ = exp_binop('%', $1, $3); }
789 | exp '+' exp
790 { $$ = exp_binop('+', $1, $3); }
791 | exp '-' exp
792 { $$ = exp_binop('-' , $1, $3); }
793 | exp LSHIFT exp
794 { $$ = exp_binop(LSHIFT , $1, $3); }
795 | exp RSHIFT exp
796 { $$ = exp_binop(RSHIFT , $1, $3); }
797 | exp EQ exp
798 { $$ = exp_binop(EQ , $1, $3); }
799 | exp NE exp
800 { $$ = exp_binop(NE , $1, $3); }
801 | exp LE exp
802 { $$ = exp_binop(LE , $1, $3); }
803 | exp GE exp
804 { $$ = exp_binop(GE , $1, $3); }
805 | exp '<' exp
806 { $$ = exp_binop('<' , $1, $3); }
807 | exp '>' exp
808 { $$ = exp_binop('>' , $1, $3); }
809 | exp '&' exp
810 { $$ = exp_binop('&' , $1, $3); }
811 | exp '^' exp
812 { $$ = exp_binop('^' , $1, $3); }
813 | exp '|' exp
814 { $$ = exp_binop('|' , $1, $3); }
815 | exp '?' exp ':' exp
816 { $$ = exp_trinop('?' , $1, $3, $5); }
817 | exp ANDAND exp
818 { $$ = exp_binop(ANDAND , $1, $3); }
819 | exp OROR exp
820 { $$ = exp_binop(OROR , $1, $3); }
821 | DEFINED '(' NAME ')'
822 { $$ = exp_nameop(DEFINED, $3); }
823 | INT
824 { $$ = exp_bigintop ($1.integer, $1.str); }
825 | SIZEOF_HEADERS
826 { $$ = exp_nameop(SIZEOF_HEADERS,0); }
827
828 | SIZEOF '(' NAME ')'
829 { $$ = exp_nameop(SIZEOF,$3); }
830 | ADDR '(' NAME ')'
831 { $$ = exp_nameop(ADDR,$3); }
832 | LOADADDR '(' NAME ')'
833 { $$ = exp_nameop(LOADADDR,$3); }
834 | ABSOLUTE '(' exp ')'
835 { $$ = exp_unop(ABSOLUTE, $3); }
836 | ALIGN_K '(' exp ')'
837 { $$ = exp_unop(ALIGN_K,$3); }
838 | ALIGN_K '(' exp ',' exp ')'
839 { $$ = exp_binop(ALIGN_K,$3,$5); }
840 | DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
841 { $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
842 | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
843 { $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
844 | DATA_SEGMENT_END '(' exp ')'
845 { $$ = exp_unop(DATA_SEGMENT_END, $3); }
846 | BLOCK '(' exp ')'
847 { $$ = exp_unop(ALIGN_K,$3); }
848 | NAME
849 { $$ = exp_nameop(NAME,$1); }
850 | MAX_K '(' exp ',' exp ')'
851 { $$ = exp_binop (MAX_K, $3, $5 ); }
852 | MIN_K '(' exp ',' exp ')'
853 { $$ = exp_binop (MIN_K, $3, $5 ); }
854 | ASSERT_K '(' exp ',' NAME ')'
855 { $$ = exp_assert ($3, $5); }
856 ;
857
858
859 memspec_at_opt:
860 AT '>' NAME { $$ = $3; }
861 | { $$ = 0; }
862 ;
863
864 opt_at:
865 AT '(' exp ')' { $$ = $3; }
866 | { $$ = 0; }
867 ;
868
869 opt_subalign:
870 SUBALIGN '(' exp ')' { $$ = $3; }
871 | { $$ = 0; }
872 ;
873
874 sect_constraint:
875 ONLY_IF_RO { $$ = ONLY_IF_RO; }
876 | ONLY_IF_RW { $$ = ONLY_IF_RW; }
877 | { $$ = 0; }
878 ;
879
880 section: NAME { ldlex_expression(); }
881 opt_exp_with_type
882 opt_at
883 opt_subalign { ldlex_popstate (); ldlex_script (); }
884 sect_constraint
885 '{'
886 {
887 lang_enter_output_section_statement($1, $3,
888 sectype,
889 0, $5, $4, $7);
890 }
891 statement_list_opt
892 '}' { ldlex_popstate (); ldlex_expression (); }
893 memspec_opt memspec_at_opt phdr_opt fill_opt
894 {
895 ldlex_popstate ();
896 lang_leave_output_section_statement ($16, $13, $15, $14);
897 }
898 opt_comma
899 {}
900 | OVERLAY
901 { ldlex_expression (); }
902 opt_exp_without_type opt_nocrossrefs opt_at opt_subalign
903 { ldlex_popstate (); ldlex_script (); }
904 '{'
905 {
906 lang_enter_overlay ($3, $6);
907 }
908 overlay_section
909 '}'
910 { ldlex_popstate (); ldlex_expression (); }
911 memspec_opt memspec_at_opt phdr_opt fill_opt
912 {
913 ldlex_popstate ();
914 lang_leave_overlay ($5, (int) $4,
915 $16, $13, $15, $14);
916 }
917 opt_comma
918 | /* The GROUP case is just enough to support the gcc
919 svr3.ifile script. It is not intended to be full
920 support. I'm not even sure what GROUP is supposed
921 to mean. */
922 GROUP { ldlex_expression (); }
923 opt_exp_with_type
924 {
925 ldlex_popstate ();
926 lang_add_assignment (exp_assop ('=', ".", $3));
927 }
928 '{' sec_or_group_p1 '}'
929 ;
930
931 type:
932 NOLOAD { sectype = noload_section; }
933 | DSECT { sectype = dsect_section; }
934 | COPY { sectype = copy_section; }
935 | INFO { sectype = info_section; }
936 | OVERLAY { sectype = overlay_section; }
937 ;
938
939 atype:
940 '(' type ')'
941 | /* EMPTY */ { sectype = normal_section; }
942 | '(' ')' { sectype = normal_section; }
943 ;
944
945 opt_exp_with_type:
946 exp atype ':' { $$ = $1; }
947 | atype ':' { $$ = (etree_type *)NULL; }
948 | /* The BIND cases are to support the gcc svr3.ifile
949 script. They aren't intended to implement full
950 support for the BIND keyword. I'm not even sure
951 what BIND is supposed to mean. */
952 BIND '(' exp ')' atype ':' { $$ = $3; }
953 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
954 { $$ = $3; }
955 ;
956
957 opt_exp_without_type:
958 exp ':' { $$ = $1; }
959 | ':' { $$ = (etree_type *) NULL; }
960 ;
961
962 opt_nocrossrefs:
963 /* empty */
964 { $$ = 0; }
965 | NOCROSSREFS
966 { $$ = 1; }
967 ;
968
969 memspec_opt:
970 '>' NAME
971 { $$ = $2; }
972 | { $$ = DEFAULT_MEMORY_REGION; }
973 ;
974
975 phdr_opt:
976 /* empty */
977 {
978 $$ = NULL;
979 }
980 | phdr_opt ':' NAME
981 {
982 struct lang_output_section_phdr_list *n;
983
984 n = ((struct lang_output_section_phdr_list *)
985 xmalloc (sizeof *n));
986 n->name = $3;
987 n->used = FALSE;
988 n->next = $1;
989 $$ = n;
990 }
991 ;
992
993 overlay_section:
994 /* empty */
995 | overlay_section
996 NAME
997 {
998 ldlex_script ();
999 lang_enter_overlay_section ($2);
1000 }
1001 '{' statement_list_opt '}'
1002 { ldlex_popstate (); ldlex_expression (); }
1003 phdr_opt fill_opt
1004 {
1005 ldlex_popstate ();
1006 lang_leave_overlay_section ($9, $8);
1007 }
1008 opt_comma
1009 ;
1010
1011 phdrs:
1012 PHDRS '{' phdr_list '}'
1013 ;
1014
1015 phdr_list:
1016 /* empty */
1017 | phdr_list phdr
1018 ;
1019
1020 phdr:
1021 NAME { ldlex_expression (); }
1022 phdr_type phdr_qualifiers { ldlex_popstate (); }
1023 ';'
1024 {
1025 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
1026 $4.flags);
1027 }
1028 ;
1029
1030 phdr_type:
1031 exp
1032 {
1033 $$ = $1;
1034
1035 if ($1->type.node_class == etree_name
1036 && $1->type.node_code == NAME)
1037 {
1038 const char *s;
1039 unsigned int i;
1040 static const char * const phdr_types[] =
1041 {
1042 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
1043 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
1044 "PT_PHDR", "PT_TLS"
1045 };
1046
1047 s = $1->name.name;
1048 for (i = 0;
1049 i < sizeof phdr_types / sizeof phdr_types[0];
1050 i++)
1051 if (strcmp (s, phdr_types[i]) == 0)
1052 {
1053 $$ = exp_intop (i);
1054 break;
1055 }
1056 if (i == sizeof phdr_types / sizeof phdr_types[0])
1057 {
1058 if (strcmp (s, "PT_GNU_EH_FRAME") == 0)
1059 $$ = exp_intop (0x6474e550);
1060 else if (strcmp (s, "PT_GNU_STACK") == 0)
1061 $$ = exp_intop (0x6474e551);
1062 else
1063 {
1064 einfo (_("\
1065 %X%P:%S: unknown phdr type `%s' (try integer literal)\n"),
1066 s);
1067 $$ = exp_intop (0);
1068 }
1069 }
1070 }
1071 }
1072 ;
1073
1074 phdr_qualifiers:
1075 /* empty */
1076 {
1077 memset (&$$, 0, sizeof (struct phdr_info));
1078 }
1079 | NAME phdr_val phdr_qualifiers
1080 {
1081 $$ = $3;
1082 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
1083 $$.filehdr = TRUE;
1084 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
1085 $$.phdrs = TRUE;
1086 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
1087 $$.flags = $2;
1088 else
1089 einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
1090 }
1091 | AT '(' exp ')' phdr_qualifiers
1092 {
1093 $$ = $5;
1094 $$.at = $3;
1095 }
1096 ;
1097
1098 phdr_val:
1099 /* empty */
1100 {
1101 $$ = NULL;
1102 }
1103 | '(' exp ')'
1104 {
1105 $$ = $2;
1106 }
1107 ;
1108
1109 /* This syntax is used within an external version script file. */
1110
1111 version_script_file:
1112 {
1113 ldlex_version_file ();
1114 PUSH_ERROR (_("VERSION script"));
1115 }
1116 vers_nodes
1117 {
1118 ldlex_popstate ();
1119 POP_ERROR ();
1120 }
1121 ;
1122
1123 /* This is used within a normal linker script file. */
1124
1125 version:
1126 {
1127 ldlex_version_script ();
1128 }
1129 VERSIONK '{' vers_nodes '}'
1130 {
1131 ldlex_popstate ();
1132 }
1133 ;
1134
1135 vers_nodes:
1136 vers_node
1137 | vers_nodes vers_node
1138 ;
1139
1140 vers_node:
1141 '{' vers_tag '}' ';'
1142 {
1143 lang_register_vers_node (NULL, $2, NULL);
1144 }
1145 | VERS_TAG '{' vers_tag '}' ';'
1146 {
1147 lang_register_vers_node ($1, $3, NULL);
1148 }
1149 | VERS_TAG '{' vers_tag '}' verdep ';'
1150 {
1151 lang_register_vers_node ($1, $3, $5);
1152 }
1153 ;
1154
1155 verdep:
1156 VERS_TAG
1157 {
1158 $$ = lang_add_vers_depend (NULL, $1);
1159 }
1160 | verdep VERS_TAG
1161 {
1162 $$ = lang_add_vers_depend ($1, $2);
1163 }
1164 ;
1165
1166 vers_tag:
1167 /* empty */
1168 {
1169 $$ = lang_new_vers_node (NULL, NULL);
1170 }
1171 | vers_defns ';'
1172 {
1173 $$ = lang_new_vers_node ($1, NULL);
1174 }
1175 | GLOBAL ':' vers_defns ';'
1176 {
1177 $$ = lang_new_vers_node ($3, NULL);
1178 }
1179 | LOCAL ':' vers_defns ';'
1180 {
1181 $$ = lang_new_vers_node (NULL, $3);
1182 }
1183 | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
1184 {
1185 $$ = lang_new_vers_node ($3, $7);
1186 }
1187 ;
1188
1189 vers_defns:
1190 VERS_IDENTIFIER
1191 {
1192 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang);
1193 }
1194 | vers_defns ';' VERS_IDENTIFIER
1195 {
1196 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang);
1197 }
1198 | vers_defns ';' EXTERN NAME '{'
1199 {
1200 $<name>$ = ldgram_vers_current_lang;
1201 ldgram_vers_current_lang = $4;
1202 }
1203 vers_defns opt_semicolon '}'
1204 {
1205 $$ = $7;
1206 ldgram_vers_current_lang = $<name>6;
1207 }
1208 | EXTERN NAME '{'
1209 {
1210 $<name>$ = ldgram_vers_current_lang;
1211 ldgram_vers_current_lang = $2;
1212 }
1213 vers_defns opt_semicolon '}'
1214 {
1215 $$ = $5;
1216 ldgram_vers_current_lang = $<name>4;
1217 }
1218 ;
1219
1220 opt_semicolon:
1221 /* empty */
1222 | ';'
1223 ;
1224
1225 %%
1226 void
1227 yyerror(arg)
1228 const char *arg;
1229 {
1230 if (ldfile_assumed_script)
1231 einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
1232 ldfile_input_filename);
1233 if (error_index > 0 && error_index < ERROR_NAME_MAX)
1234 einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
1235 else
1236 einfo ("%P%F:%S: %s\n", arg);
1237 }
This page took 0.054055 seconds and 5 git commands to generate.