Add icf_virtual_function_folding_test to check_PROGRAMS.
[binutils-gdb.git] / gold / yyscript.y
index 5ce03c5727aa089d5bec5aa51c59e67c9d5a6109..f762536c71360e23d0e0e8aee02126764d67a9b9 100644 (file)
@@ -77,6 +77,7 @@
   struct Version_dependency_list* deplist;
   struct Version_expression_list* versyms;
   struct Version_tree* versnode;
+  enum Script_section_type section_type;
 }
 
 /* Operators, including a precedence table for expressions.  */
 %token BYTE
 %token CONSTANT
 %token CONSTRUCTORS
+%token COPY
 %token CREATE_OBJECT_SYMBOLS
 %token DATA_SEGMENT_ALIGN
 %token DATA_SEGMENT_END
 %token DATA_SEGMENT_RELRO_END
 %token DEFINED
+%token DSECT
 %token ENTRY
 %token EXCLUDE_FILE
 %token EXTERN
 %token HLL
 %token INCLUDE
 %token INHIBIT_COMMON_ALLOCATION
+%token INFO
 %token INPUT
 %token KEEP
 %token LENGTH          /* LENGTH, l, len */
 %token NEXT
 %token NOCROSSREFS
 %token NOFLOAT
+%token NOLOAD
 %token ONLY_IF_RO
 %token ONLY_IF_RW
 %token ORIGIN          /* ORIGIN, o, org */
 
 /* Non-terminal types, where needed.  */
 
-%type <expr> parse_exp exp opt_address_and_section_type
+%type <expr> parse_exp exp
 %type <expr> opt_at opt_align opt_subalign opt_fill
-%type <output_section_header> section_header
+%type <output_section_header> section_header opt_address_and_section_type
+%type <section_type> section_type
 %type <output_section_trailer> section_trailer
 %type <constraint> opt_constraint
 %type <string_list> opt_phdr
@@ -234,7 +240,8 @@ linker_script:
 
 /* A command which may appear at top level of a linker script.  */
 file_cmd:
-         FORCE_COMMON_ALLOCATION
+         EXTERN '(' extern_name_list ')'
+       | FORCE_COMMON_ALLOCATION
            { script_set_common_allocation(closure, 1); }
        | GROUP
            { script_start_group(closure); }
@@ -242,8 +249,22 @@ file_cmd:
            { script_end_group(closure); }
        | INHIBIT_COMMON_ALLOCATION
            { script_set_common_allocation(closure, 0); }
+       | INPUT '(' input_list ')'
         | OPTION '(' string ')'
            { script_parse_option(closure, $3.value, $3.length); }
+       | OUTPUT_FORMAT '(' string ')'
+           {
+             if (!script_check_output_format(closure, $3.value, $3.length,
+                                             NULL, 0, NULL, 0))
+               YYABORT;
+           }
+       | OUTPUT_FORMAT '(' string ',' string ',' string ')'
+           {
+             if (!script_check_output_format(closure, $3.value, $3.length,
+                                             $5.value, $5.length,
+                                             $7.value, $7.length))
+               YYABORT;
+           }
        | PHDRS '{' phdrs_defs '}'
        | SEARCH_DIR '(' string ')'
            { script_add_search_dir(closure, $3.value, $3.length); }
@@ -251,6 +272,8 @@ file_cmd:
            { script_start_sections(closure); }
          sections_block '}'
            { script_finish_sections(closure); }
+       | TARGET_K '(' string ')'
+           { script_set_target(closure, $3.value, $3.length); }
         | VERSIONK '{'
             { script_push_lex_into_version_mode(closure); }
           version_script '}'
@@ -265,9 +288,26 @@ file_cmd:
    these is more-or-less OK since most scripts simply explicitly
    choose the default.  */
 ignore_cmd:
-         OUTPUT_FORMAT '(' string ')'
-       | OUTPUT_FORMAT '(' string ',' string ',' string ')'
-       | OUTPUT_ARCH '(' string ')'
+         OUTPUT_ARCH '(' string ')'
+       ;
+
+/* A list of external undefined symbols.  We put the lexer into
+   expression mode so that commas separate names; this is what the GNU
+   linker does.  */
+
+extern_name_list:
+           { script_push_lex_into_expression_mode(closure); }
+         extern_name_list_body
+           { script_pop_lex_mode(closure); }
+       ;
+
+extern_name_list_body:
+         string
+           { script_add_extern(closure, $1.value, $1.length); }
+       | extern_name_list_body string
+           { script_add_extern(closure, $2.value, $2.length); }
+       | extern_name_list_body ',' string
+           { script_add_extern(closure, $3.value, $3.length); }
        ;
 
 /* A list of input file names.  */
@@ -309,7 +349,8 @@ section_header:
            { script_pop_lex_mode(closure); }
          opt_constraint
            {
-             $$.address = $2;
+             $$.address = $2.address;
+             $$.section_type = $2.section_type;
              $$.load_address = $3;
              $$.align = $4;
              $$.subalign = $5;
@@ -322,18 +363,61 @@ section_header:
    '(' in section_header.  */
 
 opt_address_and_section_type:
-         ':'
-           { $$ = NULL; }
+       ':'
+           {
+             $$.address = NULL;
+             $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+           }
        | '(' ')' ':'
-           { $$ = NULL; }
+           {
+             $$.address = NULL;
+             $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+           }
        | exp ':'
-           { $$ = $1; }
+           {
+             $$.address = $1;
+             $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+           }
        | exp '(' ')' ':'
-           { $$ = $1; }
-       | exp '(' string ')' ':'
            {
-             yyerror(closure, "section types are not supported");
-             $$ = $1;
+             $$.address = $1;
+             $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+           }
+       | '(' section_type ')' ':'
+           {
+             $$.address = NULL;
+             $$.section_type = $2;
+           }
+       | exp '(' section_type ')' ':'
+           {
+             $$.address = $1;
+             $$.section_type = $3;
+           }
+       ;
+
+/* We only support NOLOAD.  */
+section_type:
+       NOLOAD
+           { $$ = SCRIPT_SECTION_TYPE_NOLOAD; }
+       | DSECT
+           {
+             yyerror(closure, "DSECT section type is unsupported");
+             $$ = SCRIPT_SECTION_TYPE_DSECT;
+           }
+       | COPY
+           {
+             yyerror(closure, "COPY section type is unsupported");
+             $$ = SCRIPT_SECTION_TYPE_COPY;
+           }
+       | INFO
+           {
+             yyerror(closure, "INFO section type is unsupported");
+             $$ = SCRIPT_SECTION_TYPE_INFO;
+           }
+       | OVERLAY
+           {
+             yyerror(closure, "OVERLAY section type is unsupported");
+             $$ = SCRIPT_SECTION_TYPE_OVERLAY;
            }
        ;
 
@@ -827,6 +911,10 @@ exp:
        | SEGMENT_START '(' string ',' exp ')'
            {
              $$ = script_exp_function_segment_start($3.value, $3.length, $5);
+             /* We need to take note of any SEGMENT_START expressions
+                because they change the behaviour of -Ttext, -Tdata and
+                -Tbss options.  */
+             script_saw_segment_start_expression(closure);
            }
        | ASSERT_K '(' exp ',' string ')'
            { $$ = script_exp_function_assert($3, $5.value, $5.length); }