419c54e5f800fe96784d66073c9036e6f36ec6e3
[platform/upstream/binutils.git] / ld / ldgram.y
1 %{
2 /*
3  * $Id$ 
4  *
5  *
6 */
7
8 /* 
9    This is a YACC grammer intended to parse a superset of the AT&T
10    linker scripting languaue.
11
12
13    Written by Steve Chamberlain steve@cygnus.com
14 */
15
16
17
18 #include "sysdep.h"
19 #include "bfd.h"
20 #include "ld.h"    
21 #include "ldexp.h"
22 #include "ldversion.h"
23 #include "ldlang.h"
24 #include "ld-emul.h"
25 #include "ldfile.h"
26 #include "ldmisc.h"
27 #define YYDEBUG 1
28
29 boolean option_v;
30 extern unsigned int lineno;
31 extern boolean trace_files;
32 extern boolean write_map;
33
34 boolean hex_mode;
35
36 strip_symbols_type strip_symbols=STRIP_NONE;
37 discard_locals_type discard_locals=DISCARD_NONE;
38
39
40 lang_memory_region_type *region;
41
42
43 lang_memory_region_type *lang_memory_region_lookup();
44 lang_output_section_statement_type *lang_output_section_statement_lookup();
45
46 #ifdef __STDC__
47
48 void lang_add_data(int type, union etree_union *exp);
49 void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, bfd_vma block_value);
50
51 #else
52
53 void lang_add_data();
54 void lang_enter_output_section_statement();
55
56 #endif /* __STDC__ */
57
58 extern args_type command_line;
59 char *current_file;
60 boolean ldgram_want_filename = true;
61 boolean had_script = false;
62 boolean force_make_executable = false;
63
64 boolean ldgram_in_script = false;
65 boolean ldgram_had_equals = false;
66 /* LOCALS */
67
68
69
70
71 %}
72 %union {
73   bfd_vma integer;
74   int voidval;
75   char *name;
76   int token;
77   union etree_union *etree;
78   asection *section;
79   struct lang_output_section_statement_struct *output_section_statement;
80   union  lang_statement_union **statement_ptr;
81   int lineno;
82   struct {
83     FILE *file;
84     char *name;
85     unsigned int lineno;
86   } state;
87
88   
89 }
90
91 %type <etree> exp  opt_exp  exp_head
92 %type <integer> fill_opt opt_block
93 %type <name> memspec_opt
94 %token <integer> INT CHAR 
95 %token <name> NAME
96 %type  <integer> length
97
98 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
99 %right <token> '?' ':'
100 %left <token> OROR
101 %left <token>  ANDAND
102 %left <token> '|'
103 %left <token>  '^'
104 %left  <token> '&'
105 %left <token>  EQ NE
106 %left  <token> '<' '>' LE GE
107 %left  <token> LSHIFT RSHIFT
108 %left  <token> '+' '-'
109 %left  <token> '*' '/' '%'
110 %right UNARY
111 %left <token> '('
112 %token <token> ALIGN_K BLOCK LONG SHORT BYTE
113 %token SECTIONS  
114 %token '{' '}'
115 %token ALIGNMENT SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
116 %token NEXT SIZEOF ADDR  SCRIPT ENDSCRIPT SIZEOF_HEADERS
117 %token MEMORY 
118 %token DSECT NOLOAD COPY INFO OVERLAY 
119 %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY 
120 %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S OPTION_sort_common
121 %token OPTION_format  OPTION_F OPTION_u
122
123 %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
124 %token OPTION_v OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT 
125 %token OPTION_n OPTION_r OPTION_o OPTION_b  OPTION_A OPTION_R
126 %token <name> OPTION_l OPTION_L  OPTION_T OPTION_Aarch OPTION_Tfile  OPTION_Texp
127 %token OPTION_Ur 
128 %token ORIGIN FILL OPTION_g
129 %token LENGTH  BIND SUBSECTION_ALIGN   CREATE_OBJECT_SYMBOLS INPUT OUTPUT
130 %type <token> assign_op SIZEOF NEXT ADDR 
131 %type <etree> assignment
132 %type <name>  filename
133
134 %{
135 ld_config_type config;
136 %}
137
138 %%
139
140
141
142 file:   command_line  { lang_final(); };
143
144
145 filename:
146   NAME;
147
148 command_line:
149                 command_line command_line_option
150         |
151         ;
152
153 command_line_option:
154                 '{'
155                         { ldgram_in_script = true; }
156                 ifile_list 
157                         { ldgram_in_script = false; }
158                 '}'
159         |       OPTION_v
160                         {       
161                         ldversion();
162                         option_v = true;
163                         }
164         |       OPTION_t {
165                         trace_files = true;
166                         }
167         |       OPTION_M {
168                         write_map = true;
169                         }
170         |       OPTION_n {
171                         config.magic_demand_paged = false;
172                         config.make_executable = false;
173                         }
174         |       OPTION_s {
175                         strip_symbols = STRIP_ALL;
176                         }
177         |       OPTION_S {
178                         strip_symbols = STRIP_DEBUGGER;
179                         }
180         |       OPTION_u NAME {
181                         ldlang_add_undef($2);
182                 }
183             
184         |       OPTION_r {
185                         config.relocateable_output = true;
186                         config.build_constructors = false;
187                         config.magic_demand_paged = false;
188                         }
189         |       OPTION_Ur {
190                         config.relocateable_output = true;
191                         config.build_constructors = true;
192                         config.magic_demand_paged = false;
193                       }             
194         |       OPTION_o filename
195                         {
196                         lang_add_output($2); 
197                         }
198         |       OPTION_e NAME
199                         { lang_add_entry($2); 
200                         }
201         |       OPTION_X {
202                         discard_locals = DISCARD_L;
203                 }
204         |       OPTION_x {
205                         discard_locals = DISCARD_ALL;
206                 }
207
208         |       OPTION_noinhibit_exec
209                         {
210                         force_make_executable = true;
211                         }
212         |      OPTION_sort_common {
213         config.sort_common = true;
214       }
215         |      OPTION_d {
216                           command_line.force_common_definition = true;
217                         }
218         |      OPTION_dc
219                          {
220                           command_line.force_common_definition = true;
221                         }
222         |       OPTION_g
223                         {
224                         /* Ignored */
225                         }
226         |       OPTION_dp
227                          {
228                           command_line.force_common_definition = true;
229                         }
230         |       OPTION_format NAME
231                    {
232                           lang_add_target($2);
233                    }
234         |       OPTION_Texp 
235                 { 
236                         hex_mode  =true; 
237                 } 
238                 INT
239                 { 
240                         lang_section_start($1,exp_intop($3));
241                         hex_mode = false; 
242                 }
243         
244         |       OPTION_Aarch 
245                 { 
246                         ldfile_add_arch($1); 
247                 }
248         |        OPTION_b NAME
249                         {
250                         lang_add_target($2);
251                         }
252         |       OPTION_L
253                         {
254                         ldfile_add_library_path($1);
255                         }
256         |       OPTION_F
257                 {
258                 /* Ignore */
259                 }
260         |       NAME
261                 { lang_add_input_file($1,lang_input_file_is_file_enum,
262                                  (char *)NULL); }
263         |       OPTION_c filename script_file
264                         { ldfile_open_command_file($2); }
265         |       OPTION_Tfile 
266                         { ldfile_open_command_file($1); } script_file
267
268         |       OPTION_T filename 
269                         { ldfile_open_command_file($2); } script_file
270
271         |       OPTION_l
272                         {
273                           lang_add_input_file($1,
274                                          lang_input_file_is_l_enum,
275                                          (char *)NULL);
276                         }
277         |       OPTION_R filename
278                         {
279                         lang_add_input_file($2,
280                                 lang_input_file_is_symbols_only_enum,
281                                 (char *)NULL);
282                         }
283         |       OPTION_defsym 
284                         {
285                         }
286                 NAME     '='
287                 exp_head 
288                         {
289                         lang_add_assignment(exp_assop($4,$3,$5));
290                         }       
291         | '-' NAME
292                  { info("%P%F Unrecognised option -%s\n", $2);  }
293
294         ;
295
296
297   
298
299
300
301
302
303 script_file:
304         { ldgram_in_script = true; }
305        ifile_list '}'
306         { ldgram_in_script = false; }
307
308         ;
309
310
311 ifile_list:
312        ifile_list ifile_p1 
313         |
314         ;
315
316
317
318 ifile_p1:
319                 memory
320         |       sections
321         |       startup
322         |       high_level_library
323         |       low_level_library
324         |       floating_point_support
325         |       statement_anywhere
326         |       TARGET_K '(' NAME ')'
327                 { lang_add_target($3); }
328         |       SEARCH_DIR '(' filename ')'
329                 { ldfile_add_library_path($3); }
330         |       OUTPUT '(' filename ')'
331                 { lang_add_output($3); }
332         |       OUTPUT_FORMAT '(' NAME ')'
333                   { lang_add_output_format($3); }
334         |       OUTPUT_ARCH '(' NAME ')'
335                   { ldfile_set_output_arch($3); }
336         |       FORCE_COMMON_ALLOCATION
337                 { command_line.force_common_definition = true ; }
338         |       INPUT '(' input_list ')'
339         |       MAP '(' filename ')'
340                 { lang_add_map($3); }
341         ;
342
343 input_list:
344                 NAME
345                 { lang_add_input_file($1,lang_input_file_is_file_enum,
346                                  (char *)NULL); }
347         |       input_list ',' NAME
348                 { lang_add_input_file($3,lang_input_file_is_file_enum,
349                                  (char *)NULL); }
350         |       input_list   NAME
351                 { lang_add_input_file($2, lang_input_file_is_file_enum,
352                                  (char *)NULL); }
353         ;
354
355 sections:
356                 SECTIONS '{'sec_or_group_p1  '}' 
357         ;
358
359 sec_or_group_p1:
360                 sec_or_group_p1 section
361         |       sec_or_group_p1 statement_anywhere
362         |
363         ;
364
365 statement_anywhere:
366                 ENTRY '(' NAME ')'
367                 { lang_add_entry($3); }
368         |       assignment end
369         ;
370
371 file_NAME_list:
372                 NAME
373                         { lang_add_wild($1, current_file); }
374         |       file_NAME_list opt_comma NAME 
375                         { lang_add_wild($3, current_file); }
376         ;
377
378 input_section_spec:
379                 NAME
380                 {
381                 lang_add_wild((char *)NULL, $1);
382                 }
383         |       '[' 
384                         {
385                         current_file = (char *)NULL;
386                         }
387                         file_NAME_list  
388                 ']' 
389         |       NAME
390                         {
391                         current_file  =$1;
392                         } 
393                 '(' file_NAME_list ')'
394         |       '*' 
395                         {       
396                         current_file = (char *)NULL;
397                         } 
398                 '(' file_NAME_list ')'
399         ;
400
401 statement:
402                 statement assignment end
403         |       statement CREATE_OBJECT_SYMBOLS
404                 {
405                   lang_add_attribute(lang_object_symbols_statement_enum); }
406
407         |       statement input_section_spec
408         |       statement length '(' exp_head ')'
409                         {
410                         lang_add_data($2,$4);
411                         }
412   
413         |       statement FILL '(' exp_head ')'
414                         {
415                           lang_add_fill
416                             (exp_get_value_int($4,
417                                                0,
418                                                "fill value",
419                                                lang_first_phase_enum));
420                         }
421         |
422         ;
423
424 length:
425                 LONG  
426                         { $$ = $1; }
427         |       SHORT 
428                         { $$ = $1; }
429         |       BYTE 
430                         { $$ = $1; }
431         ;
432
433 fill_opt:
434           '=' exp_head
435                 {
436                   $$ =   exp_get_value_int($2,
437                                            0,
438                                            "fill value",
439                                            lang_first_phase_enum); 
440                 }
441         |       {  $$ = 0; }
442         ;
443
444                 
445
446 assign_op:
447                 PLUSEQ
448                         { $$ = '+'; }
449         |       MINUSEQ 
450                         { $$ = '-'; }
451         |       MULTEQ
452                         { $$ = '*'; }
453         |       DIVEQ
454                         { $$ = '/'; }
455         |       LSHIFTEQ
456                         { $$ = LSHIFT; }
457         |       RSHIFTEQ
458                         { $$ = RSHIFT; }
459         |       ANDEQ
460                         { $$ = '&'; }
461         |       OREQ
462                         { $$ = '|'; }
463
464         ;
465
466 end:    ';' | ','
467         ;
468
469
470 assignment:
471         
472                 NAME '=' exp_head 
473                 {
474                   lang_add_assignment(exp_assop($2,$1,$3));
475                 }
476         |       NAME assign_op exp_head 
477                 {
478                   lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
479                 }
480                 
481         ;
482
483
484 opt_comma:
485                 ','     |       ;
486
487
488 memory:
489                 MEMORY '{' memory_spec memory_spec_list '}'
490         ;
491
492 memory_spec_list:
493                 memory_spec_list memory_spec 
494         |       memory_spec_list ',' memory_spec
495         |
496         ;
497
498
499 memory_spec:
500                 NAME 
501                         { region = lang_memory_region_lookup($1); }
502                 attributes_opt  ':' origin_spec opt_comma length_spec
503
504                 {
505                  
506
507                 }
508         ;
509 origin_spec:
510         ORIGIN '=' exp
511                 { region->current =
512                  region->origin =
513                  exp_get_vma($3, 0L,"origin", lang_first_phase_enum); }
514         ;
515 length_spec:
516              LENGTH '=' exp             
517                {  region->length = exp_get_vma($3,
518                                                ~((bfd_vma)0),
519                                                "length",
520                                                lang_first_phase_enum);
521                 }
522         
523
524 attributes_opt:
525                   '(' NAME ')'
526                         {
527                         lang_set_flags(&region->flags, $2);
528                         }
529         |
530   
531         ;
532
533 startup:
534         STARTUP '(' filename ')'
535                 { lang_startup($3); }
536         ;
537
538 high_level_library:
539                 HLL '('  high_level_library_NAME_list ')'
540         |       HLL '('  ')'
541                         { ldemul_hll((char *)NULL); }
542         ;
543
544 high_level_library_NAME_list:
545                 high_level_library_NAME_list  opt_comma filename
546                         { ldemul_hll($3); }
547         |       filename
548                         { ldemul_hll($1); }
549
550         ;
551
552 low_level_library:
553         SYSLIB '(' low_level_library_NAME_list ')'
554         ;
555 low_level_library_NAME_list:
556                 low_level_library_NAME_list opt_comma filename
557                         { ldemul_syslib($3); }                          
558         |
559         ;
560
561 floating_point_support:
562                 FLOAT
563                         { lang_float(true); }
564         |       NOFLOAT
565                         { lang_float(false); }  
566         ;
567                 
568
569         
570
571 exp     :
572                 '-' exp    %prec UNARY
573                         { $$ = exp_unop('-', $2); }
574         |       '(' exp ')'
575                         { $$ = $2; }
576         |       NEXT '(' exp ')' %prec UNARY
577                         { $$ = exp_unop($1,$3); }
578         |       '!' exp    %prec UNARY
579                         { $$ = exp_unop('!', $2); }
580         |       '+' exp    %prec UNARY
581                         { $$ = $2; }
582         |       '~' exp    %prec UNARY
583                         { $$ = exp_unop('~', $2);}
584
585         |       exp '*' exp
586                         { $$ = exp_binop('*', $1, $3); }
587         |       exp '/' exp
588                         { $$ = exp_binop('/', $1, $3); }
589         |       exp '%' exp
590                         { $$ = exp_binop('%', $1, $3); }
591         |       exp '+' exp
592                         { $$ = exp_binop('+', $1, $3); }
593         |       exp '-' exp
594                         { $$ = exp_binop('-' , $1, $3); }                       
595         |       exp LSHIFT exp
596                         { $$ = exp_binop(LSHIFT , $1, $3); }
597         |       exp RSHIFT exp
598                         { $$ = exp_binop(RSHIFT , $1, $3); }
599         |       exp EQ exp
600                         { $$ = exp_binop(EQ , $1, $3); }
601         |       exp NE exp
602                         { $$ = exp_binop(NE , $1, $3); }
603         |       exp LE exp
604                         { $$ = exp_binop(LE , $1, $3); }
605         |       exp GE exp
606                         { $$ = exp_binop(GE , $1, $3); }
607         |       exp '<' exp
608                         { $$ = exp_binop('<' , $1, $3); }
609         |       exp '>' exp
610                         { $$ = exp_binop('>' , $1, $3); }
611         |       exp '&' exp
612                         { $$ = exp_binop('&' , $1, $3); }
613         |       exp '^' exp
614                         { $$ = exp_binop('^' , $1, $3); }
615         |       exp '|' exp
616                         { $$ = exp_binop('|' , $1, $3); }
617         |       exp '?' exp ':' exp
618                         { $$ = exp_trinop('?' , $1, $3, $5); }
619         |       exp ANDAND exp
620                         { $$ = exp_binop(ANDAND , $1, $3); }
621         |       exp OROR exp
622                         { $$ = exp_binop(OROR , $1, $3); }
623         |       DEFINED '(' NAME ')'
624                         { $$ = exp_nameop(DEFINED, $3); }
625         |       INT
626                         { $$ = exp_intop($1); }
627         |       SIZEOF_HEADERS 
628                         { $$ = exp_nameop(SIZEOF_HEADERS,0); }
629
630         |       SIZEOF  '('  NAME ')'
631                         { $$ = exp_nameop($1,$3); }
632         |       ADDR '(' NAME ')'
633                         { $$ = exp_nameop($1,$3); }
634         |       ALIGN_K '(' exp ')'
635                         { $$ = exp_unop($1,$3); }
636         |       NAME
637                         { $$ = exp_nameop(NAME,$1); }
638         ;
639
640
641
642
643 section:        NAME opt_exp opt_block ':' opt_things'{' 
644                 {
645                 lang_enter_output_section_statement($1,$2,$3);
646                 }
647                statement        '}'     fill_opt memspec_opt
648                 {
649                   lang_leave_output_section_statement($10, $11);
650                 }
651
652         ;
653
654 opt_things: 
655         {
656
657         }
658         ;
659
660 exp_head:
661         exp { $$ = $1; }
662         ;
663
664 opt_exp:
665                 exp_head
666                         { $$ = $1; }
667         |               { $$= (etree_type *)NULL; }
668         ;
669
670 opt_block:
671                 BLOCK '(' exp_head ')'
672                 { $$ = exp_get_value_int($3,
673                                          1L,
674                                          "block",
675                                          lang_first_phase_enum); 
676                 }
677         |       { $$  = 1; }
678         ;
679   
680 memspec_opt:
681                 '>' NAME
682                 { $$ = $2; }
683         |       { $$ = "*default*"; }
684         ;
685