%token END
%left <token> '('
%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
-%token SECTIONS PHDRS SORT DATA_SEGMENT_ALIGN DATA_SEGMENT_END
+%token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
+%token SORT_BY_NAME SORT_BY_ALIGNMENT
%token '{' '}'
%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
%token INHIBIT_COMMON_ALLOCATION
%token SIZEOF_HEADERS
+%token SEGMENT_START
%token INCLUDE
%token MEMORY DEFSYMEND
%token NOLOAD DSECT COPY INFO OVERLAY
%token ORIGIN FILL
%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
%token ALIGNMOD AT SUBALIGN PROVIDE
-%type <token> assign_op atype attributes_opt
+%type <token> assign_op atype attributes_opt sect_constraint
%type <name> filename
%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
%token <name> VERS_TAG VERS_IDENTIFIER
%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
-%token KEEP
+%token KEEP ONLY_IF_RO ONLY_IF_RW
%token EXCLUDE_FILE
%type <versyms> vers_defns
%type <versnode> vers_tag
| OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
{ lang_add_output_format ($3, $5, $7, 1); }
| OUTPUT_ARCH '(' NAME ')'
- { ldfile_set_output_arch($3); }
+ { ldfile_set_output_arch ($3, bfd_arch_unknown); }
| FORCE_COMMON_ALLOCATION
{ command_line.force_common_definition = TRUE ; }
| INHIBIT_COMMON_ALLOCATION
ENTRY '(' NAME ')'
{ lang_add_entry ($3, FALSE); }
| assignment end
+ | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')'
+ { ldlex_popstate ();
+ lang_add_assignment (exp_assert ($4, $6)); }
;
/* The '*' and '?' cases are there because the lexer returns them as
wildcard_name
{
$$.name = $1;
- $$.sorted = FALSE;
+ $$.sorted = none;
$$.exclude_name_list = NULL;
}
| EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name
{
$$.name = $5;
- $$.sorted = FALSE;
+ $$.sorted = none;
$$.exclude_name_list = $3;
}
- | SORT '(' wildcard_name ')'
+ | SORT_BY_NAME '(' wildcard_name ')'
{
$$.name = $3;
- $$.sorted = TRUE;
+ $$.sorted = by_name;
$$.exclude_name_list = NULL;
}
- | SORT '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
+ | SORT_BY_ALIGNMENT '(' wildcard_name ')'
+ {
+ $$.name = $3;
+ $$.sorted = by_alignment;
+ $$.exclude_name_list = NULL;
+ }
+ | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
+ {
+ $$.name = $5;
+ $$.sorted = by_name_alignment;
+ $$.exclude_name_list = NULL;
+ }
+ | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')'
+ {
+ $$.name = $5;
+ $$.sorted = by_name;
+ $$.exclude_name_list = NULL;
+ }
+ | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')'
+ {
+ $$.name = $5;
+ $$.sorted = by_alignment_name;
+ $$.exclude_name_list = NULL;
+ }
+ | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
+ {
+ $$.name = $5;
+ $$.sorted = by_alignment;
+ $$.exclude_name_list = NULL;
+ }
+ | SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
{
$$.name = $7;
- $$.sorted = TRUE;
+ $$.sorted = by_name;
$$.exclude_name_list = $5;
}
;
struct wildcard_spec tmp;
tmp.name = $1;
tmp.exclude_name_list = NULL;
- tmp.sorted = FALSE;
+ tmp.sorted = none;
lang_add_wild (&tmp, NULL, ldgram_had_keep);
}
| '[' file_NAME_list ']'
lang_add_attribute(lang_constructors_statement_enum);
}
- | SORT '(' CONSTRUCTORS ')'
+ | SORT_BY_NAME '(' CONSTRUCTORS ')'
{
constructors_sorted = TRUE;
lang_add_attribute (lang_constructors_statement_enum);
{ $$ = exp_unop(ABSOLUTE, $3); }
| ALIGN_K '(' exp ')'
{ $$ = exp_unop(ALIGN_K,$3); }
+ | ALIGN_K '(' exp ',' exp ')'
+ { $$ = exp_binop(ALIGN_K,$3,$5); }
| DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
{ $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
+ | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
+ { $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
| DATA_SEGMENT_END '(' exp ')'
{ $$ = exp_unop(DATA_SEGMENT_END, $3); }
+ | SEGMENT_START '(' NAME ',' exp ')'
+ { /* The operands to the expression node are
+ placed in the opposite order from the way
+ in which they appear in the script as
+ that allows us to reuse more code in
+ fold_binary. */
+ $$ = exp_binop (SEGMENT_START,
+ $5,
+ exp_nameop (NAME, $3)); }
| BLOCK '(' exp ')'
{ $$ = exp_unop(ALIGN_K,$3); }
| NAME
| { $$ = 0; }
;
+sect_constraint:
+ ONLY_IF_RO { $$ = ONLY_IF_RO; }
+ | ONLY_IF_RW { $$ = ONLY_IF_RW; }
+ | { $$ = 0; }
+ ;
+
section: NAME { ldlex_expression(); }
opt_exp_with_type
opt_at
opt_subalign { ldlex_popstate (); ldlex_script (); }
+ sect_constraint
'{'
{
lang_enter_output_section_statement($1, $3,
sectype,
- 0, 0, $5, $4);
+ 0, $5, $4, $7);
}
statement_list_opt
'}' { ldlex_popstate (); ldlex_expression (); }
memspec_opt memspec_at_opt phdr_opt fill_opt
{
ldlex_popstate ();
- lang_leave_output_section_statement ($15, $12, $14, $13);
+ lang_leave_output_section_statement ($16, $13, $15, $14);
}
opt_comma
{}