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