1 /* A YACC grammar to parse a superset of the AT&T linker scripting language.
2    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3    2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4    Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
5 
6    This file is part of GNU ld.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21 
22 %{
23 /*
24 
25  */
26 
27 #define DONTDECLARE_MALLOC
28 
29 #include "bfd.h"
30 #include "sysdep.h"
31 #include "bfdlink.h"
32 #include "ld.h"
33 #include "ldexp.h"
34 #include "ldver.h"
35 #include "ldlang.h"
36 #include "ldfile.h"
37 #include "ldemul.h"
38 #include "ldmisc.h"
39 #include "ldmain.h"
40 #include "mri.h"
41 #include "ldctor.h"
42 #include "ldlex.h"
43 
44 #ifndef YYDEBUG
45 #define YYDEBUG 1
46 #endif
47 
48 static enum section_type sectype;
49 static lang_memory_region_type *region;
50 
51 FILE *saved_script_handle = NULL;
52 bfd_boolean force_make_executable = FALSE;
53 
54 bfd_boolean ldgram_in_script = FALSE;
55 bfd_boolean ldgram_had_equals = FALSE;
56 bfd_boolean ldgram_had_keep = FALSE;
57 char *ldgram_vers_current_lang = NULL;
58 
59 #define ERROR_NAME_MAX 20
60 static char *error_names[ERROR_NAME_MAX];
61 static int error_index;
62 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
63 #define POP_ERROR()   error_index--;
64 %}
65 %union {
66   bfd_vma integer;
67   struct big_int
68     {
69       bfd_vma integer;
70       char *str;
71     } bigint;
72   fill_type *fill;
73   char *name;
74   const char *cname;
75   struct wildcard_spec wildcard;
76   struct wildcard_list *wildcard_list;
77   struct name_list *name_list;
78   int token;
79   union etree_union *etree;
80   struct phdr_info
81     {
82       bfd_boolean filehdr;
83       bfd_boolean phdrs;
84       union etree_union *at;
85       union etree_union *flags;
86     } phdr;
87   struct lang_nocrossref *nocrossref;
88   struct lang_output_section_phdr_list *section_phdr;
89   struct bfd_elf_version_deps *deflist;
90   struct bfd_elf_version_expr *versyms;
91   struct bfd_elf_version_tree *versnode;
92 }
93 
94 %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
95 %type <etree> opt_exp_without_type opt_subalign opt_align
96 %type <fill> fill_opt fill_exp
97 %type <name_list> exclude_name_list
98 %type <wildcard_list> file_NAME_list
99 %type <name> memspec_opt casesymlist
100 %type <name> memspec_at_opt
101 %type <cname> wildcard_name
102 %type <wildcard> wildcard_spec
103 %token <bigint> INT
104 %token <name> NAME LNAME
105 %type <integer> length
106 %type <phdr> phdr_qualifiers
107 %type <nocrossref> nocrossref_list
108 %type <section_phdr> phdr_opt
109 %type <integer> opt_nocrossrefs
110 
111 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ
112 %right <token> '?' ':'
113 %left <token> OROR
114 %left <token>  ANDAND
115 %left <token> '|'
116 %left <token>  '^'
117 %left  <token> '&'
118 %left <token>  EQ NE
119 %left  <token> '<' '>' LE GE
120 %left  <token> LSHIFT RSHIFT
121 
122 %left  <token> '+' '-'
123 %left  <token> '*' '/' '%'
124 
125 %right UNARY
126 %token END
127 %left <token> '('
128 %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
129 %token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
130 %token SORT_BY_NAME SORT_BY_ALIGNMENT
131 %token '{' '}'
132 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
133 %token INHIBIT_COMMON_ALLOCATION
134 %token SIZEOF_HEADERS
135 %token SEGMENT_START
136 %token INCLUDE
137 %token MEMORY DEFSYMEND
138 %token NOLOAD DSECT COPY INFO OVERLAY
139 %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
140 %token <integer> NEXT
141 %token SIZEOF ADDR LOADADDR MAX_K MIN_K
142 %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
143 %token ORIGIN FILL
144 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
145 %token ALIGNMOD AT SUBALIGN PROVIDE PROVIDE_HIDDEN AS_NEEDED
146 %type <token> assign_op atype attributes_opt sect_constraint
147 %type <name>  filename
148 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
149 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
150 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
151 %token <name> VERS_TAG VERS_IDENTIFIER
152 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
153 %token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL
154 %token EXCLUDE_FILE
155 %type <versyms> vers_defns
156 %type <versnode> vers_tag
157 %type <deflist> verdep
158 
159 %%
160 
161 file:
162 		INPUT_SCRIPT script_file
163 	|	INPUT_MRI_SCRIPT mri_script_file
164 	|	INPUT_VERSION_SCRIPT version_script_file
165 	|	INPUT_DEFSYM defsym_expr
166 	;
167 
168 
169 filename:  NAME;
170 
171 
172 defsym_expr:
173 		{ ldlex_defsym(); }
174 		NAME '=' exp
175 		{
176 		  ldlex_popstate();
177 		  lang_add_assignment(exp_assop($3,$2,$4));
178 		}
179 	;
180 
181 /* SYNTAX WITHIN AN MRI SCRIPT FILE */
182 mri_script_file:
183 		{
184 		  ldlex_mri_script ();
185 		  PUSH_ERROR (_("MRI style script"));
186 		}
187 	     mri_script_lines
188 		{
189 		  ldlex_popstate ();
190 		  mri_draw_tree ();
191 		  POP_ERROR ();
192 		}
193 	;
194 
195 mri_script_lines:
196 		mri_script_lines mri_script_command NEWLINE
197           |
198 	;
199 
200 mri_script_command:
201 		CHIP  exp
202 	|	CHIP  exp ',' exp
203 	|	NAME 	{
204 			einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
205 			}
206 	|	LIST  	{
207 			config.map_filename = "-";
208 			}
209         |       ORDER ordernamelist
210 	|       ENDWORD
211         |       PUBLIC NAME '=' exp
212  			{ mri_public($2, $4); }
213         |       PUBLIC NAME ',' exp
214  			{ mri_public($2, $4); }
215         |       PUBLIC NAME  exp
216  			{ mri_public($2, $3); }
217 	| 	FORMAT NAME
218 			{ mri_format($2); }
219 	|	SECT NAME ',' exp
220 			{ mri_output_section($2, $4);}
221 	|	SECT NAME  exp
222 			{ mri_output_section($2, $3);}
223 	|	SECT NAME '=' exp
224 			{ mri_output_section($2, $4);}
225 	|	ALIGN_K NAME '=' exp
226 			{ mri_align($2,$4); }
227 	|	ALIGN_K NAME ',' exp
228 			{ mri_align($2,$4); }
229 	|	ALIGNMOD NAME '=' exp
230 			{ mri_alignmod($2,$4); }
231 	|	ALIGNMOD NAME ',' exp
232 			{ mri_alignmod($2,$4); }
233 	|	ABSOLUTE mri_abs_name_list
234 	|	LOAD	 mri_load_name_list
235 	|       NAMEWORD NAME
236 			{ mri_name($2); }
237 	|	ALIAS NAME ',' NAME
238 			{ mri_alias($2,$4,0);}
239 	|	ALIAS NAME ',' INT
240 			{ mri_alias ($2, 0, (int) $4.integer); }
241 	|	BASE     exp
242 			{ mri_base($2); }
243 	|	TRUNCATE INT
244 		{ mri_truncate ((unsigned int) $2.integer); }
245 	|	CASE casesymlist
246 	|	EXTERN extern_name_list
247 	|	INCLUDE filename
248 		{ ldlex_script (); ldfile_open_command_file($2); }
249 		mri_script_lines END
250 		{ ldlex_popstate (); }
251 	|	START NAME
252 		{ lang_add_entry ($2, FALSE); }
253         |
254 	;
255 
256 ordernamelist:
257 	      ordernamelist ',' NAME         { mri_order($3); }
258 	|     ordernamelist  NAME         { mri_order($2); }
259       	|
260 	;
261 
262 mri_load_name_list:
263 		NAME
264 			{ mri_load($1); }
265 	|	mri_load_name_list ',' NAME { mri_load($3); }
266 	;
267 
268 mri_abs_name_list:
269  		NAME
270  			{ mri_only_load($1); }
271 	|	mri_abs_name_list ','  NAME
272  			{ mri_only_load($3); }
273 	;
274 
275 casesymlist:
276 	  /* empty */ { $$ = NULL; }
277 	| NAME
278 	| casesymlist ',' NAME
279 	;
280 
281 extern_name_list:
282 	  NAME
283 			{ ldlang_add_undef ($1); }
284 	| extern_name_list NAME
285 			{ ldlang_add_undef ($2); }
286 	| extern_name_list ',' NAME
287 			{ ldlang_add_undef ($3); }
288 	;
289 
290 script_file:
291 	{
292 	 ldlex_both();
293 	}
294        ifile_list
295 	{
296 	ldlex_popstate();
297 	}
298         ;
299 
300 
301 ifile_list:
302        ifile_list ifile_p1
303         |
304 	;
305 
306 
307 
308 ifile_p1:
309 		memory
310 	|	sections
311 	|	phdrs
312 	|	startup
313 	|	high_level_library
314 	|	low_level_library
315 	|	floating_point_support
316 	|	statement_anywhere
317 	|	version
318         |	 ';'
319 	|	TARGET_K '(' NAME ')'
320 		{ lang_add_target($3); }
321 	|	SEARCH_DIR '(' filename ')'
322 		{ ldfile_add_library_path ($3, FALSE); }
323 	|	OUTPUT '(' filename ')'
324 		{ lang_add_output($3, 1); }
325         |	OUTPUT_FORMAT '(' NAME ')'
326 		  { lang_add_output_format ($3, (char *) NULL,
327 					    (char *) NULL, 1); }
328 	|	OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
329 		  { lang_add_output_format ($3, $5, $7, 1); }
330         |	OUTPUT_ARCH '(' NAME ')'
331 		  { ldfile_set_output_arch ($3, bfd_arch_unknown); }
332 	|	FORCE_COMMON_ALLOCATION
333 		{ command_line.force_common_definition = TRUE ; }
334 	|	INHIBIT_COMMON_ALLOCATION
335 		{ command_line.inhibit_common_definition = TRUE ; }
336 	|	INPUT '(' input_list ')'
337 	|	GROUP
338 		  { lang_enter_group (); }
339 		    '(' input_list ')'
340 		  { lang_leave_group (); }
341      	|	MAP '(' filename ')'
342 		{ lang_add_map($3); }
343 	|	INCLUDE filename
344 		{ ldlex_script (); ldfile_open_command_file($2); }
345 		ifile_list END
346 		{ ldlex_popstate (); }
347 	|	NOCROSSREFS '(' nocrossref_list ')'
348 		{
349 		  lang_add_nocrossref ($3);
350 		}
351 	|	EXTERN '(' extern_name_list ')'
352 	;
353 
354 input_list:
355 		NAME
356 		{ lang_add_input_file($1,lang_input_file_is_search_file_enum,
357 				 (char *)NULL); }
358 	|	input_list ',' NAME
359 		{ lang_add_input_file($3,lang_input_file_is_search_file_enum,
360 				 (char *)NULL); }
361 	|	input_list NAME
362 		{ lang_add_input_file($2,lang_input_file_is_search_file_enum,
363 				 (char *)NULL); }
364 	|	LNAME
365 		{ lang_add_input_file($1,lang_input_file_is_l_enum,
366 				 (char *)NULL); }
367 	|	input_list ',' LNAME
368 		{ lang_add_input_file($3,lang_input_file_is_l_enum,
369 				 (char *)NULL); }
370 	|	input_list LNAME
371 		{ lang_add_input_file($2,lang_input_file_is_l_enum,
372 				 (char *)NULL); }
373 	|	AS_NEEDED '('
374 		  { $<integer>$ = as_needed; as_needed = TRUE; }
375 		     input_list ')'
376 		  { as_needed = $<integer>3; }
377 	|	input_list ',' AS_NEEDED '('
378 		  { $<integer>$ = as_needed; as_needed = TRUE; }
379 		     input_list ')'
380 		  { as_needed = $<integer>5; }
381 	|	input_list AS_NEEDED '('
382 		  { $<integer>$ = as_needed; as_needed = TRUE; }
383 		     input_list ')'
384 		  { as_needed = $<integer>4; }
385 	;
386 
387 sections:
388 		SECTIONS '{' sec_or_group_p1 '}'
389 	;
390 
391 sec_or_group_p1:
392 		sec_or_group_p1 section
393 	|	sec_or_group_p1 statement_anywhere
394 	|
395 	;
396 
397 statement_anywhere:
398 		ENTRY '(' NAME ')'
399 		{ lang_add_entry ($3, FALSE); }
400 	|	assignment end
401 	|	ASSERT_K  {ldlex_expression ();} '(' exp ',' NAME ')'
402 		{ ldlex_popstate ();
403 		  lang_add_assignment (exp_assert ($4, $6)); }
404 	;
405 
406 /* The '*' and '?' cases are there because the lexer returns them as
407    separate tokens rather than as NAME.  */
408 wildcard_name:
409 		NAME
410 			{
411 			  $$ = $1;
412 			}
413 	|	'*'
414 			{
415 			  $$ = "*";
416 			}
417 	|	'?'
418 			{
419 			  $$ = "?";
420 			}
421 	;
422 
423 wildcard_spec:
424 		wildcard_name
425 			{
426 			  $$.name = $1;
427 			  $$.sorted = none;
428 			  $$.exclude_name_list = NULL;
429 			}
430 	| 	EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name
431 			{
432 			  $$.name = $5;
433 			  $$.sorted = none;
434 			  $$.exclude_name_list = $3;
435 			}
436 	|	SORT_BY_NAME '(' wildcard_name ')'
437 			{
438 			  $$.name = $3;
439 			  $$.sorted = by_name;
440 			  $$.exclude_name_list = NULL;
441 			}
442 	|	SORT_BY_ALIGNMENT '(' wildcard_name ')'
443 			{
444 			  $$.name = $3;
445 			  $$.sorted = by_alignment;
446 			  $$.exclude_name_list = NULL;
447 			}
448 	|	SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
449 			{
450 			  $$.name = $5;
451 			  $$.sorted = by_name_alignment;
452 			  $$.exclude_name_list = NULL;
453 			}
454 	|	SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')'
455 			{
456 			  $$.name = $5;
457 			  $$.sorted = by_name;
458 			  $$.exclude_name_list = NULL;
459 			}
460 	|	SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')'
461 			{
462 			  $$.name = $5;
463 			  $$.sorted = by_alignment_name;
464 			  $$.exclude_name_list = NULL;
465 			}
466 	|	SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
467 			{
468 			  $$.name = $5;
469 			  $$.sorted = by_alignment;
470 			  $$.exclude_name_list = NULL;
471 			}
472 	|	SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
473 			{
474 			  $$.name = $7;
475 			  $$.sorted = by_name;
476 			  $$.exclude_name_list = $5;
477 			}
478 	;
479 
480 exclude_name_list:
481 		exclude_name_list wildcard_name
482 			{
483 			  struct name_list *tmp;
484 			  tmp = (struct name_list *) xmalloc (sizeof *tmp);
485 			  tmp->name = $2;
486 			  tmp->next = $1;
487 			  $$ = tmp;
488 			}
489 	|
490 		wildcard_name
491 			{
492 			  struct name_list *tmp;
493 			  tmp = (struct name_list *) xmalloc (sizeof *tmp);
494 			  tmp->name = $1;
495 			  tmp->next = NULL;
496 			  $$ = tmp;
497 			}
498 	;
499 
500 file_NAME_list:
501 		file_NAME_list opt_comma wildcard_spec
502 			{
503 			  struct wildcard_list *tmp;
504 			  tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
505 			  tmp->next = $1;
506 			  tmp->spec = $3;
507 			  $$ = tmp;
508 			}
509 	|
510 		wildcard_spec
511 			{
512 			  struct wildcard_list *tmp;
513 			  tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
514 			  tmp->next = NULL;
515 			  tmp->spec = $1;
516 			  $$ = tmp;
517 			}
518 	;
519 
520 input_section_spec_no_keep:
521 		NAME
522 			{
523 			  struct wildcard_spec tmp;
524 			  tmp.name = $1;
525 			  tmp.exclude_name_list = NULL;
526 			  tmp.sorted = none;
527 			  lang_add_wild (&tmp, NULL, ldgram_had_keep);
528 			}
529         |	'[' file_NAME_list ']'
530 			{
531 			  lang_add_wild (NULL, $2, ldgram_had_keep);
532 			}
533 	|	wildcard_spec '(' file_NAME_list ')'
534 			{
535 			  lang_add_wild (&$1, $3, ldgram_had_keep);
536 			}
537 	;
538 
539 input_section_spec:
540 		input_section_spec_no_keep
541 	|	KEEP '('
542 			{ ldgram_had_keep = TRUE; }
543 		input_section_spec_no_keep ')'
544 			{ ldgram_had_keep = FALSE; }
545 	;
546 
547 statement:
548 	  	assignment end
549 	|	CREATE_OBJECT_SYMBOLS
550 		{
551  		lang_add_attribute(lang_object_symbols_statement_enum);
552 	      	}
553         |	';'
554         |	CONSTRUCTORS
555 		{
556 
557 		  lang_add_attribute(lang_constructors_statement_enum);
558 		}
559 	| SORT_BY_NAME '(' CONSTRUCTORS ')'
560 		{
561 		  constructors_sorted = TRUE;
562 		  lang_add_attribute (lang_constructors_statement_enum);
563 		}
564 	| input_section_spec
565         | length '(' mustbe_exp ')'
566         	        {
567 			  lang_add_data ((int) $1, $3);
568 			}
569 
570 	| FILL '(' fill_exp ')'
571 			{
572 			  lang_add_fill ($3);
573 			}
574 	;
575 
576 statement_list:
577 		statement_list statement
578   	|  	statement
579 	;
580 
581 statement_list_opt:
582 		/* empty */
583 	|	statement_list
584 	;
585 
586 length:
587 		QUAD
588 			{ $$ = $1; }
589 	|	SQUAD
590 			{ $$ = $1; }
591 	|	LONG
592 			{ $$ = $1; }
593 	| 	SHORT
594 			{ $$ = $1; }
595 	|	BYTE
596 			{ $$ = $1; }
597 	;
598 
599 fill_exp:
600 	mustbe_exp
601 		{
602 		  $$ = exp_get_fill ($1, 0, "fill value");
603 		}
604 	;
605 
606 fill_opt:
607 	  '=' fill_exp
608 		{ $$ = $2; }
609 	| 	{ $$ = (fill_type *) 0; }
610 	;
611 
612 assign_op:
613 		PLUSEQ
614 			{ $$ = '+'; }
615 	|	MINUSEQ
616 			{ $$ = '-'; }
617 	| 	MULTEQ
618 			{ $$ = '*'; }
619 	| 	DIVEQ
620 			{ $$ = '/'; }
621 	| 	LSHIFTEQ
622 			{ $$ = LSHIFT; }
623 	| 	RSHIFTEQ
624 			{ $$ = RSHIFT; }
625 	| 	ANDEQ
626 			{ $$ = '&'; }
627 	| 	OREQ
628 			{ $$ = '|'; }
629 
630 	;
631 
632 end:	';' | ','
633 	;
634 
635 
636 assignment:
637 		NAME '=' mustbe_exp
638 		{
639 		  lang_add_assignment (exp_assop ($2, $1, $3));
640 		}
641 	|	NAME assign_op mustbe_exp
642 		{
643 		  lang_add_assignment (exp_assop ('=', $1,
644 						  exp_binop ($2,
645 							     exp_nameop (NAME,
646 									 $1),
647 							     $3)));
648 		}
649 	|	PROVIDE '(' NAME '=' mustbe_exp ')'
650 		{
651 		  lang_add_assignment (exp_provide ($3, $5, FALSE));
652 		}
653 	|	PROVIDE_HIDDEN '(' NAME '=' mustbe_exp ')'
654 		{
655 		  lang_add_assignment (exp_provide ($3, $5, TRUE));
656 		}
657 	;
658 
659 
660 opt_comma:
661 		','	|	;
662 
663 
664 memory:
665 		MEMORY '{' memory_spec memory_spec_list '}'
666 	;
667 
668 memory_spec_list:
669 		memory_spec_list memory_spec
670 	|	memory_spec_list ',' memory_spec
671 	|
672 	;
673 
674 
675 memory_spec: 	NAME
676 		{ region = lang_memory_region_lookup ($1, TRUE); }
677 		attributes_opt ':'
678 		origin_spec opt_comma length_spec
679 		{}
680 	;
681 
682 origin_spec:
683 	ORIGIN '=' mustbe_exp
684 		{
685 		  region->origin = exp_get_vma ($3, 0, "origin");
686 		  region->current = region->origin;
687 		}
688 	;
689 
690 length_spec:
691              LENGTH '=' mustbe_exp
692 		{
693 		  region->length = exp_get_vma ($3, -1, "length");
694 		}
695 	;
696 
697 attributes_opt:
698 		/* empty */
699 		  { /* dummy action to avoid bison 1.25 error message */ }
700 	|	'(' attributes_list ')'
701 	;
702 
703 attributes_list:
704 		attributes_string
705 	|	attributes_list attributes_string
706 	;
707 
708 attributes_string:
709 		NAME
710 		  { lang_set_flags (region, $1, 0); }
711 	|	'!' NAME
712 		  { lang_set_flags (region, $2, 1); }
713 	;
714 
715 startup:
716 	STARTUP '(' filename ')'
717 		{ lang_startup($3); }
718 	;
719 
720 high_level_library:
721 		HLL '(' high_level_library_NAME_list ')'
722 	|	HLL '(' ')'
723 			{ ldemul_hll((char *)NULL); }
724 	;
725 
726 high_level_library_NAME_list:
727 		high_level_library_NAME_list opt_comma filename
728 			{ ldemul_hll($3); }
729 	|	filename
730 			{ ldemul_hll($1); }
731 
732 	;
733 
734 low_level_library:
735 	SYSLIB '(' low_level_library_NAME_list ')'
736 	; low_level_library_NAME_list:
737 		low_level_library_NAME_list opt_comma filename
738 			{ ldemul_syslib($3); }
739 	|
740 	;
741 
742 floating_point_support:
743 		FLOAT
744 			{ lang_float(TRUE); }
745 	|	NOFLOAT
746 			{ lang_float(FALSE); }
747 	;
748 
749 nocrossref_list:
750 		/* empty */
751 		{
752 		  $$ = NULL;
753 		}
754 	|	NAME nocrossref_list
755 		{
756 		  struct lang_nocrossref *n;
757 
758 		  n = (struct lang_nocrossref *) xmalloc (sizeof *n);
759 		  n->name = $1;
760 		  n->next = $2;
761 		  $$ = n;
762 		}
763 	|	NAME ',' nocrossref_list
764 		{
765 		  struct lang_nocrossref *n;
766 
767 		  n = (struct lang_nocrossref *) xmalloc (sizeof *n);
768 		  n->name = $1;
769 		  n->next = $3;
770 		  $$ = n;
771 		}
772 	;
773 
774 mustbe_exp:		 { ldlex_expression (); }
775 		exp
776 			 { ldlex_popstate (); $$=$2;}
777 	;
778 
779 exp	:
780 		'-' exp %prec UNARY
781 			{ $$ = exp_unop ('-', $2); }
782 	|	'(' exp ')'
783 			{ $$ = $2; }
784 	|	NEXT '(' exp ')' %prec UNARY
785 			{ $$ = exp_unop ((int) $1,$3); }
786 	|	'!' exp %prec UNARY
787 			{ $$ = exp_unop ('!', $2); }
788 	|	'+' exp %prec UNARY
789 			{ $$ = $2; }
790 	|	'~' exp %prec UNARY
791 			{ $$ = exp_unop ('~', $2);}
792 
793 	|	exp '*' exp
794 			{ $$ = exp_binop ('*', $1, $3); }
795 	|	exp '/' exp
796 			{ $$ = exp_binop ('/', $1, $3); }
797 	|	exp '%' exp
798 			{ $$ = exp_binop ('%', $1, $3); }
799 	|	exp '+' exp
800 			{ $$ = exp_binop ('+', $1, $3); }
801 	|	exp '-' exp
802 			{ $$ = exp_binop ('-' , $1, $3); }
803 	|	exp LSHIFT exp
804 			{ $$ = exp_binop (LSHIFT , $1, $3); }
805 	|	exp RSHIFT exp
806 			{ $$ = exp_binop (RSHIFT , $1, $3); }
807 	|	exp EQ exp
808 			{ $$ = exp_binop (EQ , $1, $3); }
809 	|	exp NE exp
810 			{ $$ = exp_binop (NE , $1, $3); }
811 	|	exp LE exp
812 			{ $$ = exp_binop (LE , $1, $3); }
813   	|	exp GE exp
814 			{ $$ = exp_binop (GE , $1, $3); }
815 	|	exp '<' exp
816 			{ $$ = exp_binop ('<' , $1, $3); }
817 	|	exp '>' exp
818 			{ $$ = exp_binop ('>' , $1, $3); }
819 	|	exp '&' exp
820 			{ $$ = exp_binop ('&' , $1, $3); }
821 	|	exp '^' exp
822 			{ $$ = exp_binop ('^' , $1, $3); }
823 	|	exp '|' exp
824 			{ $$ = exp_binop ('|' , $1, $3); }
825 	|	exp '?' exp ':' exp
826 			{ $$ = exp_trinop ('?' , $1, $3, $5); }
827 	|	exp ANDAND exp
828 			{ $$ = exp_binop (ANDAND , $1, $3); }
829 	|	exp OROR exp
830 			{ $$ = exp_binop (OROR , $1, $3); }
831 	|	DEFINED '(' NAME ')'
832 			{ $$ = exp_nameop (DEFINED, $3); }
833 	|	INT
834 			{ $$ = exp_bigintop ($1.integer, $1.str); }
835         |	SIZEOF_HEADERS
836 			{ $$ = exp_nameop (SIZEOF_HEADERS,0); }
837 
838 	|	SIZEOF '(' NAME ')'
839 			{ $$ = exp_nameop (SIZEOF,$3); }
840 	|	ADDR '(' NAME ')'
841 			{ $$ = exp_nameop (ADDR,$3); }
842 	|	LOADADDR '(' NAME ')'
843 			{ $$ = exp_nameop (LOADADDR,$3); }
844 	|	ABSOLUTE '(' exp ')'
845 			{ $$ = exp_unop (ABSOLUTE, $3); }
846 	|	ALIGN_K '(' exp ')'
847 			{ $$ = exp_unop (ALIGN_K,$3); }
848 	|	ALIGN_K '(' exp ',' exp ')'
849 			{ $$ = exp_binop (ALIGN_K,$3,$5); }
850 	|	DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
851 			{ $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
852 	|	DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
853 			{ $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
854 	|	DATA_SEGMENT_END '(' exp ')'
855 			{ $$ = exp_unop (DATA_SEGMENT_END, $3); }
856         |       SEGMENT_START '(' NAME ',' exp ')'
857                         { /* The operands to the expression node are
858 			     placed in the opposite order from the way
859 			     in which they appear in the script as
860 			     that allows us to reuse more code in
861 			     fold_binary.  */
862 			  $$ = exp_binop (SEGMENT_START,
863 					  $5,
864 					  exp_nameop (NAME, $3)); }
865 	|	BLOCK '(' exp ')'
866 			{ $$ = exp_unop (ALIGN_K,$3); }
867 	|	NAME
868 			{ $$ = exp_nameop (NAME,$1); }
869 	|	MAX_K '(' exp ',' exp ')'
870 			{ $$ = exp_binop (MAX_K, $3, $5 ); }
871 	|	MIN_K '(' exp ',' exp ')'
872 			{ $$ = exp_binop (MIN_K, $3, $5 ); }
873 	|	ASSERT_K '(' exp ',' NAME ')'
874 			{ $$ = exp_assert ($3, $5); }
875 	|	ORIGIN '(' NAME ')'
876 			{ $$ = exp_nameop (ORIGIN, $3); }
877 	|	LENGTH '(' NAME ')'
878 			{ $$ = exp_nameop (LENGTH, $3); }
879 	;
880 
881 
882 memspec_at_opt:
883                 AT '>' NAME { $$ = $3; }
884         |       { $$ = 0; }
885         ;
886 
887 opt_at:
888 		AT '(' exp ')' { $$ = $3; }
889 	|	{ $$ = 0; }
890 	;
891 
892 opt_align:
893 		ALIGN_K '(' exp ')' { $$ = $3; }
894 	|	{ $$ = 0; }
895 	;
896 
897 opt_subalign:
898 		SUBALIGN '(' exp ')' { $$ = $3; }
899 	|	{ $$ = 0; }
900 	;
901 
902 sect_constraint:
903 		ONLY_IF_RO { $$ = ONLY_IF_RO; }
904 	|	ONLY_IF_RW { $$ = ONLY_IF_RW; }
905 	|	SPECIAL { $$ = SPECIAL; }
906 	|	{ $$ = 0; }
907 	;
908 
909 section:	NAME 		{ ldlex_expression(); }
910 		opt_exp_with_type
911 		opt_at
912 		opt_align
913 		opt_subalign	{ ldlex_popstate (); ldlex_script (); }
914 		sect_constraint
915 		'{'
916 			{
917 			  lang_enter_output_section_statement($1, $3,
918 							      sectype,
919 							      $5, $6, $4, $8);
920 			}
921 		statement_list_opt
922  		'}' { ldlex_popstate (); ldlex_expression (); }
923 		memspec_opt memspec_at_opt phdr_opt fill_opt
924 		{
925 		  ldlex_popstate ();
926 		  lang_leave_output_section_statement ($17, $14, $16, $15);
927 		}
928 		opt_comma
929 		{}
930 	|	OVERLAY
931 			{ ldlex_expression (); }
932 		opt_exp_without_type opt_nocrossrefs opt_at opt_subalign
933 			{ ldlex_popstate (); ldlex_script (); }
934 		'{'
935 			{
936 			  lang_enter_overlay ($3, $6);
937 			}
938 		overlay_section
939 		'}'
940 			{ ldlex_popstate (); ldlex_expression (); }
941 		memspec_opt memspec_at_opt phdr_opt fill_opt
942 			{
943 			  ldlex_popstate ();
944 			  lang_leave_overlay ($5, (int) $4,
945 					      $16, $13, $15, $14);
946 			}
947 		opt_comma
948 	|	/* The GROUP case is just enough to support the gcc
949 		   svr3.ifile script.  It is not intended to be full
950 		   support.  I'm not even sure what GROUP is supposed
951 		   to mean.  */
952 		GROUP { ldlex_expression (); }
953 		opt_exp_with_type
954 		{
955 		  ldlex_popstate ();
956 		  lang_add_assignment (exp_assop ('=', ".", $3));
957 		}
958 		'{' sec_or_group_p1 '}'
959 	;
960 
961 type:
962 	   NOLOAD  { sectype = noload_section; }
963 	|  DSECT   { sectype = dsect_section; }
964 	|  COPY    { sectype = copy_section; }
965 	|  INFO    { sectype = info_section; }
966 	|  OVERLAY { sectype = overlay_section; }
967 	;
968 
969 atype:
970 	 	'(' type ')'
971   	| 	/* EMPTY */ { sectype = normal_section; }
972   	| 	'(' ')' { sectype = normal_section; }
973 	;
974 
975 opt_exp_with_type:
976 		exp atype ':'		{ $$ = $1; }
977 	|	atype ':'		{ $$ = (etree_type *)NULL;  }
978 	|	/* The BIND cases are to support the gcc svr3.ifile
979 		   script.  They aren't intended to implement full
980 		   support for the BIND keyword.  I'm not even sure
981 		   what BIND is supposed to mean.  */
982 		BIND '(' exp ')' atype ':' { $$ = $3; }
983 	|	BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
984 		{ $$ = $3; }
985 	;
986 
987 opt_exp_without_type:
988 		exp ':'		{ $$ = $1; }
989 	|	':'		{ $$ = (etree_type *) NULL;  }
990 	;
991 
992 opt_nocrossrefs:
993 		/* empty */
994 			{ $$ = 0; }
995 	|	NOCROSSREFS
996 			{ $$ = 1; }
997 	;
998 
999 memspec_opt:
1000 		'>' NAME
1001 		{ $$ = $2; }
1002 	|	{ $$ = DEFAULT_MEMORY_REGION; }
1003 	;
1004 
1005 phdr_opt:
1006 		/* empty */
1007 		{
1008 		  $$ = NULL;
1009 		}
1010 	|	phdr_opt ':' NAME
1011 		{
1012 		  struct lang_output_section_phdr_list *n;
1013 
1014 		  n = ((struct lang_output_section_phdr_list *)
1015 		       xmalloc (sizeof *n));
1016 		  n->name = $3;
1017 		  n->used = FALSE;
1018 		  n->next = $1;
1019 		  $$ = n;
1020 		}
1021 	;
1022 
1023 overlay_section:
1024 		/* empty */
1025 	|	overlay_section
1026 		NAME
1027 			{
1028 			  ldlex_script ();
1029 			  lang_enter_overlay_section ($2);
1030 			}
1031 		'{' statement_list_opt '}'
1032 			{ ldlex_popstate (); ldlex_expression (); }
1033 		phdr_opt fill_opt
1034 			{
1035 			  ldlex_popstate ();
1036 			  lang_leave_overlay_section ($9, $8);
1037 			}
1038 		opt_comma
1039 	;
1040 
1041 phdrs:
1042 		PHDRS '{' phdr_list '}'
1043 	;
1044 
1045 phdr_list:
1046 		/* empty */
1047 	|	phdr_list phdr
1048 	;
1049 
1050 phdr:
1051 		NAME { ldlex_expression (); }
1052 		  phdr_type phdr_qualifiers { ldlex_popstate (); }
1053 		  ';'
1054 		{
1055 		  lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
1056 				 $4.flags);
1057 		}
1058 	;
1059 
1060 phdr_type:
1061 		exp
1062 		{
1063 		  $$ = $1;
1064 
1065 		  if ($1->type.node_class == etree_name
1066 		      && $1->type.node_code == NAME)
1067 		    {
1068 		      const char *s;
1069 		      unsigned int i;
1070 		      static const char * const phdr_types[] =
1071 			{
1072 			  "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
1073 			  "PT_INTERP", "PT_NOTE", "PT_SHLIB",
1074 			  "PT_PHDR", "PT_TLS"
1075 			};
1076 
1077 		      s = $1->name.name;
1078 		      for (i = 0;
1079 			   i < sizeof phdr_types / sizeof phdr_types[0];
1080 			   i++)
1081 			if (strcmp (s, phdr_types[i]) == 0)
1082 			  {
1083 			    $$ = exp_intop (i);
1084 			    break;
1085 			  }
1086 		      if (i == sizeof phdr_types / sizeof phdr_types[0])
1087 			{
1088 			  if (strcmp (s, "PT_GNU_EH_FRAME") == 0)
1089 			    $$ = exp_intop (0x6474e550);
1090 			  else if (strcmp (s, "PT_GNU_STACK") == 0)
1091 			    $$ = exp_intop (0x6474e551);
1092 			  else
1093 			    {
1094 			      einfo (_("\
1095 %X%P:%S: unknown phdr type `%s' (try integer literal)\n"),
1096 				     s);
1097 			      $$ = exp_intop (0);
1098 			    }
1099 			}
1100 		    }
1101 		}
1102 	;
1103 
1104 phdr_qualifiers:
1105 		/* empty */
1106 		{
1107 		  memset (&$$, 0, sizeof (struct phdr_info));
1108 		}
1109 	|	NAME phdr_val phdr_qualifiers
1110 		{
1111 		  $$ = $3;
1112 		  if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
1113 		    $$.filehdr = TRUE;
1114 		  else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
1115 		    $$.phdrs = TRUE;
1116 		  else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
1117 		    $$.flags = $2;
1118 		  else
1119 		    einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
1120 		}
1121 	|	AT '(' exp ')' phdr_qualifiers
1122 		{
1123 		  $$ = $5;
1124 		  $$.at = $3;
1125 		}
1126 	;
1127 
1128 phdr_val:
1129 		/* empty */
1130 		{
1131 		  $$ = NULL;
1132 		}
1133 	| '(' exp ')'
1134 		{
1135 		  $$ = $2;
1136 		}
1137 	;
1138 
1139 /* This syntax is used within an external version script file.  */
1140 
1141 version_script_file:
1142 		{
1143 		  ldlex_version_file ();
1144 		  PUSH_ERROR (_("VERSION script"));
1145 		}
1146 		vers_nodes
1147 		{
1148 		  ldlex_popstate ();
1149 		  POP_ERROR ();
1150 		}
1151 	;
1152 
1153 /* This is used within a normal linker script file.  */
1154 
1155 version:
1156 		{
1157 		  ldlex_version_script ();
1158 		}
1159 		VERSIONK '{' vers_nodes '}'
1160 		{
1161 		  ldlex_popstate ();
1162 		}
1163 	;
1164 
1165 vers_nodes:
1166 		vers_node
1167 	|	vers_nodes vers_node
1168 	;
1169 
1170 vers_node:
1171 		'{' vers_tag '}' ';'
1172 		{
1173 		  lang_register_vers_node (NULL, $2, NULL);
1174 		}
1175 	|	VERS_TAG '{' vers_tag '}' ';'
1176 		{
1177 		  lang_register_vers_node ($1, $3, NULL);
1178 		}
1179 	|	VERS_TAG '{' vers_tag '}' verdep ';'
1180 		{
1181 		  lang_register_vers_node ($1, $3, $5);
1182 		}
1183 	;
1184 
1185 verdep:
1186 		VERS_TAG
1187 		{
1188 		  $$ = lang_add_vers_depend (NULL, $1);
1189 		}
1190 	|	verdep VERS_TAG
1191 		{
1192 		  $$ = lang_add_vers_depend ($1, $2);
1193 		}
1194 	;
1195 
1196 vers_tag:
1197 		/* empty */
1198 		{
1199 		  $$ = lang_new_vers_node (NULL, NULL);
1200 		}
1201 	|	vers_defns ';'
1202 		{
1203 		  $$ = lang_new_vers_node ($1, NULL);
1204 		}
1205 	|	GLOBAL ':' vers_defns ';'
1206 		{
1207 		  $$ = lang_new_vers_node ($3, NULL);
1208 		}
1209 	|	LOCAL ':' vers_defns ';'
1210 		{
1211 		  $$ = lang_new_vers_node (NULL, $3);
1212 		}
1213 	|	GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
1214 		{
1215 		  $$ = lang_new_vers_node ($3, $7);
1216 		}
1217 	;
1218 
1219 vers_defns:
1220 		VERS_IDENTIFIER
1221 		{
1222 		  $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, FALSE);
1223 		}
1224         |       NAME
1225 		{
1226 		  $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, TRUE);
1227 		}
1228 	|	vers_defns ';' VERS_IDENTIFIER
1229 		{
1230 		  $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, FALSE);
1231 		}
1232 	|	vers_defns ';' NAME
1233 		{
1234 		  $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, TRUE);
1235 		}
1236 	|	vers_defns ';' EXTERN NAME '{'
1237 			{
1238 			  $<name>$ = ldgram_vers_current_lang;
1239 			  ldgram_vers_current_lang = $4;
1240 			}
1241 		vers_defns opt_semicolon '}'
1242 			{
1243 			  struct bfd_elf_version_expr *pat;
1244 			  for (pat = $7; pat->next != NULL; pat = pat->next);
1245 			  pat->next = $1;
1246 			  $$ = $7;
1247 			  ldgram_vers_current_lang = $<name>6;
1248 			}
1249 	|	EXTERN NAME '{'
1250 			{
1251 			  $<name>$ = ldgram_vers_current_lang;
1252 			  ldgram_vers_current_lang = $2;
1253 			}
1254 		vers_defns opt_semicolon '}'
1255 			{
1256 			  $$ = $5;
1257 			  ldgram_vers_current_lang = $<name>4;
1258 			}
1259 	|	GLOBAL
1260 		{
1261 		  $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang, FALSE);
1262 		}
1263 	|	vers_defns ';' GLOBAL
1264 		{
1265 		  $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang, FALSE);
1266 		}
1267 	|	LOCAL
1268 		{
1269 		  $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang, FALSE);
1270 		}
1271 	|	vers_defns ';' LOCAL
1272 		{
1273 		  $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang, FALSE);
1274 		}
1275 	|	EXTERN
1276 		{
1277 		  $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang, FALSE);
1278 		}
1279 	|	vers_defns ';' EXTERN
1280 		{
1281 		  $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, FALSE);
1282 		}
1283 	;
1284 
1285 opt_semicolon:
1286 		/* empty */
1287 	|	';'
1288 	;
1289 
1290 %%
1291 void
yyerror(arg)1292 yyerror(arg)
1293      const char *arg;
1294 {
1295   if (ldfile_assumed_script)
1296     einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
1297 	   ldfile_input_filename);
1298   if (error_index > 0 && error_index < ERROR_NAME_MAX)
1299      einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
1300   else
1301      einfo ("%P%F:%S: %s\n", arg);
1302 }
1303