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