tweak
[binutils-gdb.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 LOADADDR
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 | LOADADDR '(' NAME ')'
672 { $$ = exp_nameop(LOADADDR,$3); }
673 | ABSOLUTE '(' exp ')'
674 { $$ = exp_unop(ABSOLUTE, $3); }
675 | ALIGN_K '(' exp ')'
676 { $$ = exp_unop(ALIGN_K,$3); }
677 | BLOCK '(' exp ')'
678 { $$ = exp_unop(ALIGN_K,$3); }
679 | NAME
680 { $$ = exp_nameop(NAME,$1); }
681 ;
682
683
684 opt_at:
685 AT '(' exp ')' { $$ = $3; }
686 | { $$ = 0; }
687 ;
688
689 section: NAME { ldlex_expression(); }
690 opt_exp_with_type
691 opt_at { ldlex_popstate (); ldlex_script (); }
692 '{'
693 {
694 lang_enter_output_section_statement($1, $3,
695 sectype,
696 0, 0, 0, $4);
697 }
698 statement_list_opt
699 '}' { ldlex_popstate (); ldlex_expression (); }
700 memspec_opt phdr_opt fill_opt
701 {
702 ldlex_popstate();
703 lang_leave_output_section_statement($13, $11);
704 }
705 opt_comma
706 | /* The GROUP case is just enough to support the gcc
707 svr3.ifile script. It is not intended to be full
708 support. I'm not even sure what GROUP is supposed
709 to mean. */
710 GROUP { ldlex_expression (); }
711 opt_exp_with_type
712 {
713 ldlex_popstate ();
714 lang_add_assignment (exp_assop ('=', ".", $3));
715 }
716 '{' sec_or_group_p1 '}'
717 ;
718
719 type:
720 NOLOAD { sectype = noload_section; }
721 | DSECT { sectype = dsect_section; }
722 | COPY { sectype = copy_section; }
723 | INFO { sectype = info_section; }
724 | OVERLAY { sectype = overlay_section; }
725 ;
726
727 atype:
728 '(' type ')'
729 | /* EMPTY */ { sectype = normal_section; }
730 ;
731
732 opt_exp_with_type:
733 exp atype ':' { $$ = $1; }
734 | atype ':' { $$ = (etree_type *)NULL; }
735 | /* The BIND cases are to support the gcc svr3.ifile
736 script. They aren't intended to implement full
737 support for the BIND keyword. I'm not even sure
738 what BIND is supposed to mean. */
739 BIND '(' exp ')' atype ':' { $$ = $3; }
740 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
741 { $$ = $3; }
742 ;
743
744 memspec_opt:
745 '>' NAME
746 { $$ = $2; }
747 | { $$ = "*default*"; }
748 ;
749
750 phdr_opt:
751 /* empty */
752 | phdr_opt ':' NAME
753 {
754 lang_section_in_phdr ($3);
755 }
756 ;
757
758 phdrs:
759 PHDRS '{' phdr_list '}'
760 ;
761
762 phdr_list:
763 /* empty */
764 | phdr_list phdr
765 ;
766
767 phdr:
768 NAME { ldlex_expression (); }
769 phdr_type phdr_qualifiers { ldlex_popstate (); }
770 ';'
771 {
772 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
773 $4.flags);
774 }
775 ;
776
777 phdr_type:
778 exp
779 {
780 $$ = $1;
781
782 if ($1->type.node_class == etree_name
783 && $1->type.node_code == NAME)
784 {
785 const char *s;
786 unsigned int i;
787 static const char * const phdr_types[] =
788 {
789 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
790 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
791 "PT_PHDR"
792 };
793
794 s = $1->name.name;
795 for (i = 0;
796 i < sizeof phdr_types / sizeof phdr_types[0];
797 i++)
798 if (strcmp (s, phdr_types[i]) == 0)
799 {
800 $$ = exp_intop (i);
801 break;
802 }
803 }
804 }
805 ;
806
807 phdr_qualifiers:
808 /* empty */
809 {
810 memset (&$$, 0, sizeof (struct phdr_info));
811 }
812 | NAME phdr_val phdr_qualifiers
813 {
814 $$ = $3;
815 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
816 $$.filehdr = true;
817 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
818 $$.phdrs = true;
819 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
820 $$.flags = $2;
821 else
822 einfo ("%X%P:%S: PHDRS syntax error at `%s'\n", $1);
823 }
824 | AT '(' exp ')' phdr_qualifiers
825 {
826 $$ = $5;
827 $$.at = $3;
828 }
829 ;
830
831 phdr_val:
832 /* empty */
833 {
834 $$ = NULL;
835 }
836 | '(' exp ')'
837 {
838 $$ = $2;
839 }
840 ;
841
842 %%
843 void
844 yyerror(arg)
845 const char *arg;
846 {
847 if (ldfile_assumed_script)
848 einfo ("%P:%s: file format not recognized; treating as linker script\n",
849 ldfile_input_filename);
850 if (error_index > 0 && error_index < ERROR_NAME_MAX)
851 einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
852 else
853 einfo ("%P%F:%S: %s\n", arg);
854 }