* sun build fix for thinko (?)
[binutils-gdb.git] / ld / ldgram.y
blob28fe57378731c5ae894466d5d7fd17ce39a4878d
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 "ldlex.h"
43 #ifndef YYDEBUG
44 #define YYDEBUG 1
45 #endif
47 static enum section_type sectype;
49 lang_memory_region_type *region;
51 struct wildcard_spec current_file;
52 boolean ldgram_want_filename = true;
53 boolean had_script = false;
54 boolean force_make_executable = false;
56 boolean ldgram_in_script = false;
57 boolean ldgram_had_equals = false;
58 boolean ldgram_had_keep = false;
60 #define ERROR_NAME_MAX 20
61 static char *error_names[ERROR_NAME_MAX];
62 static int error_index;
63 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
64 #define POP_ERROR() error_index--;
66 %union {
67 bfd_vma integer;
68 char *name;
69 const char *cname;
70 struct wildcard_spec wildcard;
71 int token;
72 union etree_union *etree;
73 struct phdr_info
75 boolean filehdr;
76 boolean phdrs;
77 union etree_union *at;
78 union etree_union *flags;
79 } phdr;
80 struct lang_nocrossref *nocrossref;
81 struct lang_output_section_phdr_list *section_phdr;
82 struct bfd_elf_version_deps *deflist;
83 struct bfd_elf_version_expr *versyms;
84 struct bfd_elf_version_tree *versnode;
87 %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
88 %type <etree> opt_exp_without_type
89 %type <integer> fill_opt
90 %type <name> memspec_opt casesymlist
91 %type <cname> wildcard_name
92 %type <wildcard> wildcard_spec
93 %token <integer> INT
94 %token <name> NAME LNAME
95 %type <integer> length
96 %type <phdr> phdr_qualifiers
97 %type <nocrossref> nocrossref_list
98 %type <section_phdr> phdr_opt
99 %type <integer> opt_nocrossrefs
101 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
102 %right <token> '?' ':'
103 %left <token> OROR
104 %left <token> ANDAND
105 %left <token> '|'
106 %left <token> '^'
107 %left <token> '&'
108 %left <token> EQ NE
109 %left <token> '<' '>' LE GE
110 %left <token> LSHIFT RSHIFT
112 %left <token> '+' '-'
113 %left <token> '*' '/' '%'
115 %right UNARY
116 %token END
117 %left <token> '('
118 %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
119 %token SECTIONS PHDRS SORT
120 %token '{' '}'
121 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
122 %token SIZEOF_HEADERS
123 %token INCLUDE
124 %token MEMORY DEFSYMEND
125 %token NOLOAD DSECT COPY INFO OVERLAY
126 %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
127 %token <integer> NEXT
128 %token SIZEOF ADDR LOADADDR MAX_K MIN_K
129 %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
130 %token ORIGIN FILL
131 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
132 %token ALIGNMOD AT PROVIDE
133 %type <token> assign_op atype
134 %type <name> filename
135 %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD
136 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
137 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
138 %token <name> VERS_TAG VERS_IDENTIFIER
139 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
140 %token KEEP
141 %type <versyms> vers_defns
142 %type <versnode> vers_tag
143 %type <deflist> verdep
147 file:
148 INPUT_SCRIPT script_file
149 | INPUT_MRI_SCRIPT mri_script_file
150 | INPUT_VERSION_SCRIPT version_script_file
151 | INPUT_DEFSYM defsym_expr
155 filename: NAME;
158 defsym_expr:
159 { ldlex_defsym(); }
160 NAME '=' exp
162 ldlex_popstate();
163 lang_add_assignment(exp_assop($3,$2,$4));
166 /* SYNTAX WITHIN AN MRI SCRIPT FILE */
167 mri_script_file:
169 ldlex_mri_script ();
170 PUSH_ERROR (_("MRI style script"));
172 mri_script_lines
174 ldlex_popstate ();
175 mri_draw_tree ();
176 POP_ERROR ();
180 mri_script_lines:
181 mri_script_lines mri_script_command NEWLINE
185 mri_script_command:
186 CHIP exp
187 | CHIP exp ',' exp
188 | NAME {
189 einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
191 | LIST {
192 config.map_filename = "-";
194 | ORDER ordernamelist
195 | ENDWORD
196 | PUBLIC NAME '=' exp
197 { mri_public($2, $4); }
198 | PUBLIC NAME ',' exp
199 { mri_public($2, $4); }
200 | PUBLIC NAME exp
201 { mri_public($2, $3); }
202 | FORMAT NAME
203 { mri_format($2); }
204 | SECT NAME ',' exp
205 { mri_output_section($2, $4);}
206 | SECT NAME exp
207 { mri_output_section($2, $3);}
208 | SECT NAME '=' exp
209 { mri_output_section($2, $4);}
210 | ALIGN_K NAME '=' exp
211 { mri_align($2,$4); }
212 | ALIGN_K NAME ',' exp
213 { mri_align($2,$4); }
214 | ALIGNMOD NAME '=' exp
215 { mri_alignmod($2,$4); }
216 | ALIGNMOD NAME ',' exp
217 { mri_alignmod($2,$4); }
218 | ABSOLUTE mri_abs_name_list
219 | LOAD mri_load_name_list
220 | NAMEWORD NAME
221 { mri_name($2); }
222 | ALIAS NAME ',' NAME
223 { mri_alias($2,$4,0);}
224 | ALIAS NAME ',' INT
225 { mri_alias($2,0,(int) $4);}
226 | BASE exp
227 { mri_base($2); }
228 | TRUNCATE INT
229 { mri_truncate((unsigned int) $2); }
230 | CASE casesymlist
231 | EXTERN extern_name_list
232 | INCLUDE filename
233 { ldfile_open_command_file ($2); } mri_script_lines END
234 | START NAME
235 { lang_add_entry ($2, false); }
239 ordernamelist:
240 ordernamelist ',' NAME { mri_order($3); }
241 | ordernamelist NAME { mri_order($2); }
245 mri_load_name_list:
246 NAME
247 { mri_load($1); }
248 | mri_load_name_list ',' NAME { mri_load($3); }
251 mri_abs_name_list:
252 NAME
253 { mri_only_load($1); }
254 | mri_abs_name_list ',' NAME
255 { mri_only_load($3); }
258 casesymlist:
259 /* empty */ { $$ = NULL; }
260 | NAME
261 | casesymlist ',' NAME
264 extern_name_list:
265 NAME
266 { ldlang_add_undef ($1); }
267 | extern_name_list NAME
268 { ldlang_add_undef ($2); }
269 | extern_name_list ',' NAME
270 { ldlang_add_undef ($3); }
273 script_file:
275 ldlex_both();
277 ifile_list
279 ldlex_popstate();
284 ifile_list:
285 ifile_list ifile_p1
291 ifile_p1:
292 memory
293 | sections
294 | phdrs
295 | startup
296 | high_level_library
297 | low_level_library
298 | floating_point_support
299 | statement_anywhere
300 | version
301 | ';'
302 | TARGET_K '(' NAME ')'
303 { lang_add_target($3); }
304 | SEARCH_DIR '(' filename ')'
305 { ldfile_add_library_path ($3, false); }
306 | OUTPUT '(' filename ')'
307 { lang_add_output($3, 1); }
308 | OUTPUT_FORMAT '(' NAME ')'
309 { lang_add_output_format ($3, (char *) NULL,
310 (char *) NULL, 1); }
311 | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
312 { lang_add_output_format ($3, $5, $7, 1); }
313 | OUTPUT_ARCH '(' NAME ')'
314 { ldfile_set_output_arch($3); }
315 | FORCE_COMMON_ALLOCATION
316 { command_line.force_common_definition = true ; }
317 | INPUT '(' input_list ')'
318 | GROUP
319 { lang_enter_group (); }
320 '(' input_list ')'
321 { lang_leave_group (); }
322 | MAP '(' filename ')'
323 { lang_add_map($3); }
324 | INCLUDE filename
325 { ldfile_open_command_file($2); } ifile_list END
326 | NOCROSSREFS '(' nocrossref_list ')'
328 lang_add_nocrossref ($3);
330 | EXTERN '(' extern_name_list ')'
333 input_list:
334 NAME
335 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
336 (char *)NULL); }
337 | input_list ',' NAME
338 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
339 (char *)NULL); }
340 | input_list NAME
341 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
342 (char *)NULL); }
343 | LNAME
344 { lang_add_input_file($1,lang_input_file_is_l_enum,
345 (char *)NULL); }
346 | input_list ',' LNAME
347 { lang_add_input_file($3,lang_input_file_is_l_enum,
348 (char *)NULL); }
349 | input_list LNAME
350 { lang_add_input_file($2,lang_input_file_is_l_enum,
351 (char *)NULL); }
354 sections:
355 SECTIONS '{' sec_or_group_p1 '}'
358 sec_or_group_p1:
359 sec_or_group_p1 section
360 | sec_or_group_p1 statement_anywhere
364 statement_anywhere:
365 ENTRY '(' NAME ')'
366 { lang_add_entry ($3, false); }
367 | assignment end
370 /* The '*' and '?' cases are there because the lexer returns them as
371 separate tokens rather than as NAME. */
372 wildcard_name:
373 NAME
375 $$ = $1;
377 | '*'
379 $$ = "*";
381 | '?'
383 $$ = "?";
387 wildcard_spec:
388 wildcard_name
390 $$.name = $1;
391 $$.sorted = false;
393 | SORT '(' wildcard_name ')'
395 $$.name = $3;
396 $$.sorted = true;
400 file_NAME_list:
401 wildcard_spec
403 lang_add_wild ($1.name, $1.sorted,
404 current_file.name,
405 current_file.sorted,
406 ldgram_had_keep);
408 | file_NAME_list opt_comma wildcard_spec
410 lang_add_wild ($3.name, $3.sorted,
411 current_file.name,
412 current_file.sorted,
413 ldgram_had_keep);
417 input_section_spec_no_keep:
418 NAME
420 lang_add_wild (NULL, false, $1, false,
421 ldgram_had_keep);
423 | '['
425 current_file.name = NULL;
426 current_file.sorted = false;
428 file_NAME_list ']'
429 | wildcard_spec
431 current_file = $1;
432 /* '*' matches any file name. */
433 if (strcmp (current_file.name, "*") == 0)
434 current_file.name = NULL;
436 '(' file_NAME_list ')'
439 input_section_spec:
440 input_section_spec_no_keep
441 | KEEP '('
442 { ldgram_had_keep = true; }
443 input_section_spec_no_keep ')'
444 { ldgram_had_keep = false; }
447 statement:
448 assignment end
449 | CREATE_OBJECT_SYMBOLS
451 lang_add_attribute(lang_object_symbols_statement_enum);
453 | ';'
454 | CONSTRUCTORS
457 lang_add_attribute(lang_constructors_statement_enum);
459 | input_section_spec
460 | length '(' mustbe_exp ')'
462 lang_add_data((int) $1,$3);
465 | FILL '(' mustbe_exp ')'
467 lang_add_fill
468 (exp_get_value_int($3,
470 "fill value",
471 lang_first_phase_enum));
475 statement_list:
476 statement_list statement
477 | statement
480 statement_list_opt:
481 /* empty */
482 | statement_list
485 length:
486 QUAD
487 { $$ = $1; }
488 | SQUAD
489 { $$ = $1; }
490 | LONG
491 { $$ = $1; }
492 | SHORT
493 { $$ = $1; }
494 | BYTE
495 { $$ = $1; }
498 fill_opt:
499 '=' mustbe_exp
501 $$ = exp_get_value_int($2,
503 "fill value",
504 lang_first_phase_enum);
506 | { $$ = 0; }
511 assign_op:
512 PLUSEQ
513 { $$ = '+'; }
514 | MINUSEQ
515 { $$ = '-'; }
516 | MULTEQ
517 { $$ = '*'; }
518 | DIVEQ
519 { $$ = '/'; }
520 | LSHIFTEQ
521 { $$ = LSHIFT; }
522 | RSHIFTEQ
523 { $$ = RSHIFT; }
524 | ANDEQ
525 { $$ = '&'; }
526 | OREQ
527 { $$ = '|'; }
531 end: ';' | ','
535 assignment:
536 NAME '=' mustbe_exp
538 lang_add_assignment (exp_assop ($2, $1, $3));
540 | NAME assign_op mustbe_exp
542 lang_add_assignment (exp_assop ('=', $1,
543 exp_binop ($2,
544 exp_nameop (NAME,
545 $1),
546 $3)));
548 | PROVIDE '(' NAME '=' mustbe_exp ')'
550 lang_add_assignment (exp_provide ($3, $5));
555 opt_comma:
556 ',' | ;
559 memory:
560 MEMORY '{' memory_spec memory_spec_list '}'
563 memory_spec_list:
564 memory_spec_list memory_spec
565 | memory_spec_list ',' memory_spec
570 memory_spec: NAME
571 { region = lang_memory_region_lookup($1); }
572 attributes_opt ':'
573 origin_spec opt_comma length_spec
575 ; origin_spec:
576 ORIGIN '=' mustbe_exp
577 { region->current =
578 region->origin =
579 exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
583 length_spec:
584 LENGTH '=' mustbe_exp
585 { region->length = exp_get_vma($3,
586 ~((bfd_vma)0),
587 "length",
588 lang_first_phase_enum);
592 attributes_opt:
593 '(' NAME ')'
595 lang_set_flags(region, $2);
601 startup:
602 STARTUP '(' filename ')'
603 { lang_startup($3); }
606 high_level_library:
607 HLL '(' high_level_library_NAME_list ')'
608 | HLL '(' ')'
609 { ldemul_hll((char *)NULL); }
612 high_level_library_NAME_list:
613 high_level_library_NAME_list opt_comma filename
614 { ldemul_hll($3); }
615 | filename
616 { ldemul_hll($1); }
620 low_level_library:
621 SYSLIB '(' low_level_library_NAME_list ')'
622 ; low_level_library_NAME_list:
623 low_level_library_NAME_list opt_comma filename
624 { ldemul_syslib($3); }
628 floating_point_support:
629 FLOAT
630 { lang_float(true); }
631 | NOFLOAT
632 { lang_float(false); }
635 nocrossref_list:
636 /* empty */
638 $$ = NULL;
640 | NAME nocrossref_list
642 struct lang_nocrossref *n;
644 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
645 n->name = $1;
646 n->next = $2;
647 $$ = n;
649 | NAME ',' nocrossref_list
651 struct lang_nocrossref *n;
653 n = (struct lang_nocrossref *) xmalloc (sizeof *n);
654 n->name = $1;
655 n->next = $3;
656 $$ = n;
660 mustbe_exp: { ldlex_expression(); }
662 { ldlex_popstate(); $$=$2;}
665 exp :
666 '-' exp %prec UNARY
667 { $$ = exp_unop('-', $2); }
668 | '(' exp ')'
669 { $$ = $2; }
670 | NEXT '(' exp ')' %prec UNARY
671 { $$ = exp_unop((int) $1,$3); }
672 | '!' exp %prec UNARY
673 { $$ = exp_unop('!', $2); }
674 | '+' exp %prec UNARY
675 { $$ = $2; }
676 | '~' exp %prec UNARY
677 { $$ = exp_unop('~', $2);}
679 | exp '*' exp
680 { $$ = exp_binop('*', $1, $3); }
681 | exp '/' exp
682 { $$ = exp_binop('/', $1, $3); }
683 | exp '%' exp
684 { $$ = exp_binop('%', $1, $3); }
685 | exp '+' exp
686 { $$ = exp_binop('+', $1, $3); }
687 | exp '-' exp
688 { $$ = exp_binop('-' , $1, $3); }
689 | exp LSHIFT exp
690 { $$ = exp_binop(LSHIFT , $1, $3); }
691 | exp RSHIFT exp
692 { $$ = exp_binop(RSHIFT , $1, $3); }
693 | exp EQ exp
694 { $$ = exp_binop(EQ , $1, $3); }
695 | exp NE exp
696 { $$ = exp_binop(NE , $1, $3); }
697 | exp LE exp
698 { $$ = exp_binop(LE , $1, $3); }
699 | exp GE exp
700 { $$ = exp_binop(GE , $1, $3); }
701 | exp '<' exp
702 { $$ = exp_binop('<' , $1, $3); }
703 | exp '>' exp
704 { $$ = exp_binop('>' , $1, $3); }
705 | exp '&' exp
706 { $$ = exp_binop('&' , $1, $3); }
707 | exp '^' exp
708 { $$ = exp_binop('^' , $1, $3); }
709 | exp '|' exp
710 { $$ = exp_binop('|' , $1, $3); }
711 | exp '?' exp ':' exp
712 { $$ = exp_trinop('?' , $1, $3, $5); }
713 | exp ANDAND exp
714 { $$ = exp_binop(ANDAND , $1, $3); }
715 | exp OROR exp
716 { $$ = exp_binop(OROR , $1, $3); }
717 | DEFINED '(' NAME ')'
718 { $$ = exp_nameop(DEFINED, $3); }
719 | INT
720 { $$ = exp_intop($1); }
721 | SIZEOF_HEADERS
722 { $$ = exp_nameop(SIZEOF_HEADERS,0); }
724 | SIZEOF '(' NAME ')'
725 { $$ = exp_nameop(SIZEOF,$3); }
726 | ADDR '(' NAME ')'
727 { $$ = exp_nameop(ADDR,$3); }
728 | LOADADDR '(' NAME ')'
729 { $$ = exp_nameop(LOADADDR,$3); }
730 | ABSOLUTE '(' exp ')'
731 { $$ = exp_unop(ABSOLUTE, $3); }
732 | ALIGN_K '(' exp ')'
733 { $$ = exp_unop(ALIGN_K,$3); }
734 | BLOCK '(' exp ')'
735 { $$ = exp_unop(ALIGN_K,$3); }
736 | NAME
737 { $$ = exp_nameop(NAME,$1); }
738 | MAX_K '(' exp ',' exp ')'
739 { $$ = exp_binop (MAX_K, $3, $5 ); }
740 | MIN_K '(' exp ',' exp ')'
741 { $$ = exp_binop (MIN_K, $3, $5 ); }
745 opt_at:
746 AT '(' exp ')' { $$ = $3; }
747 | { $$ = 0; }
750 section: NAME { ldlex_expression(); }
751 opt_exp_with_type
752 opt_at { ldlex_popstate (); ldlex_script (); }
755 lang_enter_output_section_statement($1, $3,
756 sectype,
757 0, 0, 0, $4);
759 statement_list_opt
760 '}' { ldlex_popstate (); ldlex_expression (); }
761 memspec_opt phdr_opt fill_opt
763 ldlex_popstate ();
764 lang_leave_output_section_statement ($13, $11, $12);
766 opt_comma
767 | OVERLAY
768 { ldlex_expression (); }
769 opt_exp_without_type opt_nocrossrefs opt_at
770 { ldlex_popstate (); ldlex_script (); }
771 '{'
773 lang_enter_overlay ($3, $5, (int) $4);
775 overlay_section
777 { ldlex_popstate (); ldlex_expression (); }
778 memspec_opt phdr_opt fill_opt
780 ldlex_popstate ();
781 lang_leave_overlay ($14, $12, $13);
783 opt_comma
784 | /* The GROUP case is just enough to support the gcc
785 svr3.ifile script. It is not intended to be full
786 support. I'm not even sure what GROUP is supposed
787 to mean. */
788 GROUP { ldlex_expression (); }
789 opt_exp_with_type
791 ldlex_popstate ();
792 lang_add_assignment (exp_assop ('=', ".", $3));
794 '{' sec_or_group_p1 '}'
797 type:
798 NOLOAD { sectype = noload_section; }
799 | DSECT { sectype = dsect_section; }
800 | COPY { sectype = copy_section; }
801 | INFO { sectype = info_section; }
802 | OVERLAY { sectype = overlay_section; }
805 atype:
806 '(' type ')'
807 | /* EMPTY */ { sectype = normal_section; }
808 | '(' ')' { sectype = normal_section; }
811 opt_exp_with_type:
812 exp atype ':' { $$ = $1; }
813 | atype ':' { $$ = (etree_type *)NULL; }
814 | /* The BIND cases are to support the gcc svr3.ifile
815 script. They aren't intended to implement full
816 support for the BIND keyword. I'm not even sure
817 what BIND is supposed to mean. */
818 BIND '(' exp ')' atype ':' { $$ = $3; }
819 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
820 { $$ = $3; }
823 opt_exp_without_type:
824 exp ':' { $$ = $1; }
825 | ':' { $$ = (etree_type *) NULL; }
828 opt_nocrossrefs:
829 /* empty */
830 { $$ = 0; }
831 | NOCROSSREFS
832 { $$ = 1; }
835 memspec_opt:
836 '>' NAME
837 { $$ = $2; }
838 | { $$ = "*default*"; }
841 phdr_opt:
842 /* empty */
844 $$ = NULL;
846 | phdr_opt ':' NAME
848 struct lang_output_section_phdr_list *n;
850 n = ((struct lang_output_section_phdr_list *)
851 xmalloc (sizeof *n));
852 n->name = $3;
853 n->used = false;
854 n->next = $1;
855 $$ = n;
859 overlay_section:
860 /* empty */
861 | overlay_section
862 NAME
864 ldlex_script ();
865 lang_enter_overlay_section ($2);
867 '{' statement_list_opt '}'
868 { ldlex_popstate (); ldlex_expression (); }
869 phdr_opt fill_opt
871 ldlex_popstate ();
872 lang_leave_overlay_section ($9, $8);
874 opt_comma
877 phdrs:
878 PHDRS '{' phdr_list '}'
881 phdr_list:
882 /* empty */
883 | phdr_list phdr
886 phdr:
887 NAME { ldlex_expression (); }
888 phdr_type phdr_qualifiers { ldlex_popstate (); }
891 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
892 $4.flags);
896 phdr_type:
899 $$ = $1;
901 if ($1->type.node_class == etree_name
902 && $1->type.node_code == NAME)
904 const char *s;
905 unsigned int i;
906 static const char * const phdr_types[] =
908 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
909 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
910 "PT_PHDR"
913 s = $1->name.name;
914 for (i = 0;
915 i < sizeof phdr_types / sizeof phdr_types[0];
916 i++)
917 if (strcmp (s, phdr_types[i]) == 0)
919 $$ = exp_intop (i);
920 break;
926 phdr_qualifiers:
927 /* empty */
929 memset (&$$, 0, sizeof (struct phdr_info));
931 | NAME phdr_val phdr_qualifiers
933 $$ = $3;
934 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
935 $$.filehdr = true;
936 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
937 $$.phdrs = true;
938 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
939 $$.flags = $2;
940 else
941 einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
943 | AT '(' exp ')' phdr_qualifiers
945 $$ = $5;
946 $$.at = $3;
950 phdr_val:
951 /* empty */
953 $$ = NULL;
955 | '(' exp ')'
957 $$ = $2;
961 /* This syntax is used within an external version script file. */
963 version_script_file:
965 ldlex_version_file ();
966 PUSH_ERROR (_("VERSION script"));
968 vers_nodes
970 ldlex_popstate ();
971 POP_ERROR ();
975 /* This is used within a normal linker script file. */
977 version:
979 ldlex_version_script ();
981 VERSIONK '{' vers_nodes '}'
983 ldlex_popstate ();
987 vers_nodes:
988 vers_node
989 | vers_nodes vers_node
992 vers_node:
993 VERS_TAG '{' vers_tag '}' ';'
995 lang_register_vers_node ($1, $3, NULL);
997 | VERS_TAG '{' vers_tag '}' verdep ';'
999 lang_register_vers_node ($1, $3, $5);
1003 verdep:
1004 VERS_TAG
1006 $$ = lang_add_vers_depend (NULL, $1);
1008 | verdep VERS_TAG
1010 $$ = lang_add_vers_depend ($1, $2);
1014 vers_tag:
1015 /* empty */
1017 $$ = lang_new_vers_node (NULL, NULL);
1019 | vers_defns ';'
1021 $$ = lang_new_vers_node ($1, NULL);
1023 | GLOBAL ':' vers_defns ';'
1025 $$ = lang_new_vers_node ($3, NULL);
1027 | LOCAL ':' vers_defns ';'
1029 $$ = lang_new_vers_node (NULL, $3);
1031 | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
1033 $$ = lang_new_vers_node ($3, $7);
1037 vers_defns:
1038 VERS_IDENTIFIER
1040 $$ = lang_new_vers_regex (NULL, $1);
1042 | vers_defns ';' VERS_IDENTIFIER
1044 $$ = lang_new_vers_regex ($1, $3);
1049 void
1050 yyerror(arg)
1051 const char *arg;
1053 if (ldfile_assumed_script)
1054 einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
1055 ldfile_input_filename);
1056 if (error_index > 0 && error_index < ERROR_NAME_MAX)
1057 einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
1058 else
1059 einfo ("%P%F:%S: %s\n", arg);