A major rewrite to move the bulk of the linker into BFD so that
[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 #include "ldlex.h"
41
42 #define YYDEBUG 1
43
44 static int typebits;
45
46 static char *dirlist_ptr;
47
48 lang_memory_region_type *region;
49
50
51 char *current_file;
52 boolean ldgram_want_filename = true;
53 boolean had_script = false;
54 boolean force_make_executable = false;
55
56 boolean ldgram_in_script = false;
57 boolean ldgram_had_equals = false;
58
59
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--;
65 %}
66 %union {
67   bfd_vma integer;
68   int voidval;
69   char *name;
70   int token;
71   union etree_union *etree;
72   struct sec *section;
73   struct lang_output_section_statement_struct *output_section_statement;
74   union  lang_statement_union **statement_ptr;
75   int lineno;
76   struct {
77     FILE *file;
78     char *name;
79     unsigned int lineno;
80   } state;
81
82   
83 }
84
85 %type <etree> exp  opt_exp_with_type  mustbe_exp opt_at
86 %type <integer> fill_opt
87 %type <name> memspec_opt
88 %token <integer> INT  
89 %token <name> NAME
90 %type  <integer> length
91
92 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
93 %right <token> '?' ':'
94 %left <token> OROR
95 %left <token>  ANDAND
96 %left <token> '|'
97 %left <token>  '^'
98 %left  <token> '&'
99 %left <token>  EQ NE
100 %left  <token> '<' '>' LE GE
101 %left  <token> LSHIFT RSHIFT
102
103 %left  <token> '+' '-'
104 %left  <token> '*' '/' '%'
105
106 /*%token <token> '+' '-' '*' '/' '%'*/
107 %right UNARY
108 %token END 
109 %left <token> '('
110 %token <token> ALIGN_K BLOCK LONG SHORT BYTE
111 %token SECTIONS  
112 %token '{' '}'
113 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
114 %token SIZEOF_HEADERS
115 %token INCLUDE
116 %token MEMORY  DEFSYMEND
117 %token NOLOAD DSECT COPY INFO OVERLAY
118 %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY 
119 %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S OPTION_sort_common OPTION_warn_common
120 %token OPTION_EB OPTION_EL OPTION_G OPTION_Gval OPTION_help
121 %token OPTION_format OPTION_oformat  OPTION_F OPTION_u OPTION_Bstatic OPTION_N
122 %token <integer> SIZEOF NEXT ADDR 
123 %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
124 %token OPTION_v OPTION_V OPTION_m OPTION_memul OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT  NOFLOAT 
125 %token OPTION_L OPTION_Map
126 %token OPTION_n OPTION_r OPTION_o OPTION_b  OPTION_R OPTION_relax OPTION_version
127 %token <name> OPTION_l OPTION_Lfile OPTION_T OPTION_Aarch OPTION_Tfile
128 %token <name> OPTION_Texp OPTION_y
129 %token OPTION_Ur 
130 %token ORIGIN FILL OPTION_g
131 %token LENGTH    CREATE_OBJECT_SYMBOLS INPUT OUTPUT  CONSTRUCTORS
132 %token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD AT
133 %token OPTION_Qy OPTION_Y OPTION_dn OPTION_call_shared OPTION_non_shared
134 %token OPTION_Oval OPTION_stats OPTION_no_keep_memory
135 %token <name> OPTION_YP
136
137 %type <token> assign_op 
138
139 %type <name>  filename
140
141
142 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
143 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
144
145 %%
146
147 file:   command_line
148
149
150 filename:  NAME;
151
152
153 command_line:
154                 command_line command_line_option
155         |
156         ;
157
158 command_line_option:
159                 OPTION_Bstatic { }
160         |       OPTION_help
161                         {       
162                         help ();
163                         exit (0);
164                         }
165         |       OPTION_v
166                         {       
167                         ldversion(0);
168                         }
169         |       OPTION_V
170                         {       
171                         ldversion(1);
172                         trace_file_tries = true;
173                         }
174         |       OPTION_version
175                         {       
176                         ldversion(0);
177                         exit(0);
178                         }
179         |       OPTION_t {
180                         trace_files = true;
181                         }
182         |     OPTION_Map  NAME
183                 {
184                 write_map = true;
185                 config.map_filename = $2;
186                 }
187         |       OPTION_m NAME
188                 {
189                   /* Ignore.  */
190                 }
191         |       OPTION_memul
192                 {
193                   /* Ignore.  */
194                 }
195         |       OPTION_M 
196                 {
197                   config.map_filename = "-";
198                 }
199         |       OPTION_n {
200                         config.magic_demand_paged = false;
201                         }
202         |       OPTION_N {
203                         config.text_read_only = false;
204                         config.magic_demand_paged = false;
205                         }
206         |       OPTION_s {
207                         link_info.strip = strip_all;
208                         }
209         |       OPTION_S {
210                         link_info.strip = strip_debugger;
211                         }
212         |       OPTION_stats {
213                         config.stats = true;
214                 }
215         |       OPTION_no_keep_memory {
216                         link_info.keep_memory = false;
217                 }
218         |       OPTION_u NAME {
219                         ldlang_add_undef($2);
220                 }
221         |       OPTION_r {
222                         link_info.relocateable = true;
223                         config.build_constructors = false;
224                         config.magic_demand_paged = false;
225                         config.text_read_only = false;
226                         }
227         |       OPTION_Ur {
228                         link_info.relocateable = true;
229                         config.build_constructors = true;
230                         config.magic_demand_paged = false;
231                         config.text_read_only = false;
232                       }             
233         |       OPTION_o filename
234                         {
235                         lang_add_output($2, 0); 
236                         }
237         |       OPTION_e NAME
238                         { lang_add_entry($2); 
239                         }
240         |       OPTION_X {
241                         link_info.discard = discard_l;
242                 }
243         |       OPTION_x {
244                         link_info.discard = discard_all;
245                 }
246
247         |       OPTION_noinhibit_exec
248                         {
249                         force_make_executable = true;
250                         }
251         |      OPTION_sort_common
252                         {
253                         config.sort_common = true;
254                         }
255         |      OPTION_warn_common
256                         {
257                         config.warn_common = true;
258                         }
259         |      OPTION_d {
260                           command_line.force_common_definition = true;
261                         }
262
263         |      OPTION_relax {
264                           command_line.relax = 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         |       OPTION_oformat NAME
283                    {
284                           lang_add_output_format($2, 0);
285                    }
286         |       OPTION_Texp 
287                 { ldlex_expression();
288                         hex_mode  = 16; 
289                 } 
290                 INT
291                 {  ldlex_popstate();
292                         lang_section_start($1,exp_intop($3));
293                         hex_mode = 0; 
294                 }
295         |       OPTION_y
296                         {
297                         add_ysym($1);
298                         }
299         |       OPTION_Aarch 
300                 { 
301                         ldfile_add_arch($1); 
302                 }
303         |        OPTION_b NAME
304                         {
305                         lang_add_target($2);
306                         }
307         |       OPTION_L NAME
308                         {
309                         ldfile_add_library_path($2);
310                         }
311         |       OPTION_Lfile
312                         {
313                         ldfile_add_library_path($1);
314                         }
315         |       OPTION_F
316                 {
317                 /* Ignore */
318                 }
319         |       OPTION_c filename 
320                         {ldfile_open_command_file($2); }
321                 mri_script_file  END {  ldlex_command();}
322
323         |       OPTION_Tfile 
324                         { ldfile_open_command_file($1); } script_file
325                         END {  ldlex_command();}
326
327         |       OPTION_T filename 
328                         { ldfile_open_command_file($2); } script_file
329                 END {  ldlex_command();}
330
331         |       OPTION_l
332                         {
333                           lang_add_input_file($1,
334                                          lang_input_file_is_l_enum,
335                                          (char *)NULL);
336                         }
337         |       OPTION_R filename
338                         {
339                         lang_add_input_file($2,
340                                 lang_input_file_is_symbols_only_enum,
341                                 (char *)NULL);
342                         }
343
344         |       OPTION_defsym  { ldlex_defsym(); }
345                 NAME     '=' exp  DEFSYMEND { ldlex_popstate();
346                         lang_add_assignment(exp_assop($4,$3,$5));
347                         }
348         |       OPTION_RETAIN_SYMBOLS_FILE filename
349                 { add_keepsyms_file ($2); }
350         |       OPTION_EB
351                 {
352                   /* FIXME: This is currently ignored.  It means
353                      ``produce a big-endian object file''.  It could
354                      be used to select an output format.  */
355                 }
356         |       OPTION_EL
357                 {
358                   /* FIXME: This is currently ignored.  It means
359                      ``produce a little-endian object file''.  It could
360                      be used to select an output format.  */
361                 }
362         |       OPTION_G NAME
363                 {
364                   g_switch_value = atoi ($2);
365                 }
366         |       OPTION_Gval
367                 {
368                   g_switch_value = yylval.integer;
369                 }
370         |       OPTION_Qy
371         |       OPTION_dn
372         |       OPTION_non_shared
373         |       OPTION_call_shared
374         |       OPTION_Oval
375         |       OPTION_YP
376                 {
377                   dirlist_ptr = $1;
378                   goto set_default_dirlist;
379                 }
380         |       OPTION_Y NAME
381                 {
382                   if (strncmp ($2, "P,", 2))
383                     einfo ("%P%F: unknown -Y option -- %s\n", $2);
384                   else
385                     {
386                       char *p;
387                       dirlist_ptr = $2;
388                     set_default_dirlist:
389                       while (1)
390                         {
391                           p = strchr (dirlist_ptr, ':');
392                           if (p != NULL)
393                             *p = 0;
394                           if (*dirlist_ptr)
395                             ldfile_add_library_path (dirlist_ptr);
396                           if (p == NULL)
397                             break;
398                           *p = ':';
399                           dirlist_ptr = p + 1;
400                         }
401                     }
402                 }
403         |       '{' script_file '}' { /* This parses compiled-in scripts.  */ }
404         |       NAME
405                 {
406                   if (*$1 == '-')
407                     einfo("%P%F: illegal option -- %s\n", $1);
408                   else
409                     lang_add_input_file($1,lang_input_file_is_file_enum,
410                                         (char *)NULL);
411                 }
412         ;
413
414
415 /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
416 mri_script_file:
417                 {       ldlex_mri_script();
418                         PUSH_ERROR("MRI style script");
419                 }
420              mri_script_lines
421                 {       ldlex_popstate(); 
422                         POP_ERROR();
423                 }
424         ;
425
426 mri_script_lines:
427                 mri_script_lines mri_script_command NEWLINE
428           |
429         ;
430
431 mri_script_command:
432                 CHIP  exp 
433         |       CHIP  exp ',' exp
434         |       NAME    {
435                         einfo("%P%F: unrecognised keyword in MRI style script '%s'\n",$1);
436                         }
437         |       LIST    {
438                         write_map = true;
439                         config.map_filename = "-";
440                         }
441         |       ORDER ordernamelist
442         |       ENDWORD 
443         |       PUBLIC NAME '=' exp 
444                         { mri_public($2, $4); }
445         |       PUBLIC NAME ',' exp 
446                         { mri_public($2, $4); }
447         |       PUBLIC NAME  exp 
448                         { mri_public($2, $3); }
449         |       FORMAT NAME
450                         { mri_format($2); }
451         |       SECT NAME ',' exp 
452                         { mri_output_section($2, $4);}
453         |       SECT NAME  exp
454                         { mri_output_section($2, $3);}
455         |       SECT NAME '=' exp
456                         { mri_output_section($2, $4);}
457         |       ALIGN_K NAME '=' exp
458                         { mri_align($2,$4); }
459         |       ALIGNMOD NAME '=' exp
460                         { mri_alignmod($2,$4); }
461         |       ABSOLUTE mri_abs_name_list
462         |       LOAD     mri_load_name_list
463         |       NAMEWORD NAME 
464                         { mri_name($2); }   
465         |       ALIAS NAME ',' NAME
466                         { mri_alias($2,$4,0);}
467         |       ALIAS NAME ',' INT
468                         { mri_alias($2,0,(int) $4);}
469         |       BASE     exp
470                         { mri_base($2); }
471         |       TRUNCATE INT
472                 {  mri_truncate((unsigned int) $2); }
473         |
474         ;
475
476 ordernamelist:
477               ordernamelist ',' NAME         { mri_order($3); }
478         |     ordernamelist  NAME         { mri_order($2); }
479         |
480         ;
481
482 mri_load_name_list:
483                 NAME
484                         { mri_load($1); }
485         |       mri_load_name_list ',' NAME { mri_load($3); }
486         ;
487
488 mri_abs_name_list:
489                 NAME
490                         { mri_only_load($1); }
491         |       mri_abs_name_list ','  NAME
492                         { mri_only_load($3); }
493         ;
494
495 script_file:
496         {
497          ldlex_both();
498         }
499        ifile_list
500         {
501         ldlex_popstate();
502         }
503         ;
504
505
506 ifile_list:
507        ifile_list ifile_p1
508         |
509         ;
510
511
512
513 ifile_p1:
514                 memory
515         |       sections
516         |       startup
517         |       high_level_library
518         |       low_level_library
519         |       floating_point_support
520         |       statement_anywhere
521         |        ';'
522         |       TARGET_K '(' NAME ')'
523                 { lang_add_target($3); }
524         |       SEARCH_DIR '(' filename ')'
525                 { ldfile_add_library_path($3); }
526         |       OUTPUT '(' filename ')'
527                 { lang_add_output($3, 1); }
528         |       OUTPUT_FORMAT '(' NAME ')'
529                   { lang_add_output_format($3, 1); }
530         |       OUTPUT_ARCH '(' NAME ')'
531                   { ldfile_set_output_arch($3); }
532         |       FORCE_COMMON_ALLOCATION
533                 { command_line.force_common_definition = true ; }
534         |       INPUT '(' input_list ')'
535         |       MAP '(' filename ')'
536                 { lang_add_map($3); }
537         |       INCLUDE filename 
538                 { ldfile_open_command_file($2); } ifile_list END
539         ;
540
541 input_list:
542                 NAME
543                 { lang_add_input_file($1,lang_input_file_is_search_file_enum,
544                                  (char *)NULL); }
545         |       input_list ',' NAME
546                 { lang_add_input_file($3,lang_input_file_is_search_file_enum,
547                                  (char *)NULL); }
548         |       input_list NAME
549                 { lang_add_input_file($2,lang_input_file_is_search_file_enum,
550                                  (char *)NULL); }
551         ;
552
553 sections:
554                 SECTIONS '{' sec_or_group_p1 '}'
555         ;
556
557 sec_or_group_p1:
558                 sec_or_group_p1 section
559         |       sec_or_group_p1 statement_anywhere
560         |
561         ;
562
563 statement_anywhere:
564                 ENTRY '(' NAME ')'
565                 { lang_add_entry($3); }
566         |       assignment end
567         ;
568
569 file_NAME_list:
570                 NAME
571                         { lang_add_wild($1, current_file); }
572         |       file_NAME_list opt_comma NAME
573                         { lang_add_wild($3, current_file); }
574         ;
575
576 input_section_spec:
577                 NAME
578                 {
579                 lang_add_wild((char *)NULL, $1);
580                 }
581         |       '['
582                         {
583                         current_file = (char *)NULL;
584                         }
585                         file_NAME_list
586                 ']'
587         |       NAME
588                         {
589                         current_file =$1;
590                         }
591                 '(' file_NAME_list ')'
592         |       '*'
593                         {
594                         current_file = (char *)NULL;
595                         }
596                 '(' file_NAME_list ')'
597         ;
598
599 statement:
600                 assignment end
601         |       CREATE_OBJECT_SYMBOLS
602                 {
603                 lang_add_attribute(lang_object_symbols_statement_enum); 
604                 }
605         |       ';'
606         |       CONSTRUCTORS
607                 {
608                 
609                   lang_add_attribute(lang_constructors_statement_enum); 
610                 }
611         | input_section_spec
612         | length '(' exp ')'
613                         {
614                         lang_add_data((int) $1,$3);
615                         }
616   
617         | FILL '(' exp ')'
618                         {
619                           lang_add_fill
620                             (exp_get_value_int($3,
621                                                0,
622                                                "fill value",
623                                                lang_first_phase_enum));
624                         }
625         ;
626
627 statement_list:
628                 statement_list statement
629         |       statement
630         ;
631   
632 statement_list_opt:
633                 /* empty */
634         |       statement_list
635         ;
636
637 length:
638                 LONG
639                         { $$ = $1; }
640         |       SHORT
641                         { $$ = $1; }
642         |       BYTE
643                         { $$ = $1; }
644         ;
645
646 fill_opt:
647           '=' mustbe_exp
648                 {
649                   $$ =   exp_get_value_int($2,
650                                            0,
651                                            "fill value",
652                                            lang_first_phase_enum);
653                 }
654         |       { $$ = 0; }
655         ;
656
657                 
658
659 assign_op:
660                 PLUSEQ
661                         { $$ = '+'; }
662         |       MINUSEQ
663                         { $$ = '-'; }
664         |       MULTEQ
665                         { $$ = '*'; }
666         |       DIVEQ
667                         { $$ = '/'; }
668         |       LSHIFTEQ
669                         { $$ = LSHIFT; }
670         |       RSHIFTEQ
671                         { $$ = RSHIFT; }
672         |       ANDEQ
673                         { $$ = '&'; }
674         |       OREQ
675                         { $$ = '|'; }
676
677         ;
678
679 end:    ';' | ','
680         ;
681
682
683 assignment:
684                 NAME '=' mustbe_exp
685                 {
686                   lang_add_assignment(exp_assop($2,$1,$3));
687                 }
688         |       NAME assign_op mustbe_exp
689                 {
690                 
691 lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
692                 }
693                 
694         ;
695
696
697 opt_comma:
698                 ','     |       ;
699
700
701 memory:
702                 MEMORY '{' memory_spec memory_spec_list '}'
703         ;
704
705 memory_spec_list:
706                 memory_spec_list memory_spec
707         |       memory_spec_list ',' memory_spec
708         |
709         ;
710
711
712 memory_spec:            NAME
713                         { region = lang_memory_region_lookup($1); }
714                 attributes_opt ':'
715                 origin_spec opt_comma length_spec
716
717         ; origin_spec:
718         ORIGIN '=' mustbe_exp
719                 { region->current =
720                  region->origin =
721                  exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
722 }
723         ; length_spec:
724              LENGTH '=' mustbe_exp
725                { region->length = exp_get_vma($3,
726                                                ~((bfd_vma)0),
727                                                "length",
728                                                lang_first_phase_enum);
729                 }
730         
731
732 attributes_opt:
733                   '(' NAME ')'
734                         {
735                         lang_set_flags(&region->flags, $2);
736                         }
737         |
738   
739         ;
740
741 startup:
742         STARTUP '(' filename ')'
743                 { lang_startup($3); }
744         ;
745
746 high_level_library:
747                 HLL '(' high_level_library_NAME_list ')'
748         |       HLL '(' ')'
749                         { ldemul_hll((char *)NULL); }
750         ;
751
752 high_level_library_NAME_list:
753                 high_level_library_NAME_list opt_comma filename
754                         { ldemul_hll($3); }
755         |       filename
756                         { ldemul_hll($1); }
757
758         ;
759
760 low_level_library:
761         SYSLIB '(' low_level_library_NAME_list ')'
762         ; low_level_library_NAME_list:
763                 low_level_library_NAME_list opt_comma filename
764                         { ldemul_syslib($3); }
765         |
766         ;
767
768 floating_point_support:
769                 FLOAT
770                         { lang_float(true); }
771         |       NOFLOAT
772                         { lang_float(false); }
773         ;
774                 
775
776 mustbe_exp:              { ldlex_expression(); }
777                 exp
778                          { ldlex_popstate(); $$=$2;}
779         ;
780
781 exp     :
782                 '-' exp %prec UNARY
783                         { $$ = exp_unop('-', $2); }
784         |       '(' exp ')'
785                         { $$ = $2; }
786         |       NEXT '(' exp ')' %prec UNARY
787                         { $$ = exp_unop((int) $1,$3); }
788         |       '!' exp %prec UNARY
789                         { $$ = exp_unop('!', $2); }
790         |       '+' exp %prec UNARY
791                         { $$ = $2; }
792         |       '~' exp %prec UNARY
793                         { $$ = exp_unop('~', $2);}
794
795         |       exp '*' exp
796                         { $$ = exp_binop('*', $1, $3); }
797         |       exp '/' exp
798                         { $$ = exp_binop('/', $1, $3); }
799         |       exp '%' exp
800                         { $$ = exp_binop('%', $1, $3); }
801         |       exp '+' exp
802                         { $$ = exp_binop('+', $1, $3); }
803         |       exp '-' exp
804                         { $$ = exp_binop('-' , $1, $3); }
805         |       exp LSHIFT exp
806                         { $$ = exp_binop(LSHIFT , $1, $3); }
807         |       exp RSHIFT exp
808                         { $$ = exp_binop(RSHIFT , $1, $3); }
809         |       exp EQ exp
810                         { $$ = exp_binop(EQ , $1, $3); }
811         |       exp NE exp
812                         { $$ = exp_binop(NE , $1, $3); }
813         |       exp LE exp
814                         { $$ = exp_binop(LE , $1, $3); }
815         |       exp GE exp
816                         { $$ = exp_binop(GE , $1, $3); }
817         |       exp '<' exp
818                         { $$ = exp_binop('<' , $1, $3); }
819         |       exp '>' exp
820                         { $$ = exp_binop('>' , $1, $3); }
821         |       exp '&' exp
822                         { $$ = exp_binop('&' , $1, $3); }
823         |       exp '^' exp
824                         { $$ = exp_binop('^' , $1, $3); }
825         |       exp '|' exp
826                         { $$ = exp_binop('|' , $1, $3); }
827         |       exp '?' exp ':' exp
828                         { $$ = exp_trinop('?' , $1, $3, $5); }
829         |       exp ANDAND exp
830                         { $$ = exp_binop(ANDAND , $1, $3); }
831         |       exp OROR exp
832                         { $$ = exp_binop(OROR , $1, $3); }
833         |       DEFINED '(' NAME ')'
834                         { $$ = exp_nameop(DEFINED, $3); }
835         |       INT
836                         { $$ = exp_intop($1); }
837         |       SIZEOF_HEADERS
838                         { $$ = exp_nameop(SIZEOF_HEADERS,0); }
839
840         |       SIZEOF '(' NAME ')'
841                         { $$ = exp_nameop(SIZEOF,$3); }
842         |       ADDR '(' NAME ')'
843                         { $$ = exp_nameop(ADDR,$3); }
844         |       ABSOLUTE '(' exp ')'
845                         { $$ = exp_unop(ABSOLUTE, $3); }
846         |       ALIGN_K '(' exp ')'
847                         { $$ = exp_unop(ALIGN_K,$3); }
848         |       NAME
849                         { $$ = exp_nameop(NAME,$1); }
850         ;
851
852
853 opt_at:
854                 AT '(' exp ')' { $$ = $3; }
855         |       { $$ = 0; }
856         ;
857
858 section:        NAME            { ldlex_expression(); }
859                 opt_exp_with_type 
860                 opt_at          { ldlex_popstate(); }
861                 '{'
862                         {
863                         lang_enter_output_section_statement($1,$3,typebits,0,0,0,$4);
864                         }
865                 statement_list_opt      
866                 '}' {ldlex_expression();} fill_opt memspec_opt
867                 {
868                   ldlex_popstate();
869                   lang_leave_output_section_statement($11, $12);
870                 }
871 opt_comma
872
873         ;
874
875 type:
876            NOLOAD  { typebits = SEC_NEVER_LOAD; }
877         |  DSECT   { typebits = 0; }
878         |  COPY    { typebits = 0; }
879         |  INFO    { typebits = 0; }
880         |  OVERLAY { typebits = 0; }
881         | { typebits = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; }
882         ;
883
884
885 opt_exp_with_type:
886                 exp ':'                 { $$ = $1; typebits =0;}
887         |       exp '(' type ')' ':'    { $$ = $1; }
888         |       ':'                     { $$= (etree_type *)NULL; typebits = 0; }
889         |       '(' type ')' ':'        { $$= (etree_type *)NULL;  }
890         ;
891
892 memspec_opt:
893                 '>' NAME
894                 { $$ = $2; }
895         |       { $$ = "*default*"; }
896         ;
897 %%
898 void
899 yyerror(arg) 
900 char *arg;
901
902   if (error_index> 0  && error_index < ERROR_NAME_MAX)
903      einfo("%P%F: %S syntax error in %s\n",error_names[error_index-1]);
904   else
905      einfo("%P%F: %S syntax error\n");
906 }