home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / ld / ldgram.y < prev    next >
Text File  |  1996-09-28  |  16KB  |  805 lines

  1. /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
  2.    Copyright (C) 1991, 92, 93, 94, 95, 1996 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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. #ifndef YYDEBUG
  43. #define YYDEBUG 1
  44. #endif
  45.  
  46. static enum section_type sectype;
  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.   char *name;
  69.   int token;
  70.   union etree_union *etree;
  71.   struct phdr_info
  72.     {
  73.       boolean filehdr;
  74.       boolean phdrs;
  75.       union etree_union *at;
  76.       union etree_union *flags;
  77.     } phdr;
  78. }
  79.  
  80. %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
  81. %type <integer> fill_opt
  82. %type <name> memspec_opt casesymlist
  83. %token <integer> INT  
  84. %token <name> NAME LNAME
  85. %type  <integer> length
  86. %type <phdr> phdr_qualifiers
  87.  
  88. %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
  89. %right <token> '?' ':'
  90. %left <token> OROR
  91. %left <token>  ANDAND
  92. %left <token> '|'
  93. %left <token>  '^'
  94. %left  <token> '&'
  95. %left <token>  EQ NE
  96. %left  <token> '<' '>' LE GE
  97. %left  <token> LSHIFT RSHIFT
  98.  
  99. %left  <token> '+' '-'
  100. %left  <token> '*' '/' '%'
  101.  
  102. %right UNARY
  103. %token END 
  104. %left <token> '('
  105. %token <token> ALIGN_K BLOCK BIND QUAD LONG SHORT BYTE
  106. %token SECTIONS PHDRS
  107. %token '{' '}'
  108. %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
  109. %token SIZEOF_HEADERS
  110. %token INCLUDE
  111. %token MEMORY DEFSYMEND
  112. %token NOLOAD DSECT COPY INFO OVERLAY
  113. %token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
  114. %token <integer> SIZEOF NEXT ADDR
  115. %token STARTUP HLL SYSLIB FLOAT NOFLOAT
  116. %token ORIGIN FILL
  117. %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
  118. %token ALIGNMOD AT PROVIDE
  119. %type <token> assign_op atype
  120. %type <name>  filename
  121. %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
  122. %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
  123. %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
  124.  
  125. %%
  126.  
  127. file:    
  128.         INPUT_SCRIPT script_file
  129.     |    INPUT_MRI_SCRIPT mri_script_file
  130.     |    INPUT_DEFSYM defsym_expr
  131.     ;
  132.  
  133.  
  134. filename:  NAME;
  135.  
  136.  
  137. defsym_expr:
  138.         { ldlex_defsym(); }
  139.         NAME '=' exp
  140.         {
  141.           ldlex_popstate();
  142.           lang_add_assignment(exp_assop($3,$2,$4));
  143.         }
  144.  
  145. /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
  146. mri_script_file:
  147.         {
  148.           ldlex_mri_script ();
  149.           PUSH_ERROR ("MRI style script");
  150.         }
  151.          mri_script_lines
  152.         {
  153.           ldlex_popstate ();
  154.           mri_draw_tree ();
  155.           POP_ERROR ();
  156.         }
  157.     ;
  158.  
  159. mri_script_lines:
  160.         mri_script_lines mri_script_command NEWLINE
  161.           |
  162.     ;
  163.  
  164. mri_script_command:
  165.         CHIP  exp 
  166.     |    CHIP  exp ',' exp
  167.     |    NAME     {
  168.             einfo("%P%F: unrecognised keyword in MRI style script '%s'\n",$1);
  169.             }
  170.     |    LIST      {
  171.             config.map_filename = "-";
  172.             }
  173.         |       ORDER ordernamelist
  174.     |       ENDWORD 
  175.         |       PUBLIC NAME '=' exp
  176.              { mri_public($2, $4); }
  177.         |       PUBLIC NAME ',' exp
  178.              { mri_public($2, $4); }
  179.         |       PUBLIC NAME  exp 
  180.              { mri_public($2, $3); }
  181.     |     FORMAT NAME
  182.             { mri_format($2); }
  183.     |    SECT NAME ',' exp
  184.             { mri_output_section($2, $4);}
  185.     |    SECT NAME  exp
  186.             { mri_output_section($2, $3);}
  187.     |    SECT NAME '=' exp
  188.             { mri_output_section($2, $4);}
  189.     |    ALIGN_K NAME '=' exp
  190.             { mri_align($2,$4); }
  191.     |    ALIGN_K NAME ',' exp
  192.             { mri_align($2,$4); }
  193.     |    ALIGNMOD NAME '=' exp
  194.             { mri_alignmod($2,$4); }
  195.     |    ALIGNMOD NAME ',' exp
  196.             { mri_alignmod($2,$4); }
  197.     |    ABSOLUTE mri_abs_name_list
  198.     |    LOAD     mri_load_name_list
  199.     |       NAMEWORD NAME 
  200.             { mri_name($2); }   
  201.     |    ALIAS NAME ',' NAME
  202.             { mri_alias($2,$4,0);}
  203.     |    ALIAS NAME ',' INT
  204.             { mri_alias($2,0,(int) $4);}
  205.     |    BASE     exp
  206.             { mri_base($2); }
  207.         |       TRUNCATE INT
  208.         {  mri_truncate((unsigned int) $2); }
  209.     |    CASE casesymlist
  210.     |    EXTERN extern_name_list
  211.     |    INCLUDE filename
  212.         { ldfile_open_command_file ($2); } mri_script_lines END
  213.     |    START NAME
  214.         { lang_add_entry ($2, false); }
  215.         |
  216.     ;
  217.  
  218. ordernamelist:
  219.           ordernamelist ',' NAME         { mri_order($3); }
  220.     |     ordernamelist  NAME         { mri_order($2); }
  221.           |
  222.     ;
  223.  
  224. mri_load_name_list:
  225.         NAME
  226.             { mri_load($1); }
  227.     |    mri_load_name_list ',' NAME { mri_load($3); }
  228.     ;
  229.  
  230. mri_abs_name_list:
  231.          NAME
  232.              { mri_only_load($1); }
  233.     |    mri_abs_name_list ','  NAME
  234.              { mri_only_load($3); }
  235.     ;
  236.  
  237. casesymlist:
  238.       /* empty */ { $$ = NULL; }
  239.     | NAME
  240.     | casesymlist ',' NAME
  241.     ;
  242.  
  243. extern_name_list:
  244.       NAME
  245.             { ldlang_add_undef ($1); }
  246.     | extern_name_list ',' NAME
  247.             { ldlang_add_undef ($3); }
  248.     ;
  249.  
  250. script_file:
  251.     {
  252.      ldlex_both();
  253.     }
  254.        ifile_list
  255.     {
  256.     ldlex_popstate();
  257.     }
  258.         ;
  259.  
  260.  
  261. ifile_list:
  262.        ifile_list ifile_p1
  263.         |
  264.     ;
  265.  
  266.  
  267.  
  268. ifile_p1:
  269.         memory
  270.     |    sections
  271.     |    phdrs
  272.     |    startup
  273.     |    high_level_library
  274.     |    low_level_library
  275.     |    floating_point_support
  276.     |    statement_anywhere
  277.         |     ';'
  278.     |    TARGET_K '(' NAME ')'
  279.         { lang_add_target($3); }
  280.     |    SEARCH_DIR '(' filename ')'
  281.         { ldfile_add_library_path ($3, false); }
  282.     |    OUTPUT '(' filename ')'
  283.         { lang_add_output($3, 1); }
  284.         |    OUTPUT_FORMAT '(' NAME ')'
  285.           { lang_add_output_format ($3, (char *) NULL,
  286.                         (char *) NULL, 1); }
  287.     |    OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
  288.           { lang_add_output_format ($3, $5, $7, 1); }
  289.         |    OUTPUT_ARCH '(' NAME ')'
  290.           { ldfile_set_output_arch($3); }
  291.     |    FORCE_COMMON_ALLOCATION
  292.         { command_line.force_common_definition = true ; }
  293.     |    INPUT '(' input_list ')'
  294.     |    GROUP
  295.           { lang_enter_group (); }
  296.             '(' input_list ')'
  297.           { lang_leave_group (); }
  298.          |    MAP '(' filename ')'
  299.         { lang_add_map($3); }
  300.     |    INCLUDE filename 
  301.         { ldfile_open_command_file($2); } ifile_list END
  302.     ;
  303.  
  304. input_list:
  305.         NAME
  306.         { lang_add_input_file($1,lang_input_file_is_search_file_enum,
  307.                  (char *)NULL); }
  308.     |    input_list ',' NAME
  309.         { lang_add_input_file($3,lang_input_file_is_search_file_enum,
  310.                  (char *)NULL); }
  311.     |    input_list NAME
  312.         { lang_add_input_file($2,lang_input_file_is_search_file_enum,
  313.                  (char *)NULL); }
  314.     |    LNAME
  315.         { lang_add_input_file($1,lang_input_file_is_l_enum,
  316.                  (char *)NULL); }
  317.     |    input_list ',' LNAME
  318.         { lang_add_input_file($3,lang_input_file_is_l_enum,
  319.                  (char *)NULL); }
  320.     |    input_list LNAME
  321.         { lang_add_input_file($2,lang_input_file_is_l_enum,
  322.                  (char *)NULL); }
  323.     ;
  324.  
  325. sections:
  326.         SECTIONS '{' sec_or_group_p1 '}'
  327.     ;
  328.  
  329. sec_or_group_p1:
  330.         sec_or_group_p1 section
  331.     |    sec_or_group_p1 statement_anywhere
  332.     |
  333.     ;
  334.  
  335. statement_anywhere:
  336.         ENTRY '(' NAME ')'
  337.         { lang_add_entry ($3, false); }
  338.     |    assignment end
  339.     ;
  340.  
  341. file_NAME_list:
  342.         NAME
  343.             { lang_add_wild($1, current_file); }
  344.     |    file_NAME_list opt_comma NAME
  345.             { lang_add_wild($3, current_file); }
  346.     ;
  347.  
  348. input_section_spec:
  349.         NAME
  350.         {
  351.         lang_add_wild((char *)NULL, $1);
  352.         }
  353.         |    '['
  354.             {
  355.             current_file = (char *)NULL;
  356.             }
  357.             file_NAME_list
  358.         ']'
  359.     |    NAME
  360.             {
  361.             current_file =$1;
  362.             }
  363.         '(' file_NAME_list ')'
  364.     |    '*'
  365.             {
  366.             current_file = (char *)NULL;
  367.             }
  368.         '(' file_NAME_list ')'
  369.     ;
  370.  
  371. statement:
  372.           assignment end
  373.     |    CREATE_OBJECT_SYMBOLS
  374.         {
  375.          lang_add_attribute(lang_object_symbols_statement_enum); 
  376.               }
  377.         |    ';'
  378.         |    CONSTRUCTORS
  379.         {
  380.          
  381.           lang_add_attribute(lang_constructors_statement_enum); 
  382.         }
  383.     | input_section_spec
  384.         | length '(' exp ')'
  385.                     {
  386.             lang_add_data((int) $1,$3);
  387.             }
  388.   
  389.     | FILL '(' exp ')'
  390.             {
  391.               lang_add_fill
  392.                 (exp_get_value_int($3,
  393.                            0,
  394.                            "fill value",
  395.                            lang_first_phase_enum));
  396.             }
  397.     ;
  398.  
  399. statement_list:
  400.         statement_list statement
  401.       |      statement
  402.     ;
  403.   
  404. statement_list_opt:
  405.         /* empty */
  406.     |    statement_list
  407.     ;
  408.  
  409. length:
  410.         QUAD
  411.             { $$ = $1; }
  412.     |    LONG
  413.             { $$ = $1; }
  414.     |     SHORT
  415.             { $$ = $1; }
  416.     |    BYTE
  417.             { $$ = $1; }
  418.     ;
  419.  
  420. fill_opt:
  421.           '=' mustbe_exp
  422.         {
  423.           $$ =     exp_get_value_int($2,
  424.                        0,
  425.                        "fill value",
  426.                        lang_first_phase_enum);
  427.         }
  428.     |     { $$ = 0; }
  429.     ;
  430.  
  431.         
  432.  
  433. assign_op:
  434.         PLUSEQ
  435.             { $$ = '+'; }
  436.     |    MINUSEQ
  437.             { $$ = '-'; }
  438.     |     MULTEQ
  439.             { $$ = '*'; }
  440.     |     DIVEQ
  441.             { $$ = '/'; }
  442.     |     LSHIFTEQ
  443.             { $$ = LSHIFT; }
  444.     |     RSHIFTEQ
  445.             { $$ = RSHIFT; }
  446.     |     ANDEQ
  447.             { $$ = '&'; }
  448.     |     OREQ
  449.             { $$ = '|'; }
  450.  
  451.     ;
  452.  
  453. end:    ';' | ','
  454.     ;
  455.  
  456.  
  457. assignment:
  458.         NAME '=' mustbe_exp
  459.         {
  460.           lang_add_assignment (exp_assop ($2, $1, $3));
  461.         }
  462.     |    NAME assign_op mustbe_exp
  463.         {
  464.           lang_add_assignment (exp_assop ('=', $1,
  465.                           exp_binop ($2,
  466.                                  exp_nameop (NAME,
  467.                                      $1),
  468.                                  $3)));
  469.         }
  470.     |    PROVIDE '(' NAME '=' mustbe_exp ')'
  471.         {
  472.           lang_add_assignment (exp_provide ($3, $5));
  473.         }
  474.     ;
  475.  
  476.  
  477. opt_comma:
  478.         ','    |    ;
  479.  
  480.  
  481. memory:
  482.         MEMORY '{' memory_spec memory_spec_list '}'
  483.     ;
  484.  
  485. memory_spec_list:
  486.         memory_spec_list memory_spec
  487.     |    memory_spec_list ',' memory_spec
  488.     |
  489.     ;
  490.  
  491.  
  492. memory_spec:         NAME
  493.             { region = lang_memory_region_lookup($1); }
  494.         attributes_opt ':'
  495.         origin_spec opt_comma length_spec
  496.  
  497.     ; origin_spec:
  498.     ORIGIN '=' mustbe_exp
  499.         { region->current =
  500.          region->origin =
  501.          exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
  502. }
  503.     ; length_spec:
  504.              LENGTH '=' mustbe_exp
  505.                { region->length = exp_get_vma($3,
  506.                            ~((bfd_vma)0),
  507.                            "length",
  508.                            lang_first_phase_enum);
  509.         }
  510.     
  511.  
  512. attributes_opt:
  513.           '(' NAME ')'
  514.             {
  515.             lang_set_flags(®ion->flags, $2);
  516.             }
  517.     |
  518.   
  519.     ;
  520.  
  521. startup:
  522.     STARTUP '(' filename ')'
  523.         { lang_startup($3); }
  524.     ;
  525.  
  526. high_level_library:
  527.         HLL '(' high_level_library_NAME_list ')'
  528.     |    HLL '(' ')'
  529.             { ldemul_hll((char *)NULL); }
  530.     ;
  531.  
  532. high_level_library_NAME_list:
  533.         high_level_library_NAME_list opt_comma filename
  534.             { ldemul_hll($3); }
  535.     |    filename
  536.             { ldemul_hll($1); }
  537.  
  538.     ;
  539.  
  540. low_level_library:
  541.     SYSLIB '(' low_level_library_NAME_list ')'
  542.     ; low_level_library_NAME_list:
  543.         low_level_library_NAME_list opt_comma filename
  544.             { ldemul_syslib($3); }
  545.     |
  546.     ;
  547.  
  548. floating_point_support:
  549.         FLOAT
  550.             { lang_float(true); }
  551.     |    NOFLOAT
  552.             { lang_float(false); }
  553.     ;
  554.         
  555.  
  556. mustbe_exp:         { ldlex_expression(); }
  557.         exp
  558.              { ldlex_popstate(); $$=$2;}
  559.     ;
  560.  
  561. exp    :
  562.         '-' exp %prec UNARY
  563.             { $$ = exp_unop('-', $2); }
  564.     |    '(' exp ')'
  565.             { $$ = $2; }
  566.     |    NEXT '(' exp ')' %prec UNARY
  567.             { $$ = exp_unop((int) $1,$3); }
  568.     |    '!' exp %prec UNARY
  569.             { $$ = exp_unop('!', $2); }
  570.     |    '+' exp %prec UNARY
  571.             { $$ = $2; }
  572.     |    '~' exp %prec UNARY
  573.             { $$ = exp_unop('~', $2);}
  574.  
  575.     |    exp '*' exp
  576.             { $$ = exp_binop('*', $1, $3); }
  577.     |    exp '/' exp
  578.             { $$ = exp_binop('/', $1, $3); }
  579.     |    exp '%' exp
  580.             { $$ = exp_binop('%', $1, $3); }
  581.     |    exp '+' exp
  582.             { $$ = exp_binop('+', $1, $3); }
  583.     |    exp '-' exp
  584.             { $$ = exp_binop('-' , $1, $3); }
  585.     |    exp LSHIFT exp
  586.             { $$ = exp_binop(LSHIFT , $1, $3); }
  587.     |    exp RSHIFT exp
  588.             { $$ = exp_binop(RSHIFT , $1, $3); }
  589.     |    exp EQ exp
  590.             { $$ = exp_binop(EQ , $1, $3); }
  591.     |    exp NE exp
  592.             { $$ = exp_binop(NE , $1, $3); }
  593.     |    exp LE exp
  594.             { $$ = exp_binop(LE , $1, $3); }
  595.       |    exp GE exp
  596.             { $$ = exp_binop(GE , $1, $3); }
  597.     |    exp '<' exp
  598.             { $$ = exp_binop('<' , $1, $3); }
  599.     |    exp '>' exp
  600.             { $$ = exp_binop('>' , $1, $3); }
  601.     |    exp '&' exp
  602.             { $$ = exp_binop('&' , $1, $3); }
  603.     |    exp '^' exp
  604.             { $$ = exp_binop('^' , $1, $3); }
  605.     |    exp '|' exp
  606.             { $$ = exp_binop('|' , $1, $3); }
  607.     |    exp '?' exp ':' exp
  608.             { $$ = exp_trinop('?' , $1, $3, $5); }
  609.     |    exp ANDAND exp
  610.             { $$ = exp_binop(ANDAND , $1, $3); }
  611.     |    exp OROR exp
  612.             { $$ = exp_binop(OROR , $1, $3); }
  613.     |    DEFINED '(' NAME ')'
  614.             { $$ = exp_nameop(DEFINED, $3); }
  615.     |    INT
  616.             { $$ = exp_intop($1); }
  617.         |    SIZEOF_HEADERS
  618.             { $$ = exp_nameop(SIZEOF_HEADERS,0); }
  619.  
  620.     |    SIZEOF '(' NAME ')'
  621.             { $$ = exp_nameop(SIZEOF,$3); }
  622.     |    ADDR '(' NAME ')'
  623.             { $$ = exp_nameop(ADDR,$3); }
  624.     |    ABSOLUTE '(' exp ')'
  625.             { $$ = exp_unop(ABSOLUTE, $3); }
  626.     |    ALIGN_K '(' exp ')'
  627.             { $$ = exp_unop(ALIGN_K,$3); }
  628.     |    BLOCK '(' exp ')'
  629.             { $$ = exp_unop(ALIGN_K,$3); }
  630.     |    NAME
  631.             { $$ = exp_nameop(NAME,$1); }
  632.     ;
  633.  
  634.  
  635. opt_at:
  636.         AT '(' exp ')' { $$ = $3; }
  637.     |    { $$ = 0; }
  638.     ;
  639.  
  640. section:    NAME         { ldlex_expression(); }
  641.         opt_exp_with_type 
  642.         opt_at       { ldlex_popstate(); }
  643.         '{'
  644.             {
  645.               lang_enter_output_section_statement($1, $3,
  646.                                   sectype,
  647.                                   0, 0, 0, $4);
  648.             }
  649.         statement_list_opt     
  650.          '}' {ldlex_expression();} memspec_opt phdr_opt fill_opt
  651.         {
  652.           ldlex_popstate();
  653.           lang_leave_output_section_statement($13, $11);
  654.         }
  655.         opt_comma
  656.     |    /* The GROUP case is just enough to support the gcc
  657.            svr3.ifile script.  It is not intended to be full
  658.            support.  I'm not even sure what GROUP is supposed
  659.            to mean.  */
  660.         GROUP { ldlex_expression (); }
  661.         opt_exp_with_type
  662.         {
  663.           ldlex_popstate ();
  664.           lang_add_assignment (exp_assop ('=', ".", $3));
  665.         }
  666.         '{' sec_or_group_p1 '}'
  667.     ;
  668.  
  669. type:
  670.        NOLOAD  { sectype = noload_section; }
  671.     |  DSECT   { sectype = dsect_section; }
  672.     |  COPY    { sectype = copy_section; }
  673.     |  INFO    { sectype = info_section; }
  674.     |  OVERLAY { sectype = overlay_section; }
  675.     ;
  676.  
  677. atype:
  678.          '(' type ')'
  679.       |     /* EMPTY */ { sectype = normal_section; }
  680.     ;
  681.  
  682. opt_exp_with_type:
  683.         exp atype ':'        { $$ = $1; }
  684.     |    atype ':'        { $$ = (etree_type *)NULL;  }
  685.     |    /* The BIND cases are to support the gcc svr3.ifile
  686.            script.  They aren't intended to implement full
  687.            support for the BIND keyword.  I'm not even sure
  688.            what BIND is supposed to mean.  */
  689.         BIND '(' exp ')' atype ':' { $$ = $3; }
  690.     |    BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
  691.         { $$ = $3; }
  692.     ;
  693.  
  694. memspec_opt:
  695.         '>' NAME
  696.         { $$ = $2; }
  697.     |    { $$ = "*default*"; }
  698.     ;
  699.  
  700. phdr_opt:
  701.         /* empty */
  702.     |    phdr_opt ':' NAME
  703.         {
  704.           lang_section_in_phdr ($3);
  705.         }
  706.     ;
  707.  
  708. phdrs:
  709.         PHDRS '{' phdr_list '}'
  710.     ;
  711.  
  712. phdr_list:
  713.         /* empty */
  714.     |    phdr_list phdr
  715.     ;
  716.  
  717. phdr:
  718.         NAME { ldlex_expression (); }
  719.           phdr_type phdr_qualifiers { ldlex_popstate (); }
  720.           ';'
  721.         {
  722.           lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
  723.                  $4.flags);
  724.         }
  725.     ;
  726.  
  727. phdr_type:
  728.         exp
  729.         {
  730.           $$ = $1;
  731.  
  732.           if ($1->type.node_class == etree_name
  733.               && $1->type.node_code == NAME)
  734.             {
  735.               const char *s;
  736.               unsigned int i;
  737.               static const char * const phdr_types[] =
  738.             {
  739.               "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
  740.               "PT_INTERP", "PT_NOTE", "PT_SHLIB",
  741.               "PT_PHDR"
  742.             };
  743.  
  744.               s = $1->name.name;
  745.               for (i = 0;
  746.                i < sizeof phdr_types / sizeof phdr_types[0];
  747.                i++)
  748.             if (strcmp (s, phdr_types[i]) == 0)
  749.               {
  750.                 $$ = exp_intop (i);
  751.                 break;
  752.               }
  753.             }
  754.         }
  755.     ;
  756.  
  757. phdr_qualifiers:
  758.         /* empty */
  759.         {
  760.           memset (&$$, 0, sizeof (struct phdr_info));
  761.         }
  762.     |    NAME phdr_val phdr_qualifiers
  763.         {
  764.           $$ = $3;
  765.           if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
  766.             $$.filehdr = true;
  767.           else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
  768.             $$.phdrs = true;
  769.           else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
  770.             $$.flags = $2;
  771.           else
  772.             einfo ("%X%P:%S: PHDRS syntax error at `%s'\n", $1);
  773.         }
  774.     |    AT '(' exp ')' phdr_qualifiers
  775.         {
  776.           $$ = $5;
  777.           $$.at = $3;
  778.         }
  779.     ;
  780.  
  781. phdr_val:
  782.         /* empty */
  783.         {
  784.           $$ = NULL;
  785.         }
  786.     | '(' exp ')'
  787.         {
  788.           $$ = $2;
  789.         }
  790.     ;
  791.  
  792. %%
  793. void
  794. yyerror(arg) 
  795.      const char *arg;
  796.   if (ldfile_assumed_script)
  797.     einfo ("%P:%s: file format not recognized; treating as linker script\n",
  798.        ldfile_input_filename);
  799.   if (error_index > 0 && error_index < ERROR_NAME_MAX)
  800.      einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
  801.   else
  802.      einfo ("%P%F:%S: %s\n", arg);
  803. }
  804.