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