home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / src / binutils.2 / ld / ldgram.y < prev    next >
Encoding:
Text File  |  1993-05-30  |  17.0 KB  |  855 lines

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