* ldgram.y (extern_name_list): Do not require symbols to be
[platform/upstream/binutils.git] / ld / ldgram.y
1 /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
2    Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
3    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "ldemul.h"
37 #include "ldfile.h"
38 #include "ldmisc.h"
39 #include "ldmain.h"
40 #include "mri.h"
41 #include "ldlex.h"
42
43 #ifndef YYDEBUG
44 #define YYDEBUG 1
45 #endif
46
47 static enum section_type sectype;
48
49 lang_memory_region_type *region;
50
51 struct wildcard_spec current_file;
52 boolean ldgram_want_filename = true;
53 boolean had_script = false;
54 boolean force_make_executable = false;
55
56 boolean ldgram_in_script = false;
57 boolean ldgram_had_equals = false;
58 boolean ldgram_had_keep = false;
59
60 #define ERROR_NAME_MAX 20
61 static char *error_names[ERROR_NAME_MAX];
62 static int error_index;
63 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
64 #define POP_ERROR()   error_index--;
65 %}
66 %union {
67   bfd_vma integer;
68   char *name;
69   const char *cname;
70   struct wildcard_spec wildcard;
71   int token;
72   union etree_union *etree;
73   struct phdr_info
74     {
75       boolean filehdr;
76       boolean phdrs;
77       union etree_union *at;
78       union etree_union *flags;
79     } phdr;
80   struct lang_nocrossref *nocrossref;
81   struct lang_output_section_phdr_list *section_phdr;
82   struct bfd_elf_version_deps *deflist;
83   struct bfd_elf_version_expr *versyms;
84   struct bfd_elf_version_tree *versnode;
85 }
86
87 %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
88 %type <etree> opt_exp_without_type
89 %type <integer> fill_opt
90 %type <name> memspec_opt casesymlist
91 %type <cname> wildcard_name
92 %type <wildcard> wildcard_spec
93 %token <integer> INT  
94 %token <name> NAME LNAME
95 %type <integer> length
96 %type <phdr> phdr_qualifiers
97 %type <nocrossref> nocrossref_list
98 %type <section_phdr> phdr_opt
99 %type <integer> opt_nocrossrefs
100
101 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
102 %right <token> '?' ':'
103 %left <token> OROR
104 %left <token>  ANDAND
105 %left <token> '|'
106 %left <token>  '^'
107 %left  <token> '&'
108 %left <token>  EQ NE
109 %left  <token> '<' '>' LE GE
110 %left  <token> LSHIFT RSHIFT
111
112 %left  <token> '+' '-'
113 %left  <token> '*' '/' '%'
114
115 %right UNARY
116 %token END 
117 %left <token> '('
118 %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
119 %token SECTIONS PHDRS SORT
120 %token '{' '}'
121 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
122 %token SIZEOF_HEADERS
123 %token INCLUDE
124 %token MEMORY DEFSYMEND
125 %token NOLOAD DSECT COPY INFO OVERLAY
126 %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
127 %token <integer> NEXT
128 %token SIZEOF ADDR LOADADDR MAX MIN
129 %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
130 %token ORIGIN FILL
131 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
132 %token ALIGNMOD AT PROVIDE
133 %type <token> assign_op atype
134 %type <name>  filename
135 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
136 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
137 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
138 %token <name> VERS_TAG VERS_IDENTIFIER
139 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
140 %token KEEP
141 %type <versyms> vers_defns
142 %type <versnode> vers_tag
143 %type <deflist> verdep
144
145 %%
146
147 file:   
148                 INPUT_SCRIPT script_file
149         |       INPUT_MRI_SCRIPT mri_script_file
150         |       INPUT_VERSION_SCRIPT version_script_file
151         |       INPUT_DEFSYM defsym_expr
152         ;
153
154
155 filename:  NAME;
156
157
158 defsym_expr:
159                 { ldlex_defsym(); }
160                 NAME '=' exp
161                 {
162                   ldlex_popstate();
163                   lang_add_assignment(exp_assop($3,$2,$4));
164                 }
165
166 /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
167 mri_script_file:
168                 {
169                   ldlex_mri_script ();
170                   PUSH_ERROR (_("MRI style script"));
171                 }
172              mri_script_lines
173                 {
174                   ldlex_popstate ();
175                   mri_draw_tree ();
176                   POP_ERROR ();
177                 }
178         ;
179
180 mri_script_lines:
181                 mri_script_lines mri_script_command NEWLINE
182           |
183         ;
184
185 mri_script_command:
186                 CHIP  exp 
187         |       CHIP  exp ',' exp
188         |       NAME    {
189                         einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
190                         }
191         |       LIST    {
192                         config.map_filename = "-";
193                         }
194         |       ORDER ordernamelist
195         |       ENDWORD 
196         |       PUBLIC NAME '=' exp
197                         { mri_public($2, $4); }
198         |       PUBLIC NAME ',' exp
199                         { mri_public($2, $4); }
200         |       PUBLIC NAME  exp 
201                         { mri_public($2, $3); }
202         |       FORMAT NAME
203                         { mri_format($2); }
204         |       SECT NAME ',' exp
205                         { mri_output_section($2, $4);}
206         |       SECT NAME  exp
207                         { mri_output_section($2, $3);}
208         |       SECT NAME '=' exp
209                         { mri_output_section($2, $4);}
210         |       ALIGN_K NAME '=' exp
211                         { mri_align($2,$4); }
212         |       ALIGN_K NAME ',' exp
213                         { mri_align($2,$4); }
214         |       ALIGNMOD NAME '=' exp
215                         { mri_alignmod($2,$4); }
216         |       ALIGNMOD NAME ',' exp
217                         { mri_alignmod($2,$4); }
218         |       ABSOLUTE mri_abs_name_list
219         |       LOAD     mri_load_name_list
220         |       NAMEWORD NAME 
221                         { mri_name($2); }   
222         |       ALIAS NAME ',' NAME
223                         { mri_alias($2,$4,0);}
224         |       ALIAS NAME ',' INT
225                         { mri_alias($2,0,(int) $4);}
226         |       BASE     exp
227                         { mri_base($2); }
228         |       TRUNCATE INT
229                 {  mri_truncate((unsigned int) $2); }
230         |       CASE casesymlist
231         |       EXTERN extern_name_list
232         |       INCLUDE filename
233                 { ldfile_open_command_file ($2); } mri_script_lines END
234         |       START NAME
235                 { lang_add_entry ($2, false); }
236         |
237         ;
238
239 ordernamelist:
240               ordernamelist ',' NAME         { mri_order($3); }
241         |     ordernamelist  NAME         { mri_order($2); }
242         |
243         ;
244
245 mri_load_name_list:
246                 NAME
247                         { mri_load($1); }
248         |       mri_load_name_list ',' NAME { mri_load($3); }
249         ;
250
251 mri_abs_name_list:
252                 NAME
253                         { mri_only_load($1); }
254         |       mri_abs_name_list ','  NAME
255                         { mri_only_load($3); }
256         ;
257
258 casesymlist:
259           /* empty */ { $$ = NULL; }
260         | NAME
261         | casesymlist ',' NAME
262         ;
263
264 extern_name_list:
265           NAME
266                         { ldlang_add_undef ($1); }
267         | extern_name_list NAME
268                         { ldlang_add_undef ($2); }
269         | extern_name_list ',' NAME
270                         { ldlang_add_undef ($3); }
271         ;
272
273 script_file:
274         {
275          ldlex_both();
276         }
277        ifile_list
278         {
279         ldlex_popstate();
280         }
281         ;
282
283
284 ifile_list:
285        ifile_list ifile_p1
286         |
287         ;
288
289
290
291 ifile_p1:
292                 memory
293         |       sections
294         |       phdrs
295         |       startup
296         |       high_level_library
297         |       low_level_library
298         |       floating_point_support
299         |       statement_anywhere
300         |       version
301         |        ';'
302         |       TARGET_K '(' NAME ')'
303                 { lang_add_target($3); }
304         |       SEARCH_DIR '(' filename ')'
305                 { ldfile_add_library_path ($3, false); }
306         |       OUTPUT '(' filename ')'
307                 { lang_add_output($3, 1); }
308         |       OUTPUT_FORMAT '(' NAME ')'
309                   { lang_add_output_format ($3, (char *) NULL,
310                                             (char *) NULL, 1); }
311         |       OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
312                   { lang_add_output_format ($3, $5, $7, 1); }
313         |       OUTPUT_ARCH '(' NAME ')'
314                   { ldfile_set_output_arch($3); }
315         |       FORCE_COMMON_ALLOCATION
316                 { command_line.force_common_definition = true ; }
317         |       INPUT '(' input_list ')'
318         |       GROUP
319                   { lang_enter_group (); }
320                     '(' input_list ')'
321                   { lang_leave_group (); }
322         |       MAP '(' filename ')'
323                 { lang_add_map($3); }
324         |       INCLUDE filename 
325                 { ldfile_open_command_file($2); } ifile_list END
326         |       NOCROSSREFS '(' nocrossref_list ')'
327                 {
328                   lang_add_nocrossref ($3);
329                 }
330         |       EXTERN '(' extern_name_list ')'
331         ;
332
333 input_list:
334                 NAME
335                 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
336                                  (char *)NULL); }
337         |       input_list ',' NAME
338                 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
339                                  (char *)NULL); }
340         |       input_list NAME
341                 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
342                                  (char *)NULL); }
343         |       LNAME
344                 { lang_add_input_file($1,lang_input_file_is_l_enum,
345                                  (char *)NULL); }
346         |       input_list ',' LNAME
347                 { lang_add_input_file($3,lang_input_file_is_l_enum,
348                                  (char *)NULL); }
349         |       input_list LNAME
350                 { lang_add_input_file($2,lang_input_file_is_l_enum,
351                                  (char *)NULL); }
352         ;
353
354 sections:
355                 SECTIONS '{' sec_or_group_p1 '}'
356         ;
357
358 sec_or_group_p1:
359                 sec_or_group_p1 section
360         |       sec_or_group_p1 statement_anywhere
361         |
362         ;
363
364 statement_anywhere:
365                 ENTRY '(' NAME ')'
366                 { lang_add_entry ($3, false); }
367         |       assignment end
368         ;
369
370 /* The '*' and '?' cases are there because the lexer returns them as
371    separate tokens rather than as NAME.  */
372 wildcard_name:
373                 NAME
374                         {
375                           $$ = $1;
376                         }
377         |       '*'
378                         {
379                           $$ = "*";
380                         }
381         |       '?'
382                         {
383                           $$ = "?";
384                         }
385         ;
386
387 wildcard_spec:
388                 wildcard_name
389                         {
390                           $$.name = $1;
391                           $$.sorted = false;
392                         }
393         |       SORT '(' wildcard_name ')'
394                         {
395                           $$.name = $3;
396                           $$.sorted = true;
397                         }
398         ;
399
400 file_NAME_list:
401                 wildcard_spec
402                         {
403                           lang_add_wild ($1.name, $1.sorted,
404                                          current_file.name,
405                                          current_file.sorted,
406                                          ldgram_had_keep);
407                         }
408         |       file_NAME_list opt_comma wildcard_spec
409                         {
410                           lang_add_wild ($3.name, $3.sorted,
411                                          current_file.name,
412                                          current_file.sorted,
413                                          ldgram_had_keep);
414                         }
415         ;
416
417 input_section_spec_no_keep:
418                 NAME
419                         {
420                           lang_add_wild (NULL, false, $1, false,
421                                          ldgram_had_keep);
422                         }
423         |       '['
424                         {
425                           current_file.name = NULL;
426                           current_file.sorted = false;
427                         }
428                 file_NAME_list ']'
429         |       wildcard_spec
430                         {
431                           current_file = $1;
432                           /* '*' matches any file name.  */
433                           if (strcmp (current_file.name, "*") == 0)
434                             current_file.name = NULL;
435                         }
436                 '(' file_NAME_list ')'
437         ;
438
439 input_section_spec:
440                 input_section_spec_no_keep
441         |       KEEP '('
442                         { ldgram_had_keep = true; }
443                 input_section_spec_no_keep ')'
444                         { ldgram_had_keep = false; }
445         ;
446
447 statement:
448                 assignment end
449         |       CREATE_OBJECT_SYMBOLS
450                 {
451                 lang_add_attribute(lang_object_symbols_statement_enum); 
452                 }
453         |       ';'
454         |       CONSTRUCTORS
455                 {
456                 
457                   lang_add_attribute(lang_constructors_statement_enum); 
458                 }
459         | input_section_spec
460         | length '(' mustbe_exp ')'
461                         {
462                         lang_add_data((int) $1,$3);
463                         }
464   
465         | FILL '(' mustbe_exp ')'
466                         {
467                           lang_add_fill
468                             (exp_get_value_int($3,
469                                                0,
470                                                "fill value",
471                                                lang_first_phase_enum));
472                         }
473         ;
474
475 statement_list:
476                 statement_list statement
477         |       statement
478         ;
479   
480 statement_list_opt:
481                 /* empty */
482         |       statement_list
483         ;
484
485 length:
486                 QUAD
487                         { $$ = $1; }
488         |       SQUAD
489                         { $$ = $1; }
490         |       LONG
491                         { $$ = $1; }
492         |       SHORT
493                         { $$ = $1; }
494         |       BYTE
495                         { $$ = $1; }
496         ;
497
498 fill_opt:
499           '=' mustbe_exp
500                 {
501                   $$ =   exp_get_value_int($2,
502                                            0,
503                                            "fill value",
504                                            lang_first_phase_enum);
505                 }
506         |       { $$ = 0; }
507         ;
508
509                 
510
511 assign_op:
512                 PLUSEQ
513                         { $$ = '+'; }
514         |       MINUSEQ
515                         { $$ = '-'; }
516         |       MULTEQ
517                         { $$ = '*'; }
518         |       DIVEQ
519                         { $$ = '/'; }
520         |       LSHIFTEQ
521                         { $$ = LSHIFT; }
522         |       RSHIFTEQ
523                         { $$ = RSHIFT; }
524         |       ANDEQ
525                         { $$ = '&'; }
526         |       OREQ
527                         { $$ = '|'; }
528
529         ;
530
531 end:    ';' | ','
532         ;
533
534
535 assignment:
536                 NAME '=' mustbe_exp
537                 {
538                   lang_add_assignment (exp_assop ($2, $1, $3));
539                 }
540         |       NAME assign_op mustbe_exp
541                 {
542                   lang_add_assignment (exp_assop ('=', $1,
543                                                   exp_binop ($2,
544                                                              exp_nameop (NAME,
545                                                                          $1),
546                                                              $3)));
547                 }
548         |       PROVIDE '(' NAME '=' mustbe_exp ')'
549                 {
550                   lang_add_assignment (exp_provide ($3, $5));
551                 }
552         ;
553
554
555 opt_comma:
556                 ','     |       ;
557
558
559 memory:
560                 MEMORY '{' memory_spec memory_spec_list '}'
561         ;
562
563 memory_spec_list:
564                 memory_spec_list memory_spec
565         |       memory_spec_list ',' memory_spec
566         |
567         ;
568
569
570 memory_spec:            NAME
571                         { region = lang_memory_region_lookup($1); }
572                 attributes_opt ':'
573                 origin_spec opt_comma length_spec
574
575         ; origin_spec:
576         ORIGIN '=' mustbe_exp
577                 { region->current =
578                  region->origin =
579                  exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
580 }
581         ;
582
583 length_spec:
584              LENGTH '=' mustbe_exp
585                { region->length = exp_get_vma($3,
586                                                ~((bfd_vma)0),
587                                                "length",
588                                                lang_first_phase_enum);
589                 }
590         
591
592 attributes_opt:
593                   '(' NAME ')'
594                         {
595                         lang_set_flags(region, $2);
596                         }
597         |
598   
599         ;
600
601 startup:
602         STARTUP '(' filename ')'
603                 { lang_startup($3); }
604         ;
605
606 high_level_library:
607                 HLL '(' high_level_library_NAME_list ')'
608         |       HLL '(' ')'
609                         { ldemul_hll((char *)NULL); }
610         ;
611
612 high_level_library_NAME_list:
613                 high_level_library_NAME_list opt_comma filename
614                         { ldemul_hll($3); }
615         |       filename
616                         { ldemul_hll($1); }
617
618         ;
619
620 low_level_library:
621         SYSLIB '(' low_level_library_NAME_list ')'
622         ; low_level_library_NAME_list:
623                 low_level_library_NAME_list opt_comma filename
624                         { ldemul_syslib($3); }
625         |
626         ;
627
628 floating_point_support:
629                 FLOAT
630                         { lang_float(true); }
631         |       NOFLOAT
632                         { lang_float(false); }
633         ;
634                 
635 nocrossref_list:
636                 /* empty */
637                 {
638                   $$ = NULL;
639                 }
640         |       NAME nocrossref_list
641                 {
642                   struct lang_nocrossref *n;
643
644                   n = (struct lang_nocrossref *) xmalloc (sizeof *n);
645                   n->name = $1;
646                   n->next = $2;
647                   $$ = n;
648                 }
649         |       NAME ',' nocrossref_list
650                 {
651                   struct lang_nocrossref *n;
652
653                   n = (struct lang_nocrossref *) xmalloc (sizeof *n);
654                   n->name = $1;
655                   n->next = $3;
656                   $$ = n;
657                 }
658         ;
659
660 mustbe_exp:              { ldlex_expression(); }
661                 exp
662                          { ldlex_popstate(); $$=$2;}
663         ;
664
665 exp     :
666                 '-' exp %prec UNARY
667                         { $$ = exp_unop('-', $2); }
668         |       '(' exp ')'
669                         { $$ = $2; }
670         |       NEXT '(' exp ')' %prec UNARY
671                         { $$ = exp_unop((int) $1,$3); }
672         |       '!' exp %prec UNARY
673                         { $$ = exp_unop('!', $2); }
674         |       '+' exp %prec UNARY
675                         { $$ = $2; }
676         |       '~' exp %prec UNARY
677                         { $$ = exp_unop('~', $2);}
678
679         |       exp '*' exp
680                         { $$ = exp_binop('*', $1, $3); }
681         |       exp '/' exp
682                         { $$ = exp_binop('/', $1, $3); }
683         |       exp '%' exp
684                         { $$ = exp_binop('%', $1, $3); }
685         |       exp '+' exp
686                         { $$ = exp_binop('+', $1, $3); }
687         |       exp '-' exp
688                         { $$ = exp_binop('-' , $1, $3); }
689         |       exp LSHIFT exp
690                         { $$ = exp_binop(LSHIFT , $1, $3); }
691         |       exp RSHIFT exp
692                         { $$ = exp_binop(RSHIFT , $1, $3); }
693         |       exp EQ exp
694                         { $$ = exp_binop(EQ , $1, $3); }
695         |       exp NE exp
696                         { $$ = exp_binop(NE , $1, $3); }
697         |       exp LE exp
698                         { $$ = exp_binop(LE , $1, $3); }
699         |       exp GE exp
700                         { $$ = exp_binop(GE , $1, $3); }
701         |       exp '<' exp
702                         { $$ = exp_binop('<' , $1, $3); }
703         |       exp '>' exp
704                         { $$ = exp_binop('>' , $1, $3); }
705         |       exp '&' exp
706                         { $$ = exp_binop('&' , $1, $3); }
707         |       exp '^' exp
708                         { $$ = exp_binop('^' , $1, $3); }
709         |       exp '|' exp
710                         { $$ = exp_binop('|' , $1, $3); }
711         |       exp '?' exp ':' exp
712                         { $$ = exp_trinop('?' , $1, $3, $5); }
713         |       exp ANDAND exp
714                         { $$ = exp_binop(ANDAND , $1, $3); }
715         |       exp OROR exp
716                         { $$ = exp_binop(OROR , $1, $3); }
717         |       DEFINED '(' NAME ')'
718                         { $$ = exp_nameop(DEFINED, $3); }
719         |       INT
720                         { $$ = exp_intop($1); }
721         |       SIZEOF_HEADERS
722                         { $$ = exp_nameop(SIZEOF_HEADERS,0); }
723
724         |       SIZEOF '(' NAME ')'
725                         { $$ = exp_nameop(SIZEOF,$3); }
726         |       ADDR '(' NAME ')'
727                         { $$ = exp_nameop(ADDR,$3); }
728         |       LOADADDR '(' NAME ')'
729                         { $$ = exp_nameop(LOADADDR,$3); }
730         |       ABSOLUTE '(' exp ')'
731                         { $$ = exp_unop(ABSOLUTE, $3); }
732         |       ALIGN_K '(' exp ')'
733                         { $$ = exp_unop(ALIGN_K,$3); }
734         |       BLOCK '(' exp ')'
735                         { $$ = exp_unop(ALIGN_K,$3); }
736         |       NAME
737                         { $$ = exp_nameop(NAME,$1); }
738         |       MAX '(' exp ',' exp ')'
739                         { $$ = exp_binop (MAX, $3, $5 ); }
740         |       MIN '(' exp ',' exp ')'
741                         { $$ = exp_binop (MIN, $3, $5 ); }
742         ;
743
744
745 opt_at:
746                 AT '(' exp ')' { $$ = $3; }
747         |       { $$ = 0; }
748         ;
749
750 section:        NAME            { ldlex_expression(); }
751                 opt_exp_with_type 
752                 opt_at          { ldlex_popstate (); ldlex_script (); }
753                 '{'
754                         {
755                           lang_enter_output_section_statement($1, $3,
756                                                               sectype,
757                                                               0, 0, 0, $4);
758                         }
759                 statement_list_opt      
760                 '}' { ldlex_popstate (); ldlex_expression (); }
761                 memspec_opt phdr_opt fill_opt
762                 {
763                   ldlex_popstate ();
764                   lang_leave_output_section_statement ($13, $11, $12);
765                 }
766                 opt_comma
767         |       OVERLAY
768                         { ldlex_expression (); }
769                 opt_exp_without_type opt_nocrossrefs opt_at
770                         { ldlex_popstate (); ldlex_script (); }
771                 '{' 
772                         {
773                           lang_enter_overlay ($3, $5, (int) $4);
774                         }
775                 overlay_section
776                 '}'
777                         { ldlex_popstate (); ldlex_expression (); }
778                 memspec_opt phdr_opt fill_opt
779                         {
780                           ldlex_popstate ();
781                           lang_leave_overlay ($14, $12, $13);
782                         }
783                 opt_comma
784         |       /* The GROUP case is just enough to support the gcc
785                    svr3.ifile script.  It is not intended to be full
786                    support.  I'm not even sure what GROUP is supposed
787                    to mean.  */
788                 GROUP { ldlex_expression (); }
789                 opt_exp_with_type
790                 {
791                   ldlex_popstate ();
792                   lang_add_assignment (exp_assop ('=', ".", $3));
793                 }
794                 '{' sec_or_group_p1 '}'
795         ;
796
797 type:
798            NOLOAD  { sectype = noload_section; }
799         |  DSECT   { sectype = dsect_section; }
800         |  COPY    { sectype = copy_section; }
801         |  INFO    { sectype = info_section; }
802         |  OVERLAY { sectype = overlay_section; }
803         ;
804
805 atype:
806                 '(' type ')'
807         |       /* EMPTY */ { sectype = normal_section; }
808         |       '(' ')' { sectype = normal_section; }
809         ;
810
811 opt_exp_with_type:
812                 exp atype ':'           { $$ = $1; }
813         |       atype ':'               { $$ = (etree_type *)NULL;  }
814         |       /* The BIND cases are to support the gcc svr3.ifile
815                    script.  They aren't intended to implement full
816                    support for the BIND keyword.  I'm not even sure
817                    what BIND is supposed to mean.  */
818                 BIND '(' exp ')' atype ':' { $$ = $3; }
819         |       BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
820                 { $$ = $3; }
821         ;
822
823 opt_exp_without_type:
824                 exp ':'         { $$ = $1; }
825         |       ':'             { $$ = (etree_type *) NULL;  }
826         ;
827
828 opt_nocrossrefs:
829                 /* empty */
830                         { $$ = 0; }
831         |       NOCROSSREFS
832                         { $$ = 1; }
833         ;
834
835 memspec_opt:
836                 '>' NAME
837                 { $$ = $2; }
838         |       { $$ = "*default*"; }
839         ;
840
841 phdr_opt:
842                 /* empty */
843                 {
844                   $$ = NULL;
845                 }
846         |       phdr_opt ':' NAME
847                 {
848                   struct lang_output_section_phdr_list *n;
849
850                   n = ((struct lang_output_section_phdr_list *)
851                        xmalloc (sizeof *n));
852                   n->name = $3;
853                   n->used = false;
854                   n->next = $1;
855                   $$ = n;
856                 }
857         ;
858
859 overlay_section:
860                 /* empty */
861         |       overlay_section
862                 NAME
863                         {
864                           ldlex_script ();
865                           lang_enter_overlay_section ($2);
866                         }
867                 '{' statement_list_opt '}'
868                         { ldlex_popstate (); ldlex_expression (); }
869                 phdr_opt fill_opt
870                         {
871                           ldlex_popstate ();
872                           lang_leave_overlay_section ($9, $8);
873                         }
874                 opt_comma
875         ;
876
877 phdrs:
878                 PHDRS '{' phdr_list '}'
879         ;
880
881 phdr_list:
882                 /* empty */
883         |       phdr_list phdr
884         ;
885
886 phdr:
887                 NAME { ldlex_expression (); }
888                   phdr_type phdr_qualifiers { ldlex_popstate (); }
889                   ';'
890                 {
891                   lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
892                                  $4.flags);
893                 }
894         ;
895
896 phdr_type:
897                 exp
898                 {
899                   $$ = $1;
900
901                   if ($1->type.node_class == etree_name
902                       && $1->type.node_code == NAME)
903                     {
904                       const char *s;
905                       unsigned int i;
906                       static const char * const phdr_types[] =
907                         {
908                           "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
909                           "PT_INTERP", "PT_NOTE", "PT_SHLIB",
910                           "PT_PHDR"
911                         };
912
913                       s = $1->name.name;
914                       for (i = 0;
915                            i < sizeof phdr_types / sizeof phdr_types[0];
916                            i++)
917                         if (strcmp (s, phdr_types[i]) == 0)
918                           {
919                             $$ = exp_intop (i);
920                             break;
921                           }
922                     }
923                 }
924         ;
925
926 phdr_qualifiers:
927                 /* empty */
928                 {
929                   memset (&$$, 0, sizeof (struct phdr_info));
930                 }
931         |       NAME phdr_val phdr_qualifiers
932                 {
933                   $$ = $3;
934                   if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
935                     $$.filehdr = true;
936                   else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
937                     $$.phdrs = true;
938                   else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
939                     $$.flags = $2;
940                   else
941                     einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
942                 }
943         |       AT '(' exp ')' phdr_qualifiers
944                 {
945                   $$ = $5;
946                   $$.at = $3;
947                 }
948         ;
949
950 phdr_val:
951                 /* empty */
952                 {
953                   $$ = NULL;
954                 }
955         | '(' exp ')'
956                 {
957                   $$ = $2;
958                 }
959         ;
960
961 /* This syntax is used within an external version script file.  */
962
963 version_script_file:
964                 {
965                   ldlex_version_file ();
966                   PUSH_ERROR (_("VERSION script"));
967                 }
968                 vers_nodes
969                 {
970                   ldlex_popstate ();
971                   POP_ERROR ();
972                 }
973         ;
974
975 /* This is used within a normal linker script file.  */
976
977 version:
978                 {
979                   ldlex_version_script ();
980                 }
981                 VERSIONK '{' vers_nodes '}'
982                 {
983                   ldlex_popstate ();
984                 }
985         ;
986
987 vers_nodes:
988                 vers_node
989         |       vers_nodes vers_node
990         ;
991
992 vers_node:
993                 VERS_TAG '{' vers_tag '}' ';'
994                 {
995                   lang_register_vers_node ($1, $3, NULL);
996                 }
997         |       VERS_TAG '{' vers_tag '}' verdep ';'
998                 {
999                   lang_register_vers_node ($1, $3, $5);
1000                 }
1001         ;
1002
1003 verdep:
1004                 VERS_TAG
1005                 {
1006                   $$ = lang_add_vers_depend (NULL, $1);
1007                 }
1008         |       verdep VERS_TAG
1009                 {
1010                   $$ = lang_add_vers_depend ($1, $2);
1011                 }
1012         ;
1013
1014 vers_tag:
1015                 /* empty */
1016                 {
1017                   $$ = lang_new_vers_node (NULL, NULL);
1018                 }
1019         |       vers_defns ';'
1020                 {
1021                   $$ = lang_new_vers_node ($1, NULL);
1022                 }
1023         |       GLOBAL ':' vers_defns ';'
1024                 {
1025                   $$ = lang_new_vers_node ($3, NULL);
1026                 }
1027         |       LOCAL ':' vers_defns ';'
1028                 {
1029                   $$ = lang_new_vers_node (NULL, $3);
1030                 }
1031         |       GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
1032                 {
1033                   $$ = lang_new_vers_node ($3, $7);
1034                 }
1035         ;
1036
1037 vers_defns:
1038                 VERS_IDENTIFIER
1039                 {
1040                   $$ = lang_new_vers_regex (NULL, $1);
1041                 }
1042         |       vers_defns ';' VERS_IDENTIFIER
1043                 {
1044                   $$ = lang_new_vers_regex ($1, $3);
1045                 }
1046         ;
1047
1048 %%
1049 void
1050 yyerror(arg) 
1051      const char *arg;
1052
1053   if (ldfile_assumed_script)
1054     einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
1055            ldfile_input_filename);
1056   if (error_index > 0 && error_index < ERROR_NAME_MAX)
1057      einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
1058   else
1059      einfo ("%P%F:%S: %s\n", arg);
1060 }