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