]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame_incremental - ld/ldgram.y
Mention whitespace in script expressions
[thirdparty/binutils-gdb.git] / ld / ldgram.y
... / ...
CommitLineData
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
49static enum section_type sectype;
50static lang_memory_region_type *region;
51
52static bool ldgram_had_keep = false;
53static char *ldgram_vers_current_lang = NULL;
54
55#define ERROR_NAME_MAX 20
56static char *error_names[ERROR_NAME_MAX];
57static 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 memspec_at_opt paren_script_name casesymlist
100%type <cname> wildcard_name
101%type <wildcard> section_name_spec filename_spec wildcard_maybe_exclude
102%token <bigint> INT
103%token <name> NAME LNAME
104%type <integer> length
105%type <phdr> phdr_qualifiers
106%type <nocrossref> nocrossref_list
107%type <section_phdr> phdr_opt
108%type <integer> opt_nocrossrefs
109
110%right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
111%right <token> '?' ':'
112%left <token> OROR
113%left <token> ANDAND
114%left <token> '|'
115%left <token> '^'
116%left <token> '&'
117%left <token> EQ NE
118%left <token> '<' '>' LE GE
119%left <token> LSHIFT RSHIFT
120
121%left <token> '+' '-'
122%left <token> '*' '/' '%'
123
124%right UNARY
125%token END
126%left <token> '('
127%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
128%token SECTIONS PHDRS INSERT_K AFTER BEFORE
129%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
130%token SORT_BY_NAME SORT_BY_ALIGNMENT SORT_NONE
131%token SORT_BY_INIT_PRIORITY
132%token '{' '}'
133%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
134%token INHIBIT_COMMON_ALLOCATION FORCE_GROUP_ALLOCATION
135%token SEGMENT_START
136%token INCLUDE
137%token MEMORY
138%token REGION_ALIAS
139%token LD_FEATURE
140%token NOLOAD DSECT COPY INFO OVERLAY
141%token READONLY
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
166file:
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
175filename: NAME;
176
177
178defsym_expr:
179 { ldlex_expression(); }
180 assignment
181 { ldlex_popstate(); }
182 ;
183
184/* SYNTAX WITHIN AN MRI SCRIPT FILE */
185mri_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
198mri_script_lines:
199 mri_script_lines mri_script_command NEWLINE
200 |
201 ;
202
203mri_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
259ordernamelist:
260 ordernamelist ',' NAME { mri_order($3); }
261 | ordernamelist NAME { mri_order($2); }
262 |
263 ;
264
265mri_load_name_list:
266 NAME
267 { mri_load($1); }
268 | mri_load_name_list ',' NAME { mri_load($3); }
269 ;
270
271mri_abs_name_list:
272 NAME
273 { mri_only_load($1); }
274 | mri_abs_name_list ',' NAME
275 { mri_only_load($3); }
276 ;
277
278casesymlist:
279 /* empty */ { $$ = NULL; }
280 | NAME
281 | casesymlist ',' NAME
282 ;
283
284/* Parsed as expressions so that commas separate entries */
285extern_name_list:
286 { ldlex_expression (); }
287 extern_name_list_body
288 { ldlex_popstate (); }
289
290extern_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
299script_file:
300 { ldlex_both(); }
301 ifile_list
302 { ldlex_popstate(); }
303 ;
304
305ifile_list:
306 ifile_list ifile_p1
307 |
308 ;
309
310
311ifile_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
371input_list:
372 { ldlex_inputlist(); }
373 input_list1
374 { ldlex_popstate(); }
375
376input_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
412sections:
413 SECTIONS '{' sec_or_group_p1 '}'
414 ;
415
416sec_or_group_p1:
417 sec_or_group_p1 section
418 | sec_or_group_p1 statement_anywhere
419 |
420 ;
421
422statement_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. */
433wildcard_name:
434 NAME
435 {
436 $$ = $1;
437 }
438 | '*'
439 {
440 $$ = "*";
441 }
442 | '?'
443 {
444 $$ = "?";
445 }
446 ;
447
448wildcard_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
465filename_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
479section_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
523sect_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
561sect_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
574exclude_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
594section_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
614input_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
657input_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
665statement:
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
701statement_list:
702 statement_list statement
703 | statement
704 ;
705
706statement_list_opt:
707 /* empty */
708 | statement_list
709 ;
710
711length:
712 QUAD
713 { $$ = $1; }
714 | SQUAD
715 { $$ = $1; }
716 | LONG
717 { $$ = $1; }
718 | SHORT
719 { $$ = $1; }
720 | BYTE
721 { $$ = $1; }
722 ;
723
724fill_exp:
725 mustbe_exp
726 {
727 $$ = exp_get_fill ($1, 0, "fill value");
728 }
729 ;
730
731fill_opt:
732 '=' fill_exp
733 { $$ = $2; }
734 | { $$ = (fill_type *) 0; }
735 ;
736
737assign_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
757end: ';' | ','
758 ;
759
760
761assignment:
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
789opt_comma:
790 ',' | ;
791
792
793memory:
794 MEMORY '{' memory_spec_list_opt '}'
795 ;
796
797memory_spec_list_opt: memory_spec_list | ;
798
799memory_spec_list:
800 memory_spec_list opt_comma memory_spec
801 | memory_spec
802 ;
803
804
805memory_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
816origin_spec:
817 ORIGIN '=' mustbe_exp
818 {
819 region->origin_exp = $3;
820 }
821 ;
822
823length_spec:
824 LENGTH '=' mustbe_exp
825 {
826 region->length_exp = $3;
827 }
828 ;
829
830attributes_opt:
831 /* empty */
832 { /* dummy action to avoid bison 1.25 error message */ }
833 | '(' attributes_list ')'
834 ;
835
836attributes_list:
837 attributes_string
838 | attributes_list attributes_string
839 ;
840
841attributes_string:
842 NAME
843 { lang_set_flags (region, $1, 0); }
844 | '!' NAME
845 { lang_set_flags (region, $2, 1); }
846 ;
847
848startup:
849 STARTUP '(' filename ')'
850 { lang_startup($3); }
851 ;
852
853high_level_library:
854 HLL '(' high_level_library_NAME_list ')'
855 | HLL '(' ')'
856 { ldemul_hll((char *)NULL); }
857 ;
858
859high_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
866low_level_library:
867 SYSLIB '(' low_level_library_NAME_list ')'
868 ;
869
870low_level_library_NAME_list:
871 low_level_library_NAME_list opt_comma filename
872 { ldemul_syslib($3); }
873 |
874 ;
875
876floating_point_support:
877 FLOAT
878 { lang_float(true); }
879 | NOFLOAT
880 { lang_float(false); }
881 ;
882
883nocrossref_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
908paren_script_name:
909 { ldlex_script (); } '(' NAME { ldlex_popstate (); } ')'
910 { $$ = $3; }
911
912mustbe_exp: { ldlex_expression (); }
913 exp
914 { ldlex_popstate (); $$=$2;}
915 ;
916
917exp :
918 '-' exp %prec UNARY
919 { $$ = exp_unop ('-', $2); }
920 | '(' exp ')'
921 { $$ = $2; }
922 | NEXT '(' exp ')' %prec UNARY
923 { $$ = exp_unop ((int) $1,$3); }
924 | '!' exp %prec UNARY
925 { $$ = exp_unop ('!', $2); }
926 | '+' exp %prec UNARY
927 { $$ = $2; }
928 | '~' exp %prec UNARY
929 { $$ = exp_unop ('~', $2);}
930
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 '+' exp
938 { $$ = exp_binop ('+', $1, $3); }
939 | exp '-' exp
940 { $$ = exp_binop ('-' , $1, $3); }
941 | exp LSHIFT exp
942 { $$ = exp_binop (LSHIFT , $1, $3); }
943 | exp RSHIFT exp
944 { $$ = exp_binop (RSHIFT , $1, $3); }
945 | exp EQ exp
946 { $$ = exp_binop (EQ , $1, $3); }
947 | exp NE exp
948 { $$ = exp_binop (NE , $1, $3); }
949 | exp LE exp
950 { $$ = exp_binop (LE , $1, $3); }
951 | exp GE exp
952 { $$ = exp_binop (GE , $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
960 { $$ = exp_binop ('^' , $1, $3); }
961 | exp '|' exp
962 { $$ = exp_binop ('|' , $1, $3); }
963 | exp '?' exp ':' exp
964 { $$ = exp_trinop ('?' , $1, $3, $5); }
965 | exp ANDAND exp
966 { $$ = exp_binop (ANDAND , $1, $3); }
967 | exp OROR exp
968 { $$ = exp_binop (OROR , $1, $3); }
969 | DEFINED '(' NAME ')'
970 { $$ = exp_nameop (DEFINED, $3); }
971 | INT
972 { $$ = exp_bigintop ($1.integer, $1.str); }
973 | SIZEOF_HEADERS
974 { $$ = exp_nameop (SIZEOF_HEADERS,0); }
975
976 | ALIGNOF paren_script_name
977 { $$ = exp_nameop (ALIGNOF, $2); }
978 | SIZEOF paren_script_name
979 { $$ = exp_nameop (SIZEOF, $2); }
980 | ADDR paren_script_name
981 { $$ = exp_nameop (ADDR, $2); }
982 | LOADADDR paren_script_name
983 { $$ = exp_nameop (LOADADDR, $2); }
984 | CONSTANT '(' NAME ')'
985 { $$ = exp_nameop (CONSTANT,$3); }
986 | ABSOLUTE '(' exp ')'
987 { $$ = exp_unop (ABSOLUTE, $3); }
988 | ALIGN_K '(' exp ')'
989 { $$ = exp_unop (ALIGN_K,$3); }
990 | ALIGN_K '(' exp ',' exp ')'
991 { $$ = exp_binop (ALIGN_K,$3,$5); }
992 | DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
993 { $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
994 | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
995 { $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
996 | DATA_SEGMENT_END '(' exp ')'
997 { $$ = exp_unop (DATA_SEGMENT_END, $3); }
998 | SEGMENT_START { ldlex_script (); } '(' NAME
999 { ldlex_popstate (); } ',' exp ')'
1000 { /* The operands to the expression node are
1001 placed in the opposite order from the way
1002 in which they appear in the script as
1003 that allows us to reuse more code in
1004 fold_binary. */
1005 $$ = exp_binop (SEGMENT_START,
1006 $7,
1007 exp_nameop (NAME, $4)); }
1008 | BLOCK '(' exp ')'
1009 { $$ = exp_unop (ALIGN_K,$3); }
1010 | NAME
1011 { $$ = exp_nameop (NAME,$1); }
1012 | MAX_K '(' exp ',' exp ')'
1013 { $$ = exp_binop (MAX_K, $3, $5 ); }
1014 | MIN_K '(' exp ',' exp ')'
1015 { $$ = exp_binop (MIN_K, $3, $5 ); }
1016 | ASSERT_K '(' exp ',' NAME ')'
1017 { $$ = exp_assert ($3, $5); }
1018 | ORIGIN '(' NAME ')'
1019 { $$ = exp_nameop (ORIGIN, $3); }
1020 | LENGTH '(' NAME ')'
1021 { $$ = exp_nameop (LENGTH, $3); }
1022 | LOG2CEIL '(' exp ')'
1023 { $$ = exp_unop (LOG2CEIL, $3); }
1024 ;
1025
1026
1027memspec_at_opt:
1028 AT '>' NAME { $$ = $3; }
1029 | { $$ = 0; }
1030 ;
1031
1032opt_at:
1033 AT '(' exp ')' { $$ = $3; }
1034 | { $$ = 0; }
1035 ;
1036
1037opt_align:
1038 ALIGN_K '(' exp ')' { $$ = $3; }
1039 | { $$ = 0; }
1040 ;
1041
1042opt_align_with_input:
1043 ALIGN_WITH_INPUT { $$ = ALIGN_WITH_INPUT; }
1044 | { $$ = 0; }
1045 ;
1046
1047opt_subalign:
1048 SUBALIGN '(' exp ')' { $$ = $3; }
1049 | { $$ = 0; }
1050 ;
1051
1052sect_constraint:
1053 ONLY_IF_RO { $$ = ONLY_IF_RO; }
1054 | ONLY_IF_RW { $$ = ONLY_IF_RW; }
1055 | SPECIAL { $$ = SPECIAL; }
1056 | { $$ = 0; }
1057 ;
1058
1059section: NAME { ldlex_expression(); }
1060 opt_exp_with_type
1061 opt_at
1062 opt_align
1063 opt_align_with_input
1064 opt_subalign { ldlex_popstate (); ldlex_script (); }
1065 sect_constraint
1066 '{'
1067 {
1068 lang_enter_output_section_statement($1, $3,
1069 sectype,
1070 $5, $7, $4, $9, $6);
1071 }
1072 statement_list_opt
1073 '}' { ldlex_popstate (); ldlex_expression (); }
1074 memspec_opt memspec_at_opt phdr_opt fill_opt
1075 {
1076 if (yychar == NAME)
1077 {
1078 yyclearin;
1079 ldlex_backup ();
1080 }
1081 ldlex_popstate ();
1082 lang_leave_output_section_statement ($18, $15, $17, $16);
1083 }
1084 opt_comma
1085 | OVERLAY
1086 { ldlex_expression (); }
1087 opt_exp_without_type opt_nocrossrefs opt_at opt_subalign
1088 { ldlex_popstate (); ldlex_script (); }
1089 '{'
1090 {
1091 lang_enter_overlay ($3, $6);
1092 }
1093 overlay_section
1094 '}'
1095 { ldlex_popstate (); ldlex_expression (); }
1096 memspec_opt memspec_at_opt phdr_opt fill_opt
1097 {
1098 if (yychar == NAME)
1099 {
1100 yyclearin;
1101 ldlex_backup ();
1102 }
1103 ldlex_popstate ();
1104 lang_leave_overlay ($5, (int) $4,
1105 $16, $13, $15, $14);
1106 }
1107 opt_comma
1108 | /* The GROUP case is just enough to support the gcc
1109 svr3.ifile script. It is not intended to be full
1110 support. I'm not even sure what GROUP is supposed
1111 to mean. */
1112 GROUP { ldlex_expression (); }
1113 opt_exp_with_type
1114 {
1115 ldlex_popstate ();
1116 lang_add_assignment (exp_assign (".", $3, false));
1117 }
1118 '{' sec_or_group_p1 '}'
1119 | INCLUDE filename
1120 { ldlex_script (); ldfile_open_command_file($2); }
1121 sec_or_group_p1 END
1122 { ldlex_popstate (); }
1123 ;
1124
1125type:
1126 NOLOAD { sectype = noload_section; }
1127 | DSECT { sectype = noalloc_section; }
1128 | COPY { sectype = noalloc_section; }
1129 | INFO { sectype = noalloc_section; }
1130 | OVERLAY { sectype = noalloc_section; }
1131 | READONLY { sectype = readonly_section; }
1132 ;
1133
1134atype:
1135 '(' type ')'
1136 | /* EMPTY */ { sectype = normal_section; }
1137 | '(' ')' { sectype = normal_section; }
1138 ;
1139
1140opt_exp_with_type:
1141 exp atype ':' { $$ = $1; }
1142 | atype ':' { $$ = (etree_type *)NULL; }
1143 | /* The BIND cases are to support the gcc svr3.ifile
1144 script. They aren't intended to implement full
1145 support for the BIND keyword. I'm not even sure
1146 what BIND is supposed to mean. */
1147 BIND '(' exp ')' atype ':' { $$ = $3; }
1148 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
1149 { $$ = $3; }
1150 ;
1151
1152opt_exp_without_type:
1153 exp ':' { $$ = $1; }
1154 | ':' { $$ = (etree_type *) NULL; }
1155 ;
1156
1157opt_nocrossrefs:
1158 /* empty */
1159 { $$ = 0; }
1160 | NOCROSSREFS
1161 { $$ = 1; }
1162 ;
1163
1164memspec_opt:
1165 '>' NAME
1166 { $$ = $2; }
1167 | { $$ = DEFAULT_MEMORY_REGION; }
1168 ;
1169
1170phdr_opt:
1171 /* empty */
1172 {
1173 $$ = NULL;
1174 }
1175 | phdr_opt ':' NAME
1176 {
1177 struct lang_output_section_phdr_list *n;
1178
1179 n = ((struct lang_output_section_phdr_list *)
1180 xmalloc (sizeof *n));
1181 n->name = $3;
1182 n->used = false;
1183 n->next = $1;
1184 $$ = n;
1185 }
1186 ;
1187
1188overlay_section:
1189 /* empty */
1190 | overlay_section
1191 NAME
1192 {
1193 lang_enter_overlay_section ($2);
1194 }
1195 '{' statement_list_opt '}'
1196 { ldlex_expression (); }
1197 phdr_opt fill_opt
1198 {
1199 if (yychar == NAME)
1200 {
1201 yyclearin;
1202 ldlex_backup ();
1203 }
1204 ldlex_popstate ();
1205 lang_leave_overlay_section ($9, $8);
1206 }
1207 opt_comma
1208 ;
1209
1210phdrs:
1211 PHDRS '{' phdr_list '}'
1212 ;
1213
1214phdr_list:
1215 /* empty */
1216 | phdr_list phdr
1217 ;
1218
1219phdr:
1220 NAME { ldlex_expression (); }
1221 phdr_type phdr_qualifiers { ldlex_popstate (); }
1222 ';'
1223 {
1224 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
1225 $4.flags);
1226 }
1227 ;
1228
1229phdr_type:
1230 exp
1231 {
1232 $$ = $1;
1233
1234 if ($1->type.node_class == etree_name
1235 && $1->type.node_code == NAME)
1236 {
1237 const char *s;
1238 unsigned int i;
1239 static const char * const phdr_types[] =
1240 {
1241 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
1242 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
1243 "PT_PHDR", "PT_TLS"
1244 };
1245
1246 s = $1->name.name;
1247 for (i = 0;
1248 i < sizeof phdr_types / sizeof phdr_types[0];
1249 i++)
1250 if (strcmp (s, phdr_types[i]) == 0)
1251 {
1252 $$ = exp_intop (i);
1253 break;
1254 }
1255 if (i == sizeof phdr_types / sizeof phdr_types[0])
1256 {
1257 if (strcmp (s, "PT_GNU_EH_FRAME") == 0)
1258 $$ = exp_intop (0x6474e550);
1259 else if (strcmp (s, "PT_GNU_STACK") == 0)
1260 $$ = exp_intop (0x6474e551);
1261 else
1262 {
1263 einfo (_("\
1264%X%P:%pS: unknown phdr type `%s' (try integer literal)\n"),
1265 NULL, s);
1266 $$ = exp_intop (0);
1267 }
1268 }
1269 }
1270 }
1271 ;
1272
1273phdr_qualifiers:
1274 /* empty */
1275 {
1276 memset (&$$, 0, sizeof (struct phdr_info));
1277 }
1278 | NAME phdr_val phdr_qualifiers
1279 {
1280 $$ = $3;
1281 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
1282 $$.filehdr = true;
1283 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
1284 $$.phdrs = true;
1285 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
1286 $$.flags = $2;
1287 else
1288 einfo (_("%X%P:%pS: PHDRS syntax error at `%s'\n"),
1289 NULL, $1);
1290 }
1291 | AT '(' exp ')' phdr_qualifiers
1292 {
1293 $$ = $5;
1294 $$.at = $3;
1295 }
1296 ;
1297
1298phdr_val:
1299 /* empty */
1300 {
1301 $$ = NULL;
1302 }
1303 | '(' exp ')'
1304 {
1305 $$ = $2;
1306 }
1307 ;
1308
1309dynamic_list_file:
1310 {
1311 ldlex_version_file ();
1312 PUSH_ERROR (_("dynamic list"));
1313 }
1314 dynamic_list_nodes
1315 {
1316 ldlex_popstate ();
1317 POP_ERROR ();
1318 }
1319 ;
1320
1321dynamic_list_nodes:
1322 dynamic_list_node
1323 | dynamic_list_nodes dynamic_list_node
1324 ;
1325
1326dynamic_list_node:
1327 '{' dynamic_list_tag '}' ';'
1328 ;
1329
1330dynamic_list_tag:
1331 vers_defns ';'
1332 {
1333 lang_append_dynamic_list (current_dynamic_list_p, $1);
1334 }
1335 ;
1336
1337/* This syntax is used within an external version script file. */
1338
1339version_script_file:
1340 {
1341 ldlex_version_file ();
1342 PUSH_ERROR (_("VERSION script"));
1343 }
1344 vers_nodes
1345 {
1346 ldlex_popstate ();
1347 POP_ERROR ();
1348 }
1349 ;
1350
1351/* This is used within a normal linker script file. */
1352
1353version:
1354 {
1355 ldlex_version_script ();
1356 }
1357 VERSIONK '{' vers_nodes '}'
1358 {
1359 ldlex_popstate ();
1360 }
1361 ;
1362
1363vers_nodes:
1364 vers_node
1365 | vers_nodes vers_node
1366 ;
1367
1368vers_node:
1369 '{' vers_tag '}' ';'
1370 {
1371 lang_register_vers_node (NULL, $2, NULL);
1372 }
1373 | VERS_TAG '{' vers_tag '}' ';'
1374 {
1375 lang_register_vers_node ($1, $3, NULL);
1376 }
1377 | VERS_TAG '{' vers_tag '}' verdep ';'
1378 {
1379 lang_register_vers_node ($1, $3, $5);
1380 }
1381 ;
1382
1383verdep:
1384 VERS_TAG
1385 {
1386 $$ = lang_add_vers_depend (NULL, $1);
1387 }
1388 | verdep VERS_TAG
1389 {
1390 $$ = lang_add_vers_depend ($1, $2);
1391 }
1392 ;
1393
1394vers_tag:
1395 /* empty */
1396 {
1397 $$ = lang_new_vers_node (NULL, NULL);
1398 }
1399 | vers_defns ';'
1400 {
1401 $$ = lang_new_vers_node ($1, NULL);
1402 }
1403 | GLOBAL ':' vers_defns ';'
1404 {
1405 $$ = lang_new_vers_node ($3, NULL);
1406 }
1407 | LOCAL ':' vers_defns ';'
1408 {
1409 $$ = lang_new_vers_node (NULL, $3);
1410 }
1411 | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
1412 {
1413 $$ = lang_new_vers_node ($3, $7);
1414 }
1415 ;
1416
1417vers_defns:
1418 VERS_IDENTIFIER
1419 {
1420 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, false);
1421 }
1422 | NAME
1423 {
1424 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, true);
1425 }
1426 | vers_defns ';' VERS_IDENTIFIER
1427 {
1428 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, false);
1429 }
1430 | vers_defns ';' NAME
1431 {
1432 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, true);
1433 }
1434 | vers_defns ';' EXTERN NAME '{'
1435 {
1436 $<name>$ = ldgram_vers_current_lang;
1437 ldgram_vers_current_lang = $4;
1438 }
1439 vers_defns opt_semicolon '}'
1440 {
1441 struct bfd_elf_version_expr *pat;
1442 for (pat = $7; pat->next != NULL; pat = pat->next);
1443 pat->next = $1;
1444 $$ = $7;
1445 ldgram_vers_current_lang = $<name>6;
1446 }
1447 | EXTERN NAME '{'
1448 {
1449 $<name>$ = ldgram_vers_current_lang;
1450 ldgram_vers_current_lang = $2;
1451 }
1452 vers_defns opt_semicolon '}'
1453 {
1454 $$ = $5;
1455 ldgram_vers_current_lang = $<name>4;
1456 }
1457 | GLOBAL
1458 {
1459 $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang, false);
1460 }
1461 | vers_defns ';' GLOBAL
1462 {
1463 $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang, false);
1464 }
1465 | LOCAL
1466 {
1467 $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang, false);
1468 }
1469 | vers_defns ';' LOCAL
1470 {
1471 $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang, false);
1472 }
1473 | EXTERN
1474 {
1475 $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang, false);
1476 }
1477 | vers_defns ';' EXTERN
1478 {
1479 $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, false);
1480 }
1481 ;
1482
1483opt_semicolon:
1484 /* empty */
1485 | ';'
1486 ;
1487
1488%%
1489void
1490yyerror(arg)
1491 const char *arg;
1492{
1493 if (ldfile_assumed_script)
1494 einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
1495 ldlex_filename ());
1496 if (error_index > 0 && error_index < ERROR_NAME_MAX)
1497 einfo ("%F%P:%pS: %s in %s\n", NULL, arg, error_names[error_index - 1]);
1498 else
1499 einfo ("%F%P:%pS: %s\n", NULL, arg);
1500}