* ld.h (check_nocrossrefs): Declare.
[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, 1996 Free Software Foundation, Inc.
3    Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
4
5 This file is part of GNU ld.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 %{
22 /*
23
24  */
25
26 #define DONTDECLARE_MALLOC
27
28 #include "bfd.h"
29 #include "sysdep.h"
30 #include "bfdlink.h"
31 #include "ld.h"    
32 #include "ldexp.h"
33 #include "ldver.h"
34 #include "ldlang.h"
35 #include "ldemul.h"
36 #include "ldfile.h"
37 #include "ldmisc.h"
38 #include "ldmain.h"
39 #include "mri.h"
40 #include "ldlex.h"
41
42 #ifndef YYDEBUG
43 #define YYDEBUG 1
44 #endif
45
46 static enum section_type sectype;
47
48 lang_memory_region_type *region;
49
50
51 char *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
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   int token;
70   union etree_union *etree;
71   struct phdr_info
72     {
73       boolean filehdr;
74       boolean phdrs;
75       union etree_union *at;
76       union etree_union *flags;
77     } phdr;
78   struct lang_nocrossref *nocrossref;
79 }
80
81 %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
82 %type <integer> fill_opt
83 %type <name> memspec_opt casesymlist
84 %token <integer> INT  
85 %token <name> NAME LNAME
86 %type <integer> length
87 %type <phdr> phdr_qualifiers
88 %type <nocrossref> nocrossref_list
89
90 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
91 %right <token> '?' ':'
92 %left <token> OROR
93 %left <token>  ANDAND
94 %left <token> '|'
95 %left <token>  '^'
96 %left  <token> '&'
97 %left <token>  EQ NE
98 %left  <token> '<' '>' LE GE
99 %left  <token> LSHIFT RSHIFT
100
101 %left  <token> '+' '-'
102 %left  <token> '*' '/' '%'
103
104 %right UNARY
105 %token END 
106 %left <token> '('
107 %token <token> ALIGN_K BLOCK BIND QUAD LONG SHORT BYTE
108 %token SECTIONS PHDRS
109 %token '{' '}'
110 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
111 %token SIZEOF_HEADERS
112 %token INCLUDE
113 %token MEMORY DEFSYMEND
114 %token NOLOAD DSECT COPY INFO OVERLAY
115 %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
116 %token <integer> SIZEOF NEXT ADDR
117 %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
118 %token ORIGIN FILL
119 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
120 %token ALIGNMOD AT PROVIDE
121 %type <token> assign_op atype
122 %type <name>  filename
123 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
124 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
125 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
126
127 %%
128
129 file:   
130                 INPUT_SCRIPT script_file
131         |       INPUT_MRI_SCRIPT mri_script_file
132         |       INPUT_DEFSYM defsym_expr
133         ;
134
135
136 filename:  NAME;
137
138
139 defsym_expr:
140                 { ldlex_defsym(); }
141                 NAME '=' exp
142                 {
143                   ldlex_popstate();
144                   lang_add_assignment(exp_assop($3,$2,$4));
145                 }
146
147 /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
148 mri_script_file:
149                 {
150                   ldlex_mri_script ();
151                   PUSH_ERROR ("MRI style script");
152                 }
153              mri_script_lines
154                 {
155                   ldlex_popstate ();
156                   mri_draw_tree ();
157                   POP_ERROR ();
158                 }
159         ;
160
161 mri_script_lines:
162                 mri_script_lines mri_script_command NEWLINE
163           |
164         ;
165
166 mri_script_command:
167                 CHIP  exp 
168         |       CHIP  exp ',' exp
169         |       NAME    {
170                         einfo("%P%F: unrecognised keyword in MRI style script '%s'\n",$1);
171                         }
172         |       LIST    {
173                         config.map_filename = "-";
174                         }
175         |       ORDER ordernamelist
176         |       ENDWORD 
177         |       PUBLIC NAME '=' exp
178                         { mri_public($2, $4); }
179         |       PUBLIC NAME ',' exp
180                         { mri_public($2, $4); }
181         |       PUBLIC NAME  exp 
182                         { mri_public($2, $3); }
183         |       FORMAT NAME
184                         { mri_format($2); }
185         |       SECT NAME ',' exp
186                         { mri_output_section($2, $4);}
187         |       SECT NAME  exp
188                         { mri_output_section($2, $3);}
189         |       SECT NAME '=' exp
190                         { mri_output_section($2, $4);}
191         |       ALIGN_K NAME '=' exp
192                         { mri_align($2,$4); }
193         |       ALIGN_K NAME ',' exp
194                         { mri_align($2,$4); }
195         |       ALIGNMOD NAME '=' exp
196                         { mri_alignmod($2,$4); }
197         |       ALIGNMOD NAME ',' exp
198                         { mri_alignmod($2,$4); }
199         |       ABSOLUTE mri_abs_name_list
200         |       LOAD     mri_load_name_list
201         |       NAMEWORD NAME 
202                         { mri_name($2); }   
203         |       ALIAS NAME ',' NAME
204                         { mri_alias($2,$4,0);}
205         |       ALIAS NAME ',' INT
206                         { mri_alias($2,0,(int) $4);}
207         |       BASE     exp
208                         { mri_base($2); }
209         |       TRUNCATE INT
210                 {  mri_truncate((unsigned int) $2); }
211         |       CASE casesymlist
212         |       EXTERN extern_name_list
213         |       INCLUDE filename
214                 { ldfile_open_command_file ($2); } mri_script_lines END
215         |       START NAME
216                 { lang_add_entry ($2, false); }
217         |
218         ;
219
220 ordernamelist:
221               ordernamelist ',' NAME         { mri_order($3); }
222         |     ordernamelist  NAME         { mri_order($2); }
223         |
224         ;
225
226 mri_load_name_list:
227                 NAME
228                         { mri_load($1); }
229         |       mri_load_name_list ',' NAME { mri_load($3); }
230         ;
231
232 mri_abs_name_list:
233                 NAME
234                         { mri_only_load($1); }
235         |       mri_abs_name_list ','  NAME
236                         { mri_only_load($3); }
237         ;
238
239 casesymlist:
240           /* empty */ { $$ = NULL; }
241         | NAME
242         | casesymlist ',' NAME
243         ;
244
245 extern_name_list:
246           NAME
247                         { ldlang_add_undef ($1); }
248         | extern_name_list ',' NAME
249                         { ldlang_add_undef ($3); }
250         ;
251
252 script_file:
253         {
254          ldlex_both();
255         }
256        ifile_list
257         {
258         ldlex_popstate();
259         }
260         ;
261
262
263 ifile_list:
264        ifile_list ifile_p1
265         |
266         ;
267
268
269
270 ifile_p1:
271                 memory
272         |       sections
273         |       phdrs
274         |       startup
275         |       high_level_library
276         |       low_level_library
277         |       floating_point_support
278         |       statement_anywhere
279         |        ';'
280         |       TARGET_K '(' NAME ')'
281                 { lang_add_target($3); }
282         |       SEARCH_DIR '(' filename ')'
283                 { ldfile_add_library_path ($3, false); }
284         |       OUTPUT '(' filename ')'
285                 { lang_add_output($3, 1); }
286         |       OUTPUT_FORMAT '(' NAME ')'
287                   { lang_add_output_format ($3, (char *) NULL,
288                                             (char *) NULL, 1); }
289         |       OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
290                   { lang_add_output_format ($3, $5, $7, 1); }
291         |       OUTPUT_ARCH '(' NAME ')'
292                   { ldfile_set_output_arch($3); }
293         |       FORCE_COMMON_ALLOCATION
294                 { command_line.force_common_definition = true ; }
295         |       INPUT '(' input_list ')'
296         |       GROUP
297                   { lang_enter_group (); }
298                     '(' input_list ')'
299                   { lang_leave_group (); }
300         |       MAP '(' filename ')'
301                 { lang_add_map($3); }
302         |       INCLUDE filename 
303                 { ldfile_open_command_file($2); } ifile_list END
304         |       NOCROSSREFS '(' nocrossref_list ')'
305                 {
306                   lang_add_nocrossref ($3);
307                 }
308         ;
309
310 input_list:
311                 NAME
312                 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
313                                  (char *)NULL); }
314         |       input_list ',' NAME
315                 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
316                                  (char *)NULL); }
317         |       input_list NAME
318                 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
319                                  (char *)NULL); }
320         |       LNAME
321                 { lang_add_input_file($1,lang_input_file_is_l_enum,
322                                  (char *)NULL); }
323         |       input_list ',' LNAME
324                 { lang_add_input_file($3,lang_input_file_is_l_enum,
325                                  (char *)NULL); }
326         |       input_list LNAME
327                 { lang_add_input_file($2,lang_input_file_is_l_enum,
328                                  (char *)NULL); }
329         ;
330
331 sections:
332                 SECTIONS '{' sec_or_group_p1 '}'
333         ;
334
335 sec_or_group_p1:
336                 sec_or_group_p1 section
337         |       sec_or_group_p1 statement_anywhere
338         |
339         ;
340
341 statement_anywhere:
342                 ENTRY '(' NAME ')'
343                 { lang_add_entry ($3, false); }
344         |       assignment end
345         ;
346
347 /* The '*' and '?' cases are there because the lexer returns them as
348    separate tokens rather than as NAME.  */
349 file_NAME_list:
350                 NAME
351                         { lang_add_wild ($1, current_file); }
352         |       '*'
353                         { lang_add_wild ("*", current_file); }
354         |       '?'
355                         { lang_add_wild ("?", current_file); }
356         |       file_NAME_list opt_comma NAME
357                         { lang_add_wild ($3, current_file); }
358         |       file_NAME_list opt_comma '*'
359                         { lang_add_wild ("*", current_file); }
360         |       file_NAME_list opt_comma '?'
361                         { lang_add_wild ("?", current_file); }
362         ;
363
364 input_section_spec:
365                 NAME
366                 {
367                 lang_add_wild((char *)NULL, $1);
368                 }
369         |       '['
370                         {
371                         current_file = (char *)NULL;
372                         }
373                         file_NAME_list
374                 ']'
375         |       NAME
376                         {
377                         current_file = $1;
378                         }
379                 '(' file_NAME_list ')'
380         |       '?'
381                 /* This case is needed because the lexer returns a
382                    single question mark as '?' rather than NAME.  */
383                         {
384                         current_file = "?";
385                         }
386                 '(' file_NAME_list ')'
387         |       '*'
388                         {
389                         current_file = (char *)NULL;
390                         }
391                 '(' file_NAME_list ')'
392         ;
393
394 statement:
395                 assignment end
396         |       CREATE_OBJECT_SYMBOLS
397                 {
398                 lang_add_attribute(lang_object_symbols_statement_enum); 
399                 }
400         |       ';'
401         |       CONSTRUCTORS
402                 {
403                 
404                   lang_add_attribute(lang_constructors_statement_enum); 
405                 }
406         | input_section_spec
407         | length '(' mustbe_exp ')'
408                         {
409                         lang_add_data((int) $1,$3);
410                         }
411   
412         | FILL '(' mustbe_exp ')'
413                         {
414                           lang_add_fill
415                             (exp_get_value_int($3,
416                                                0,
417                                                "fill value",
418                                                lang_first_phase_enum));
419                         }
420         ;
421
422 statement_list:
423                 statement_list statement
424         |       statement
425         ;
426   
427 statement_list_opt:
428                 /* empty */
429         |       statement_list
430         ;
431
432 length:
433                 QUAD
434                         { $$ = $1; }
435         |       LONG
436                         { $$ = $1; }
437         |       SHORT
438                         { $$ = $1; }
439         |       BYTE
440                         { $$ = $1; }
441         ;
442
443 fill_opt:
444           '=' mustbe_exp
445                 {
446                   $$ =   exp_get_value_int($2,
447                                            0,
448                                            "fill value",
449                                            lang_first_phase_enum);
450                 }
451         |       { $$ = 0; }
452         ;
453
454                 
455
456 assign_op:
457                 PLUSEQ
458                         { $$ = '+'; }
459         |       MINUSEQ
460                         { $$ = '-'; }
461         |       MULTEQ
462                         { $$ = '*'; }
463         |       DIVEQ
464                         { $$ = '/'; }
465         |       LSHIFTEQ
466                         { $$ = LSHIFT; }
467         |       RSHIFTEQ
468                         { $$ = RSHIFT; }
469         |       ANDEQ
470                         { $$ = '&'; }
471         |       OREQ
472                         { $$ = '|'; }
473
474         ;
475
476 end:    ';' | ','
477         ;
478
479
480 assignment:
481                 NAME '=' mustbe_exp
482                 {
483                   lang_add_assignment (exp_assop ($2, $1, $3));
484                 }
485         |       NAME assign_op mustbe_exp
486                 {
487                   lang_add_assignment (exp_assop ('=', $1,
488                                                   exp_binop ($2,
489                                                              exp_nameop (NAME,
490                                                                          $1),
491                                                              $3)));
492                 }
493         |       PROVIDE '(' NAME '=' mustbe_exp ')'
494                 {
495                   lang_add_assignment (exp_provide ($3, $5));
496                 }
497         ;
498
499
500 opt_comma:
501                 ','     |       ;
502
503
504 memory:
505                 MEMORY '{' memory_spec memory_spec_list '}'
506         ;
507
508 memory_spec_list:
509                 memory_spec_list memory_spec
510         |       memory_spec_list ',' memory_spec
511         |
512         ;
513
514
515 memory_spec:            NAME
516                         { region = lang_memory_region_lookup($1); }
517                 attributes_opt ':'
518                 origin_spec opt_comma length_spec
519
520         ; origin_spec:
521         ORIGIN '=' mustbe_exp
522                 { region->current =
523                  region->origin =
524                  exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
525 }
526         ; length_spec:
527              LENGTH '=' mustbe_exp
528                { region->length = exp_get_vma($3,
529                                                ~((bfd_vma)0),
530                                                "length",
531                                                lang_first_phase_enum);
532                 }
533         
534
535 attributes_opt:
536                   '(' NAME ')'
537                         {
538                         lang_set_flags(&region->flags, $2);
539                         }
540         |
541   
542         ;
543
544 startup:
545         STARTUP '(' filename ')'
546                 { lang_startup($3); }
547         ;
548
549 high_level_library:
550                 HLL '(' high_level_library_NAME_list ')'
551         |       HLL '(' ')'
552                         { ldemul_hll((char *)NULL); }
553         ;
554
555 high_level_library_NAME_list:
556                 high_level_library_NAME_list opt_comma filename
557                         { ldemul_hll($3); }
558         |       filename
559                         { ldemul_hll($1); }
560
561         ;
562
563 low_level_library:
564         SYSLIB '(' low_level_library_NAME_list ')'
565         ; low_level_library_NAME_list:
566                 low_level_library_NAME_list opt_comma filename
567                         { ldemul_syslib($3); }
568         |
569         ;
570
571 floating_point_support:
572                 FLOAT
573                         { lang_float(true); }
574         |       NOFLOAT
575                         { lang_float(false); }
576         ;
577                 
578 nocrossref_list:
579                 /* empty */
580                 {
581                   $$ = NULL;
582                 }
583         |       NAME nocrossref_list
584                 {
585                   struct lang_nocrossref *n;
586
587                   n = (struct lang_nocrossref *) xmalloc (sizeof *n);
588                   n->name = $1;
589                   n->next = $2;
590                   $$ = n;
591                 }
592         |       NAME ',' nocrossref_list
593                 {
594                   struct lang_nocrossref *n;
595
596                   n = (struct lang_nocrossref *) xmalloc (sizeof *n);
597                   n->name = $1;
598                   n->next = $3;
599                   $$ = n;
600                 }
601         ;
602
603 mustbe_exp:              { ldlex_expression(); }
604                 exp
605                          { ldlex_popstate(); $$=$2;}
606         ;
607
608 exp     :
609                 '-' exp %prec UNARY
610                         { $$ = exp_unop('-', $2); }
611         |       '(' exp ')'
612                         { $$ = $2; }
613         |       NEXT '(' exp ')' %prec UNARY
614                         { $$ = exp_unop((int) $1,$3); }
615         |       '!' exp %prec UNARY
616                         { $$ = exp_unop('!', $2); }
617         |       '+' exp %prec UNARY
618                         { $$ = $2; }
619         |       '~' exp %prec UNARY
620                         { $$ = exp_unop('~', $2);}
621
622         |       exp '*' exp
623                         { $$ = exp_binop('*', $1, $3); }
624         |       exp '/' exp
625                         { $$ = exp_binop('/', $1, $3); }
626         |       exp '%' exp
627                         { $$ = exp_binop('%', $1, $3); }
628         |       exp '+' exp
629                         { $$ = exp_binop('+', $1, $3); }
630         |       exp '-' exp
631                         { $$ = exp_binop('-' , $1, $3); }
632         |       exp LSHIFT exp
633                         { $$ = exp_binop(LSHIFT , $1, $3); }
634         |       exp RSHIFT exp
635                         { $$ = exp_binop(RSHIFT , $1, $3); }
636         |       exp EQ exp
637                         { $$ = exp_binop(EQ , $1, $3); }
638         |       exp NE exp
639                         { $$ = exp_binop(NE , $1, $3); }
640         |       exp LE exp
641                         { $$ = exp_binop(LE , $1, $3); }
642         |       exp GE exp
643                         { $$ = exp_binop(GE , $1, $3); }
644         |       exp '<' exp
645                         { $$ = exp_binop('<' , $1, $3); }
646         |       exp '>' exp
647                         { $$ = exp_binop('>' , $1, $3); }
648         |       exp '&' exp
649                         { $$ = exp_binop('&' , $1, $3); }
650         |       exp '^' exp
651                         { $$ = exp_binop('^' , $1, $3); }
652         |       exp '|' exp
653                         { $$ = exp_binop('|' , $1, $3); }
654         |       exp '?' exp ':' exp
655                         { $$ = exp_trinop('?' , $1, $3, $5); }
656         |       exp ANDAND exp
657                         { $$ = exp_binop(ANDAND , $1, $3); }
658         |       exp OROR exp
659                         { $$ = exp_binop(OROR , $1, $3); }
660         |       DEFINED '(' NAME ')'
661                         { $$ = exp_nameop(DEFINED, $3); }
662         |       INT
663                         { $$ = exp_intop($1); }
664         |       SIZEOF_HEADERS
665                         { $$ = exp_nameop(SIZEOF_HEADERS,0); }
666
667         |       SIZEOF '(' NAME ')'
668                         { $$ = exp_nameop(SIZEOF,$3); }
669         |       ADDR '(' NAME ')'
670                         { $$ = exp_nameop(ADDR,$3); }
671         |       ABSOLUTE '(' exp ')'
672                         { $$ = exp_unop(ABSOLUTE, $3); }
673         |       ALIGN_K '(' exp ')'
674                         { $$ = exp_unop(ALIGN_K,$3); }
675         |       BLOCK '(' exp ')'
676                         { $$ = exp_unop(ALIGN_K,$3); }
677         |       NAME
678                         { $$ = exp_nameop(NAME,$1); }
679         ;
680
681
682 opt_at:
683                 AT '(' exp ')' { $$ = $3; }
684         |       { $$ = 0; }
685         ;
686
687 section:        NAME            { ldlex_expression(); }
688                 opt_exp_with_type 
689                 opt_at          { ldlex_popstate (); ldlex_script (); }
690                 '{'
691                         {
692                           lang_enter_output_section_statement($1, $3,
693                                                               sectype,
694                                                               0, 0, 0, $4);
695                         }
696                 statement_list_opt      
697                 '}' { ldlex_popstate (); ldlex_expression (); }
698                 memspec_opt phdr_opt fill_opt
699                 {
700                   ldlex_popstate();
701                   lang_leave_output_section_statement($13, $11);
702                 }
703                 opt_comma
704         |       /* The GROUP case is just enough to support the gcc
705                    svr3.ifile script.  It is not intended to be full
706                    support.  I'm not even sure what GROUP is supposed
707                    to mean.  */
708                 GROUP { ldlex_expression (); }
709                 opt_exp_with_type
710                 {
711                   ldlex_popstate ();
712                   lang_add_assignment (exp_assop ('=', ".", $3));
713                 }
714                 '{' sec_or_group_p1 '}'
715         ;
716
717 type:
718            NOLOAD  { sectype = noload_section; }
719         |  DSECT   { sectype = dsect_section; }
720         |  COPY    { sectype = copy_section; }
721         |  INFO    { sectype = info_section; }
722         |  OVERLAY { sectype = overlay_section; }
723         ;
724
725 atype:
726                 '(' type ')'
727         |       /* EMPTY */ { sectype = normal_section; }
728         ;
729
730 opt_exp_with_type:
731                 exp atype ':'           { $$ = $1; }
732         |       atype ':'               { $$ = (etree_type *)NULL;  }
733         |       /* The BIND cases are to support the gcc svr3.ifile
734                    script.  They aren't intended to implement full
735                    support for the BIND keyword.  I'm not even sure
736                    what BIND is supposed to mean.  */
737                 BIND '(' exp ')' atype ':' { $$ = $3; }
738         |       BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
739                 { $$ = $3; }
740         ;
741
742 memspec_opt:
743                 '>' NAME
744                 { $$ = $2; }
745         |       { $$ = "*default*"; }
746         ;
747
748 phdr_opt:
749                 /* empty */
750         |       phdr_opt ':' NAME
751                 {
752                   lang_section_in_phdr ($3);
753                 }
754         ;
755
756 phdrs:
757                 PHDRS '{' phdr_list '}'
758         ;
759
760 phdr_list:
761                 /* empty */
762         |       phdr_list phdr
763         ;
764
765 phdr:
766                 NAME { ldlex_expression (); }
767                   phdr_type phdr_qualifiers { ldlex_popstate (); }
768                   ';'
769                 {
770                   lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
771                                  $4.flags);
772                 }
773         ;
774
775 phdr_type:
776                 exp
777                 {
778                   $$ = $1;
779
780                   if ($1->type.node_class == etree_name
781                       && $1->type.node_code == NAME)
782                     {
783                       const char *s;
784                       unsigned int i;
785                       static const char * const phdr_types[] =
786                         {
787                           "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
788                           "PT_INTERP", "PT_NOTE", "PT_SHLIB",
789                           "PT_PHDR"
790                         };
791
792                       s = $1->name.name;
793                       for (i = 0;
794                            i < sizeof phdr_types / sizeof phdr_types[0];
795                            i++)
796                         if (strcmp (s, phdr_types[i]) == 0)
797                           {
798                             $$ = exp_intop (i);
799                             break;
800                           }
801                     }
802                 }
803         ;
804
805 phdr_qualifiers:
806                 /* empty */
807                 {
808                   memset (&$$, 0, sizeof (struct phdr_info));
809                 }
810         |       NAME phdr_val phdr_qualifiers
811                 {
812                   $$ = $3;
813                   if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
814                     $$.filehdr = true;
815                   else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
816                     $$.phdrs = true;
817                   else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
818                     $$.flags = $2;
819                   else
820                     einfo ("%X%P:%S: PHDRS syntax error at `%s'\n", $1);
821                 }
822         |       AT '(' exp ')' phdr_qualifiers
823                 {
824                   $$ = $5;
825                   $$.at = $3;
826                 }
827         ;
828
829 phdr_val:
830                 /* empty */
831                 {
832                   $$ = NULL;
833                 }
834         | '(' exp ')'
835                 {
836                   $$ = $2;
837                 }
838         ;
839
840 %%
841 void
842 yyerror(arg) 
843      const char *arg;
844
845   if (ldfile_assumed_script)
846     einfo ("%P:%s: file format not recognized; treating as linker script\n",
847            ldfile_input_filename);
848   if (error_index > 0 && error_index < ERROR_NAME_MAX)
849      einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
850   else
851      einfo ("%P%F:%S: %s\n", arg);
852 }