1/* A YACC grammar to parse a superset of the AT&T linker scripting language.
2   Copyright (C) 1991-2017 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
48static enum section_type sectype;
49static lang_memory_region_type *region;
50
51bfd_boolean ldgram_had_keep = FALSE;
52char *ldgram_vers_current_lang = NULL;
53
54#define ERROR_NAME_MAX 20
55static char *error_names[ERROR_NAME_MAX];
56static 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> section_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
165file:
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
174filename:  NAME;
175
176
177defsym_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 */
187mri_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
200mri_script_lines:
201		mri_script_lines mri_script_command NEWLINE
202          |
203	;
204
205mri_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
261ordernamelist:
262	      ordernamelist ',' NAME         { mri_order($3); }
263	|     ordernamelist  NAME         { mri_order($2); }
264      	|
265	;
266
267mri_load_name_list:
268		NAME
269			{ mri_load($1); }
270	|	mri_load_name_list ',' NAME { mri_load($3); }
271	;
272
273mri_abs_name_list:
274 		NAME
275 			{ mri_only_load($1); }
276	|	mri_abs_name_list ','  NAME
277 			{ mri_only_load($3); }
278	;
279
280casesymlist:
281	  /* empty */ { $$ = NULL; }
282	| NAME
283	| casesymlist ',' NAME
284	;
285
286/* Parsed as expressions so that commas separate entries */
287extern_name_list:
288	{ ldlex_expression (); }
289	extern_name_list_body
290	{ ldlex_popstate (); }
291
292extern_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
301script_file:
302	{ ldlex_both(); }
303	ifile_list
304	{ ldlex_popstate(); }
305        ;
306
307ifile_list:
308	ifile_list ifile_p1
309        |
310	;
311
312
313ifile_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
371input_list:
372		{ ldlex_inputlist(); }
373		input_list1
374		{ ldlex_popstate(); }
375
376input_list1:
377		NAME
378		{ lang_add_input_file($1,lang_input_file_is_search_file_enum,
379				 (char *)NULL); }
380	|	input_list1 ',' NAME
381		{ lang_add_input_file($3,lang_input_file_is_search_file_enum,
382				 (char *)NULL); }
383	|	input_list1 NAME
384		{ lang_add_input_file($2,lang_input_file_is_search_file_enum,
385				 (char *)NULL); }
386	|	LNAME
387		{ lang_add_input_file($1,lang_input_file_is_l_enum,
388				 (char *)NULL); }
389	|	input_list1 ',' LNAME
390		{ lang_add_input_file($3,lang_input_file_is_l_enum,
391				 (char *)NULL); }
392	|	input_list1 LNAME
393		{ lang_add_input_file($2,lang_input_file_is_l_enum,
394				 (char *)NULL); }
395	|	AS_NEEDED '('
396		  { $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
397		    input_flags.add_DT_NEEDED_for_regular = TRUE; }
398		     input_list1 ')'
399		  { input_flags.add_DT_NEEDED_for_regular = $<integer>3; }
400	|	input_list1 ',' AS_NEEDED '('
401		  { $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
402		    input_flags.add_DT_NEEDED_for_regular = TRUE; }
403		     input_list1 ')'
404		  { input_flags.add_DT_NEEDED_for_regular = $<integer>5; }
405	|	input_list1 AS_NEEDED '('
406		  { $<integer>$ = input_flags.add_DT_NEEDED_for_regular;
407		    input_flags.add_DT_NEEDED_for_regular = TRUE; }
408		     input_list1 ')'
409		  { input_flags.add_DT_NEEDED_for_regular = $<integer>4; }
410	;
411
412sections:
413		SECTIONS '{' sec_or_group_p1 '}'
414	;
415
416sec_or_group_p1:
417		sec_or_group_p1 section
418	|	sec_or_group_p1 statement_anywhere
419	|
420	;
421
422statement_anywhere:
423		ENTRY '(' NAME ')'
424		{ lang_add_entry ($3, FALSE); }
425	|	assignment end
426	|	ASSERT_K  {ldlex_expression ();} '(' exp ',' NAME ')'
427		{ ldlex_popstate ();
428		  lang_add_assignment (exp_assert ($4, $6)); }
429	;
430
431/* The '*' and '?' cases are there because the lexer returns them as
432   separate tokens rather than as NAME.  */
433wildcard_name:
434		NAME
435			{
436			  $$ = $1;
437			}
438	|	'*'
439			{
440			  $$ = "*";
441			}
442	|	'?'
443			{
444			  $$ = "?";
445			}
446	;
447
448wildcard_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
528sect_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
566sect_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
579exclude_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
599section_NAME_list:
600		section_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
619input_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        |	'[' section_NAME_list ']'
639			{
640			  lang_add_wild (NULL, $2, ldgram_had_keep);
641			}
642        |	sect_flags '[' section_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 '(' section_NAME_list ')'
652			{
653			  lang_add_wild (&$1, $3, ldgram_had_keep);
654			}
655	|	sect_flags wildcard_spec '(' section_NAME_list ')'
656			{
657			  $2.section_flag_list = $1;
658			  lang_add_wild (&$2, $4, ldgram_had_keep);
659			}
660	;
661
662input_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
670statement:
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
706statement_list:
707		statement_list statement
708  	|  	statement
709	;
710
711statement_list_opt:
712		/* empty */
713	|	statement_list
714	;
715
716length:
717		QUAD
718			{ $$ = $1; }
719	|	SQUAD
720			{ $$ = $1; }
721	|	LONG
722			{ $$ = $1; }
723	| 	SHORT
724			{ $$ = $1; }
725	|	BYTE
726			{ $$ = $1; }
727	;
728
729fill_exp:
730	mustbe_exp
731		{
732		  $$ = exp_get_fill ($1, 0, "fill value");
733		}
734	;
735
736fill_opt:
737	  '=' fill_exp
738		{ $$ = $2; }
739	| 	{ $$ = (fill_type *) 0; }
740	;
741
742assign_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
762end:	';' | ','
763	;
764
765
766assignment:
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
794opt_comma:
795		','	|	;
796
797
798memory:
799		MEMORY '{' memory_spec_list_opt '}'
800	;
801
802memory_spec_list_opt: memory_spec_list | ;
803
804memory_spec_list:
805		memory_spec_list opt_comma memory_spec
806	|	memory_spec
807	;
808
809
810memory_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
821origin_spec:
822	ORIGIN '=' mustbe_exp
823		{
824		  region->origin_exp = $3;
825		  region->current = region->origin;
826		}
827	;
828
829length_spec:
830             LENGTH '=' mustbe_exp
831		{
832		  region->length_exp = $3;
833		}
834	;
835
836attributes_opt:
837		/* empty */
838		  { /* dummy action to avoid bison 1.25 error message */ }
839	|	'(' attributes_list ')'
840	;
841
842attributes_list:
843		attributes_string
844	|	attributes_list attributes_string
845	;
846
847attributes_string:
848		NAME
849		  { lang_set_flags (region, $1, 0); }
850	|	'!' NAME
851		  { lang_set_flags (region, $2, 1); }
852	;
853
854startup:
855	STARTUP '(' filename ')'
856		{ lang_startup($3); }
857	;
858
859high_level_library:
860		HLL '(' high_level_library_NAME_list ')'
861	|	HLL '(' ')'
862			{ ldemul_hll((char *)NULL); }
863	;
864
865high_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
873low_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
881floating_point_support:
882		FLOAT
883			{ lang_float(TRUE); }
884	|	NOFLOAT
885			{ lang_float(FALSE); }
886	;
887
888nocrossref_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
913mustbe_exp:		 { ldlex_expression (); }
914		exp
915			 { ldlex_popstate (); $$=$2;}
916	;
917
918exp	:
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
1027memspec_at_opt:
1028                AT '>' NAME { $$ = $3; }
1029        |       { $$ = 0; }
1030        ;
1031
1032opt_at:
1033		AT '(' exp ')' { $$ = $3; }
1034	|	{ $$ = 0; }
1035	;
1036
1037opt_align:
1038		ALIGN_K '(' exp ')' { $$ = $3; }
1039	|	{ $$ = 0; }
1040	;
1041
1042opt_align_with_input:
1043		ALIGN_WITH_INPUT { $$ = ALIGN_WITH_INPUT; }
1044	|	{ $$ = 0; }
1045	;
1046
1047opt_subalign:
1048		SUBALIGN '(' exp ')' { $$ = $3; }
1049	|	{ $$ = 0; }
1050	;
1051
1052sect_constraint:
1053		ONLY_IF_RO { $$ = ONLY_IF_RO; }
1054	|	ONLY_IF_RW { $$ = ONLY_IF_RW; }
1055	|	SPECIAL { $$ = SPECIAL; }
1056	|	{ $$ = 0; }
1057	;
1058
1059section:	NAME 		{ ldlex_expression(); }
1060		opt_exp_with_type
1061		opt_at
1062		opt_align
1063		opt_align_with_input
1064		opt_subalign	{ ldlex_popstate (); ldlex_script (); }
1065		sect_constraint
1066		'{'
1067			{
1068			  lang_enter_output_section_statement($1, $3,
1069							      sectype,
1070							      $5, $7, $4, $9, $6);
1071			}
1072		statement_list_opt
1073 		'}' { ldlex_popstate (); ldlex_expression (); }
1074		memspec_opt memspec_at_opt phdr_opt fill_opt
1075		{
1076		  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
1116type:
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
1124atype:
1125	 	'(' type ')'
1126  	| 	/* EMPTY */ { sectype = normal_section; }
1127  	| 	'(' ')' { sectype = normal_section; }
1128	;
1129
1130opt_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
1142opt_exp_without_type:
1143		exp ':'		{ $$ = $1; }
1144	|	':'		{ $$ = (etree_type *) NULL;  }
1145	;
1146
1147opt_nocrossrefs:
1148		/* empty */
1149			{ $$ = 0; }
1150	|	NOCROSSREFS
1151			{ $$ = 1; }
1152	;
1153
1154memspec_opt:
1155		'>' NAME
1156		{ $$ = $2; }
1157	|	{ $$ = DEFAULT_MEMORY_REGION; }
1158	;
1159
1160phdr_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
1178overlay_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
1196phdrs:
1197		PHDRS '{' phdr_list '}'
1198	;
1199
1200phdr_list:
1201		/* empty */
1202	|	phdr_list phdr
1203	;
1204
1205phdr:
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
1215phdr_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
1259phdr_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
1284phdr_val:
1285		/* empty */
1286		{
1287		  $$ = NULL;
1288		}
1289	| '(' exp ')'
1290		{
1291		  $$ = $2;
1292		}
1293	;
1294
1295dynamic_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
1307dynamic_list_nodes:
1308		dynamic_list_node
1309	|	dynamic_list_nodes dynamic_list_node
1310	;
1311
1312dynamic_list_node:
1313		'{' dynamic_list_tag '}' ';'
1314	;
1315
1316dynamic_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
1325version_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
1339version:
1340		{
1341		  ldlex_version_script ();
1342		}
1343		VERSIONK '{' vers_nodes '}'
1344		{
1345		  ldlex_popstate ();
1346		}
1347	;
1348
1349vers_nodes:
1350		vers_node
1351	|	vers_nodes vers_node
1352	;
1353
1354vers_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
1369verdep:
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
1380vers_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
1403vers_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
1469opt_semicolon:
1470		/* empty */
1471	|	';'
1472	;
1473
1474%%
1475void
1476yyerror(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