* ldgram.y (dirlist_ptr): Removed; not used.
[platform/upstream/binutils.git] / ld / ldgram.y
1 /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
2    Copyright (C) 1991, 1993 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 "bfdlink.h"
31 #include "ld.h"    
32 #include "ldexp.h"
33 #include "ldver.h"
34 #include "ldlang.h"
35 #include "ldemul.h"
36 #include "ldfile.h"
37 #include "ldmisc.h"
38 #include "ldmain.h"
39 #include "mri.h"
40
41 #define YYDEBUG 1
42
43 static int typebits;
44
45 lang_memory_region_type *region;
46
47
48 char *current_file;
49 boolean ldgram_want_filename = true;
50 boolean had_script = false;
51 boolean force_make_executable = false;
52
53 boolean ldgram_in_script = false;
54 boolean ldgram_had_equals = false;
55
56
57 #define ERROR_NAME_MAX 20
58 static char *error_names[ERROR_NAME_MAX];
59 static int error_index;
60 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
61 #define POP_ERROR()   error_index--;
62 %}
63 %union {
64   bfd_vma integer;
65   char *name;
66   int token;
67   union etree_union *etree;
68 }
69
70 %type <etree> exp  opt_exp_with_type  mustbe_exp opt_at
71 %type <integer> fill_opt
72 %type <name> memspec_opt
73 %token <integer> INT  
74 %token <name> NAME
75 %type  <integer> length
76
77 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
78 %right <token> '?' ':'
79 %left <token> OROR
80 %left <token>  ANDAND
81 %left <token> '|'
82 %left <token>  '^'
83 %left  <token> '&'
84 %left <token>  EQ NE
85 %left  <token> '<' '>' LE GE
86 %left  <token> LSHIFT RSHIFT
87
88 %left  <token> '+' '-'
89 %left  <token> '*' '/' '%'
90
91 %right UNARY
92 %token END 
93 %left <token> '('
94 %token <token> ALIGN_K BLOCK QUAD LONG SHORT BYTE
95 %token SECTIONS
96 %token '{' '}'
97 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
98 %token SIZEOF_HEADERS
99 %token INCLUDE
100 %token MEMORY DEFSYMEND
101 %token NOLOAD DSECT COPY INFO OVERLAY
102 %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
103 %token <integer> SIZEOF NEXT ADDR
104 %token STARTUP HLL SYSLIB FLOAT NOFLOAT
105 %token ORIGIN FILL
106 %token LENGTH CREATE_OBJECT_SYMBOLS INPUT OUTPUT CONSTRUCTORS
107 %token ALIGNMOD AT
108 %type <token> assign_op 
109 %type <name>  filename
110 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
111 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
112 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM
113
114 %{
115 /* For byacc, this has to come after INPUT_SCRIPT et al. are defined.  */
116 #include "ldlex.h"
117 %}
118 %%
119
120 file:   
121                 INPUT_SCRIPT script_file
122         |       INPUT_MRI_SCRIPT mri_script_file
123         |       INPUT_DEFSYM defsym_expr
124         ;
125
126
127 filename:  NAME;
128
129
130 defsym_expr:
131                 { ldlex_defsym(); }
132                 NAME '=' exp
133                 {
134                   ldlex_popstate();
135                   lang_add_assignment(exp_assop($3,$2,$4));
136                 }
137
138 /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
139 mri_script_file:
140                 {       ldlex_mri_script();
141                         PUSH_ERROR("MRI style script");
142                 }
143              mri_script_lines
144                 {       ldlex_popstate(); 
145                         POP_ERROR();
146                 }
147         ;
148
149 mri_script_lines:
150                 mri_script_lines mri_script_command NEWLINE
151           |
152         ;
153
154 mri_script_command:
155                 CHIP  exp 
156         |       CHIP  exp ',' exp
157         |       NAME    {
158                         einfo("%P%F: unrecognised keyword in MRI style script '%s'\n",$1);
159                         }
160         |       LIST    {
161                         write_map = true;
162                         config.map_filename = "-";
163                         }
164         |       ORDER ordernamelist
165         |       ENDWORD 
166         |       PUBLIC NAME '=' exp 
167                         { mri_public($2, $4); }
168         |       PUBLIC NAME ',' exp 
169                         { mri_public($2, $4); }
170         |       PUBLIC NAME  exp 
171                         { mri_public($2, $3); }
172         |       FORMAT NAME
173                         { mri_format($2); }
174         |       SECT NAME ',' exp 
175                         { mri_output_section($2, $4);}
176         |       SECT NAME  exp
177                         { mri_output_section($2, $3);}
178         |       SECT NAME '=' exp
179                         { mri_output_section($2, $4);}
180         |       ALIGN_K NAME '=' exp
181                         { mri_align($2,$4); }
182         |       ALIGNMOD NAME '=' exp
183                         { mri_alignmod($2,$4); }
184         |       ABSOLUTE mri_abs_name_list
185         |       LOAD     mri_load_name_list
186         |       NAMEWORD NAME 
187                         { mri_name($2); }   
188         |       ALIAS NAME ',' NAME
189                         { mri_alias($2,$4,0);}
190         |       ALIAS NAME ',' INT
191                         { mri_alias($2,0,(int) $4);}
192         |       BASE     exp
193                         { mri_base($2); }
194         |       TRUNCATE INT
195                 {  mri_truncate((unsigned int) $2); }
196         |
197         ;
198
199 ordernamelist:
200               ordernamelist ',' NAME         { mri_order($3); }
201         |     ordernamelist  NAME         { mri_order($2); }
202         |
203         ;
204
205 mri_load_name_list:
206                 NAME
207                         { mri_load($1); }
208         |       mri_load_name_list ',' NAME { mri_load($3); }
209         ;
210
211 mri_abs_name_list:
212                 NAME
213                         { mri_only_load($1); }
214         |       mri_abs_name_list ','  NAME
215                         { mri_only_load($3); }
216         ;
217
218 script_file:
219         {
220          ldlex_both();
221         }
222        ifile_list
223         {
224         ldlex_popstate();
225         }
226         ;
227
228
229 ifile_list:
230        ifile_list ifile_p1
231         |
232         ;
233
234
235
236 ifile_p1:
237                 memory
238         |       sections
239         |       startup
240         |       high_level_library
241         |       low_level_library
242         |       floating_point_support
243         |       statement_anywhere
244         |        ';'
245         |       TARGET_K '(' NAME ')'
246                 { lang_add_target($3); }
247         |       SEARCH_DIR '(' filename ')'
248                 { ldfile_add_library_path($3); }
249         |       OUTPUT '(' filename ')'
250                 { lang_add_output($3, 1); }
251         |       OUTPUT_FORMAT '(' NAME ')'
252                   { lang_add_output_format($3, 1); }
253         |       OUTPUT_ARCH '(' NAME ')'
254                   { ldfile_set_output_arch($3); }
255         |       FORCE_COMMON_ALLOCATION
256                 { command_line.force_common_definition = true ; }
257         |       INPUT '(' input_list ')'
258         |       MAP '(' filename ')'
259                 { lang_add_map($3); }
260         |       INCLUDE filename 
261                 { ldfile_open_command_file($2); } ifile_list END
262         ;
263
264 input_list:
265                 NAME
266                 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
267                                  (char *)NULL); }
268         |       input_list ',' NAME
269                 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
270                                  (char *)NULL); }
271         |       input_list NAME
272                 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
273                                  (char *)NULL); }
274         ;
275
276 sections:
277                 SECTIONS '{' sec_or_group_p1 '}'
278         ;
279
280 sec_or_group_p1:
281                 sec_or_group_p1 section
282         |       sec_or_group_p1 statement_anywhere
283         |
284         ;
285
286 statement_anywhere:
287                 ENTRY '(' NAME ')'
288                 { lang_add_entry($3); }
289         |       assignment end
290         ;
291
292 file_NAME_list:
293                 NAME
294                         { lang_add_wild($1, current_file); }
295         |       file_NAME_list opt_comma NAME
296                         { lang_add_wild($3, current_file); }
297         ;
298
299 input_section_spec:
300                 NAME
301                 {
302                 lang_add_wild((char *)NULL, $1);
303                 }
304         |       '['
305                         {
306                         current_file = (char *)NULL;
307                         }
308                         file_NAME_list
309                 ']'
310         |       NAME
311                         {
312                         current_file =$1;
313                         }
314                 '(' file_NAME_list ')'
315         |       '*'
316                         {
317                         current_file = (char *)NULL;
318                         }
319                 '(' file_NAME_list ')'
320         ;
321
322 statement:
323                 assignment end
324         |       CREATE_OBJECT_SYMBOLS
325                 {
326                 lang_add_attribute(lang_object_symbols_statement_enum); 
327                 }
328         |       ';'
329         |       CONSTRUCTORS
330                 {
331                 
332                   lang_add_attribute(lang_constructors_statement_enum); 
333                 }
334         | input_section_spec
335         | length '(' exp ')'
336                         {
337                         lang_add_data((int) $1,$3);
338                         }
339   
340         | FILL '(' exp ')'
341                         {
342                           lang_add_fill
343                             (exp_get_value_int($3,
344                                                0,
345                                                "fill value",
346                                                lang_first_phase_enum));
347                         }
348         ;
349
350 statement_list:
351                 statement_list statement
352         |       statement
353         ;
354   
355 statement_list_opt:
356                 /* empty */
357         |       statement_list
358         ;
359
360 length:
361                 QUAD
362                         { $$ = $1; }
363         |       LONG
364                         { $$ = $1; }
365         |       SHORT
366                         { $$ = $1; }
367         |       BYTE
368                         { $$ = $1; }
369         ;
370
371 fill_opt:
372           '=' mustbe_exp
373                 {
374                   $$ =   exp_get_value_int($2,
375                                            0,
376                                            "fill value",
377                                            lang_first_phase_enum);
378                 }
379         |       { $$ = 0; }
380         ;
381
382                 
383
384 assign_op:
385                 PLUSEQ
386                         { $$ = '+'; }
387         |       MINUSEQ
388                         { $$ = '-'; }
389         |       MULTEQ
390                         { $$ = '*'; }
391         |       DIVEQ
392                         { $$ = '/'; }
393         |       LSHIFTEQ
394                         { $$ = LSHIFT; }
395         |       RSHIFTEQ
396                         { $$ = RSHIFT; }
397         |       ANDEQ
398                         { $$ = '&'; }
399         |       OREQ
400                         { $$ = '|'; }
401
402         ;
403
404 end:    ';' | ','
405         ;
406
407
408 assignment:
409                 NAME '=' mustbe_exp
410                 {
411                   lang_add_assignment(exp_assop($2,$1,$3));
412                 }
413         |       NAME assign_op mustbe_exp
414                 {
415                 
416 lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
417                 }
418                 
419         ;
420
421
422 opt_comma:
423                 ','     |       ;
424
425
426 memory:
427                 MEMORY '{' memory_spec memory_spec_list '}'
428         ;
429
430 memory_spec_list:
431                 memory_spec_list memory_spec
432         |       memory_spec_list ',' memory_spec
433         |
434         ;
435
436
437 memory_spec:            NAME
438                         { region = lang_memory_region_lookup($1); }
439                 attributes_opt ':'
440                 origin_spec opt_comma length_spec
441
442         ; origin_spec:
443         ORIGIN '=' mustbe_exp
444                 { region->current =
445                  region->origin =
446                  exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
447 }
448         ; length_spec:
449              LENGTH '=' mustbe_exp
450                { region->length = exp_get_vma($3,
451                                                ~((bfd_vma)0),
452                                                "length",
453                                                lang_first_phase_enum);
454                 }
455         
456
457 attributes_opt:
458                   '(' NAME ')'
459                         {
460                         lang_set_flags(&region->flags, $2);
461                         }
462         |
463   
464         ;
465
466 startup:
467         STARTUP '(' filename ')'
468                 { lang_startup($3); }
469         ;
470
471 high_level_library:
472                 HLL '(' high_level_library_NAME_list ')'
473         |       HLL '(' ')'
474                         { ldemul_hll((char *)NULL); }
475         ;
476
477 high_level_library_NAME_list:
478                 high_level_library_NAME_list opt_comma filename
479                         { ldemul_hll($3); }
480         |       filename
481                         { ldemul_hll($1); }
482
483         ;
484
485 low_level_library:
486         SYSLIB '(' low_level_library_NAME_list ')'
487         ; low_level_library_NAME_list:
488                 low_level_library_NAME_list opt_comma filename
489                         { ldemul_syslib($3); }
490         |
491         ;
492
493 floating_point_support:
494                 FLOAT
495                         { lang_float(true); }
496         |       NOFLOAT
497                         { lang_float(false); }
498         ;
499                 
500
501 mustbe_exp:              { ldlex_expression(); }
502                 exp
503                          { ldlex_popstate(); $$=$2;}
504         ;
505
506 exp     :
507                 '-' exp %prec UNARY
508                         { $$ = exp_unop('-', $2); }
509         |       '(' exp ')'
510                         { $$ = $2; }
511         |       NEXT '(' exp ')' %prec UNARY
512                         { $$ = exp_unop((int) $1,$3); }
513         |       '!' exp %prec UNARY
514                         { $$ = exp_unop('!', $2); }
515         |       '+' exp %prec UNARY
516                         { $$ = $2; }
517         |       '~' exp %prec UNARY
518                         { $$ = exp_unop('~', $2);}
519
520         |       exp '*' exp
521                         { $$ = exp_binop('*', $1, $3); }
522         |       exp '/' exp
523                         { $$ = exp_binop('/', $1, $3); }
524         |       exp '%' exp
525                         { $$ = exp_binop('%', $1, $3); }
526         |       exp '+' exp
527                         { $$ = exp_binop('+', $1, $3); }
528         |       exp '-' exp
529                         { $$ = exp_binop('-' , $1, $3); }
530         |       exp LSHIFT exp
531                         { $$ = exp_binop(LSHIFT , $1, $3); }
532         |       exp RSHIFT exp
533                         { $$ = exp_binop(RSHIFT , $1, $3); }
534         |       exp EQ exp
535                         { $$ = exp_binop(EQ , $1, $3); }
536         |       exp NE exp
537                         { $$ = exp_binop(NE , $1, $3); }
538         |       exp LE exp
539                         { $$ = exp_binop(LE , $1, $3); }
540         |       exp GE exp
541                         { $$ = exp_binop(GE , $1, $3); }
542         |       exp '<' exp
543                         { $$ = exp_binop('<' , $1, $3); }
544         |       exp '>' exp
545                         { $$ = exp_binop('>' , $1, $3); }
546         |       exp '&' exp
547                         { $$ = exp_binop('&' , $1, $3); }
548         |       exp '^' exp
549                         { $$ = exp_binop('^' , $1, $3); }
550         |       exp '|' exp
551                         { $$ = exp_binop('|' , $1, $3); }
552         |       exp '?' exp ':' exp
553                         { $$ = exp_trinop('?' , $1, $3, $5); }
554         |       exp ANDAND exp
555                         { $$ = exp_binop(ANDAND , $1, $3); }
556         |       exp OROR exp
557                         { $$ = exp_binop(OROR , $1, $3); }
558         |       DEFINED '(' NAME ')'
559                         { $$ = exp_nameop(DEFINED, $3); }
560         |       INT
561                         { $$ = exp_intop($1); }
562         |       SIZEOF_HEADERS
563                         { $$ = exp_nameop(SIZEOF_HEADERS,0); }
564
565         |       SIZEOF '(' NAME ')'
566                         { $$ = exp_nameop(SIZEOF,$3); }
567         |       ADDR '(' NAME ')'
568                         { $$ = exp_nameop(ADDR,$3); }
569         |       ABSOLUTE '(' exp ')'
570                         { $$ = exp_unop(ABSOLUTE, $3); }
571         |       ALIGN_K '(' exp ')'
572                         { $$ = exp_unop(ALIGN_K,$3); }
573         |       NAME
574                         { $$ = exp_nameop(NAME,$1); }
575         ;
576
577
578 opt_at:
579                 AT '(' exp ')' { $$ = $3; }
580         |       { $$ = 0; }
581         ;
582
583 section:        NAME            { ldlex_expression(); }
584                 opt_exp_with_type 
585                 opt_at          { ldlex_popstate(); }
586                 '{'
587                         {
588                         lang_enter_output_section_statement($1,$3,typebits,0,0,0,$4);
589                         }
590                 statement_list_opt      
591                 '}' {ldlex_expression();} fill_opt memspec_opt
592                 {
593                   ldlex_popstate();
594                   lang_leave_output_section_statement($11, $12);
595                 }
596 opt_comma
597
598         ;
599
600 type:
601            NOLOAD  { typebits = SEC_NEVER_LOAD; }
602         |  DSECT   { typebits = 0; }
603         |  COPY    { typebits = 0; }
604         |  INFO    { typebits = 0; }
605         |  OVERLAY { typebits = 0; }
606         | { typebits = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; }
607         ;
608
609
610 opt_exp_with_type:
611                 exp ':'                 { $$ = $1; typebits =0;}
612         |       exp '(' type ')' ':'    { $$ = $1; }
613         |       ':'                     { $$= (etree_type *)NULL; typebits = 0; }
614         |       '(' type ')' ':'        { $$= (etree_type *)NULL;  }
615         ;
616
617 memspec_opt:
618                 '>' NAME
619                 { $$ = $2; }
620         |       { $$ = "*default*"; }
621         ;
622 %%
623 void
624 yyerror(arg) 
625      const char *arg;
626
627   if (error_index > 0 && error_index < ERROR_NAME_MAX)
628      einfo("%P%F: %S %s in %s\n", arg, error_names[error_index-1]);
629   else
630      einfo("%P%F: %S %s\n", arg);
631 }