Initial revision
[binutils.git] / ld / ldgram.y
bloba1f3ed60c225023a619cce4de2c76abfb42cac33
1 /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
2 Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
3 Free Software Foundation, Inc.
4 Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
6 This file is part of GNU ld.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 #define DONTDECLARE_MALLOC
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"
44 #ifndef YYDEBUG
45 #define YYDEBUG 1
46 #endif
48 static enum section_type sectype;
50 lang_memory_region_type *region;
52 struct wildcard_spec current_file;
53 boolean ldgram_want_filename = true;
54 boolean had_script = false;
55 boolean force_make_executable = false;
57 boolean ldgram_in_script = false;
58 boolean ldgram_had_equals = false;
59 boolean ldgram_had_keep = false;
60 char *ldgram_vers_current_lang = NULL;
62 #define ERROR_NAME_MAX 20
63 static char *error_names[ERROR_NAME_MAX];
64 static 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--;
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
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;
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
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
114 %left <token> '+' '-'
115 %left <token> '*' '/' '%'
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
135 %type <token> assign_op atype
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
150 file:
151 INPUT_SCRIPT script_file
152 | INPUT_MRI_SCRIPT mri_script_file
153 | INPUT_VERSION_SCRIPT version_script_file
154 | INPUT_DEFSYM defsym_expr
158 filename: NAME;
161 defsym_expr:
162 { ldlex_defsym(); }
163 NAME '=' exp
165 ldlex_popstate();
166 lang_add_assignment(exp_assop($3,$2,$4));
169 /* SYNTAX WITHIN AN MRI SCRIPT FILE */
170 mri_script_file:
172 ldlex_mri_script ();
173 PUSH_ERROR (_("MRI style script"));
175 mri_script_lines
177 ldlex_popstate ();
178 mri_draw_tree ();
179 POP_ERROR ();
183 mri_script_lines:
184 mri_script_lines mri_script_command NEWLINE
188 mri_script_command:
189 CHIP exp
190 | CHIP exp ',' exp
191 | NAME {
192 einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
194 | LIST {
195 config.map_filename = "-";
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); }
242 ordernamelist:
243 ordernamelist ',' NAME { mri_order($3); }
244 | ordernamelist NAME { mri_order($2); }
248 mri_load_name_list:
249 NAME
250 { mri_load($1); }
251 | mri_load_name_list ',' NAME { mri_load($3); }
254 mri_abs_name_list:
255 NAME
256 { mri_only_load($1); }
257 | mri_abs_name_list ',' NAME
258 { mri_only_load($3); }
261 casesymlist:
262 /* empty */ { $$ = NULL; }
263 | NAME
264 | casesymlist ',' NAME
267 extern_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); }
276 script_file:
278 ldlex_both();
280 ifile_list
282 ldlex_popstate();
287 ifile_list:
288 ifile_list ifile_p1
294 ifile_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 ')'
331 lang_add_nocrossref ($3);
333 | EXTERN '(' extern_name_list ')'
336 input_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); }
357 sections:
358 SECTIONS '{' sec_or_group_p1 '}'
361 sec_or_group_p1:
362 sec_or_group_p1 section
363 | sec_or_group_p1 statement_anywhere
367 statement_anywhere:
368 ENTRY '(' NAME ')'
369 { lang_add_entry ($3, false); }
370 | assignment end
373 /* The '*' and '?' cases are there because the lexer returns them as
374 separate tokens rather than as NAME. */
375 wildcard_name:
376 NAME
378 $$ = $1;
380 | '*'
382 $$ = "*";
384 | '?'
386 $$ = "?";
390 wildcard_spec:
391 wildcard_name
393 $$.name = $1;
394 $$.sorted = false;
395 $$.exclude_name = NULL;
397 | EXCLUDE_FILE '(' wildcard_name ')' wildcard_name
399 $$.name = $5;
400 $$.sorted = false;
401 $$.exclude_name = $3;
403 | SORT '(' wildcard_name ')'
405 $$.name = $3;
406 $$.sorted = true;
407 $$.exclude_name = NULL;
409 | SORT '(' EXCLUDE_FILE '(' wildcard_name ')' wildcard_name ')'
411 $$.name = $7;
412 $$.sorted = true;
413 $$.exclude_name = $5;
418 file_NAME_list:
419 wildcard_spec
421 lang_add_wild ($1.name, $1.sorted,
422 current_file.name,
423 current_file.sorted,
424 ldgram_had_keep, $1.exclude_name);
426 | file_NAME_list opt_comma wildcard_spec
428 lang_add_wild ($3.name, $3.sorted,
429 current_file.name,
430 current_file.sorted,
431 ldgram_had_keep, $3.exclude_name);
435 input_section_spec_no_keep:
436 NAME
438 lang_add_wild (NULL, false, $1, false,
439 ldgram_had_keep, NULL);
441 | '['
443 current_file.name = NULL;
444 current_file.sorted = false;
446 file_NAME_list ']'
447 | wildcard_spec
449 current_file = $1;
450 /* '*' matches any file name. */
451 if (strcmp (current_file.name, "*") == 0)
452 current_file.name = NULL;
454 '(' file_NAME_list ')'
457 input_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; }
465 statement:
466 assignment end
467 | CREATE_OBJECT_SYMBOLS
469 lang_add_attribute(lang_object_symbols_statement_enum);
471 | ';'
472 | CONSTRUCTORS
475 lang_add_attribute(lang_constructors_statement_enum);
477 | SORT '(' CONSTRUCTORS ')'
479 constructors_sorted = true;
480 lang_add_attribute (lang_constructors_statement_enum);
482 | input_section_spec
483 | length '(' mustbe_exp ')'
485 lang_add_data((int) $1,$3);
488 | FILL '(' mustbe_exp ')'
490 lang_add_fill
491 (exp_get_value_int($3,
493 "fill value",
494 lang_first_phase_enum));
498 statement_list:
499 statement_list statement
500 | statement
503 statement_list_opt:
504 /* empty */
505 | statement_list
508 length:
509 QUAD
510 { $$ = $1; }
511 | SQUAD
512 { $$ = $1; }
513 | LONG
514 { $$ = $1; }
515 | SHORT
516 { $$ = $1; }
517 | BYTE
518 { $$ = $1; }
521 fill_opt:
522 '=' mustbe_exp
524 $$ = exp_get_value_int($2,
526 "fill value",
527 lang_first_phase_enum);
529 | { $$ = 0; }
534 assign_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 { $$ = '|'; }
554 end: ';' | ','
558 assignment:
559 NAME '=' mustbe_exp
561 lang_add_assignment (exp_assop ($2, $1, $3));
563 | NAME assign_op mustbe_exp
565 lang_add_assignment (exp_assop ('=', $1,
566 exp_binop ($2,
567 exp_nameop (NAME,
568 $1),
569 $3)));
571 | PROVIDE '(' NAME '=' mustbe_exp ')'
573 lang_add_assignment (exp_provide ($3, $5));
578 opt_comma:
579 ',' | ;
582 memory:
583 MEMORY '{' memory_spec memory_spec_list '}'
586 memory_spec_list:
587 memory_spec_list memory_spec
588 | memory_spec_list ',' memory_spec
593 memory_spec: NAME
594 { region = lang_memory_region_lookup($1); }
595 attributes_opt ':'
596 origin_spec opt_comma length_spec
598 ; origin_spec:
599 ORIGIN '=' mustbe_exp
600 { region->current =
601 region->origin =
602 exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
606 length_spec:
607 LENGTH '=' mustbe_exp
608 { region->length = exp_get_vma($3,
609 ~((bfd_vma)0),
610 "length",
611 lang_first_phase_enum);
615 attributes_opt:
616 '(' NAME ')'
618 lang_set_flags(region, $2);
624 startup:
625 STARTUP '(' filename ')'
626 { lang_startup($3); }
629 high_level_library:
630 HLL '(' high_level_library_NAME_list ')'
631 | HLL '(' ')'
632 { ldemul_hll((char *)NULL); }
635 high_level_library_NAME_list:
636 high_level_library_NAME_list opt_comma filename
637 { ldemul_hll($3); }
638 | filename
639 { ldemul_hll($1); }
643 low_level_library:
644 SYSLIB '(' low_level_library_NAME_list ')'
645 ; low_level_library_NAME_list:
646 low_level_library_NAME_list opt_comma filename
647 { ldemul_syslib($3); }
651 floating_point_support:
652 FLOAT
653 { lang_float(true); }
654 | NOFLOAT
655 { lang_float(false); }
658 nocrossref_list:
659 /* empty */
661 $$ = NULL;
663 | NAME nocrossref_list
665 struct lang_nocrossref *n;
667 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
668 n->name = $1;
669 n->next = $2;
670 $$ = n;
672 | NAME ',' nocrossref_list
674 struct lang_nocrossref *n;
676 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
677 n->name = $1;
678 n->next = $3;
679 $$ = n;
683 mustbe_exp: { ldlex_expression(); }
685 { ldlex_popstate(); $$=$2;}
688 exp :
689 '-' exp %prec UNARY
690 { $$ = exp_unop('-', $2); }
691 | '(' exp ')'
692 { $$ = $2; }
693 | NEXT '(' exp ')' %prec UNARY
694 { $$ = exp_unop((int) $1,$3); }
695 | '!' exp %prec UNARY
696 { $$ = exp_unop('!', $2); }
697 | '+' exp %prec UNARY
698 { $$ = $2; }
699 | '~' exp %prec UNARY
700 { $$ = exp_unop('~', $2);}
702 | exp '*' exp
703 { $$ = exp_binop('*', $1, $3); }
704 | exp '/' exp
705 { $$ = exp_binop('/', $1, $3); }
706 | exp '%' exp
707 { $$ = exp_binop('%', $1, $3); }
708 | exp '+' exp
709 { $$ = exp_binop('+', $1, $3); }
710 | exp '-' exp
711 { $$ = exp_binop('-' , $1, $3); }
712 | exp LSHIFT exp
713 { $$ = exp_binop(LSHIFT , $1, $3); }
714 | exp RSHIFT exp
715 { $$ = exp_binop(RSHIFT , $1, $3); }
716 | exp EQ exp
717 { $$ = exp_binop(EQ , $1, $3); }
718 | exp NE exp
719 { $$ = exp_binop(NE , $1, $3); }
720 | exp LE exp
721 { $$ = exp_binop(LE , $1, $3); }
722 | exp GE exp
723 { $$ = exp_binop(GE , $1, $3); }
724 | exp '<' exp
725 { $$ = exp_binop('<' , $1, $3); }
726 | exp '>' exp
727 { $$ = exp_binop('>' , $1, $3); }
728 | exp '&' exp
729 { $$ = exp_binop('&' , $1, $3); }
730 | exp '^' exp
731 { $$ = exp_binop('^' , $1, $3); }
732 | exp '|' exp
733 { $$ = exp_binop('|' , $1, $3); }
734 | exp '?' exp ':' exp
735 { $$ = exp_trinop('?' , $1, $3, $5); }
736 | exp ANDAND exp
737 { $$ = exp_binop(ANDAND , $1, $3); }
738 | exp OROR exp
739 { $$ = exp_binop(OROR , $1, $3); }
740 | DEFINED '(' NAME ')'
741 { $$ = exp_nameop(DEFINED, $3); }
742 | INT
743 { $$ = exp_intop($1); }
744 | SIZEOF_HEADERS
745 { $$ = exp_nameop(SIZEOF_HEADERS,0); }
747 | SIZEOF '(' NAME ')'
748 { $$ = exp_nameop(SIZEOF,$3); }
749 | ADDR '(' NAME ')'
750 { $$ = exp_nameop(ADDR,$3); }
751 | LOADADDR '(' NAME ')'
752 { $$ = exp_nameop(LOADADDR,$3); }
753 | ABSOLUTE '(' exp ')'
754 { $$ = exp_unop(ABSOLUTE, $3); }
755 | ALIGN_K '(' exp ')'
756 { $$ = exp_unop(ALIGN_K,$3); }
757 | BLOCK '(' exp ')'
758 { $$ = exp_unop(ALIGN_K,$3); }
759 | NAME
760 { $$ = exp_nameop(NAME,$1); }
761 | MAX_K '(' exp ',' exp ')'
762 { $$ = exp_binop (MAX_K, $3, $5 ); }
763 | MIN_K '(' exp ',' exp ')'
764 { $$ = exp_binop (MIN_K, $3, $5 ); }
765 | ASSERT_K '(' exp ',' NAME ')'
766 { $$ = exp_assert ($3, $5); }
770 opt_at:
771 AT '(' exp ')' { $$ = $3; }
772 | { $$ = 0; }
775 section: NAME { ldlex_expression(); }
776 opt_exp_with_type
777 opt_at { ldlex_popstate (); ldlex_script (); }
780 lang_enter_output_section_statement($1, $3,
781 sectype,
782 0, 0, 0, $4);
784 statement_list_opt
785 '}' { ldlex_popstate (); ldlex_expression (); }
786 memspec_opt phdr_opt fill_opt
788 ldlex_popstate ();
789 lang_leave_output_section_statement ($13, $11, $12);
791 opt_comma
792 | OVERLAY
793 { ldlex_expression (); }
794 opt_exp_without_type opt_nocrossrefs opt_at
795 { ldlex_popstate (); ldlex_script (); }
796 '{'
798 lang_enter_overlay ($3, $5, (int) $4);
800 overlay_section
802 { ldlex_popstate (); ldlex_expression (); }
803 memspec_opt phdr_opt fill_opt
805 ldlex_popstate ();
806 lang_leave_overlay ($14, $12, $13);
808 opt_comma
809 | /* The GROUP case is just enough to support the gcc
810 svr3.ifile script. It is not intended to be full
811 support. I'm not even sure what GROUP is supposed
812 to mean. */
813 GROUP { ldlex_expression (); }
814 opt_exp_with_type
816 ldlex_popstate ();
817 lang_add_assignment (exp_assop ('=', ".", $3));
819 '{' sec_or_group_p1 '}'
822 type:
823 NOLOAD { sectype = noload_section; }
824 | DSECT { sectype = dsect_section; }
825 | COPY { sectype = copy_section; }
826 | INFO { sectype = info_section; }
827 | OVERLAY { sectype = overlay_section; }
830 atype:
831 '(' type ')'
832 | /* EMPTY */ { sectype = normal_section; }
833 | '(' ')' { sectype = normal_section; }
836 opt_exp_with_type:
837 exp atype ':' { $$ = $1; }
838 | atype ':' { $$ = (etree_type *)NULL; }
839 | /* The BIND cases are to support the gcc svr3.ifile
840 script. They aren't intended to implement full
841 support for the BIND keyword. I'm not even sure
842 what BIND is supposed to mean. */
843 BIND '(' exp ')' atype ':' { $$ = $3; }
844 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
845 { $$ = $3; }
848 opt_exp_without_type:
849 exp ':' { $$ = $1; }
850 | ':' { $$ = (etree_type *) NULL; }
853 opt_nocrossrefs:
854 /* empty */
855 { $$ = 0; }
856 | NOCROSSREFS
857 { $$ = 1; }
860 memspec_opt:
861 '>' NAME
862 { $$ = $2; }
863 | { $$ = "*default*"; }
866 phdr_opt:
867 /* empty */
869 $$ = NULL;
871 | phdr_opt ':' NAME
873 struct lang_output_section_phdr_list *n;
875 n = ((struct lang_output_section_phdr_list *)
876 xmalloc (sizeof *n));
877 n->name = $3;
878 n->used = false;
879 n->next = $1;
880 $$ = n;
884 overlay_section:
885 /* empty */
886 | overlay_section
887 NAME
889 ldlex_script ();
890 lang_enter_overlay_section ($2);
892 '{' statement_list_opt '}'
893 { ldlex_popstate (); ldlex_expression (); }
894 phdr_opt fill_opt
896 ldlex_popstate ();
897 lang_leave_overlay_section ($9, $8);
899 opt_comma
902 phdrs:
903 PHDRS '{' phdr_list '}'
906 phdr_list:
907 /* empty */
908 | phdr_list phdr
911 phdr:
912 NAME { ldlex_expression (); }
913 phdr_type phdr_qualifiers { ldlex_popstate (); }
916 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
917 $4.flags);
921 phdr_type:
924 $$ = $1;
926 if ($1->type.node_class == etree_name
927 && $1->type.node_code == NAME)
929 const char *s;
930 unsigned int i;
931 static const char * const phdr_types[] =
933 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
934 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
935 "PT_PHDR"
938 s = $1->name.name;
939 for (i = 0;
940 i < sizeof phdr_types / sizeof phdr_types[0];
941 i++)
942 if (strcmp (s, phdr_types[i]) == 0)
944 $$ = exp_intop (i);
945 break;
951 phdr_qualifiers:
952 /* empty */
954 memset (&$$, 0, sizeof (struct phdr_info));
956 | NAME phdr_val phdr_qualifiers
958 $$ = $3;
959 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
960 $$.filehdr = true;
961 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
962 $$.phdrs = true;
963 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
964 $$.flags = $2;
965 else
966 einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
968 | AT '(' exp ')' phdr_qualifiers
970 $$ = $5;
971 $$.at = $3;
975 phdr_val:
976 /* empty */
978 $$ = NULL;
980 | '(' exp ')'
982 $$ = $2;
986 /* This syntax is used within an external version script file. */
988 version_script_file:
990 ldlex_version_file ();
991 PUSH_ERROR (_("VERSION script"));
993 vers_nodes
995 ldlex_popstate ();
996 POP_ERROR ();
1000 /* This is used within a normal linker script file. */
1002 version:
1004 ldlex_version_script ();
1006 VERSIONK '{' vers_nodes '}'
1008 ldlex_popstate ();
1012 vers_nodes:
1013 vers_node
1014 | vers_nodes vers_node
1017 vers_node:
1018 VERS_TAG '{' vers_tag '}' ';'
1020 lang_register_vers_node ($1, $3, NULL);
1022 | VERS_TAG '{' vers_tag '}' verdep ';'
1024 lang_register_vers_node ($1, $3, $5);
1028 verdep:
1029 VERS_TAG
1031 $$ = lang_add_vers_depend (NULL, $1);
1033 | verdep VERS_TAG
1035 $$ = lang_add_vers_depend ($1, $2);
1039 vers_tag:
1040 /* empty */
1042 $$ = lang_new_vers_node (NULL, NULL);
1044 | vers_defns ';'
1046 $$ = lang_new_vers_node ($1, NULL);
1048 | GLOBAL ':' vers_defns ';'
1050 $$ = lang_new_vers_node ($3, NULL);
1052 | LOCAL ':' vers_defns ';'
1054 $$ = lang_new_vers_node (NULL, $3);
1056 | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
1058 $$ = lang_new_vers_node ($3, $7);
1062 vers_defns:
1063 VERS_IDENTIFIER
1065 $$ = lang_new_vers_regex (NULL, $1, ldgram_vers_current_lang);
1067 | vers_defns ';' VERS_IDENTIFIER
1069 $$ = lang_new_vers_regex ($1, $3, ldgram_vers_current_lang);
1071 | EXTERN NAME '{'
1073 $<name>$ = ldgram_vers_current_lang;
1074 ldgram_vers_current_lang = $2;
1076 vers_defns '}'
1078 ldgram_vers_current_lang = $<name>4;
1083 void
1084 yyerror(arg)
1085 const char *arg;
1087 if (ldfile_assumed_script)
1088 einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
1089 ldfile_input_filename);
1090 if (error_index > 0 && error_index < ERROR_NAME_MAX)
1091 einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
1092 else
1093 einfo ("%P%F:%S: %s\n", arg);