[gdb/testsuite] Add untested case in selftest_setup
[deliverable/binutils-gdb.git] / ld / ldgram.y
1 /* A YACC grammar to parse a superset of the AT&T linker scripting language.
2 Copyright (C) 1991-2021 Free Software Foundation, Inc.
3 Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
4
5 This file is part of the GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22 %{
23 /*
24
25 */
26
27 #define DONTDECLARE_MALLOC
28
29 #include "sysdep.h"
30 #include "bfd.h"
31 #include "bfdlink.h"
32 #include "ctf-api.h"
33 #include "ld.h"
34 #include "ldexp.h"
35 #include "ldver.h"
36 #include "ldlang.h"
37 #include "ldfile.h"
38 #include "ldemul.h"
39 #include "ldmisc.h"
40 #include "ldmain.h"
41 #include "mri.h"
42 #include "ldctor.h"
43 #include "ldlex.h"
44
45 #ifndef YYDEBUG
46 #define YYDEBUG 1
47 #endif
48
49 static enum section_type sectype;
50 static lang_memory_region_type *region;
51
52 static bool ldgram_had_keep = false;
53 static char *ldgram_vers_current_lang = NULL;
54
55 #define ERROR_NAME_MAX 20
56 static char *error_names[ERROR_NAME_MAX];
57 static int error_index;
58 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
59 #define POP_ERROR() error_index--;
60 %}
61 %union {
62 bfd_vma integer;
63 struct big_int
64 {
65 bfd_vma integer;
66 char *str;
67 } bigint;
68 fill_type *fill;
69 char *name;
70 const char *cname;
71 struct wildcard_spec wildcard;
72 struct wildcard_list *wildcard_list;
73 struct name_list *name_list;
74 struct flag_info_list *flag_info_list;
75 struct flag_info *flag_info;
76 int token;
77 union etree_union *etree;
78 struct phdr_info
79 {
80 bool filehdr;
81 bool phdrs;
82 union etree_union *at;
83 union etree_union *flags;
84 } phdr;
85 struct lang_nocrossref *nocrossref;
86 struct lang_output_section_phdr_list *section_phdr;
87 struct bfd_elf_version_deps *deflist;
88 struct bfd_elf_version_expr *versyms;
89 struct bfd_elf_version_tree *versnode;
90 }
91
92 %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
93 %type <etree> opt_exp_without_type opt_subalign opt_align
94 %type <fill> fill_opt fill_exp
95 %type <name_list> exclude_name_list
96 %type <wildcard_list> section_name_list
97 %type <flag_info_list> sect_flag_list
98 %type <flag_info> sect_flags
99 %type <name> memspec_opt casesymlist
100 %type <name> memspec_at_opt
101 %type <cname> wildcard_name
102 %type <wildcard> section_name_spec filename_spec wildcard_maybe_exclude
103 %token <bigint> INT
104 %token <name> NAME LNAME
105 %type <integer> length
106 %type <phdr> phdr_qualifiers
107 %type <nocrossref> nocrossref_list
108 %type <section_phdr> phdr_opt
109 %type <integer> opt_nocrossrefs
110
111 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
112 %right <token> '?' ':'
113 %left <token> OROR
114 %left <token> ANDAND
115 %left <token> '|'
116 %left <token> '^'
117 %left <token> '&'
118 %left <token> EQ NE
119 %left <token> '<' '>' LE GE
120 %left <token> LSHIFT RSHIFT
121
122 %left <token> '+' '-'
123 %left <token> '*' '/' '%'
124
125 %right UNARY
126 %token END
127 %left <token> '('
128 %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
129 %token SECTIONS PHDRS INSERT_K AFTER BEFORE
130 %token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
131 %token SORT_BY_NAME SORT_BY_ALIGNMENT SORT_NONE
132 %token SORT_BY_INIT_PRIORITY
133 %token '{' '}'
134 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
135 %token INHIBIT_COMMON_ALLOCATION FORCE_GROUP_ALLOCATION
136 %token SEGMENT_START
137 %token INCLUDE
138 %token MEMORY
139 %token REGION_ALIAS
140 %token LD_FEATURE
141 %token NOLOAD DSECT COPY INFO OVERLAY
142 %token DEFINED TARGET_K SEARCH_DIR MAP ENTRY
143 %token <integer> NEXT
144 %token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K
145 %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS NOCROSSREFS_TO
146 %token ORIGIN FILL
147 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
148 %token ALIGNMOD AT SUBALIGN HIDDEN PROVIDE PROVIDE_HIDDEN AS_NEEDED
149 %type <token> assign_op atype attributes_opt sect_constraint opt_align_with_input
150 %type <name> filename
151 %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
152 %token LOG2CEIL FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
153 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
154 %token <name> VERS_TAG VERS_IDENTIFIER
155 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
156 %token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL INPUT_SECTION_FLAGS ALIGN_WITH_INPUT
157 %token EXCLUDE_FILE
158 %token CONSTANT
159 %type <versyms> vers_defns
160 %type <versnode> vers_tag
161 %type <deflist> verdep
162 %token INPUT_DYNAMIC_LIST
163
164 %%
165
166 file:
167 INPUT_SCRIPT script_file
168 | INPUT_MRI_SCRIPT mri_script_file
169 | INPUT_VERSION_SCRIPT version_script_file
170 | INPUT_DYNAMIC_LIST dynamic_list_file
171 | INPUT_DEFSYM defsym_expr
172 ;
173
174
175 filename: NAME;
176
177
178 defsym_expr:
179 { ldlex_expression(); }
180 assignment
181 { ldlex_popstate(); }
182 ;
183
184 /* SYNTAX WITHIN AN MRI SCRIPT FILE */
185 mri_script_file:
186 {
187 ldlex_mri_script ();
188 PUSH_ERROR (_("MRI style script"));
189 }
190 mri_script_lines
191 {
192 ldlex_popstate ();
193 mri_draw_tree ();
194 POP_ERROR ();
195 }
196 ;
197
198 mri_script_lines:
199 mri_script_lines mri_script_command NEWLINE
200 |
201 ;
202
203 mri_script_command:
204 CHIP exp
205 | CHIP exp ',' exp
206 | NAME {
207 einfo(_("%F%P: unrecognised keyword in MRI style script '%s'\n"),$1);
208 }
209 | LIST {
210 config.map_filename = "-";
211 }
212 | ORDER ordernamelist
213 | ENDWORD
214 | PUBLIC NAME '=' exp
215 { mri_public($2, $4); }
216 | PUBLIC NAME ',' exp
217 { mri_public($2, $4); }
218 | PUBLIC NAME exp
219 { mri_public($2, $3); }
220 | FORMAT NAME
221 { mri_format($2); }
222 | SECT NAME ',' exp
223 { mri_output_section($2, $4);}
224 | SECT NAME exp
225 { mri_output_section($2, $3);}
226 | SECT NAME '=' exp
227 { mri_output_section($2, $4);}
228 | ALIGN_K NAME '=' exp
229 { mri_align($2,$4); }
230 | ALIGN_K NAME ',' exp
231 { mri_align($2,$4); }
232 | ALIGNMOD NAME '=' exp
233 { mri_alignmod($2,$4); }
234 | ALIGNMOD NAME ',' exp
235 { mri_alignmod($2,$4); }
236 | ABSOLUTE mri_abs_name_list
237 | LOAD mri_load_name_list
238 | NAMEWORD NAME
239 { mri_name($2); }
240 | ALIAS NAME ',' NAME
241 { mri_alias($2,$4,0);}
242 | ALIAS NAME ',' INT
243 { mri_alias ($2, 0, (int) $4.integer); }
244 | BASE exp
245 { mri_base($2); }
246 | TRUNCATE INT
247 { mri_truncate ((unsigned int) $2.integer); }
248 | CASE casesymlist
249 | EXTERN extern_name_list
250 | INCLUDE filename
251 { ldlex_script (); ldfile_open_command_file($2); }
252 mri_script_lines END
253 { ldlex_popstate (); }
254 | START NAME
255 { lang_add_entry ($2, false); }
256 |
257 ;
258
259 ordernamelist:
260 ordernamelist ',' NAME { mri_order($3); }
261 | ordernamelist NAME { mri_order($2); }
262 |
263 ;
264
265 mri_load_name_list:
266 NAME
267 { mri_load($1); }
268 | mri_load_name_list ',' NAME { mri_load($3); }
269 ;
270
271 mri_abs_name_list:
272 NAME
273 { mri_only_load($1); }
274 | mri_abs_name_list ',' NAME
275 { mri_only_load($3); }
276 ;
277
278 casesymlist:
279 /* empty */ { $$ = NULL; }
280 | NAME
281 | casesymlist ',' NAME
282 ;
283
284 /* Parsed as expressions so that commas separate entries */
285 extern_name_list:
286 { ldlex_expression (); }
287 extern_name_list_body
288 { ldlex_popstate (); }
289
290 extern_name_list_body:
291 NAME
292 { ldlang_add_undef ($1, false); }
293 | extern_name_list_body NAME
294 { ldlang_add_undef ($2, false); }
295 | extern_name_list_body ',' NAME
296 { ldlang_add_undef ($3, false); }
297 ;
298
299 script_file:
300 { ldlex_both(); }
301 ifile_list
302 { ldlex_popstate(); }
303 ;
304
305 ifile_list:
306 ifile_list ifile_p1
307 |
308 ;
309
310
311 ifile_p1:
312 memory
313 | sections
314 | phdrs
315 | startup
316 | high_level_library
317 | low_level_library
318 | floating_point_support
319 | statement_anywhere
320 | version
321 | ';'
322 | TARGET_K '(' NAME ')'
323 { lang_add_target($3); }
324 | SEARCH_DIR '(' filename ')'
325 { ldfile_add_library_path ($3, false); }
326 | OUTPUT '(' filename ')'
327 { lang_add_output($3, 1); }
328 | OUTPUT_FORMAT '(' NAME ')'
329 { lang_add_output_format ($3, (char *) NULL,
330 (char *) NULL, 1); }
331 | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
332 { lang_add_output_format ($3, $5, $7, 1); }
333 | OUTPUT_ARCH '(' NAME ')'
334 { ldfile_set_output_arch ($3, bfd_arch_unknown); }
335 | FORCE_COMMON_ALLOCATION
336 { command_line.force_common_definition = true ; }
337 | FORCE_GROUP_ALLOCATION
338 { command_line.force_group_allocation = true ; }
339 | INHIBIT_COMMON_ALLOCATION
340 { link_info.inhibit_common_definition = true ; }
341 | INPUT '(' input_list ')'
342 | GROUP
343 { lang_enter_group (); }
344 '(' input_list ')'
345 { lang_leave_group (); }
346 | MAP '(' filename ')'
347 { lang_add_map($3); }
348 | INCLUDE filename
349 { ldlex_script (); ldfile_open_command_file($2); }
350 ifile_list END
351 { ldlex_popstate (); }
352 | NOCROSSREFS '(' nocrossref_list ')'
353 {
354 lang_add_nocrossref ($3);
355 }
356 | NOCROSSREFS_TO '(' nocrossref_list ')'
357 {
358 lang_add_nocrossref_to ($3);
359 }
360 | EXTERN '(' extern_name_list ')'
361 | INSERT_K AFTER NAME
362 { lang_add_insert ($3, 0); }
363 | INSERT_K BEFORE NAME
364 { lang_add_insert ($3, 1); }
365 | REGION_ALIAS '(' NAME ',' NAME ')'
366 { lang_memory_region_alias ($3, $5); }
367 | LD_FEATURE '(' NAME ')'
368 { lang_ld_feature ($3); }
369 ;
370
371 input_list:
372 { ldlex_inputlist(); }
373 input_list1
374 { ldlex_popstate(); }
375
376 input_list1:
377 NAME
378 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
379 (char *)NULL); }
380 | input_list1 ',' NAME
381 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
382 (char *)NULL); }
383 | input_list1 NAME
384 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
385 (char *)NULL); }
386 | LNAME
387 { lang_add_input_file($1,lang_input_file_is_l_enum,
388 (char *)NULL); }
389 | input_list1 ',' LNAME
390 { lang_add_input_file($3,lang_input_file_is_l_enum,
391 (char *)NULL); }
392 | input_list1 LNAME
393 { lang_add_input_file($2,lang_input_file_is_l_enum,
394 (char *)NULL); }
395 | AS_NEEDED '('
396 { $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
397 input_flags.add_DT_NEEDED_for_regular = true; }
398 input_list1 ')'
399 { input_flags.add_DT_NEEDED_for_regular = $<integer>3; }
400 | input_list1 ',' AS_NEEDED '('
401 { $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
402 input_flags.add_DT_NEEDED_for_regular = true; }
403 input_list1 ')'
404 { input_flags.add_DT_NEEDED_for_regular = $<integer>5; }
405 | input_list1 AS_NEEDED '('
406 { $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
407 input_flags.add_DT_NEEDED_for_regular = true; }
408 input_list1 ')'
409 { input_flags.add_DT_NEEDED_for_regular = $<integer>4; }
410 ;
411
412 sections:
413 SECTIONS '{' sec_or_group_p1 '}'
414 ;
415
416 sec_or_group_p1:
417 sec_or_group_p1 section
418 | sec_or_group_p1 statement_anywhere
419 |
420 ;
421
422 statement_anywhere:
423 ENTRY '(' NAME ')'
424 { lang_add_entry ($3, false); }
425 | assignment end
426 | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')'
427 { ldlex_popstate ();
428 lang_add_assignment (exp_assert ($4, $6)); }
429 ;
430
431 /* The '*' and '?' cases are there because the lexer returns them as
432 separate tokens rather than as NAME. */
433 wildcard_name:
434 NAME
435 {
436 $$ = $1;
437 }
438 | '*'
439 {
440 $$ = "*";
441 }
442 | '?'
443 {
444 $$ = "?";
445 }
446 ;
447
448 wildcard_maybe_exclude:
449 wildcard_name
450 {
451 $$.name = $1;
452 $$.sorted = none;
453 $$.exclude_name_list = NULL;
454 $$.section_flag_list = NULL;
455 }
456 | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name
457 {
458 $$.name = $5;
459 $$.sorted = none;
460 $$.exclude_name_list = $3;
461 $$.section_flag_list = NULL;
462 }
463 ;
464
465 filename_spec:
466 wildcard_maybe_exclude
467 | SORT_BY_NAME '(' wildcard_maybe_exclude ')'
468 {
469 $$ = $3;
470 $$.sorted = by_name;
471 }
472 | SORT_NONE '(' wildcard_maybe_exclude ')'
473 {
474 $$ = $3;
475 $$.sorted = by_none;
476 }
477 ;
478
479 section_name_spec:
480 wildcard_maybe_exclude
481 | SORT_BY_NAME '(' wildcard_maybe_exclude ')'
482 {
483 $$ = $3;
484 $$.sorted = by_name;
485 }
486 | SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')'
487 {
488 $$ = $3;
489 $$.sorted = by_alignment;
490 }
491 | SORT_NONE '(' wildcard_maybe_exclude ')'
492 {
493 $$ = $3;
494 $$.sorted = by_none;
495 }
496 | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' ')'
497 {
498 $$ = $5;
499 $$.sorted = by_name_alignment;
500 }
501 | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_maybe_exclude ')' ')'
502 {
503 $$ = $5;
504 $$.sorted = by_name;
505 }
506 | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_maybe_exclude ')' ')'
507 {
508 $$ = $5;
509 $$.sorted = by_alignment_name;
510 }
511 | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' ')'
512 {
513 $$ = $5;
514 $$.sorted = by_alignment;
515 }
516 | SORT_BY_INIT_PRIORITY '(' wildcard_maybe_exclude ')'
517 {
518 $$ = $3;
519 $$.sorted = by_init_priority;
520 }
521 ;
522
523 sect_flag_list: NAME
524 {
525 struct flag_info_list *n;
526 n = ((struct flag_info_list *) xmalloc (sizeof *n));
527 if ($1[0] == '!')
528 {
529 n->with = without_flags;
530 n->name = &$1[1];
531 }
532 else
533 {
534 n->with = with_flags;
535 n->name = $1;
536 }
537 n->valid = false;
538 n->next = NULL;
539 $$ = n;
540 }
541 | sect_flag_list '&' NAME
542 {
543 struct flag_info_list *n;
544 n = ((struct flag_info_list *) xmalloc (sizeof *n));
545 if ($3[0] == '!')
546 {
547 n->with = without_flags;
548 n->name = &$3[1];
549 }
550 else
551 {
552 n->with = with_flags;
553 n->name = $3;
554 }
555 n->valid = false;
556 n->next = $1;
557 $$ = n;
558 }
559 ;
560
561 sect_flags:
562 INPUT_SECTION_FLAGS '(' sect_flag_list ')'
563 {
564 struct flag_info *n;
565 n = ((struct flag_info *) xmalloc (sizeof *n));
566 n->flag_list = $3;
567 n->flags_initialized = false;
568 n->not_with_flags = 0;
569 n->only_with_flags = 0;
570 $$ = n;
571 }
572 ;
573
574 exclude_name_list:
575 exclude_name_list wildcard_name
576 {
577 struct name_list *tmp;
578 tmp = (struct name_list *) xmalloc (sizeof *tmp);
579 tmp->name = $2;
580 tmp->next = $1;
581 $$ = tmp;
582 }
583 |
584 wildcard_name
585 {
586 struct name_list *tmp;
587 tmp = (struct name_list *) xmalloc (sizeof *tmp);
588 tmp->name = $1;
589 tmp->next = NULL;
590 $$ = tmp;
591 }
592 ;
593
594 section_name_list:
595 section_name_list opt_comma section_name_spec
596 {
597 struct wildcard_list *tmp;
598 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
599 tmp->next = $1;
600 tmp->spec = $3;
601 $$ = tmp;
602 }
603 |
604 section_name_spec
605 {
606 struct wildcard_list *tmp;
607 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
608 tmp->next = NULL;
609 tmp->spec = $1;
610 $$ = tmp;
611 }
612 ;
613
614 input_section_spec_no_keep:
615 NAME
616 {
617 struct wildcard_spec tmp;
618 tmp.name = $1;
619 tmp.exclude_name_list = NULL;
620 tmp.sorted = none;
621 tmp.section_flag_list = NULL;
622 lang_add_wild (&tmp, NULL, ldgram_had_keep);
623 }
624 | sect_flags NAME
625 {
626 struct wildcard_spec tmp;
627 tmp.name = $2;
628 tmp.exclude_name_list = NULL;
629 tmp.sorted = none;
630 tmp.section_flag_list = $1;
631 lang_add_wild (&tmp, NULL, ldgram_had_keep);
632 }
633 | '[' section_name_list ']'
634 {
635 lang_add_wild (NULL, $2, ldgram_had_keep);
636 }
637 | sect_flags '[' section_name_list ']'
638 {
639 struct wildcard_spec tmp;
640 tmp.name = NULL;
641 tmp.exclude_name_list = NULL;
642 tmp.sorted = none;
643 tmp.section_flag_list = $1;
644 lang_add_wild (&tmp, $3, ldgram_had_keep);
645 }
646 | filename_spec '(' section_name_list ')'
647 {
648 lang_add_wild (&$1, $3, ldgram_had_keep);
649 }
650 | sect_flags filename_spec '(' section_name_list ')'
651 {
652 $2.section_flag_list = $1;
653 lang_add_wild (&$2, $4, ldgram_had_keep);
654 }
655 ;
656
657 input_section_spec:
658 input_section_spec_no_keep
659 | KEEP '('
660 { ldgram_had_keep = true; }
661 input_section_spec_no_keep ')'
662 { ldgram_had_keep = false; }
663 ;
664
665 statement:
666 assignment end
667 | CREATE_OBJECT_SYMBOLS
668 {
669 lang_add_attribute(lang_object_symbols_statement_enum);
670 }
671 | ';'
672 | CONSTRUCTORS
673 {
674
675 lang_add_attribute(lang_constructors_statement_enum);
676 }
677 | SORT_BY_NAME '(' CONSTRUCTORS ')'
678 {
679 constructors_sorted = true;
680 lang_add_attribute (lang_constructors_statement_enum);
681 }
682 | input_section_spec
683 | length '(' mustbe_exp ')'
684 {
685 lang_add_data ((int) $1, $3);
686 }
687
688 | FILL '(' fill_exp ')'
689 {
690 lang_add_fill ($3);
691 }
692 | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')' end
693 { ldlex_popstate ();
694 lang_add_assignment (exp_assert ($4, $6)); }
695 | INCLUDE filename
696 { ldlex_script (); ldfile_open_command_file($2); }
697 statement_list_opt END
698 { ldlex_popstate (); }
699 ;
700
701 statement_list:
702 statement_list statement
703 | statement
704 ;
705
706 statement_list_opt:
707 /* empty */
708 | statement_list
709 ;
710
711 length:
712 QUAD
713 { $$ = $1; }
714 | SQUAD
715 { $$ = $1; }
716 | LONG
717 { $$ = $1; }
718 | SHORT
719 { $$ = $1; }
720 | BYTE
721 { $$ = $1; }
722 ;
723
724 fill_exp:
725 mustbe_exp
726 {
727 $$ = exp_get_fill ($1, 0, "fill value");
728 }
729 ;
730
731 fill_opt:
732 '=' fill_exp
733 { $$ = $2; }
734 | { $$ = (fill_type *) 0; }
735 ;
736
737 assign_op:
738 PLUSEQ
739 { $$ = '+'; }
740 | MINUSEQ
741 { $$ = '-'; }
742 | MULTEQ
743 { $$ = '*'; }
744 | DIVEQ
745 { $$ = '/'; }
746 | LSHIFTEQ
747 { $$ = LSHIFT; }
748 | RSHIFTEQ
749 { $$ = RSHIFT; }
750 | ANDEQ
751 { $$ = '&'; }
752 | OREQ
753 { $$ = '|'; }
754
755 ;
756
757 end: ';' | ','
758 ;
759
760
761 assignment:
762 NAME '=' mustbe_exp
763 {
764 lang_add_assignment (exp_assign ($1, $3, false));
765 }
766 | NAME assign_op mustbe_exp
767 {
768 lang_add_assignment (exp_assign ($1,
769 exp_binop ($2,
770 exp_nameop (NAME,
771 $1),
772 $3), false));
773 }
774 | HIDDEN '(' NAME '=' mustbe_exp ')'
775 {
776 lang_add_assignment (exp_assign ($3, $5, true));
777 }
778 | PROVIDE '(' NAME '=' mustbe_exp ')'
779 {
780 lang_add_assignment (exp_provide ($3, $5, false));
781 }
782 | PROVIDE_HIDDEN '(' NAME '=' mustbe_exp ')'
783 {
784 lang_add_assignment (exp_provide ($3, $5, true));
785 }
786 ;
787
788
789 opt_comma:
790 ',' | ;
791
792
793 memory:
794 MEMORY '{' memory_spec_list_opt '}'
795 ;
796
797 memory_spec_list_opt: memory_spec_list | ;
798
799 memory_spec_list:
800 memory_spec_list opt_comma memory_spec
801 | memory_spec
802 ;
803
804
805 memory_spec: NAME
806 { region = lang_memory_region_lookup ($1, true); }
807 attributes_opt ':'
808 origin_spec opt_comma length_spec
809 {}
810 | INCLUDE filename
811 { ldlex_script (); ldfile_open_command_file($2); }
812 memory_spec_list_opt END
813 { ldlex_popstate (); }
814 ;
815
816 origin_spec:
817 ORIGIN '=' mustbe_exp
818 {
819 region->origin_exp = $3;
820 }
821 ;
822
823 length_spec:
824 LENGTH '=' mustbe_exp
825 {
826 region->length_exp = $3;
827 }
828 ;
829
830 attributes_opt:
831 /* empty */
832 { /* dummy action to avoid bison 1.25 error message */ }
833 | '(' attributes_list ')'
834 ;
835
836 attributes_list:
837 attributes_string
838 | attributes_list attributes_string
839 ;
840
841 attributes_string:
842 NAME
843 { lang_set_flags (region, $1, 0); }
844 | '!' NAME
845 { lang_set_flags (region, $2, 1); }
846 ;
847
848 startup:
849 STARTUP '(' filename ')'
850 { lang_startup($3); }
851 ;
852
853 high_level_library:
854 HLL '(' high_level_library_NAME_list ')'
855 | HLL '(' ')'
856 { ldemul_hll((char *)NULL); }
857 ;
858
859 high_level_library_NAME_list:
860 high_level_library_NAME_list opt_comma filename
861 { ldemul_hll($3); }
862 | filename
863 { ldemul_hll($1); }
864 ;
865
866 low_level_library:
867 SYSLIB '(' low_level_library_NAME_list ')'
868 ;
869
870 low_level_library_NAME_list:
871 low_level_library_NAME_list opt_comma filename
872 { ldemul_syslib($3); }
873 |
874 ;
875
876 floating_point_support:
877 FLOAT
878 { lang_float(true); }
879 | NOFLOAT
880 { lang_float(false); }
881 ;
882
883 nocrossref_list:
884 /* empty */
885 {
886 $$ = NULL;
887 }
888 | NAME nocrossref_list
889 {
890 struct lang_nocrossref *n;
891
892 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
893 n->name = $1;
894 n->next = $2;
895 $$ = n;
896 }
897 | NAME ',' nocrossref_list
898 {
899 struct lang_nocrossref *n;
900
901 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
902 n->name = $1;
903 n->next = $3;
904 $$ = n;
905 }
906 ;
907
908 mustbe_exp: { ldlex_expression (); }
909 exp
910 { ldlex_popstate (); $$=$2;}
911 ;
912
913 exp :
914 '-' exp %prec UNARY
915 { $$ = exp_unop ('-', $2); }
916 | '(' exp ')'
917 { $$ = $2; }
918 | NEXT '(' exp ')' %prec UNARY
919 { $$ = exp_unop ((int) $1,$3); }
920 | '!' exp %prec UNARY
921 { $$ = exp_unop ('!', $2); }
922 | '+' exp %prec UNARY
923 { $$ = $2; }
924 | '~' exp %prec UNARY
925 { $$ = exp_unop ('~', $2);}
926
927 | exp '*' exp
928 { $$ = exp_binop ('*', $1, $3); }
929 | exp '/' exp
930 { $$ = exp_binop ('/', $1, $3); }
931 | exp '%' exp
932 { $$ = exp_binop ('%', $1, $3); }
933 | exp '+' exp
934 { $$ = exp_binop ('+', $1, $3); }
935 | exp '-' exp
936 { $$ = exp_binop ('-' , $1, $3); }
937 | exp LSHIFT exp
938 { $$ = exp_binop (LSHIFT , $1, $3); }
939 | exp RSHIFT exp
940 { $$ = exp_binop (RSHIFT , $1, $3); }
941 | exp EQ exp
942 { $$ = exp_binop (EQ , $1, $3); }
943 | exp NE exp
944 { $$ = exp_binop (NE , $1, $3); }
945 | exp LE exp
946 { $$ = exp_binop (LE , $1, $3); }
947 | exp GE exp
948 { $$ = exp_binop (GE , $1, $3); }
949 | exp '<' exp
950 { $$ = exp_binop ('<' , $1, $3); }
951 | exp '>' exp
952 { $$ = exp_binop ('>' , $1, $3); }
953 | exp '&' exp
954 { $$ = exp_binop ('&' , $1, $3); }
955 | exp '^' exp
956 { $$ = exp_binop ('^' , $1, $3); }
957 | exp '|' exp
958 { $$ = exp_binop ('|' , $1, $3); }
959 | exp '?' exp ':' exp
960 { $$ = exp_trinop ('?' , $1, $3, $5); }
961 | exp ANDAND exp
962 { $$ = exp_binop (ANDAND , $1, $3); }
963 | exp OROR exp
964 { $$ = exp_binop (OROR , $1, $3); }
965 | DEFINED '(' NAME ')'
966 { $$ = exp_nameop (DEFINED, $3); }
967 | INT
968 { $$ = exp_bigintop ($1.integer, $1.str); }
969 | SIZEOF_HEADERS
970 { $$ = exp_nameop (SIZEOF_HEADERS,0); }
971
972 | ALIGNOF '(' NAME ')'
973 { $$ = exp_nameop (ALIGNOF,$3); }
974 | SIZEOF '(' NAME ')'
975 { $$ = exp_nameop (SIZEOF,$3); }
976 | ADDR '(' NAME ')'
977 { $$ = exp_nameop (ADDR,$3); }
978 | LOADADDR '(' NAME ')'
979 { $$ = exp_nameop (LOADADDR,$3); }
980 | CONSTANT '(' NAME ')'
981 { $$ = exp_nameop (CONSTANT,$3); }
982 | ABSOLUTE '(' exp ')'
983 { $$ = exp_unop (ABSOLUTE, $3); }
984 | ALIGN_K '(' exp ')'
985 { $$ = exp_unop (ALIGN_K,$3); }
986 | ALIGN_K '(' exp ',' exp ')'
987 { $$ = exp_binop (ALIGN_K,$3,$5); }
988 | DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
989 { $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
990 | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
991 { $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
992 | DATA_SEGMENT_END '(' exp ')'
993 { $$ = exp_unop (DATA_SEGMENT_END, $3); }
994 | SEGMENT_START '(' NAME ',' exp ')'
995 { /* The operands to the expression node are
996 placed in the opposite order from the way
997 in which they appear in the script as
998 that allows us to reuse more code in
999 fold_binary. */
1000 $$ = exp_binop (SEGMENT_START,
1001 $5,
1002 exp_nameop (NAME, $3)); }
1003 | BLOCK '(' exp ')'
1004 { $$ = exp_unop (ALIGN_K,$3); }
1005 | NAME
1006 { $$ = exp_nameop (NAME,$1); }
1007 | MAX_K '(' exp ',' exp ')'
1008 { $$ = exp_binop (MAX_K, $3, $5 ); }
1009 | MIN_K '(' exp ',' exp ')'
1010 { $$ = exp_binop (MIN_K, $3, $5 ); }
1011 | ASSERT_K '(' exp ',' NAME ')'
1012 { $$ = exp_assert ($3, $5); }
1013 | ORIGIN '(' NAME ')'
1014 { $$ = exp_nameop (ORIGIN, $3); }
1015 | LENGTH '(' NAME ')'
1016 { $$ = exp_nameop (LENGTH, $3); }
1017 | LOG2CEIL '(' exp ')'
1018 { $$ = exp_unop (LOG2CEIL, $3); }
1019 ;
1020
1021
1022 memspec_at_opt:
1023 AT '>' NAME { $$ = $3; }
1024 | { $$ = 0; }
1025 ;
1026
1027 opt_at:
1028 AT '(' exp ')' { $$ = $3; }
1029 | { $$ = 0; }
1030 ;
1031
1032 opt_align:
1033 ALIGN_K '(' exp ')' { $$ = $3; }
1034 | { $$ = 0; }
1035 ;
1036
1037 opt_align_with_input:
1038 ALIGN_WITH_INPUT { $$ = ALIGN_WITH_INPUT; }
1039 | { $$ = 0; }
1040 ;
1041
1042 opt_subalign:
1043 SUBALIGN '(' exp ')' { $$ = $3; }
1044 | { $$ = 0; }
1045 ;
1046
1047 sect_constraint:
1048 ONLY_IF_RO { $$ = ONLY_IF_RO; }
1049 | ONLY_IF_RW { $$ = ONLY_IF_RW; }
1050 | SPECIAL { $$ = SPECIAL; }
1051 | { $$ = 0; }
1052 ;
1053
1054 section: NAME { ldlex_expression(); }
1055 opt_exp_with_type
1056 opt_at
1057 opt_align
1058 opt_align_with_input
1059 opt_subalign { ldlex_popstate (); ldlex_script (); }
1060 sect_constraint
1061 '{'
1062 {
1063 lang_enter_output_section_statement($1, $3,
1064 sectype,
1065 $5, $7, $4, $9, $6);
1066 }
1067 statement_list_opt
1068 '}' { ldlex_popstate (); ldlex_expression (); }
1069 memspec_opt memspec_at_opt phdr_opt fill_opt
1070 {
1071 if (yychar == NAME)
1072 {
1073 yyclearin;
1074 ldlex_backup ();
1075 }
1076 ldlex_popstate ();
1077 lang_leave_output_section_statement ($18, $15, $17, $16);
1078 }
1079 opt_comma
1080 | OVERLAY
1081 { ldlex_expression (); }
1082 opt_exp_without_type opt_nocrossrefs opt_at opt_subalign
1083 { ldlex_popstate (); ldlex_script (); }
1084 '{'
1085 {
1086 lang_enter_overlay ($3, $6);
1087 }
1088 overlay_section
1089 '}'
1090 { ldlex_popstate (); ldlex_expression (); }
1091 memspec_opt memspec_at_opt phdr_opt fill_opt
1092 {
1093 if (yychar == NAME)
1094 {
1095 yyclearin;
1096 ldlex_backup ();
1097 }
1098 ldlex_popstate ();
1099 lang_leave_overlay ($5, (int) $4,
1100 $16, $13, $15, $14);
1101 }
1102 opt_comma
1103 | /* The GROUP case is just enough to support the gcc
1104 svr3.ifile script. It is not intended to be full
1105 support. I'm not even sure what GROUP is supposed
1106 to mean. */
1107 GROUP { ldlex_expression (); }
1108 opt_exp_with_type
1109 {
1110 ldlex_popstate ();
1111 lang_add_assignment (exp_assign (".", $3, false));
1112 }
1113 '{' sec_or_group_p1 '}'
1114 | INCLUDE filename
1115 { ldlex_script (); ldfile_open_command_file($2); }
1116 sec_or_group_p1 END
1117 { ldlex_popstate (); }
1118 ;
1119
1120 type:
1121 NOLOAD { sectype = noload_section; }
1122 | DSECT { sectype = noalloc_section; }
1123 | COPY { sectype = noalloc_section; }
1124 | INFO { sectype = noalloc_section; }
1125 | OVERLAY { sectype = noalloc_section; }
1126 ;
1127
1128 atype:
1129 '(' type ')'
1130 | /* EMPTY */ { sectype = normal_section; }
1131 | '(' ')' { sectype = normal_section; }
1132 ;
1133
1134 opt_exp_with_type:
1135 exp atype ':' { $$ = $1; }
1136 | atype ':' { $$ = (etree_type *)NULL; }
1137 | /* The BIND cases are to support the gcc svr3.ifile
1138 script. They aren't intended to implement full
1139 support for the BIND keyword. I'm not even sure
1140 what BIND is supposed to mean. */
1141 BIND '(' exp ')' atype ':' { $$ = $3; }
1142 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
1143 { $$ = $3; }
1144 ;
1145
1146 opt_exp_without_type:
1147 exp ':' { $$ = $1; }
1148 | ':' { $$ = (etree_type *) NULL; }
1149 ;
1150
1151 opt_nocrossrefs:
1152 /* empty */
1153 { $$ = 0; }
1154 | NOCROSSREFS
1155 { $$ = 1; }
1156 ;
1157
1158 memspec_opt:
1159 '>' NAME
1160 { $$ = $2; }
1161 | { $$ = DEFAULT_MEMORY_REGION; }
1162 ;
1163
1164 phdr_opt:
1165 /* empty */
1166 {
1167 $$ = NULL;
1168 }
1169 | phdr_opt ':' NAME
1170 {
1171 struct lang_output_section_phdr_list *n;
1172
1173 n = ((struct lang_output_section_phdr_list *)
1174 xmalloc (sizeof *n));
1175 n->name = $3;
1176 n->used = false;
1177 n->next = $1;
1178 $$ = n;
1179 }
1180 ;
1181
1182 overlay_section:
1183 /* empty */
1184 | overlay_section
1185 NAME
1186 {
1187 ldlex_script ();
1188 lang_enter_overlay_section ($2);
1189 }
1190 '{' statement_list_opt '}'
1191 { ldlex_popstate (); ldlex_expression (); }
1192 phdr_opt fill_opt
1193 {
1194 ldlex_popstate ();
1195 lang_leave_overlay_section ($9, $8);
1196 }
1197 opt_comma
1198 ;
1199
1200 phdrs:
1201 PHDRS '{' phdr_list '}'
1202 ;
1203
1204 phdr_list:
1205 /* empty */
1206 | phdr_list phdr
1207 ;
1208
1209 phdr:
1210 NAME { ldlex_expression (); }
1211 phdr_type phdr_qualifiers { ldlex_popstate (); }
1212 ';'
1213 {
1214 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
1215 $4.flags);
1216 }
1217 ;
1218
1219 phdr_type:
1220 exp
1221 {
1222 $$ = $1;
1223
1224 if ($1->type.node_class == etree_name
1225 && $1->type.node_code == NAME)
1226 {
1227 const char *s;
1228 unsigned int i;
1229 static const char * const phdr_types[] =
1230 {
1231 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
1232 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
1233 "PT_PHDR", "PT_TLS"
1234 };
1235
1236 s = $1->name.name;
1237 for (i = 0;
1238 i < sizeof phdr_types / sizeof phdr_types[0];
1239 i++)
1240 if (strcmp (s, phdr_types[i]) == 0)
1241 {
1242 $$ = exp_intop (i);
1243 break;
1244 }
1245 if (i == sizeof phdr_types / sizeof phdr_types[0])
1246 {
1247 if (strcmp (s, "PT_GNU_EH_FRAME") == 0)
1248 $$ = exp_intop (0x6474e550);
1249 else if (strcmp (s, "PT_GNU_STACK") == 0)
1250 $$ = exp_intop (0x6474e551);
1251 else
1252 {
1253 einfo (_("\
1254 %X%P:%pS: unknown phdr type `%s' (try integer literal)\n"),
1255 NULL, s);
1256 $$ = exp_intop (0);
1257 }
1258 }
1259 }
1260 }
1261 ;
1262
1263 phdr_qualifiers:
1264 /* empty */
1265 {
1266 memset (&$$, 0, sizeof (struct phdr_info));
1267 }
1268 | NAME phdr_val phdr_qualifiers
1269 {
1270 $$ = $3;
1271 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
1272 $$.filehdr = true;
1273 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
1274 $$.phdrs = true;
1275 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
1276 $$.flags = $2;
1277 else
1278 einfo (_("%X%P:%pS: PHDRS syntax error at `%s'\n"),
1279 NULL, $1);
1280 }
1281 | AT '(' exp ')' phdr_qualifiers
1282 {
1283 $$ = $5;
1284 $$.at = $3;
1285 }
1286 ;
1287
1288 phdr_val:
1289 /* empty */
1290 {
1291 $$ = NULL;
1292 }
1293 | '(' exp ')'
1294 {
1295 $$ = $2;
1296 }
1297 ;
1298
1299 dynamic_list_file:
1300 {
1301 ldlex_version_file ();
1302 PUSH_ERROR (_("dynamic list"));
1303 }
1304 dynamic_list_nodes
1305 {
1306 ldlex_popstate ();
1307 POP_ERROR ();
1308 }
1309 ;
1310
1311 dynamic_list_nodes:
1312 dynamic_list_node
1313 | dynamic_list_nodes dynamic_list_node
1314 ;
1315
1316 dynamic_list_node:
1317 '{' dynamic_list_tag '}' ';'
1318 ;
1319
1320 dynamic_list_tag:
1321 vers_defns ';'
1322 {
1323 lang_append_dynamic_list (current_dynamic_list_p, $1);
1324 }
1325 ;
1326
1327 /* This syntax is used within an external version script file. */
1328
1329 version_script_file:
1330 {
1331 ldlex_version_file ();
1332 PUSH_ERROR (_("VERSION script"));
1333 }
1334 vers_nodes
1335 {
1336 ldlex_popstate ();
1337 POP_ERROR ();
1338 }
1339 ;
1340
1341 /* This is used within a normal linker script file. */
1342
1343 version:
1344 {
1345 ldlex_version_script ();
1346 }
1347 VERSIONK '{' vers_nodes '}'
1348 {
1349 ldlex_popstate ();
1350 }
1351 ;
1352
1353 vers_nodes:
1354 vers_node
1355 | vers_nodes vers_node
1356 ;
1357
1358 vers_node:
1359 '{' vers_tag '}' ';'
1360 {
1361 lang_register_vers_node (NULL, $2, NULL);
1362 }
1363 | VERS_TAG '{' vers_tag '}' ';'
1364 {
1365 lang_register_vers_node ($1, $3, NULL);
1366 }
1367 | VERS_TAG '{' vers_tag '}' verdep ';'
1368 {
1369 lang_register_vers_node ($1, $3, $5);
1370 }
1371 ;
1372
1373 verdep:
1374 VERS_TAG
1375 {
1376 $$ = lang_add_vers_depend (NULL, $1);
1377 }
1378 | verdep VERS_TAG
1379 {
1380 $$ = lang_add_vers_depend ($1, $2);
1381 }
1382 ;
1383
1384 vers_tag:
1385 /* empty */
1386 {
1387 $$ = lang_new_vers_node (NULL, NULL);
1388 }
1389 | vers_defns ';'
1390 {
1391 $$ = lang_new_vers_node ($1, NULL);
1392 }
1393 | GLOBAL ':' vers_defns ';'
1394 {
1395 $$ = lang_new_vers_node ($3, NULL);
1396 }
1397 | LOCAL ':' vers_defns ';'
1398 {
1399 $$ = lang_new_vers_node (NULL, $3);
1400 }
1401 | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
1402 {
1403 $$ = lang_new_vers_node ($3, $7);
1404 }
1405 ;
1406
1407 vers_defns:
1408 VERS_IDENTIFIER
1409 {
1410 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, false);
1411 }
1412 | NAME
1413 {
1414 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, true);
1415 }
1416 | vers_defns ';' VERS_IDENTIFIER
1417 {
1418 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, false);
1419 }
1420 | vers_defns ';' NAME
1421 {
1422 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, true);
1423 }
1424 | vers_defns ';' EXTERN NAME '{'
1425 {
1426 $<name>$ = ldgram_vers_current_lang;
1427 ldgram_vers_current_lang = $4;
1428 }
1429 vers_defns opt_semicolon '}'
1430 {
1431 struct bfd_elf_version_expr *pat;
1432 for (pat = $7; pat->next != NULL; pat = pat->next);
1433 pat->next = $1;
1434 $$ = $7;
1435 ldgram_vers_current_lang = $<name>6;
1436 }
1437 | EXTERN NAME '{'
1438 {
1439 $<name>$ = ldgram_vers_current_lang;
1440 ldgram_vers_current_lang = $2;
1441 }
1442 vers_defns opt_semicolon '}'
1443 {
1444 $$ = $5;
1445 ldgram_vers_current_lang = $<name>4;
1446 }
1447 | GLOBAL
1448 {
1449 $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang, false);
1450 }
1451 | vers_defns ';' GLOBAL
1452 {
1453 $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang, false);
1454 }
1455 | LOCAL
1456 {
1457 $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang, false);
1458 }
1459 | vers_defns ';' LOCAL
1460 {
1461 $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang, false);
1462 }
1463 | EXTERN
1464 {
1465 $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang, false);
1466 }
1467 | vers_defns ';' EXTERN
1468 {
1469 $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, false);
1470 }
1471 ;
1472
1473 opt_semicolon:
1474 /* empty */
1475 | ';'
1476 ;
1477
1478 %%
1479 void
1480 yyerror(arg)
1481 const char *arg;
1482 {
1483 if (ldfile_assumed_script)
1484 einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
1485 ldlex_filename ());
1486 if (error_index > 0 && error_index < ERROR_NAME_MAX)
1487 einfo ("%F%P:%pS: %s in %s\n", NULL, arg, error_names[error_index - 1]);
1488 else
1489 einfo ("%F%P:%pS: %s\n", NULL, arg);
1490 }
This page took 0.058793 seconds and 4 git commands to generate.