/* yyscript.y -- linker script grammar for gold. */
-/* Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor <iant@google.com>.
This file is part of gold.
%token FORCE_COMMON_ALLOCATION
%token GLOBAL /* global */
%token GROUP
+%token HIDDEN
%token HLL
%token INCLUDE
%token INHIBIT_COMMON_ALLOCATION
%token INFO
%token INPUT
%token KEEP
+%token LEN
%token LENGTH /* LENGTH, l, len */
%token LOADADDR
%token LOCAL /* local */
%token NOLOAD
%token ONLY_IF_RO
%token ONLY_IF_RW
+%token ORG
%token ORIGIN /* ORIGIN, o, org */
%token OUTPUT
%token OUTPUT_ARCH
%token SIZEOF
%token SIZEOF_HEADERS /* SIZEOF_HEADERS, sizeof_headers */
%token SORT_BY_ALIGNMENT
+%token SORT_BY_INIT_PRIORITY
%token SORT_BY_NAME
%token SPECIAL
%token SQUAD
%token PARSING_VERSION_SCRIPT
%token PARSING_DEFSYM
%token PARSING_DYNAMIC_LIST
+%token PARSING_SECTIONS_BLOCK
+%token PARSING_SECTION_COMMANDS
+%token PARSING_MEMORY_DEF
/* Non-terminal types, where needed. */
%type <wildcard_section> wildcard_file wildcard_section
%type <string_list> exclude_names
%type <string> wildcard_name
-%type <integer> phdr_type
+%type <integer> phdr_type memory_attr
%type <phdr_info> phdr_info
%type <versyms> vers_defns
%type <versnode> vers_tag
| PARSING_VERSION_SCRIPT version_script
| PARSING_DEFSYM defsym_expr
| PARSING_DYNAMIC_LIST dynamic_list_expr
+ | PARSING_SECTIONS_BLOCK sections_block
+ | PARSING_SECTION_COMMANDS section_cmds
+ | PARSING_MEMORY_DEF memory_defs
;
/* A file contains a list of commands. */
| INHIBIT_COMMON_ALLOCATION
{ script_set_common_allocation(closure, 0); }
| INPUT '(' input_list ')'
+ | MEMORY '{' memory_defs '}'
| OPTION '(' string ')'
{ script_parse_option(closure, $3.value, $3.length); }
| OUTPUT_FORMAT '(' string ')'
{ script_push_lex_into_version_mode(closure); }
version_script '}'
{ script_pop_lex_mode(closure); }
- | file_or_sections_cmd
+ | ENTRY '(' string ')'
+ { script_set_entry(closure, $3.value, $3.length); }
+ | assignment end
+ | ASSERT_K '(' parse_exp ',' string ')'
+ { script_add_assertion(closure, $3, $5.value, $5.length); }
+ | INCLUDE string
+ { script_include_directive(PARSING_LINKER_SCRIPT, closure,
+ $2.value, $2.length); }
| ignore_cmd
| ';'
;
/* A command which may appear within a SECTIONS block. */
section_block_cmd:
- file_or_sections_cmd
+ ENTRY '(' string ')'
+ { script_set_entry(closure, $3.value, $3.length); }
+ | assignment end
+ | ASSERT_K '(' parse_exp ',' string ')'
+ { script_add_assertion(closure, $3, $5.value, $5.length); }
+ | INCLUDE string
+ { script_include_directive(PARSING_SECTIONS_BLOCK, closure,
+ $2.value, $2.length); }
| string section_header
{ script_start_output_section(closure, $1.value, $1.length, &$2); }
'{' section_cmds '}' section_trailer
/* A memory specification for an output section. */
opt_memspec:
'>' string
- { yyerror(closure, "memory regions are not supported"); }
+ { script_set_section_region(closure, $2.value, $2.length, 1); }
| /* empty */
;
/* A memory specification for where to load an output section. */
opt_at_memspec:
AT '>' string
- { yyerror(closure, "memory regions are not supported"); }
+ { script_set_section_region(closure, $3.value, $3.length, 0); }
| /* empty */
;
nothing, we accept it and ignore it. */
}
| SORT_BY_NAME '(' CONSTRUCTORS ')'
+ | INCLUDE string
+ { script_include_directive(PARSING_SECTION_COMMANDS, closure,
+ $2.value, $2.length); }
| ';'
;
abort();
}
}
+ | SORT_BY_INIT_PRIORITY '(' wildcard_name ')'
+ {
+ $$.name = $3;
+ $$.sort = SORT_WILDCARD_BY_INIT_PRIORITY;
+ }
;
/* A list of file names to exclude. */
}
;
-/* A command which may appear at the top level of a linker script, or
- within a SECTIONS block. */
-file_or_sections_cmd:
- ENTRY '(' string ')'
- { script_set_entry(closure, $3.value, $3.length); }
- | assignment end
- | ASSERT_K '(' parse_exp ',' string ')'
- { script_add_assertion(closure, $3, $5.value, $5.length); }
+/* A list of MEMORY definitions. */
+memory_defs:
+ memory_defs opt_comma memory_def
+ | /* empty */
+ ;
+
+/* A single MEMORY definition. */
+memory_def:
+ string memory_attr ':' memory_origin '=' parse_exp opt_comma memory_length '=' parse_exp
+ { script_add_memory(closure, $1.value, $1.length, $2, $6, $10); }
+ |
+ INCLUDE string
+ { script_include_directive(PARSING_MEMORY_DEF, closure,
+ $2.value, $2.length); }
+ |
+ ;
+
+/* The (optional) attributes of a MEMORY region. */
+memory_attr:
+ '(' string ')'
+ { $$ = script_parse_memory_attr(closure, $2.value, $2.length, 0); }
+ | /* Inverted attributes. */
+ '(' '!' string ')'
+ { $$ = script_parse_memory_attr(closure, $3.value, $3.length, 1); }
+ | /* empty */
+ { $$ = 0; }
+ ;
+
+memory_origin:
+ ORIGIN
+ |
+ ORG
+ |
+ 'o'
+ ;
+
+memory_length:
+ LENGTH
+ |
+ LEN
+ |
+ 'l'
;
/* A list of program header definitions. */
Expression_ptr e = script_exp_binary_bitwise_or(s, $3);
script_set_symbol(closure, $1.value, $1.length, e, 0, 0);
}
+ | HIDDEN '(' string '=' parse_exp ')'
+ { script_set_symbol(closure, $3.value, $3.length, $5, 0, 1); }
| PROVIDE '(' string '=' parse_exp ')'
{ script_set_symbol(closure, $3.value, $3.length, $5, 1, 0); }
| PROVIDE_HIDDEN '(' string '=' parse_exp ')'
| LOADADDR '(' string ')'
{ $$ = script_exp_function_loadaddr($3.value, $3.length); }
| ORIGIN '(' string ')'
- { $$ = script_exp_function_origin($3.value, $3.length); }
+ { $$ = script_exp_function_origin(closure, $3.value, $3.length); }
| LENGTH '(' string ')'
- { $$ = script_exp_function_length($3.value, $3.length); }
+ { $$ = script_exp_function_length(closure, $3.value, $3.length); }
| CONSTANT '(' string ')'
{ $$ = script_exp_function_constant($3.value, $3.length); }
| ABSOLUTE '(' exp ')'