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