]>
Commit | Line | Data |
---|---|---|
c611e285 | 1 | /* A YACC grammer to parse a superset of the AT&T linker scripting languaue. |
86bc0974 | 2 | Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. |
c611e285 | 3 | Written by Steve Chamberlain of Cygnus Support ([email protected]). |
2fa0b342 | 4 | |
c611e285 | 5 | This file is part of GNU ld. |
2fa0b342 | 6 | |
c611e285 SC |
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. | |
2fa0b342 | 11 | |
c611e285 SC |
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. | |
2fa0b342 | 16 | |
c611e285 SC |
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 | |
3a473096 | 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
c611e285 SC |
20 | |
21 | %{ | |
22 | /* | |
2e2bf962 | 23 | |
c611e285 | 24 | */ |
2fa0b342 | 25 | |
f177a611 | 26 | #define DONTDECLARE_MALLOC |
2fa0b342 | 27 | |
2fa0b342 | 28 | #include "bfd.h" |
f177a611 | 29 | #include "sysdep.h" |
4a6afc88 | 30 | #include "bfdlink.h" |
2fa0b342 DHW |
31 | #include "ld.h" |
32 | #include "ldexp.h" | |
7cb9aa50 | 33 | #include "ldver.h" |
2fa0b342 | 34 | #include "ldlang.h" |
f177a611 | 35 | #include "ldemul.h" |
2fa0b342 DHW |
36 | #include "ldfile.h" |
37 | #include "ldmisc.h" | |
fcf276c4 | 38 | #include "ldmain.h" |
3d2b83ea | 39 | #include "mri.h" |
6232b6c4 | 40 | #include "ldlex.h" |
f177a611 | 41 | |
3a473096 ILT |
42 | #ifndef YYDEBUG |
43 | #define YYDEBUG 1 | |
44 | #endif | |
45 | ||
86bc0974 | 46 | static enum section_type sectype; |
2fa0b342 | 47 | |
2fa0b342 DHW |
48 | lang_memory_region_type *region; |
49 | ||
50 | ||
2fa0b342 DHW |
51 | char *current_file; |
52 | boolean ldgram_want_filename = true; | |
53 | boolean had_script = false; | |
54 | boolean force_make_executable = false; | |
1d45ccb3 | 55 | |
1418c83b | 56 | boolean ldgram_in_script = false; |
1d45ccb3 | 57 | boolean ldgram_had_equals = false; |
2fa0b342 DHW |
58 | |
59 | ||
3d2b83ea SC |
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--; | |
2fa0b342 DHW |
65 | %} |
66 | %union { | |
67 | bfd_vma integer; | |
2fa0b342 DHW |
68 | char *name; |
69 | int token; | |
70 | union etree_union *etree; | |
86bc0974 ILT |
71 | struct phdr_info |
72 | { | |
73 | boolean filehdr; | |
74 | boolean phdrs; | |
75 | union etree_union *at; | |
76 | union etree_union *flags; | |
77 | } phdr; | |
582dd77f | 78 | struct lang_nocrossref *nocrossref; |
2fa0b342 DHW |
79 | } |
80 | ||
86bc0974 | 81 | %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val |
dadd414a | 82 | %type <integer> fill_opt |
9b222190 | 83 | %type <name> memspec_opt casesymlist |
6812f0e8 | 84 | %token <integer> INT |
3a473096 | 85 | %token <name> NAME LNAME |
582dd77f | 86 | %type <integer> length |
86bc0974 | 87 | %type <phdr> phdr_qualifiers |
582dd77f | 88 | %type <nocrossref> nocrossref_list |
2fa0b342 | 89 | |
a37cc0c0 | 90 | %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ |
2fa0b342 DHW |
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 | |
6812f0e8 | 100 | |
2fa0b342 DHW |
101 | %left <token> '+' '-' |
102 | %left <token> '*' '/' '%' | |
6812f0e8 | 103 | |
2fa0b342 | 104 | %right UNARY |
2e38b71d | 105 | %token END |
2fa0b342 | 106 | %left <token> '(' |
86bc0974 ILT |
107 | %token <token> ALIGN_K BLOCK BIND QUAD LONG SHORT BYTE |
108 | %token SECTIONS PHDRS | |
2fa0b342 | 109 | %token '{' '}' |
6812f0e8 SC |
110 | %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH |
111 | %token SIZEOF_HEADERS | |
dadd414a | 112 | %token INCLUDE |
d4e5e3c3 | 113 | %token MEMORY DEFSYMEND |
f177a611 | 114 | %token NOLOAD DSECT COPY INFO OVERLAY |
3a473096 | 115 | %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY |
d4e5e3c3 | 116 | %token <integer> SIZEOF NEXT ADDR |
582dd77f | 117 | %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS |
d4e5e3c3 | 118 | %token ORIGIN FILL |
0b3499f6 ILT |
119 | %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS |
120 | %token ALIGNMOD AT PROVIDE | |
86bc0974 | 121 | %type <token> assign_op atype |
2fa0b342 | 122 | %type <name> filename |
e14a43bf | 123 | %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD |
4a6afc88 | 124 | %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL |
3a473096 | 125 | %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START |
3d2b83ea | 126 | |
2fa0b342 DHW |
127 | %% |
128 | ||
d4e5e3c3 DM |
129 | file: |
130 | INPUT_SCRIPT script_file | |
131 | | INPUT_MRI_SCRIPT mri_script_file | |
132 | | INPUT_DEFSYM defsym_expr | |
2fa0b342 DHW |
133 | ; |
134 | ||
2fa0b342 | 135 | |
d4e5e3c3 | 136 | filename: NAME; |
2fa0b342 | 137 | |
e14a43bf | 138 | |
d4e5e3c3 DM |
139 | defsym_expr: |
140 | { ldlex_defsym(); } | |
141 | NAME '=' exp | |
8ddef552 | 142 | { |
d4e5e3c3 DM |
143 | ldlex_popstate(); |
144 | lang_add_assignment(exp_assop($3,$2,$4)); | |
8ddef552 | 145 | } |
2fa0b342 | 146 | |
3d2b83ea SC |
147 | /* SYNTAX WITHIN AN MRI SCRIPT FILE */ |
148 | mri_script_file: | |
86bc0974 ILT |
149 | { |
150 | ldlex_mri_script (); | |
151 | PUSH_ERROR ("MRI style script"); | |
3d2b83ea SC |
152 | } |
153 | mri_script_lines | |
86bc0974 ILT |
154 | { |
155 | ldlex_popstate (); | |
156 | mri_draw_tree (); | |
157 | POP_ERROR (); | |
3d2b83ea SC |
158 | } |
159 | ; | |
2fa0b342 | 160 | |
3d2b83ea | 161 | mri_script_lines: |
2e38b71d SC |
162 | mri_script_lines mri_script_command NEWLINE |
163 | | | |
3d2b83ea | 164 | ; |
2fa0b342 | 165 | |
2e38b71d | 166 | mri_script_command: |
3d2b83ea SC |
167 | CHIP exp |
168 | | CHIP exp ',' exp | |
169 | | NAME { | |
2e38b71d | 170 | einfo("%P%F: unrecognised keyword in MRI style script '%s'\n",$1); |
3d2b83ea SC |
171 | } |
172 | | LIST { | |
3d2b83ea SC |
173 | config.map_filename = "-"; |
174 | } | |
2e38b71d SC |
175 | | ORDER ordernamelist |
176 | | ENDWORD | |
3a473096 | 177 | | PUBLIC NAME '=' exp |
e14a43bf | 178 | { mri_public($2, $4); } |
3a473096 | 179 | | PUBLIC NAME ',' exp |
e14a43bf SC |
180 | { mri_public($2, $4); } |
181 | | PUBLIC NAME exp | |
182 | { mri_public($2, $3); } | |
2e38b71d SC |
183 | | FORMAT NAME |
184 | { mri_format($2); } | |
3a473096 | 185 | | SECT NAME ',' exp |
3d2b83ea SC |
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);} | |
dadd414a SC |
191 | | ALIGN_K NAME '=' exp |
192 | { mri_align($2,$4); } | |
86bc0974 ILT |
193 | | ALIGN_K NAME ',' exp |
194 | { mri_align($2,$4); } | |
dadd414a SC |
195 | | ALIGNMOD NAME '=' exp |
196 | { mri_alignmod($2,$4); } | |
86bc0974 ILT |
197 | | ALIGNMOD NAME ',' exp |
198 | { mri_alignmod($2,$4); } | |
3d2b83ea SC |
199 | | ABSOLUTE mri_abs_name_list |
200 | | LOAD mri_load_name_list | |
2e38b71d SC |
201 | | NAMEWORD NAME |
202 | { mri_name($2); } | |
e14a43bf SC |
203 | | ALIAS NAME ',' NAME |
204 | { mri_alias($2,$4,0);} | |
205 | | ALIAS NAME ',' INT | |
4a6afc88 | 206 | { mri_alias($2,0,(int) $4);} |
e14a43bf SC |
207 | | BASE exp |
208 | { mri_base($2); } | |
dadd414a | 209 | | TRUNCATE INT |
4a6afc88 | 210 | { mri_truncate((unsigned int) $2); } |
3a473096 ILT |
211 | | CASE casesymlist |
212 | | EXTERN extern_name_list | |
213 | | INCLUDE filename | |
214 | { ldfile_open_command_file ($2); } mri_script_lines END | |
215 | | START NAME | |
86bc0974 | 216 | { lang_add_entry ($2, false); } |
2e38b71d SC |
217 | | |
218 | ; | |
219 | ||
220 | ordernamelist: | |
221 | ordernamelist ',' NAME { mri_order($3); } | |
222 | | ordernamelist NAME { mri_order($2); } | |
223 | | | |
3d2b83ea | 224 | ; |
2fa0b342 | 225 | |
3d2b83ea SC |
226 | mri_load_name_list: |
227 | NAME | |
228 | { mri_load($1); } | |
229 | | mri_load_name_list ',' NAME { mri_load($3); } | |
230 | ; | |
1418c83b | 231 | |
3d2b83ea SC |
232 | mri_abs_name_list: |
233 | NAME | |
234 | { mri_only_load($1); } | |
235 | | mri_abs_name_list ',' NAME | |
236 | { mri_only_load($3); } | |
237 | ; | |
1418c83b | 238 | |
3a473096 | 239 | casesymlist: |
9b222190 | 240 | /* empty */ { $$ = NULL; } |
3a473096 ILT |
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 | ||
3d2b83ea | 252 | script_file: |
9d1fe8a4 SC |
253 | { |
254 | ldlex_both(); | |
255 | } | |
3d2b83ea | 256 | ifile_list |
9d1fe8a4 SC |
257 | { |
258 | ldlex_popstate(); | |
259 | } | |
1418c83b SC |
260 | ; |
261 | ||
262 | ||
263 | ifile_list: | |
3d2b83ea | 264 | ifile_list ifile_p1 |
13a0e8d7 | 265 | | |
2fa0b342 DHW |
266 | ; |
267 | ||
268 | ||
269 | ||
270 | ifile_p1: | |
271 | memory | |
272 | | sections | |
86bc0974 | 273 | | phdrs |
2fa0b342 DHW |
274 | | startup |
275 | | high_level_library | |
276 | | low_level_library | |
277 | | floating_point_support | |
ac004870 | 278 | | statement_anywhere |
9d1fe8a4 | 279 | | ';' |
2fa0b342 DHW |
280 | | TARGET_K '(' NAME ')' |
281 | { lang_add_target($3); } | |
282 | | SEARCH_DIR '(' filename ')' | |
0cd82d00 | 283 | { ldfile_add_library_path ($3, false); } |
2fa0b342 | 284 | | OUTPUT '(' filename ')' |
f651733a ILT |
285 | { lang_add_output($3, 1); } |
286 | | OUTPUT_FORMAT '(' NAME ')' | |
3a473096 ILT |
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); } | |
f651733a | 291 | | OUTPUT_ARCH '(' NAME ')' |
a37cc0c0 | 292 | { ldfile_set_output_arch($3); } |
13a0e8d7 SC |
293 | | FORCE_COMMON_ALLOCATION |
294 | { command_line.force_common_definition = true ; } | |
2fa0b342 | 295 | | INPUT '(' input_list ')' |
0b3499f6 ILT |
296 | | GROUP |
297 | { lang_enter_group (); } | |
298 | '(' input_list ')' | |
299 | { lang_leave_group (); } | |
2fa0b342 DHW |
300 | | MAP '(' filename ')' |
301 | { lang_add_map($3); } | |
dadd414a SC |
302 | | INCLUDE filename |
303 | { ldfile_open_command_file($2); } ifile_list END | |
582dd77f ILT |
304 | | NOCROSSREFS '(' nocrossref_list ')' |
305 | { | |
306 | lang_add_nocrossref ($3); | |
307 | } | |
2fa0b342 DHW |
308 | ; |
309 | ||
310 | input_list: | |
311 | NAME | |
f651733a | 312 | { lang_add_input_file($1,lang_input_file_is_search_file_enum, |
2fa0b342 DHW |
313 | (char *)NULL); } |
314 | | input_list ',' NAME | |
f651733a | 315 | { lang_add_input_file($3,lang_input_file_is_search_file_enum, |
2fa0b342 | 316 | (char *)NULL); } |
3d2b83ea | 317 | | input_list NAME |
f651733a | 318 | { lang_add_input_file($2,lang_input_file_is_search_file_enum, |
2fa0b342 | 319 | (char *)NULL); } |
3a473096 ILT |
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); } | |
2fa0b342 DHW |
329 | ; |
330 | ||
331 | sections: | |
3d2b83ea | 332 | SECTIONS '{' sec_or_group_p1 '}' |
2fa0b342 DHW |
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 ')' | |
86bc0974 | 343 | { lang_add_entry ($3, false); } |
2fa0b342 DHW |
344 | | assignment end |
345 | ; | |
346 | ||
86bc0974 ILT |
347 | /* The '*' and '?' cases are there because the lexer returns them as |
348 | separate tokens rather than as NAME. */ | |
1418c83b SC |
349 | file_NAME_list: |
350 | NAME | |
86bc0974 ILT |
351 | { lang_add_wild ($1, current_file); } |
352 | | '*' | |
353 | { lang_add_wild ("*", current_file); } | |
354 | | '?' | |
355 | { lang_add_wild ("?", current_file); } | |
3d2b83ea | 356 | | file_NAME_list opt_comma NAME |
86bc0974 ILT |
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); } | |
1418c83b SC |
362 | ; |
363 | ||
364 | input_section_spec: | |
365 | NAME | |
366 | { | |
367 | lang_add_wild((char *)NULL, $1); | |
368 | } | |
3d2b83ea | 369 | | '[' |
1418c83b SC |
370 | { |
371 | current_file = (char *)NULL; | |
372 | } | |
3d2b83ea SC |
373 | file_NAME_list |
374 | ']' | |
1418c83b SC |
375 | | NAME |
376 | { | |
86bc0974 ILT |
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 = "?"; | |
3d2b83ea | 385 | } |
1418c83b | 386 | '(' file_NAME_list ')' |
3d2b83ea SC |
387 | | '*' |
388 | { | |
1418c83b | 389 | current_file = (char *)NULL; |
3d2b83ea | 390 | } |
1418c83b SC |
391 | '(' file_NAME_list ')' |
392 | ; | |
393 | ||
2fa0b342 | 394 | statement: |
9fce28ed SC |
395 | assignment end |
396 | | CREATE_OBJECT_SYMBOLS | |
13a0e8d7 | 397 | { |
9fce28ed SC |
398 | lang_add_attribute(lang_object_symbols_statement_enum); |
399 | } | |
400 | | ';' | |
401 | | CONSTRUCTORS | |
f177a611 | 402 | { |
3d2b83ea | 403 | |
9fce28ed SC |
404 | lang_add_attribute(lang_constructors_statement_enum); |
405 | } | |
406 | | input_section_spec | |
86bc0974 | 407 | | length '(' mustbe_exp ')' |
2fa0b342 | 408 | { |
4a6afc88 | 409 | lang_add_data((int) $1,$3); |
2fa0b342 DHW |
410 | } |
411 | ||
86bc0974 | 412 | | FILL '(' mustbe_exp ')' |
2fa0b342 DHW |
413 | { |
414 | lang_add_fill | |
9fce28ed | 415 | (exp_get_value_int($3, |
2fa0b342 DHW |
416 | 0, |
417 | "fill value", | |
9fce28ed | 418 | lang_first_phase_enum)); |
2fa0b342 | 419 | } |
2fa0b342 DHW |
420 | ; |
421 | ||
9fce28ed SC |
422 | statement_list: |
423 | statement_list statement | |
424 | | statement | |
425 | ; | |
426 | ||
8ddef552 DM |
427 | statement_list_opt: |
428 | /* empty */ | |
429 | | statement_list | |
430 | ; | |
431 | ||
2fa0b342 | 432 | length: |
c477527c ILT |
433 | QUAD |
434 | { $$ = $1; } | |
435 | | LONG | |
2fa0b342 | 436 | { $$ = $1; } |
3d2b83ea | 437 | | SHORT |
2fa0b342 | 438 | { $$ = $1; } |
3d2b83ea | 439 | | BYTE |
2fa0b342 DHW |
440 | { $$ = $1; } |
441 | ; | |
442 | ||
443 | fill_opt: | |
9d1fe8a4 | 444 | '=' mustbe_exp |
2fa0b342 DHW |
445 | { |
446 | $$ = exp_get_value_int($2, | |
447 | 0, | |
448 | "fill value", | |
3d2b83ea | 449 | lang_first_phase_enum); |
2fa0b342 | 450 | } |
3d2b83ea | 451 | | { $$ = 0; } |
2fa0b342 DHW |
452 | ; |
453 | ||
454 | ||
455 | ||
456 | assign_op: | |
457 | PLUSEQ | |
458 | { $$ = '+'; } | |
3d2b83ea | 459 | | MINUSEQ |
2fa0b342 DHW |
460 | { $$ = '-'; } |
461 | | MULTEQ | |
462 | { $$ = '*'; } | |
463 | | DIVEQ | |
464 | { $$ = '/'; } | |
465 | | LSHIFTEQ | |
466 | { $$ = LSHIFT; } | |
467 | | RSHIFTEQ | |
468 | { $$ = RSHIFT; } | |
469 | | ANDEQ | |
470 | { $$ = '&'; } | |
471 | | OREQ | |
472 | { $$ = '|'; } | |
473 | ||
474 | ; | |
475 | ||
9d1fe8a4 | 476 | end: ';' | ',' |
2fa0b342 DHW |
477 | ; |
478 | ||
2fa0b342 DHW |
479 | |
480 | assignment: | |
3d2b83ea | 481 | NAME '=' mustbe_exp |
2fa0b342 | 482 | { |
0b3499f6 | 483 | lang_add_assignment (exp_assop ($2, $1, $3)); |
2fa0b342 | 484 | } |
3d2b83ea | 485 | | NAME assign_op mustbe_exp |
2fa0b342 | 486 | { |
0b3499f6 ILT |
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)); | |
2fa0b342 | 496 | } |
2fa0b342 DHW |
497 | ; |
498 | ||
499 | ||
500 | opt_comma: | |
501 | ',' | ; | |
502 | ||
503 | ||
504 | memory: | |
3d2b83ea | 505 | MEMORY '{' memory_spec memory_spec_list '}' |
2fa0b342 DHW |
506 | ; |
507 | ||
508 | memory_spec_list: | |
3d2b83ea | 509 | memory_spec_list memory_spec |
2fa0b342 DHW |
510 | | memory_spec_list ',' memory_spec |
511 | | | |
512 | ; | |
513 | ||
514 | ||
3d2b83ea | 515 | memory_spec: NAME |
2fa0b342 | 516 | { region = lang_memory_region_lookup($1); } |
3d2b83ea | 517 | attributes_opt ':' |
9d1fe8a4 | 518 | origin_spec opt_comma length_spec |
2fa0b342 | 519 | |
3d2b83ea | 520 | ; origin_spec: |
9d1fe8a4 | 521 | ORIGIN '=' mustbe_exp |
2fa0b342 DHW |
522 | { region->current = |
523 | region->origin = | |
3d2b83ea SC |
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, | |
2fa0b342 DHW |
529 | ~((bfd_vma)0), |
530 | "length", | |
531 | lang_first_phase_enum); | |
532 | } | |
533 | ||
534 | ||
535 | attributes_opt: | |
536 | '(' NAME ')' | |
537 | { | |
538 | lang_set_flags(®ion->flags, $2); | |
539 | } | |
540 | | | |
541 | ||
542 | ; | |
543 | ||
544 | startup: | |
545 | STARTUP '(' filename ')' | |
546 | { lang_startup($3); } | |
547 | ; | |
548 | ||
549 | high_level_library: | |
3d2b83ea SC |
550 | HLL '(' high_level_library_NAME_list ')' |
551 | | HLL '(' ')' | |
2fa0b342 DHW |
552 | { ldemul_hll((char *)NULL); } |
553 | ; | |
554 | ||
555 | high_level_library_NAME_list: | |
3d2b83ea | 556 | high_level_library_NAME_list opt_comma filename |
2fa0b342 DHW |
557 | { ldemul_hll($3); } |
558 | | filename | |
559 | { ldemul_hll($1); } | |
560 | ||
561 | ; | |
562 | ||
563 | low_level_library: | |
564 | SYSLIB '(' low_level_library_NAME_list ')' | |
3d2b83ea | 565 | ; low_level_library_NAME_list: |
2fa0b342 | 566 | low_level_library_NAME_list opt_comma filename |
3d2b83ea | 567 | { ldemul_syslib($3); } |
2fa0b342 DHW |
568 | | |
569 | ; | |
570 | ||
571 | floating_point_support: | |
572 | FLOAT | |
573 | { lang_float(true); } | |
574 | | NOFLOAT | |
3d2b83ea | 575 | { lang_float(false); } |
2fa0b342 DHW |
576 | ; |
577 | ||
582dd77f ILT |
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 | ; | |
2fa0b342 | 602 | |
3d2b83ea | 603 | mustbe_exp: { ldlex_expression(); } |
9d1fe8a4 SC |
604 | exp |
605 | { ldlex_popstate(); $$=$2;} | |
606 | ; | |
2fa0b342 DHW |
607 | |
608 | exp : | |
3d2b83ea | 609 | '-' exp %prec UNARY |
2fa0b342 | 610 | { $$ = exp_unop('-', $2); } |
9d1fe8a4 | 611 | | '(' exp ')' |
2fa0b342 DHW |
612 | { $$ = $2; } |
613 | | NEXT '(' exp ')' %prec UNARY | |
4a6afc88 | 614 | { $$ = exp_unop((int) $1,$3); } |
3d2b83ea | 615 | | '!' exp %prec UNARY |
2fa0b342 | 616 | { $$ = exp_unop('!', $2); } |
3d2b83ea | 617 | | '+' exp %prec UNARY |
2fa0b342 | 618 | { $$ = $2; } |
3d2b83ea | 619 | | '~' exp %prec UNARY |
2fa0b342 DHW |
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 | |
3d2b83ea | 631 | { $$ = exp_binop('-' , $1, $3); } |
2fa0b342 DHW |
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); } | |
3d2b83ea | 642 | | exp GE exp |
2fa0b342 DHW |
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); } | |
3d2b83ea | 664 | | SIZEOF_HEADERS |
65c552e3 | 665 | { $$ = exp_nameop(SIZEOF_HEADERS,0); } |
2fa0b342 | 666 | |
3d2b83ea | 667 | | SIZEOF '(' NAME ')' |
f177a611 | 668 | { $$ = exp_nameop(SIZEOF,$3); } |
2fa0b342 | 669 | | ADDR '(' NAME ')' |
f177a611 | 670 | { $$ = exp_nameop(ADDR,$3); } |
ae475b39 SC |
671 | | ABSOLUTE '(' exp ')' |
672 | { $$ = exp_unop(ABSOLUTE, $3); } | |
2fa0b342 | 673 | | ALIGN_K '(' exp ')' |
f177a611 | 674 | { $$ = exp_unop(ALIGN_K,$3); } |
0b3499f6 ILT |
675 | | BLOCK '(' exp ')' |
676 | { $$ = exp_unop(ALIGN_K,$3); } | |
2fa0b342 DHW |
677 | | NAME |
678 | { $$ = exp_nameop(NAME,$1); } | |
679 | ; | |
680 | ||
681 | ||
9fce28ed SC |
682 | opt_at: |
683 | AT '(' exp ')' { $$ = $3; } | |
684 | | { $$ = 0; } | |
685 | ; | |
2fa0b342 | 686 | |
3d2b83ea | 687 | section: NAME { ldlex_expression(); } |
9fce28ed | 688 | opt_exp_with_type |
86bc0974 | 689 | opt_at { ldlex_popstate (); ldlex_script (); } |
dadd414a | 690 | '{' |
9fce28ed | 691 | { |
86bc0974 ILT |
692 | lang_enter_output_section_statement($1, $3, |
693 | sectype, | |
694 | 0, 0, 0, $4); | |
9fce28ed | 695 | } |
8ddef552 | 696 | statement_list_opt |
86bc0974 ILT |
697 | '}' { ldlex_popstate (); ldlex_expression (); } |
698 | memspec_opt phdr_opt fill_opt | |
2fa0b342 | 699 | { |
e14a43bf | 700 | ldlex_popstate(); |
86bc0974 | 701 | lang_leave_output_section_statement($13, $11); |
2fa0b342 | 702 | } |
86bc0974 ILT |
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 '}' | |
2fa0b342 DHW |
715 | ; |
716 | ||
dadd414a | 717 | type: |
86bc0974 ILT |
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; } | |
f177a611 JG |
723 | ; |
724 | ||
86bc0974 ILT |
725 | atype: |
726 | '(' type ')' | |
727 | | /* EMPTY */ { sectype = normal_section; } | |
728 | ; | |
6812f0e8 | 729 | |
dadd414a | 730 | opt_exp_with_type: |
86bc0974 ILT |
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; } | |
2fa0b342 DHW |
740 | ; |
741 | ||
2fa0b342 | 742 | memspec_opt: |
9d1fe8a4 | 743 | '>' NAME |
2fa0b342 DHW |
744 | { $$ = $2; } |
745 | | { $$ = "*default*"; } | |
746 | ; | |
86bc0974 ILT |
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 | ||
3d2b83ea SC |
840 | %% |
841 | void | |
842 | yyerror(arg) | |
c477527c | 843 | const char *arg; |
3d2b83ea | 844 | { |
0b3499f6 ILT |
845 | if (ldfile_assumed_script) |
846 | einfo ("%P:%s: file format not recognized; treating as linker script\n", | |
847 | ldfile_input_filename); | |
c477527c | 848 | if (error_index > 0 && error_index < ERROR_NAME_MAX) |
0b3499f6 | 849 | einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]); |
3d2b83ea | 850 | else |
0b3499f6 | 851 | einfo ("%P%F:%S: %s\n", arg); |
3d2b83ea | 852 | } |