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).
5 This file is part of GNU ld.
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.
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.
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. */
26 #define DONTDECLARE_MALLOC
46 static enum section_type sectype;
48 lang_memory_region_type *region;
52 boolean ldgram_want_filename = true;
53 boolean had_script = false;
54 boolean force_make_executable = false;
56 boolean ldgram_in_script = false;
57 boolean ldgram_had_equals = false;
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--;
70 union etree_union *etree;
75 union etree_union *at;
76 union etree_union *flags;
80 %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
81 %type <integer> fill_opt
82 %type <name> memspec_opt casesymlist
84 %token <name> NAME LNAME
85 %type <integer> length
86 %type <phdr> phdr_qualifiers
88 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
89 %right <token> '?' ':'
96 %left <token> '<' '>' LE GE
97 %left <token> LSHIFT RSHIFT
100 %left <token> '*' '/' '%'
105 %token <token> ALIGN_K BLOCK BIND QUAD LONG SHORT BYTE
106 %token SECTIONS PHDRS
108 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
109 %token SIZEOF_HEADERS
111 %token MEMORY DEFSYMEND
112 %token NOLOAD DSECT COPY INFO OVERLAY
113 %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
114 %token <integer> SIZEOF NEXT ADDR
115 %token STARTUP HLL SYSLIB FLOAT NOFLOAT
117 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
118 %token ALIGNMOD AT PROVIDE
119 %type <token> assign_op atype
120 %type <name> filename
121 %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD
122 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
123 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
128 INPUT_SCRIPT script_file
129 | INPUT_MRI_SCRIPT mri_script_file
130 | INPUT_DEFSYM defsym_expr
142 lang_add_assignment(exp_assop($3,$2,$4));
145 /* SYNTAX WITHIN AN MRI SCRIPT FILE */
149 PUSH_ERROR ("MRI style script");
160 mri_script_lines mri_script_command NEWLINE
168 einfo("%P%F: unrecognised keyword in MRI style script '%s'\n",$1);
171 config.map_filename = "-";
173 | ORDER ordernamelist
175 | PUBLIC NAME '=' exp
176 { mri_public($2, $4); }
177 | PUBLIC NAME ',' exp
178 { mri_public($2, $4); }
180 { mri_public($2, $3); }
184 { mri_output_section($2, $4);}
186 { mri_output_section($2, $3);}
188 { mri_output_section($2, $4);}
189 | ALIGN_K NAME '=' exp
190 { mri_align($2,$4); }
191 | ALIGN_K NAME ',' exp
192 { mri_align($2,$4); }
193 | ALIGNMOD NAME '=' exp
194 { mri_alignmod($2,$4); }
195 | ALIGNMOD NAME ',' exp
196 { mri_alignmod($2,$4); }
197 | ABSOLUTE mri_abs_name_list
198 | LOAD mri_load_name_list
201 | ALIAS NAME ',' NAME
202 { mri_alias($2,$4,0);}
204 { mri_alias($2,0,(int) $4);}
208 { mri_truncate((unsigned int) $2); }
210 | EXTERN extern_name_list
212 { ldfile_open_command_file ($2); } mri_script_lines END
214 { lang_add_entry ($2, false); }
219 ordernamelist ',' NAME { mri_order($3); }
220 | ordernamelist NAME { mri_order($2); }
227 | mri_load_name_list ',' NAME { mri_load($3); }
232 { mri_only_load($1); }
233 | mri_abs_name_list ',' NAME
234 { mri_only_load($3); }
238 /* empty */ { $$ = NULL; }
240 | casesymlist ',' NAME
245 { ldlang_add_undef ($1); }
246 | extern_name_list ',' NAME
247 { ldlang_add_undef ($3); }
275 | floating_point_support
278 | TARGET_K '(' NAME ')'
279 { lang_add_target($3); }
280 | SEARCH_DIR '(' filename ')'
281 { ldfile_add_library_path ($3, false); }
282 | OUTPUT '(' filename ')'
283 { lang_add_output($3, 1); }
284 | OUTPUT_FORMAT '(' NAME ')'
285 { lang_add_output_format ($3, (char *) NULL,
287 | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
288 { lang_add_output_format ($3, $5, $7, 1); }
289 | OUTPUT_ARCH '(' NAME ')'
290 { ldfile_set_output_arch($3); }
291 | FORCE_COMMON_ALLOCATION
292 { command_line.force_common_definition = true ; }
293 | INPUT '(' input_list ')'
295 { lang_enter_group (); }
297 { lang_leave_group (); }
298 | MAP '(' filename ')'
299 { lang_add_map($3); }
301 { ldfile_open_command_file($2); } ifile_list END
306 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
308 | input_list ',' NAME
309 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
312 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
315 { lang_add_input_file($1,lang_input_file_is_l_enum,
317 | input_list ',' LNAME
318 { lang_add_input_file($3,lang_input_file_is_l_enum,
321 { lang_add_input_file($2,lang_input_file_is_l_enum,
326 SECTIONS '{' sec_or_group_p1 '}'
330 sec_or_group_p1 section
331 | sec_or_group_p1 statement_anywhere
337 { lang_add_entry ($3, false); }
341 /* The '*' and '?' cases are there because the lexer returns them as
342 separate tokens rather than as NAME. */
345 { lang_add_wild ($1, current_file); }
347 { lang_add_wild ("*", current_file); }
349 { lang_add_wild ("?", current_file); }
350 | file_NAME_list opt_comma NAME
351 { lang_add_wild ($3, current_file); }
352 | file_NAME_list opt_comma '*'
353 { lang_add_wild ("*", current_file); }
354 | file_NAME_list opt_comma '?'
355 { lang_add_wild ("?", current_file); }
361 lang_add_wild((char *)NULL, $1);
365 current_file = (char *)NULL;
373 '(' file_NAME_list ')'
375 /* This case is needed because the lexer returns a
376 single question mark as '?' rather than NAME. */
380 '(' file_NAME_list ')'
383 current_file = (char *)NULL;
385 '(' file_NAME_list ')'
390 | CREATE_OBJECT_SYMBOLS
392 lang_add_attribute(lang_object_symbols_statement_enum);
398 lang_add_attribute(lang_constructors_statement_enum);
401 | length '(' mustbe_exp ')'
403 lang_add_data((int) $1,$3);
406 | FILL '(' mustbe_exp ')'
409 (exp_get_value_int($3,
412 lang_first_phase_enum));
417 statement_list statement
440 $$ = exp_get_value_int($2,
443 lang_first_phase_enum);
477 lang_add_assignment (exp_assop ($2, $1, $3));
479 | NAME assign_op mustbe_exp
481 lang_add_assignment (exp_assop ('=', $1,
487 | PROVIDE '(' NAME '=' mustbe_exp ')'
489 lang_add_assignment (exp_provide ($3, $5));
499 MEMORY '{' memory_spec memory_spec_list '}'
503 memory_spec_list memory_spec
504 | memory_spec_list ',' memory_spec
510 { region = lang_memory_region_lookup($1); }
512 origin_spec opt_comma length_spec
515 ORIGIN '=' mustbe_exp
518 exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
521 LENGTH '=' mustbe_exp
522 { region->length = exp_get_vma($3,
525 lang_first_phase_enum);
532 lang_set_flags(®ion->flags, $2);
539 STARTUP '(' filename ')'
540 { lang_startup($3); }
544 HLL '(' high_level_library_NAME_list ')'
546 { ldemul_hll((char *)NULL); }
549 high_level_library_NAME_list:
550 high_level_library_NAME_list opt_comma filename
558 SYSLIB '(' low_level_library_NAME_list ')'
559 ; low_level_library_NAME_list:
560 low_level_library_NAME_list opt_comma filename
561 { ldemul_syslib($3); }
565 floating_point_support:
567 { lang_float(true); }
569 { lang_float(false); }
573 mustbe_exp: { ldlex_expression(); }
575 { ldlex_popstate(); $$=$2;}
580 { $$ = exp_unop('-', $2); }
583 | NEXT '(' exp ')' %prec UNARY
584 { $$ = exp_unop((int) $1,$3); }
585 | '!' exp %prec UNARY
586 { $$ = exp_unop('!', $2); }
587 | '+' exp %prec UNARY
589 | '~' exp %prec UNARY
590 { $$ = exp_unop('~', $2);}
593 { $$ = exp_binop('*', $1, $3); }
595 { $$ = exp_binop('/', $1, $3); }
597 { $$ = exp_binop('%', $1, $3); }
599 { $$ = exp_binop('+', $1, $3); }
601 { $$ = exp_binop('-' , $1, $3); }
603 { $$ = exp_binop(LSHIFT , $1, $3); }
605 { $$ = exp_binop(RSHIFT , $1, $3); }
607 { $$ = exp_binop(EQ , $1, $3); }
609 { $$ = exp_binop(NE , $1, $3); }
611 { $$ = exp_binop(LE , $1, $3); }
613 { $$ = exp_binop(GE , $1, $3); }
615 { $$ = exp_binop('<' , $1, $3); }
617 { $$ = exp_binop('>' , $1, $3); }
619 { $$ = exp_binop('&' , $1, $3); }
621 { $$ = exp_binop('^' , $1, $3); }
623 { $$ = exp_binop('|' , $1, $3); }
624 | exp '?' exp ':' exp
625 { $$ = exp_trinop('?' , $1, $3, $5); }
627 { $$ = exp_binop(ANDAND , $1, $3); }
629 { $$ = exp_binop(OROR , $1, $3); }
630 | DEFINED '(' NAME ')'
631 { $$ = exp_nameop(DEFINED, $3); }
633 { $$ = exp_intop($1); }
635 { $$ = exp_nameop(SIZEOF_HEADERS,0); }
637 | SIZEOF '(' NAME ')'
638 { $$ = exp_nameop(SIZEOF,$3); }
640 { $$ = exp_nameop(ADDR,$3); }
641 | ABSOLUTE '(' exp ')'
642 { $$ = exp_unop(ABSOLUTE, $3); }
643 | ALIGN_K '(' exp ')'
644 { $$ = exp_unop(ALIGN_K,$3); }
646 { $$ = exp_unop(ALIGN_K,$3); }
648 { $$ = exp_nameop(NAME,$1); }
653 AT '(' exp ')' { $$ = $3; }
657 section: NAME { ldlex_expression(); }
659 opt_at { ldlex_popstate (); ldlex_script (); }
662 lang_enter_output_section_statement($1, $3,
667 '}' { ldlex_popstate (); ldlex_expression (); }
668 memspec_opt phdr_opt fill_opt
671 lang_leave_output_section_statement($13, $11);
674 | /* The GROUP case is just enough to support the gcc
675 svr3.ifile script. It is not intended to be full
676 support. I'm not even sure what GROUP is supposed
678 GROUP { ldlex_expression (); }
682 lang_add_assignment (exp_assop ('=', ".", $3));
684 '{' sec_or_group_p1 '}'
688 NOLOAD { sectype = noload_section; }
689 | DSECT { sectype = dsect_section; }
690 | COPY { sectype = copy_section; }
691 | INFO { sectype = info_section; }
692 | OVERLAY { sectype = overlay_section; }
697 | /* EMPTY */ { sectype = normal_section; }
701 exp atype ':' { $$ = $1; }
702 | atype ':' { $$ = (etree_type *)NULL; }
703 | /* The BIND cases are to support the gcc svr3.ifile
704 script. They aren't intended to implement full
705 support for the BIND keyword. I'm not even sure
706 what BIND is supposed to mean. */
707 BIND '(' exp ')' atype ':' { $$ = $3; }
708 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
715 | { $$ = "*default*"; }
722 lang_section_in_phdr ($3);
727 PHDRS '{' phdr_list '}'
736 NAME { ldlex_expression (); }
737 phdr_type phdr_qualifiers { ldlex_popstate (); }
740 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
750 if ($1->type.node_class == etree_name
751 && $1->type.node_code == NAME)
755 static const char * const phdr_types[] =
757 "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
758 "PT_INTERP", "PT_NOTE", "PT_SHLIB",
764 i < sizeof phdr_types / sizeof phdr_types[0];
766 if (strcmp (s, phdr_types[i]) == 0)
778 memset (&$$, 0, sizeof (struct phdr_info));
780 | NAME phdr_val phdr_qualifiers
783 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
785 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
787 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
790 einfo ("%X%P:%S: PHDRS syntax error at `%s'\n", $1);
792 | AT '(' exp ')' phdr_qualifiers
815 if (ldfile_assumed_script)
816 einfo ("%P:%s: file format not recognized; treating as linker script\n",
817 ldfile_input_filename);
818 if (error_index > 0 && error_index < ERROR_NAME_MAX)
819 einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
821 einfo ("%P%F:%S: %s\n", arg);