178828Sobrien/* A YACC grammar to parse a superset of the AT&T linker scripting language.
278828Sobrien   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3218822Sdim   2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
433965Sjdp   Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
533965Sjdp
6218822Sdim   This file is part of GNU ld.
733965Sjdp
8218822Sdim   This program is free software; you can redistribute it and/or modify
9218822Sdim   it under the terms of the GNU General Public License as published by
10218822Sdim   the Free Software Foundation; either version 2 of the License, or
11218822Sdim   (at your option) any later version.
1233965Sjdp
13218822Sdim   This program is distributed in the hope that it will be useful,
14218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
15218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16218822Sdim   GNU General Public License for more details.
1733965Sjdp
18218822Sdim   You should have received a copy of the GNU General Public License
19218822Sdim   along with this program; if not, write to the Free Software
20218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2133965Sjdp
2233965Sjdp%{
2333965Sjdp/*
2433965Sjdp
2533965Sjdp */
2633965Sjdp
2733965Sjdp#define DONTDECLARE_MALLOC
2833965Sjdp
29218822Sdim#include "sysdep.h"
3033965Sjdp#include "bfd.h"
3133965Sjdp#include "bfdlink.h"
32130561Sobrien#include "ld.h"
3333965Sjdp#include "ldexp.h"
3433965Sjdp#include "ldver.h"
3533965Sjdp#include "ldlang.h"
3677298Sobrien#include "ldfile.h"
3733965Sjdp#include "ldemul.h"
3833965Sjdp#include "ldmisc.h"
3933965Sjdp#include "ldmain.h"
4033965Sjdp#include "mri.h"
4160484Sobrien#include "ldctor.h"
4233965Sjdp#include "ldlex.h"
4333965Sjdp
4433965Sjdp#ifndef YYDEBUG
4533965Sjdp#define YYDEBUG 1
4633965Sjdp#endif
4733965Sjdp
4833965Sjdpstatic enum section_type sectype;
49218822Sdimstatic lang_memory_region_type *region;
5033965Sjdp
51130561SobrienFILE *saved_script_handle = NULL;
52130561Sobrienbfd_boolean force_make_executable = FALSE;
5333965Sjdp
54130561Sobrienbfd_boolean ldgram_in_script = FALSE;
55130561Sobrienbfd_boolean ldgram_had_equals = FALSE;
56130561Sobrienbfd_boolean ldgram_had_keep = FALSE;
5760484Sobrienchar *ldgram_vers_current_lang = NULL;
5833965Sjdp
5933965Sjdp#define ERROR_NAME_MAX 20
6033965Sjdpstatic char *error_names[ERROR_NAME_MAX];
6133965Sjdpstatic int error_index;
6233965Sjdp#define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
6333965Sjdp#define POP_ERROR()   error_index--;
6433965Sjdp%}
6533965Sjdp%union {
6633965Sjdp  bfd_vma integer;
67104834Sobrien  struct big_int
68104834Sobrien    {
69104834Sobrien      bfd_vma integer;
70104834Sobrien      char *str;
71104834Sobrien    } bigint;
72104834Sobrien  fill_type *fill;
7333965Sjdp  char *name;
7460484Sobrien  const char *cname;
7560484Sobrien  struct wildcard_spec wildcard;
7689857Sobrien  struct wildcard_list *wildcard_list;
7760484Sobrien  struct name_list *name_list;
7833965Sjdp  int token;
7933965Sjdp  union etree_union *etree;
8033965Sjdp  struct phdr_info
8133965Sjdp    {
82130561Sobrien      bfd_boolean filehdr;
83130561Sobrien      bfd_boolean phdrs;
8433965Sjdp      union etree_union *at;
8533965Sjdp      union etree_union *flags;
8633965Sjdp    } phdr;
8733965Sjdp  struct lang_nocrossref *nocrossref;
8833965Sjdp  struct lang_output_section_phdr_list *section_phdr;
8933965Sjdp  struct bfd_elf_version_deps *deflist;
9033965Sjdp  struct bfd_elf_version_expr *versyms;
9133965Sjdp  struct bfd_elf_version_tree *versnode;
9233965Sjdp}
9333965Sjdp
9433965Sjdp%type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
95218822Sdim%type <etree> opt_exp_without_type opt_subalign opt_align
96104834Sobrien%type <fill> fill_opt fill_exp
9760484Sobrien%type <name_list> exclude_name_list
9889857Sobrien%type <wildcard_list> file_NAME_list
9933965Sjdp%type <name> memspec_opt casesymlist
10060484Sobrien%type <name> memspec_at_opt
10160484Sobrien%type <cname> wildcard_name
10260484Sobrien%type <wildcard> wildcard_spec
103130561Sobrien%token <bigint> INT
10433965Sjdp%token <name> NAME LNAME
10533965Sjdp%type <integer> length
10633965Sjdp%type <phdr> phdr_qualifiers
10733965Sjdp%type <nocrossref> nocrossref_list
10833965Sjdp%type <section_phdr> phdr_opt
10933965Sjdp%type <integer> opt_nocrossrefs
11033965Sjdp
111130561Sobrien%right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ
11233965Sjdp%right <token> '?' ':'
11333965Sjdp%left <token> OROR
11433965Sjdp%left <token>  ANDAND
11533965Sjdp%left <token> '|'
11633965Sjdp%left <token>  '^'
11733965Sjdp%left  <token> '&'
11833965Sjdp%left <token>  EQ NE
11933965Sjdp%left  <token> '<' '>' LE GE
12033965Sjdp%left  <token> LSHIFT RSHIFT
12133965Sjdp
12233965Sjdp%left  <token> '+' '-'
12333965Sjdp%left  <token> '*' '/' '%'
12433965Sjdp
12533965Sjdp%right UNARY
126130561Sobrien%token END
12733965Sjdp%left <token> '('
12838889Sjdp%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
129218822Sdim%token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
130218822Sdim%token SORT_BY_NAME SORT_BY_ALIGNMENT
13133965Sjdp%token '{' '}'
13233965Sjdp%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
13389857Sobrien%token INHIBIT_COMMON_ALLOCATION
134218822Sdim%token SEGMENT_START
13533965Sjdp%token INCLUDE
136218822Sdim%token MEMORY
13733965Sjdp%token NOLOAD DSECT COPY INFO OVERLAY
138218822Sdim%token DEFINED TARGET_K SEARCH_DIR MAP ENTRY
13933965Sjdp%token <integer> NEXT
140218822Sdim%token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K
14133965Sjdp%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
14233965Sjdp%token ORIGIN FILL
14333965Sjdp%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
144218822Sdim%token ALIGNMOD AT SUBALIGN PROVIDE PROVIDE_HIDDEN AS_NEEDED
145218822Sdim%type <token> assign_op atype attributes_opt sect_constraint
14633965Sjdp%type <name>  filename
14760484Sobrien%token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
14833965Sjdp%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
14933965Sjdp%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
15033965Sjdp%token <name> VERS_TAG VERS_IDENTIFIER
15138889Sjdp%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
152218822Sdim%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL
15360484Sobrien%token EXCLUDE_FILE
154218822Sdim%token CONSTANT
15533965Sjdp%type <versyms> vers_defns
15633965Sjdp%type <versnode> vers_tag
15733965Sjdp%type <deflist> verdep
158218822Sdim%token INPUT_DYNAMIC_LIST
15933965Sjdp
16033965Sjdp%%
16133965Sjdp
162130561Sobrienfile:
16333965Sjdp		INPUT_SCRIPT script_file
16433965Sjdp	|	INPUT_MRI_SCRIPT mri_script_file
16533965Sjdp	|	INPUT_VERSION_SCRIPT version_script_file
166218822Sdim	|	INPUT_DYNAMIC_LIST dynamic_list_file
16733965Sjdp	|	INPUT_DEFSYM defsym_expr
16833965Sjdp	;
16933965Sjdp
17033965Sjdp
17133965Sjdpfilename:  NAME;
17233965Sjdp
17333965Sjdp
17433965Sjdpdefsym_expr:
17533965Sjdp		{ ldlex_defsym(); }
17633965Sjdp		NAME '=' exp
17733965Sjdp		{
17833965Sjdp		  ldlex_popstate();
17933965Sjdp		  lang_add_assignment(exp_assop($3,$2,$4));
18033965Sjdp		}
181104834Sobrien	;
18233965Sjdp
183130561Sobrien/* SYNTAX WITHIN AN MRI SCRIPT FILE */
18433965Sjdpmri_script_file:
18533965Sjdp		{
18633965Sjdp		  ldlex_mri_script ();
18760484Sobrien		  PUSH_ERROR (_("MRI style script"));
18833965Sjdp		}
18933965Sjdp	     mri_script_lines
19033965Sjdp		{
19133965Sjdp		  ldlex_popstate ();
19233965Sjdp		  mri_draw_tree ();
19333965Sjdp		  POP_ERROR ();
19433965Sjdp		}
19533965Sjdp	;
19633965Sjdp
19733965Sjdpmri_script_lines:
19833965Sjdp		mri_script_lines mri_script_command NEWLINE
19933965Sjdp          |
20033965Sjdp	;
20133965Sjdp
20233965Sjdpmri_script_command:
203130561Sobrien		CHIP  exp
20433965Sjdp	|	CHIP  exp ',' exp
20533965Sjdp	|	NAME 	{
20660484Sobrien			einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
20733965Sjdp			}
20833965Sjdp	|	LIST  	{
20933965Sjdp			config.map_filename = "-";
21033965Sjdp			}
21133965Sjdp        |       ORDER ordernamelist
212130561Sobrien	|       ENDWORD
21333965Sjdp        |       PUBLIC NAME '=' exp
21433965Sjdp 			{ mri_public($2, $4); }
21533965Sjdp        |       PUBLIC NAME ',' exp
21633965Sjdp 			{ mri_public($2, $4); }
217130561Sobrien        |       PUBLIC NAME  exp
21833965Sjdp 			{ mri_public($2, $3); }
21933965Sjdp	| 	FORMAT NAME
22033965Sjdp			{ mri_format($2); }
22133965Sjdp	|	SECT NAME ',' exp
22233965Sjdp			{ mri_output_section($2, $4);}
22333965Sjdp	|	SECT NAME  exp
22433965Sjdp			{ mri_output_section($2, $3);}
22533965Sjdp	|	SECT NAME '=' exp
22633965Sjdp			{ mri_output_section($2, $4);}
22733965Sjdp	|	ALIGN_K NAME '=' exp
22833965Sjdp			{ mri_align($2,$4); }
22933965Sjdp	|	ALIGN_K NAME ',' exp
23033965Sjdp			{ mri_align($2,$4); }
23133965Sjdp	|	ALIGNMOD NAME '=' exp
23233965Sjdp			{ mri_alignmod($2,$4); }
23333965Sjdp	|	ALIGNMOD NAME ',' exp
23433965Sjdp			{ mri_alignmod($2,$4); }
23533965Sjdp	|	ABSOLUTE mri_abs_name_list
23633965Sjdp	|	LOAD	 mri_load_name_list
237130561Sobrien	|       NAMEWORD NAME
238130561Sobrien			{ mri_name($2); }
23933965Sjdp	|	ALIAS NAME ',' NAME
24033965Sjdp			{ mri_alias($2,$4,0);}
24133965Sjdp	|	ALIAS NAME ',' INT
242104834Sobrien			{ mri_alias ($2, 0, (int) $4.integer); }
24333965Sjdp	|	BASE     exp
24433965Sjdp			{ mri_base($2); }
245104834Sobrien	|	TRUNCATE INT
246104834Sobrien		{ mri_truncate ((unsigned int) $2.integer); }
24733965Sjdp	|	CASE casesymlist
24833965Sjdp	|	EXTERN extern_name_list
24933965Sjdp	|	INCLUDE filename
25089857Sobrien		{ ldlex_script (); ldfile_open_command_file($2); }
25189857Sobrien		mri_script_lines END
25289857Sobrien		{ ldlex_popstate (); }
25333965Sjdp	|	START NAME
254130561Sobrien		{ lang_add_entry ($2, FALSE); }
25533965Sjdp        |
25633965Sjdp	;
25733965Sjdp
25833965Sjdpordernamelist:
25933965Sjdp	      ordernamelist ',' NAME         { mri_order($3); }
26033965Sjdp	|     ordernamelist  NAME         { mri_order($2); }
26133965Sjdp      	|
26233965Sjdp	;
26333965Sjdp
26433965Sjdpmri_load_name_list:
26533965Sjdp		NAME
26633965Sjdp			{ mri_load($1); }
26733965Sjdp	|	mri_load_name_list ',' NAME { mri_load($3); }
26833965Sjdp	;
26933965Sjdp
27033965Sjdpmri_abs_name_list:
27133965Sjdp 		NAME
27233965Sjdp 			{ mri_only_load($1); }
27333965Sjdp	|	mri_abs_name_list ','  NAME
27433965Sjdp 			{ mri_only_load($3); }
27533965Sjdp	;
27633965Sjdp
27733965Sjdpcasesymlist:
27833965Sjdp	  /* empty */ { $$ = NULL; }
27933965Sjdp	| NAME
28033965Sjdp	| casesymlist ',' NAME
28133965Sjdp	;
28233965Sjdp
283218822Sdim/* Parsed as expressions so that commas separate entries */
28433965Sjdpextern_name_list:
285218822Sdim	{ ldlex_expression (); }
286218822Sdim	extern_name_list_body
287218822Sdim	{ ldlex_popstate (); }
288218822Sdim
289218822Sdimextern_name_list_body:
29033965Sjdp	  NAME
29133965Sjdp			{ ldlang_add_undef ($1); }
292218822Sdim	| extern_name_list_body NAME
29360484Sobrien			{ ldlang_add_undef ($2); }
294218822Sdim	| extern_name_list_body ',' NAME
29533965Sjdp			{ ldlang_add_undef ($3); }
29633965Sjdp	;
29733965Sjdp
29833965Sjdpscript_file:
299218822Sdim	{ ldlex_both(); }
300218822Sdim	ifile_list
301218822Sdim	{ ldlex_popstate(); }
30233965Sjdp        ;
30333965Sjdp
30433965Sjdpifile_list:
305218822Sdim	ifile_list ifile_p1
30633965Sjdp        |
30733965Sjdp	;
30833965Sjdp
30933965Sjdp
31033965Sjdpifile_p1:
31133965Sjdp		memory
31233965Sjdp	|	sections
31333965Sjdp	|	phdrs
31433965Sjdp	|	startup
31533965Sjdp	|	high_level_library
31633965Sjdp	|	low_level_library
31733965Sjdp	|	floating_point_support
31833965Sjdp	|	statement_anywhere
31933965Sjdp	|	version
32033965Sjdp        |	 ';'
32133965Sjdp	|	TARGET_K '(' NAME ')'
32233965Sjdp		{ lang_add_target($3); }
32333965Sjdp	|	SEARCH_DIR '(' filename ')'
324130561Sobrien		{ ldfile_add_library_path ($3, FALSE); }
32533965Sjdp	|	OUTPUT '(' filename ')'
32633965Sjdp		{ lang_add_output($3, 1); }
32733965Sjdp        |	OUTPUT_FORMAT '(' NAME ')'
32833965Sjdp		  { lang_add_output_format ($3, (char *) NULL,
32933965Sjdp					    (char *) NULL, 1); }
33033965Sjdp	|	OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
33133965Sjdp		  { lang_add_output_format ($3, $5, $7, 1); }
33233965Sjdp        |	OUTPUT_ARCH '(' NAME ')'
333130561Sobrien		  { ldfile_set_output_arch ($3, bfd_arch_unknown); }
33433965Sjdp	|	FORCE_COMMON_ALLOCATION
335130561Sobrien		{ command_line.force_common_definition = TRUE ; }
33689857Sobrien	|	INHIBIT_COMMON_ALLOCATION
337130561Sobrien		{ command_line.inhibit_common_definition = TRUE ; }
33833965Sjdp	|	INPUT '(' input_list ')'
33933965Sjdp	|	GROUP
34033965Sjdp		  { lang_enter_group (); }
34133965Sjdp		    '(' input_list ')'
34233965Sjdp		  { lang_leave_group (); }
34333965Sjdp     	|	MAP '(' filename ')'
34433965Sjdp		{ lang_add_map($3); }
345130561Sobrien	|	INCLUDE filename
34689857Sobrien		{ ldlex_script (); ldfile_open_command_file($2); }
34789857Sobrien		ifile_list END
34889857Sobrien		{ ldlex_popstate (); }
34933965Sjdp	|	NOCROSSREFS '(' nocrossref_list ')'
35033965Sjdp		{
35133965Sjdp		  lang_add_nocrossref ($3);
35233965Sjdp		}
35360484Sobrien	|	EXTERN '(' extern_name_list ')'
35433965Sjdp	;
35533965Sjdp
35633965Sjdpinput_list:
35733965Sjdp		NAME
35833965Sjdp		{ lang_add_input_file($1,lang_input_file_is_search_file_enum,
35933965Sjdp				 (char *)NULL); }
36033965Sjdp	|	input_list ',' NAME
36133965Sjdp		{ lang_add_input_file($3,lang_input_file_is_search_file_enum,
36233965Sjdp				 (char *)NULL); }
36333965Sjdp	|	input_list NAME
36433965Sjdp		{ lang_add_input_file($2,lang_input_file_is_search_file_enum,
36533965Sjdp				 (char *)NULL); }
36633965Sjdp	|	LNAME
36733965Sjdp		{ lang_add_input_file($1,lang_input_file_is_l_enum,
36833965Sjdp				 (char *)NULL); }
36933965Sjdp	|	input_list ',' LNAME
37033965Sjdp		{ lang_add_input_file($3,lang_input_file_is_l_enum,
37133965Sjdp				 (char *)NULL); }
37233965Sjdp	|	input_list LNAME
37333965Sjdp		{ lang_add_input_file($2,lang_input_file_is_l_enum,
37433965Sjdp				 (char *)NULL); }
375218822Sdim	|	AS_NEEDED '('
376218822Sdim		  { $<integer>$ = as_needed; as_needed = TRUE; }
377218822Sdim		     input_list ')'
378218822Sdim		  { as_needed = $<integer>3; }
379218822Sdim	|	input_list ',' AS_NEEDED '('
380218822Sdim		  { $<integer>$ = as_needed; as_needed = TRUE; }
381218822Sdim		     input_list ')'
382218822Sdim		  { as_needed = $<integer>5; }
383218822Sdim	|	input_list AS_NEEDED '('
384218822Sdim		  { $<integer>$ = as_needed; as_needed = TRUE; }
385218822Sdim		     input_list ')'
386218822Sdim		  { as_needed = $<integer>4; }
38733965Sjdp	;
38833965Sjdp
38933965Sjdpsections:
39033965Sjdp		SECTIONS '{' sec_or_group_p1 '}'
39133965Sjdp	;
39233965Sjdp
39333965Sjdpsec_or_group_p1:
39433965Sjdp		sec_or_group_p1 section
39533965Sjdp	|	sec_or_group_p1 statement_anywhere
39633965Sjdp	|
39733965Sjdp	;
39833965Sjdp
39933965Sjdpstatement_anywhere:
40033965Sjdp		ENTRY '(' NAME ')'
401130561Sobrien		{ lang_add_entry ($3, FALSE); }
40233965Sjdp	|	assignment end
403130561Sobrien	|	ASSERT_K  {ldlex_expression ();} '(' exp ',' NAME ')'
404130561Sobrien		{ ldlex_popstate ();
405130561Sobrien		  lang_add_assignment (exp_assert ($4, $6)); }
40633965Sjdp	;
40733965Sjdp
40833965Sjdp/* The '*' and '?' cases are there because the lexer returns them as
40933965Sjdp   separate tokens rather than as NAME.  */
41060484Sobrienwildcard_name:
41133965Sjdp		NAME
41260484Sobrien			{
41360484Sobrien			  $$ = $1;
41460484Sobrien			}
41533965Sjdp	|	'*'
41660484Sobrien			{
41760484Sobrien			  $$ = "*";
41860484Sobrien			}
41933965Sjdp	|	'?'
42060484Sobrien			{
42160484Sobrien			  $$ = "?";
42260484Sobrien			}
42333965Sjdp	;
42433965Sjdp
42560484Sobrienwildcard_spec:
42660484Sobrien		wildcard_name
42733965Sjdp			{
42860484Sobrien			  $$.name = $1;
429218822Sdim			  $$.sorted = none;
43060484Sobrien			  $$.exclude_name_list = NULL;
43133965Sjdp			}
43260484Sobrien	| 	EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name
43333965Sjdp			{
43460484Sobrien			  $$.name = $5;
435218822Sdim			  $$.sorted = none;
43660484Sobrien			  $$.exclude_name_list = $3;
43733965Sjdp			}
438218822Sdim	|	SORT_BY_NAME '(' wildcard_name ')'
43933965Sjdp			{
44060484Sobrien			  $$.name = $3;
441218822Sdim			  $$.sorted = by_name;
44260484Sobrien			  $$.exclude_name_list = NULL;
44333965Sjdp			}
444218822Sdim	|	SORT_BY_ALIGNMENT '(' wildcard_name ')'
44533965Sjdp			{
446218822Sdim			  $$.name = $3;
447218822Sdim			  $$.sorted = by_alignment;
448218822Sdim			  $$.exclude_name_list = NULL;
449218822Sdim			}
450218822Sdim	|	SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
451218822Sdim			{
452218822Sdim			  $$.name = $5;
453218822Sdim			  $$.sorted = by_name_alignment;
454218822Sdim			  $$.exclude_name_list = NULL;
455218822Sdim			}
456218822Sdim	|	SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')'
457218822Sdim			{
458218822Sdim			  $$.name = $5;
459218822Sdim			  $$.sorted = by_name;
460218822Sdim			  $$.exclude_name_list = NULL;
461218822Sdim			}
462218822Sdim	|	SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')'
463218822Sdim			{
464218822Sdim			  $$.name = $5;
465218822Sdim			  $$.sorted = by_alignment_name;
466218822Sdim			  $$.exclude_name_list = NULL;
467218822Sdim			}
468218822Sdim	|	SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
469218822Sdim			{
470218822Sdim			  $$.name = $5;
471218822Sdim			  $$.sorted = by_alignment;
472218822Sdim			  $$.exclude_name_list = NULL;
473218822Sdim			}
474218822Sdim	|	SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
475218822Sdim			{
47660484Sobrien			  $$.name = $7;
477218822Sdim			  $$.sorted = by_name;
47860484Sobrien			  $$.exclude_name_list = $5;
47933965Sjdp			}
48060484Sobrien	;
48160484Sobrien
48260484Sobrienexclude_name_list:
48360484Sobrien		exclude_name_list wildcard_name
48460484Sobrien			{
48560484Sobrien			  struct name_list *tmp;
48660484Sobrien			  tmp = (struct name_list *) xmalloc (sizeof *tmp);
48760484Sobrien			  tmp->name = $2;
48860484Sobrien			  tmp->next = $1;
489130561Sobrien			  $$ = tmp;
49060484Sobrien			}
49160484Sobrien	|
49260484Sobrien		wildcard_name
49360484Sobrien			{
49460484Sobrien			  struct name_list *tmp;
49560484Sobrien			  tmp = (struct name_list *) xmalloc (sizeof *tmp);
49660484Sobrien			  tmp->name = $1;
49760484Sobrien			  tmp->next = NULL;
49860484Sobrien			  $$ = tmp;
49960484Sobrien			}
50060484Sobrien	;
50160484Sobrien
50260484Sobrienfile_NAME_list:
50389857Sobrien		file_NAME_list opt_comma wildcard_spec
50460484Sobrien			{
50589857Sobrien			  struct wildcard_list *tmp;
50689857Sobrien			  tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
50789857Sobrien			  tmp->next = $1;
50889857Sobrien			  tmp->spec = $3;
50989857Sobrien			  $$ = tmp;
51060484Sobrien			}
51189857Sobrien	|
51289857Sobrien		wildcard_spec
51360484Sobrien			{
51489857Sobrien			  struct wildcard_list *tmp;
51589857Sobrien			  tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
51689857Sobrien			  tmp->next = NULL;
51789857Sobrien			  tmp->spec = $1;
51889857Sobrien			  $$ = tmp;
51960484Sobrien			}
52060484Sobrien	;
52160484Sobrien
52260484Sobrieninput_section_spec_no_keep:
52360484Sobrien		NAME
52460484Sobrien			{
52589857Sobrien			  struct wildcard_spec tmp;
52689857Sobrien			  tmp.name = $1;
52789857Sobrien			  tmp.exclude_name_list = NULL;
528218822Sdim			  tmp.sorted = none;
52989857Sobrien			  lang_add_wild (&tmp, NULL, ldgram_had_keep);
53060484Sobrien			}
53189857Sobrien        |	'[' file_NAME_list ']'
53260484Sobrien			{
53389857Sobrien			  lang_add_wild (NULL, $2, ldgram_had_keep);
53460484Sobrien			}
53589857Sobrien	|	wildcard_spec '(' file_NAME_list ')'
53660484Sobrien			{
53789857Sobrien			  lang_add_wild (&$1, $3, ldgram_had_keep);
53860484Sobrien			}
53933965Sjdp	;
54033965Sjdp
54160484Sobrieninput_section_spec:
54260484Sobrien		input_section_spec_no_keep
54360484Sobrien	|	KEEP '('
544130561Sobrien			{ ldgram_had_keep = TRUE; }
54560484Sobrien		input_section_spec_no_keep ')'
546130561Sobrien			{ ldgram_had_keep = FALSE; }
54760484Sobrien	;
54860484Sobrien
54933965Sjdpstatement:
55033965Sjdp	  	assignment end
55133965Sjdp	|	CREATE_OBJECT_SYMBOLS
55233965Sjdp		{
553130561Sobrien 		lang_add_attribute(lang_object_symbols_statement_enum);
55433965Sjdp	      	}
55533965Sjdp        |	';'
55633965Sjdp        |	CONSTRUCTORS
55733965Sjdp		{
558130561Sobrien
559130561Sobrien		  lang_add_attribute(lang_constructors_statement_enum);
56033965Sjdp		}
561218822Sdim	| SORT_BY_NAME '(' CONSTRUCTORS ')'
56260484Sobrien		{
563130561Sobrien		  constructors_sorted = TRUE;
56460484Sobrien		  lang_add_attribute (lang_constructors_statement_enum);
56560484Sobrien		}
56633965Sjdp	| input_section_spec
56733965Sjdp        | length '(' mustbe_exp ')'
56833965Sjdp        	        {
569104834Sobrien			  lang_add_data ((int) $1, $3);
57033965Sjdp			}
571130561Sobrien
572104834Sobrien	| FILL '(' fill_exp ')'
57333965Sjdp			{
574104834Sobrien			  lang_add_fill ($3);
57533965Sjdp			}
576218822Sdim	| ASSERT_K  {ldlex_expression ();} '(' exp ',' NAME ')' end
577218822Sdim			{ ldlex_popstate ();
578218822Sdim			  lang_add_assignment (exp_assert ($4, $6)); }
57933965Sjdp	;
58033965Sjdp
58133965Sjdpstatement_list:
58233965Sjdp		statement_list statement
58333965Sjdp  	|  	statement
58433965Sjdp	;
585130561Sobrien
58633965Sjdpstatement_list_opt:
58733965Sjdp		/* empty */
58833965Sjdp	|	statement_list
58933965Sjdp	;
59033965Sjdp
59133965Sjdplength:
59233965Sjdp		QUAD
59333965Sjdp			{ $$ = $1; }
59438889Sjdp	|	SQUAD
59538889Sjdp			{ $$ = $1; }
59633965Sjdp	|	LONG
59733965Sjdp			{ $$ = $1; }
59833965Sjdp	| 	SHORT
59933965Sjdp			{ $$ = $1; }
60033965Sjdp	|	BYTE
60133965Sjdp			{ $$ = $1; }
60233965Sjdp	;
60333965Sjdp
604104834Sobrienfill_exp:
605104834Sobrien	mustbe_exp
60633965Sjdp		{
607218822Sdim		  $$ = exp_get_fill ($1, 0, "fill value");
60833965Sjdp		}
60933965Sjdp	;
61033965Sjdp
611104834Sobrienfill_opt:
612104834Sobrien	  '=' fill_exp
613104834Sobrien		{ $$ = $2; }
614104834Sobrien	| 	{ $$ = (fill_type *) 0; }
615104834Sobrien	;
61633965Sjdp
61733965Sjdpassign_op:
61833965Sjdp		PLUSEQ
61933965Sjdp			{ $$ = '+'; }
62033965Sjdp	|	MINUSEQ
62133965Sjdp			{ $$ = '-'; }
62233965Sjdp	| 	MULTEQ
62333965Sjdp			{ $$ = '*'; }
62433965Sjdp	| 	DIVEQ
62533965Sjdp			{ $$ = '/'; }
62633965Sjdp	| 	LSHIFTEQ
62733965Sjdp			{ $$ = LSHIFT; }
62833965Sjdp	| 	RSHIFTEQ
62933965Sjdp			{ $$ = RSHIFT; }
63033965Sjdp	| 	ANDEQ
63133965Sjdp			{ $$ = '&'; }
63233965Sjdp	| 	OREQ
63333965Sjdp			{ $$ = '|'; }
63433965Sjdp
63533965Sjdp	;
63633965Sjdp
63733965Sjdpend:	';' | ','
63833965Sjdp	;
63933965Sjdp
64033965Sjdp
64133965Sjdpassignment:
64233965Sjdp		NAME '=' mustbe_exp
64333965Sjdp		{
64433965Sjdp		  lang_add_assignment (exp_assop ($2, $1, $3));
64533965Sjdp		}
64633965Sjdp	|	NAME assign_op mustbe_exp
64733965Sjdp		{
64833965Sjdp		  lang_add_assignment (exp_assop ('=', $1,
64933965Sjdp						  exp_binop ($2,
65033965Sjdp							     exp_nameop (NAME,
65133965Sjdp									 $1),
65233965Sjdp							     $3)));
65333965Sjdp		}
65433965Sjdp	|	PROVIDE '(' NAME '=' mustbe_exp ')'
65533965Sjdp		{
656218822Sdim		  lang_add_assignment (exp_provide ($3, $5, FALSE));
65733965Sjdp		}
658218822Sdim	|	PROVIDE_HIDDEN '(' NAME '=' mustbe_exp ')'
659218822Sdim		{
660218822Sdim		  lang_add_assignment (exp_provide ($3, $5, TRUE));
661218822Sdim		}
66233965Sjdp	;
66333965Sjdp
66433965Sjdp
66533965Sjdpopt_comma:
66633965Sjdp		','	|	;
66733965Sjdp
66833965Sjdp
66933965Sjdpmemory:
67033965Sjdp		MEMORY '{' memory_spec memory_spec_list '}'
67133965Sjdp	;
67233965Sjdp
67333965Sjdpmemory_spec_list:
67433965Sjdp		memory_spec_list memory_spec
67533965Sjdp	|	memory_spec_list ',' memory_spec
67633965Sjdp	|
67733965Sjdp	;
67833965Sjdp
67933965Sjdp
680107492Sobrienmemory_spec: 	NAME
681130561Sobrien		{ region = lang_memory_region_lookup ($1, TRUE); }
68233965Sjdp		attributes_opt ':'
68333965Sjdp		origin_spec opt_comma length_spec
684107492Sobrien		{}
68577298Sobrien	;
68677298Sobrien
68777298Sobrienorigin_spec:
68833965Sjdp	ORIGIN '=' mustbe_exp
689218822Sdim		{
690218822Sdim		  region->origin = exp_get_vma ($3, 0, "origin");
691218822Sdim		  region->current = region->origin;
692218822Sdim		}
69338889Sjdp	;
69438889Sjdp
69538889Sjdplength_spec:
69633965Sjdp             LENGTH '=' mustbe_exp
697218822Sdim		{
698218822Sdim		  region->length = exp_get_vma ($3, -1, "length");
69933965Sjdp		}
70060484Sobrien	;
70133965Sjdp
70233965Sjdpattributes_opt:
70360484Sobrien		/* empty */
70460484Sobrien		  { /* dummy action to avoid bison 1.25 error message */ }
70560484Sobrien	|	'(' attributes_list ')'
70633965Sjdp	;
70733965Sjdp
70860484Sobrienattributes_list:
70960484Sobrien		attributes_string
71060484Sobrien	|	attributes_list attributes_string
71160484Sobrien	;
71260484Sobrien
71360484Sobrienattributes_string:
71460484Sobrien		NAME
71560484Sobrien		  { lang_set_flags (region, $1, 0); }
71660484Sobrien	|	'!' NAME
71760484Sobrien		  { lang_set_flags (region, $2, 1); }
71860484Sobrien	;
71960484Sobrien
72033965Sjdpstartup:
72133965Sjdp	STARTUP '(' filename ')'
72233965Sjdp		{ lang_startup($3); }
72333965Sjdp	;
72433965Sjdp
72533965Sjdphigh_level_library:
72633965Sjdp		HLL '(' high_level_library_NAME_list ')'
72733965Sjdp	|	HLL '(' ')'
72833965Sjdp			{ ldemul_hll((char *)NULL); }
72933965Sjdp	;
73033965Sjdp
73133965Sjdphigh_level_library_NAME_list:
73233965Sjdp		high_level_library_NAME_list opt_comma filename
73333965Sjdp			{ ldemul_hll($3); }
73433965Sjdp	|	filename
73533965Sjdp			{ ldemul_hll($1); }
73633965Sjdp
73733965Sjdp	;
73833965Sjdp
73933965Sjdplow_level_library:
74033965Sjdp	SYSLIB '(' low_level_library_NAME_list ')'
74133965Sjdp	; low_level_library_NAME_list:
74233965Sjdp		low_level_library_NAME_list opt_comma filename
74333965Sjdp			{ ldemul_syslib($3); }
74433965Sjdp	|
74533965Sjdp	;
74633965Sjdp
74733965Sjdpfloating_point_support:
74833965Sjdp		FLOAT
749130561Sobrien			{ lang_float(TRUE); }
75033965Sjdp	|	NOFLOAT
751130561Sobrien			{ lang_float(FALSE); }
75233965Sjdp	;
753130561Sobrien
75433965Sjdpnocrossref_list:
75533965Sjdp		/* empty */
75633965Sjdp		{
75733965Sjdp		  $$ = NULL;
75833965Sjdp		}
75933965Sjdp	|	NAME nocrossref_list
76033965Sjdp		{
76133965Sjdp		  struct lang_nocrossref *n;
76233965Sjdp
76333965Sjdp		  n = (struct lang_nocrossref *) xmalloc (sizeof *n);
76433965Sjdp		  n->name = $1;
76533965Sjdp		  n->next = $2;
76633965Sjdp		  $$ = n;
76733965Sjdp		}
76833965Sjdp	|	NAME ',' nocrossref_list
76933965Sjdp		{
77033965Sjdp		  struct lang_nocrossref *n;
77133965Sjdp
77233965Sjdp		  n = (struct lang_nocrossref *) xmalloc (sizeof *n);
77333965Sjdp		  n->name = $1;
77433965Sjdp		  n->next = $3;
77533965Sjdp		  $$ = n;
77633965Sjdp		}
77733965Sjdp	;
77833965Sjdp
779218822Sdimmustbe_exp:		 { ldlex_expression (); }
78033965Sjdp		exp
781218822Sdim			 { ldlex_popstate (); $$=$2;}
78233965Sjdp	;
78333965Sjdp
78433965Sjdpexp	:
78533965Sjdp		'-' exp %prec UNARY
786218822Sdim			{ $$ = exp_unop ('-', $2); }
78733965Sjdp	|	'(' exp ')'
78833965Sjdp			{ $$ = $2; }
78933965Sjdp	|	NEXT '(' exp ')' %prec UNARY
790218822Sdim			{ $$ = exp_unop ((int) $1,$3); }
79133965Sjdp	|	'!' exp %prec UNARY
792218822Sdim			{ $$ = exp_unop ('!', $2); }
79333965Sjdp	|	'+' exp %prec UNARY
79433965Sjdp			{ $$ = $2; }
79533965Sjdp	|	'~' exp %prec UNARY
796218822Sdim			{ $$ = exp_unop ('~', $2);}
79733965Sjdp
79833965Sjdp	|	exp '*' exp
799218822Sdim			{ $$ = exp_binop ('*', $1, $3); }
80033965Sjdp	|	exp '/' exp
801218822Sdim			{ $$ = exp_binop ('/', $1, $3); }
80233965Sjdp	|	exp '%' exp
803218822Sdim			{ $$ = exp_binop ('%', $1, $3); }
80433965Sjdp	|	exp '+' exp
805218822Sdim			{ $$ = exp_binop ('+', $1, $3); }
80633965Sjdp	|	exp '-' exp
807218822Sdim			{ $$ = exp_binop ('-' , $1, $3); }
80833965Sjdp	|	exp LSHIFT exp
809218822Sdim			{ $$ = exp_binop (LSHIFT , $1, $3); }
81033965Sjdp	|	exp RSHIFT exp
811218822Sdim			{ $$ = exp_binop (RSHIFT , $1, $3); }
81233965Sjdp	|	exp EQ exp
813218822Sdim			{ $$ = exp_binop (EQ , $1, $3); }
81433965Sjdp	|	exp NE exp
815218822Sdim			{ $$ = exp_binop (NE , $1, $3); }
81633965Sjdp	|	exp LE exp
817218822Sdim			{ $$ = exp_binop (LE , $1, $3); }
81833965Sjdp  	|	exp GE exp
819218822Sdim			{ $$ = exp_binop (GE , $1, $3); }
82033965Sjdp	|	exp '<' exp
821218822Sdim			{ $$ = exp_binop ('<' , $1, $3); }
82233965Sjdp	|	exp '>' exp
823218822Sdim			{ $$ = exp_binop ('>' , $1, $3); }
82433965Sjdp	|	exp '&' exp
825218822Sdim			{ $$ = exp_binop ('&' , $1, $3); }
82633965Sjdp	|	exp '^' exp
827218822Sdim			{ $$ = exp_binop ('^' , $1, $3); }
82833965Sjdp	|	exp '|' exp
829218822Sdim			{ $$ = exp_binop ('|' , $1, $3); }
83033965Sjdp	|	exp '?' exp ':' exp
831218822Sdim			{ $$ = exp_trinop ('?' , $1, $3, $5); }
83233965Sjdp	|	exp ANDAND exp
833218822Sdim			{ $$ = exp_binop (ANDAND , $1, $3); }
83433965Sjdp	|	exp OROR exp
835218822Sdim			{ $$ = exp_binop (OROR , $1, $3); }
83633965Sjdp	|	DEFINED '(' NAME ')'
837218822Sdim			{ $$ = exp_nameop (DEFINED, $3); }
83833965Sjdp	|	INT
839104834Sobrien			{ $$ = exp_bigintop ($1.integer, $1.str); }
84033965Sjdp        |	SIZEOF_HEADERS
841218822Sdim			{ $$ = exp_nameop (SIZEOF_HEADERS,0); }
84233965Sjdp
843218822Sdim	|	ALIGNOF '(' NAME ')'
844218822Sdim			{ $$ = exp_nameop (ALIGNOF,$3); }
84533965Sjdp	|	SIZEOF '(' NAME ')'
846218822Sdim			{ $$ = exp_nameop (SIZEOF,$3); }
84733965Sjdp	|	ADDR '(' NAME ')'
848218822Sdim			{ $$ = exp_nameop (ADDR,$3); }
84933965Sjdp	|	LOADADDR '(' NAME ')'
850218822Sdim			{ $$ = exp_nameop (LOADADDR,$3); }
851218822Sdim	|	CONSTANT '(' NAME ')'
852218822Sdim			{ $$ = exp_nameop (CONSTANT,$3); }
85333965Sjdp	|	ABSOLUTE '(' exp ')'
854218822Sdim			{ $$ = exp_unop (ABSOLUTE, $3); }
85533965Sjdp	|	ALIGN_K '(' exp ')'
856218822Sdim			{ $$ = exp_unop (ALIGN_K,$3); }
857130561Sobrien	|	ALIGN_K '(' exp ',' exp ')'
858218822Sdim			{ $$ = exp_binop (ALIGN_K,$3,$5); }
859104834Sobrien	|	DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
860104834Sobrien			{ $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
861218822Sdim	|	DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
862218822Sdim			{ $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
863104834Sobrien	|	DATA_SEGMENT_END '(' exp ')'
864218822Sdim			{ $$ = exp_unop (DATA_SEGMENT_END, $3); }
865218822Sdim        |       SEGMENT_START '(' NAME ',' exp ')'
866218822Sdim                        { /* The operands to the expression node are
867218822Sdim			     placed in the opposite order from the way
868218822Sdim			     in which they appear in the script as
869218822Sdim			     that allows us to reuse more code in
870218822Sdim			     fold_binary.  */
871218822Sdim			  $$ = exp_binop (SEGMENT_START,
872218822Sdim					  $5,
873218822Sdim					  exp_nameop (NAME, $3)); }
87433965Sjdp	|	BLOCK '(' exp ')'
875218822Sdim			{ $$ = exp_unop (ALIGN_K,$3); }
87633965Sjdp	|	NAME
877218822Sdim			{ $$ = exp_nameop (NAME,$1); }
87860484Sobrien	|	MAX_K '(' exp ',' exp ')'
87960484Sobrien			{ $$ = exp_binop (MAX_K, $3, $5 ); }
88060484Sobrien	|	MIN_K '(' exp ',' exp ')'
88160484Sobrien			{ $$ = exp_binop (MIN_K, $3, $5 ); }
88260484Sobrien	|	ASSERT_K '(' exp ',' NAME ')'
88360484Sobrien			{ $$ = exp_assert ($3, $5); }
884218822Sdim	|	ORIGIN '(' NAME ')'
885218822Sdim			{ $$ = exp_nameop (ORIGIN, $3); }
886218822Sdim	|	LENGTH '(' NAME ')'
887218822Sdim			{ $$ = exp_nameop (LENGTH, $3); }
88833965Sjdp	;
88933965Sjdp
89033965Sjdp
89160484Sobrienmemspec_at_opt:
89260484Sobrien                AT '>' NAME { $$ = $3; }
893104834Sobrien        |       { $$ = 0; }
89460484Sobrien        ;
89560484Sobrien
89633965Sjdpopt_at:
89733965Sjdp		AT '(' exp ')' { $$ = $3; }
89833965Sjdp	|	{ $$ = 0; }
89933965Sjdp	;
90033965Sjdp
901218822Sdimopt_align:
902218822Sdim		ALIGN_K '(' exp ')' { $$ = $3; }
903218822Sdim	|	{ $$ = 0; }
904218822Sdim	;
905218822Sdim
906130561Sobrienopt_subalign:
907130561Sobrien		SUBALIGN '(' exp ')' { $$ = $3; }
908130561Sobrien	|	{ $$ = 0; }
909130561Sobrien	;
910130561Sobrien
911218822Sdimsect_constraint:
912218822Sdim		ONLY_IF_RO { $$ = ONLY_IF_RO; }
913218822Sdim	|	ONLY_IF_RW { $$ = ONLY_IF_RW; }
914218822Sdim	|	SPECIAL { $$ = SPECIAL; }
915218822Sdim	|	{ $$ = 0; }
916218822Sdim	;
917218822Sdim
91833965Sjdpsection:	NAME 		{ ldlex_expression(); }
919130561Sobrien		opt_exp_with_type
920130561Sobrien		opt_at
921218822Sdim		opt_align
922130561Sobrien		opt_subalign	{ ldlex_popstate (); ldlex_script (); }
923218822Sdim		sect_constraint
92433965Sjdp		'{'
92533965Sjdp			{
92633965Sjdp			  lang_enter_output_section_statement($1, $3,
92733965Sjdp							      sectype,
928218822Sdim							      $5, $6, $4, $8);
92933965Sjdp			}
930130561Sobrien		statement_list_opt
93133965Sjdp 		'}' { ldlex_popstate (); ldlex_expression (); }
93260484Sobrien		memspec_opt memspec_at_opt phdr_opt fill_opt
93333965Sjdp		{
93433965Sjdp		  ldlex_popstate ();
935218822Sdim		  lang_leave_output_section_statement ($17, $14, $16, $15);
93633965Sjdp		}
93733965Sjdp		opt_comma
938107492Sobrien		{}
93933965Sjdp	|	OVERLAY
94033965Sjdp			{ ldlex_expression (); }
941130561Sobrien		opt_exp_without_type opt_nocrossrefs opt_at opt_subalign
94233965Sjdp			{ ldlex_popstate (); ldlex_script (); }
943130561Sobrien		'{'
94433965Sjdp			{
945130561Sobrien			  lang_enter_overlay ($3, $6);
94633965Sjdp			}
94733965Sjdp		overlay_section
94833965Sjdp		'}'
94933965Sjdp			{ ldlex_popstate (); ldlex_expression (); }
95060484Sobrien		memspec_opt memspec_at_opt phdr_opt fill_opt
95133965Sjdp			{
95233965Sjdp			  ldlex_popstate ();
953104834Sobrien			  lang_leave_overlay ($5, (int) $4,
954130561Sobrien					      $16, $13, $15, $14);
95533965Sjdp			}
95633965Sjdp		opt_comma
95733965Sjdp	|	/* The GROUP case is just enough to support the gcc
95833965Sjdp		   svr3.ifile script.  It is not intended to be full
95933965Sjdp		   support.  I'm not even sure what GROUP is supposed
96033965Sjdp		   to mean.  */
96133965Sjdp		GROUP { ldlex_expression (); }
96233965Sjdp		opt_exp_with_type
96333965Sjdp		{
96433965Sjdp		  ldlex_popstate ();
96533965Sjdp		  lang_add_assignment (exp_assop ('=', ".", $3));
96633965Sjdp		}
96733965Sjdp		'{' sec_or_group_p1 '}'
96833965Sjdp	;
96933965Sjdp
97033965Sjdptype:
97133965Sjdp	   NOLOAD  { sectype = noload_section; }
972218822Sdim	|  DSECT   { sectype = noalloc_section; }
973218822Sdim	|  COPY    { sectype = noalloc_section; }
974218822Sdim	|  INFO    { sectype = noalloc_section; }
975218822Sdim	|  OVERLAY { sectype = noalloc_section; }
97633965Sjdp	;
97733965Sjdp
97833965Sjdpatype:
97933965Sjdp	 	'(' type ')'
98033965Sjdp  	| 	/* EMPTY */ { sectype = normal_section; }
98138889Sjdp  	| 	'(' ')' { sectype = normal_section; }
98233965Sjdp	;
98333965Sjdp
98433965Sjdpopt_exp_with_type:
98533965Sjdp		exp atype ':'		{ $$ = $1; }
98633965Sjdp	|	atype ':'		{ $$ = (etree_type *)NULL;  }
98733965Sjdp	|	/* The BIND cases are to support the gcc svr3.ifile
98833965Sjdp		   script.  They aren't intended to implement full
98933965Sjdp		   support for the BIND keyword.  I'm not even sure
99033965Sjdp		   what BIND is supposed to mean.  */
99133965Sjdp		BIND '(' exp ')' atype ':' { $$ = $3; }
99233965Sjdp	|	BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
99333965Sjdp		{ $$ = $3; }
99433965Sjdp	;
99533965Sjdp
99633965Sjdpopt_exp_without_type:
99733965Sjdp		exp ':'		{ $$ = $1; }
99833965Sjdp	|	':'		{ $$ = (etree_type *) NULL;  }
99933965Sjdp	;
100033965Sjdp
100133965Sjdpopt_nocrossrefs:
100233965Sjdp		/* empty */
100333965Sjdp			{ $$ = 0; }
100433965Sjdp	|	NOCROSSREFS
100533965Sjdp			{ $$ = 1; }
100633965Sjdp	;
100733965Sjdp
100833965Sjdpmemspec_opt:
100933965Sjdp		'>' NAME
101033965Sjdp		{ $$ = $2; }
1011130561Sobrien	|	{ $$ = DEFAULT_MEMORY_REGION; }
101233965Sjdp	;
101333965Sjdp
101433965Sjdpphdr_opt:
101533965Sjdp		/* empty */
101633965Sjdp		{
101733965Sjdp		  $$ = NULL;
101833965Sjdp		}
101933965Sjdp	|	phdr_opt ':' NAME
102033965Sjdp		{
102133965Sjdp		  struct lang_output_section_phdr_list *n;
102233965Sjdp
102333965Sjdp		  n = ((struct lang_output_section_phdr_list *)
102433965Sjdp		       xmalloc (sizeof *n));
102533965Sjdp		  n->name = $3;
1026130561Sobrien		  n->used = FALSE;
102733965Sjdp		  n->next = $1;
102833965Sjdp		  $$ = n;
102933965Sjdp		}
103033965Sjdp	;
103133965Sjdp
103233965Sjdpoverlay_section:
103333965Sjdp		/* empty */
103433965Sjdp	|	overlay_section
103533965Sjdp		NAME
103633965Sjdp			{
103733965Sjdp			  ldlex_script ();
103833965Sjdp			  lang_enter_overlay_section ($2);
103933965Sjdp			}
104033965Sjdp		'{' statement_list_opt '}'
104133965Sjdp			{ ldlex_popstate (); ldlex_expression (); }
104233965Sjdp		phdr_opt fill_opt
104333965Sjdp			{
104433965Sjdp			  ldlex_popstate ();
104533965Sjdp			  lang_leave_overlay_section ($9, $8);
104633965Sjdp			}
104733965Sjdp		opt_comma
104833965Sjdp	;
104933965Sjdp
105033965Sjdpphdrs:
105133965Sjdp		PHDRS '{' phdr_list '}'
105233965Sjdp	;
105333965Sjdp
105433965Sjdpphdr_list:
105533965Sjdp		/* empty */
105633965Sjdp	|	phdr_list phdr
105733965Sjdp	;
105833965Sjdp
105933965Sjdpphdr:
106033965Sjdp		NAME { ldlex_expression (); }
106133965Sjdp		  phdr_type phdr_qualifiers { ldlex_popstate (); }
106233965Sjdp		  ';'
106333965Sjdp		{
106433965Sjdp		  lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
106533965Sjdp				 $4.flags);
106633965Sjdp		}
106733965Sjdp	;
106833965Sjdp
106933965Sjdpphdr_type:
107033965Sjdp		exp
107133965Sjdp		{
107233965Sjdp		  $$ = $1;
107333965Sjdp
107433965Sjdp		  if ($1->type.node_class == etree_name
107533965Sjdp		      && $1->type.node_code == NAME)
107633965Sjdp		    {
107733965Sjdp		      const char *s;
107833965Sjdp		      unsigned int i;
107933965Sjdp		      static const char * const phdr_types[] =
108033965Sjdp			{
108133965Sjdp			  "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
108233965Sjdp			  "PT_INTERP", "PT_NOTE", "PT_SHLIB",
1083130561Sobrien			  "PT_PHDR", "PT_TLS"
108433965Sjdp			};
108533965Sjdp
108633965Sjdp		      s = $1->name.name;
108733965Sjdp		      for (i = 0;
108833965Sjdp			   i < sizeof phdr_types / sizeof phdr_types[0];
108933965Sjdp			   i++)
109033965Sjdp			if (strcmp (s, phdr_types[i]) == 0)
109133965Sjdp			  {
109233965Sjdp			    $$ = exp_intop (i);
109333965Sjdp			    break;
109433965Sjdp			  }
1095130561Sobrien		      if (i == sizeof phdr_types / sizeof phdr_types[0])
1096130561Sobrien			{
1097130561Sobrien			  if (strcmp (s, "PT_GNU_EH_FRAME") == 0)
1098130561Sobrien			    $$ = exp_intop (0x6474e550);
1099130561Sobrien			  else if (strcmp (s, "PT_GNU_STACK") == 0)
1100130561Sobrien			    $$ = exp_intop (0x6474e551);
1101130561Sobrien			  else
1102130561Sobrien			    {
1103130561Sobrien			      einfo (_("\
1104130561Sobrien%X%P:%S: unknown phdr type `%s' (try integer literal)\n"),
1105130561Sobrien				     s);
1106130561Sobrien			      $$ = exp_intop (0);
1107130561Sobrien			    }
1108130561Sobrien			}
110933965Sjdp		    }
111033965Sjdp		}
111133965Sjdp	;
111233965Sjdp
111333965Sjdpphdr_qualifiers:
111433965Sjdp		/* empty */
111533965Sjdp		{
111633965Sjdp		  memset (&$$, 0, sizeof (struct phdr_info));
111733965Sjdp		}
111833965Sjdp	|	NAME phdr_val phdr_qualifiers
111933965Sjdp		{
112033965Sjdp		  $$ = $3;
112133965Sjdp		  if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
1122130561Sobrien		    $$.filehdr = TRUE;
112333965Sjdp		  else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
1124130561Sobrien		    $$.phdrs = TRUE;
112533965Sjdp		  else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
112633965Sjdp		    $$.flags = $2;
112733965Sjdp		  else
112860484Sobrien		    einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
112933965Sjdp		}
113033965Sjdp	|	AT '(' exp ')' phdr_qualifiers
113133965Sjdp		{
113233965Sjdp		  $$ = $5;
113333965Sjdp		  $$.at = $3;
113433965Sjdp		}
113533965Sjdp	;
113633965Sjdp
113733965Sjdpphdr_val:
113833965Sjdp		/* empty */
113933965Sjdp		{
114033965Sjdp		  $$ = NULL;
114133965Sjdp		}
114233965Sjdp	| '(' exp ')'
114333965Sjdp		{
114433965Sjdp		  $$ = $2;
114533965Sjdp		}
114633965Sjdp	;
114733965Sjdp
1148218822Sdimdynamic_list_file:
1149218822Sdim		{
1150218822Sdim		  ldlex_version_file ();
1151218822Sdim		  PUSH_ERROR (_("dynamic list"));
1152218822Sdim		}
1153218822Sdim		dynamic_list_nodes
1154218822Sdim		{
1155218822Sdim		  ldlex_popstate ();
1156218822Sdim		  POP_ERROR ();
1157218822Sdim		}
1158218822Sdim	;
1159218822Sdim
1160218822Sdimdynamic_list_nodes:
1161218822Sdim		dynamic_list_node
1162218822Sdim	|	dynamic_list_nodes dynamic_list_node
1163218822Sdim	;
1164218822Sdim
1165218822Sdimdynamic_list_node:
1166218822Sdim		'{' dynamic_list_tag '}' ';'
1167218822Sdim	;
1168218822Sdim
1169218822Sdimdynamic_list_tag:
1170218822Sdim		vers_defns ';'
1171218822Sdim		{
1172218822Sdim		  lang_append_dynamic_list ($1);
1173218822Sdim		}
1174218822Sdim	;
1175218822Sdim
117633965Sjdp/* This syntax is used within an external version script file.  */
117733965Sjdp
117833965Sjdpversion_script_file:
117933965Sjdp		{
118033965Sjdp		  ldlex_version_file ();
118160484Sobrien		  PUSH_ERROR (_("VERSION script"));
118233965Sjdp		}
118333965Sjdp		vers_nodes
118433965Sjdp		{
118533965Sjdp		  ldlex_popstate ();
118633965Sjdp		  POP_ERROR ();
118733965Sjdp		}
118833965Sjdp	;
118933965Sjdp
119033965Sjdp/* This is used within a normal linker script file.  */
119133965Sjdp
119233965Sjdpversion:
119333965Sjdp		{
119433965Sjdp		  ldlex_version_script ();
119533965Sjdp		}
119638889Sjdp		VERSIONK '{' vers_nodes '}'
119733965Sjdp		{
119833965Sjdp		  ldlex_popstate ();
119933965Sjdp		}
120033965Sjdp	;
120133965Sjdp
120233965Sjdpvers_nodes:
120333965Sjdp		vers_node
120433965Sjdp	|	vers_nodes vers_node
120533965Sjdp	;
120633965Sjdp
120733965Sjdpvers_node:
120889857Sobrien		'{' vers_tag '}' ';'
120933965Sjdp		{
121089857Sobrien		  lang_register_vers_node (NULL, $2, NULL);
121189857Sobrien		}
121289857Sobrien	|	VERS_TAG '{' vers_tag '}' ';'
121389857Sobrien		{
121433965Sjdp		  lang_register_vers_node ($1, $3, NULL);
121533965Sjdp		}
121633965Sjdp	|	VERS_TAG '{' vers_tag '}' verdep ';'
121733965Sjdp		{
121833965Sjdp		  lang_register_vers_node ($1, $3, $5);
121933965Sjdp		}
122033965Sjdp	;
122133965Sjdp
122233965Sjdpverdep:
122333965Sjdp		VERS_TAG
122433965Sjdp		{
122533965Sjdp		  $$ = lang_add_vers_depend (NULL, $1);
122633965Sjdp		}
122733965Sjdp	|	verdep VERS_TAG
122833965Sjdp		{
122933965Sjdp		  $$ = lang_add_vers_depend ($1, $2);
123033965Sjdp		}
123133965Sjdp	;
123233965Sjdp
123333965Sjdpvers_tag:
123433965Sjdp		/* empty */
123533965Sjdp		{
123633965Sjdp		  $$ = lang_new_vers_node (NULL, NULL);
123733965Sjdp		}
123833965Sjdp	|	vers_defns ';'
123933965Sjdp		{
124033965Sjdp		  $$ = lang_new_vers_node ($1, NULL);
124133965Sjdp		}
124233965Sjdp	|	GLOBAL ':' vers_defns ';'
124333965Sjdp		{
124433965Sjdp		  $$ = lang_new_vers_node ($3, NULL);
124533965Sjdp		}
124633965Sjdp	|	LOCAL ':' vers_defns ';'
124733965Sjdp		{
124833965Sjdp		  $$ = lang_new_vers_node (NULL, $3);
124933965Sjdp		}
125033965Sjdp	|	GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
125133965Sjdp		{
125233965Sjdp		  $$ = lang_new_vers_node ($3, $7);
125333965Sjdp		}
125433965Sjdp	;
125533965Sjdp
125633965Sjdpvers_defns:
125733965Sjdp		VERS_IDENTIFIER
125833965Sjdp		{
1259218822Sdim		  $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, FALSE);
126033965Sjdp		}
1261218822Sdim        |       NAME
1262218822Sdim		{
1263218822Sdim		  $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, TRUE);
1264218822Sdim		}
126533965Sjdp	|	vers_defns ';' VERS_IDENTIFIER
126633965Sjdp		{
1267218822Sdim		  $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, FALSE);
126833965Sjdp		}
1269218822Sdim	|	vers_defns ';' NAME
1270218822Sdim		{
1271218822Sdim		  $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, TRUE);
1272218822Sdim		}
1273130561Sobrien	|	vers_defns ';' EXTERN NAME '{'
1274130561Sobrien			{
1275130561Sobrien			  $<name>$ = ldgram_vers_current_lang;
1276130561Sobrien			  ldgram_vers_current_lang = $4;
1277130561Sobrien			}
1278130561Sobrien		vers_defns opt_semicolon '}'
1279130561Sobrien			{
1280218822Sdim			  struct bfd_elf_version_expr *pat;
1281218822Sdim			  for (pat = $7; pat->next != NULL; pat = pat->next);
1282218822Sdim			  pat->next = $1;
1283130561Sobrien			  $$ = $7;
1284130561Sobrien			  ldgram_vers_current_lang = $<name>6;
1285130561Sobrien			}
128660484Sobrien	|	EXTERN NAME '{'
128760484Sobrien			{
128860484Sobrien			  $<name>$ = ldgram_vers_current_lang;
128960484Sobrien			  ldgram_vers_current_lang = $2;
129060484Sobrien			}
1291130561Sobrien		vers_defns opt_semicolon '}'
129260484Sobrien			{
129377298Sobrien			  $$ = $5;
129460484Sobrien			  ldgram_vers_current_lang = $<name>4;
129560484Sobrien			}
1296218822Sdim	|	GLOBAL
1297218822Sdim		{
1298218822Sdim		  $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang, FALSE);
1299218822Sdim		}
1300218822Sdim	|	vers_defns ';' GLOBAL
1301218822Sdim		{
1302218822Sdim		  $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang, FALSE);
1303218822Sdim		}
1304218822Sdim	|	LOCAL
1305218822Sdim		{
1306218822Sdim		  $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang, FALSE);
1307218822Sdim		}
1308218822Sdim	|	vers_defns ';' LOCAL
1309218822Sdim		{
1310218822Sdim		  $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang, FALSE);
1311218822Sdim		}
1312218822Sdim	|	EXTERN
1313218822Sdim		{
1314218822Sdim		  $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang, FALSE);
1315218822Sdim		}
1316218822Sdim	|	vers_defns ';' EXTERN
1317218822Sdim		{
1318218822Sdim		  $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, FALSE);
1319218822Sdim		}
132033965Sjdp	;
132133965Sjdp
1322130561Sobrienopt_semicolon:
1323130561Sobrien		/* empty */
1324130561Sobrien	|	';'
1325130561Sobrien	;
1326130561Sobrien
132733965Sjdp%%
132833965Sjdpvoid
1329130561Sobrienyyerror(arg)
133033965Sjdp     const char *arg;
1331130561Sobrien{
133233965Sjdp  if (ldfile_assumed_script)
133360484Sobrien    einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
133433965Sjdp	   ldfile_input_filename);
133533965Sjdp  if (error_index > 0 && error_index < ERROR_NAME_MAX)
133633965Sjdp     einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
133733965Sjdp  else
133833965Sjdp     einfo ("%P%F:%S: %s\n", arg);
133933965Sjdp}
1340