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