ldgram.y revision 60484
169408Sache/* A YACC grammer to parse a superset of the AT&T linker scripting languaue. 269408Sache Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000 3100616Smp Free Software Foundation, Inc. 4231990Smp Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com). 5195609Smp 6100616SmpThis file is part of GNU ld. 7231990Smp 8100616SmpThis program is free software; you can redistribute it and/or modify 969408Sacheit under the terms of the GNU General Public License as published by 1069408Sachethe Free Software Foundation; either version 2 of the License, or 1169408Sache(at your option) any later version. 1269408Sache 1369408SacheThis program is distributed in the hope that it will be useful, 1469408Sachebut WITHOUT ANY WARRANTY; without even the implied warranty of 1569408SacheMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1669408SacheGNU General Public License for more details. 1769408Sache 1869408SacheYou should have received a copy of the GNU General Public License 1969408Sachealong with this program; if not, write to the Free Software 2069408SacheFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 21195609Smp 22195609Smp%{ 2369408Sache/* 2469408Sache 2569408Sache */ 2669408Sache 2769408Sache#define DONTDECLARE_MALLOC 2869408Sache 29195609Smp#include "bfd.h" 30231990Smp#include "sysdep.h" 31231990Smp#include "bfdlink.h" 32231990Smp#include "ld.h" 3369408Sache#include "ldexp.h" 3469408Sache#include "ldver.h" 3569408Sache#include "ldlang.h" 3669408Sache#include "ldemul.h" 3769408Sache#include "ldfile.h" 38231990Smp#include "ldmisc.h" 39231990Smp#include "ldmain.h" 4069408Sache#include "mri.h" 41100616Smp#include "ldctor.h" 42100616Smp#include "ldlex.h" 43100616Smp 44100616Smp#ifndef YYDEBUG 45100616Smp#define YYDEBUG 1 46100616Smp#endif 47100616Smp 48100616Smpstatic enum section_type sectype; 49100616Smp 50100616Smplang_memory_region_type *region; 51100616Smp 52100616Smpstruct wildcard_spec current_file; 53100616Smpboolean ldgram_want_filename = true; 54100616Smpboolean had_script = false; 55100616Smpboolean force_make_executable = false; 56100616Smp 57100616Smpboolean ldgram_in_script = false; 58100616Smpboolean ldgram_had_equals = false; 59231990Smpboolean ldgram_had_keep = false; 60231990Smpchar *ldgram_vers_current_lang = NULL; 61231990Smp 62100616Smp#define ERROR_NAME_MAX 20 63100616Smpstatic char *error_names[ERROR_NAME_MAX]; 64100616Smpstatic int error_index; 65100616Smp#define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++; 66100616Smp#define POP_ERROR() error_index--; 67100616Smp%} 68100616Smp%union { 69100616Smp bfd_vma integer; 70100616Smp char *name; 71100616Smp const char *cname; 72100616Smp struct wildcard_spec wildcard; 73195609Smp struct name_list *name_list; 74100616Smp int token; 75195609Smp union etree_union *etree; 76100616Smp struct phdr_info 77195609Smp { 78100616Smp boolean filehdr; 79100616Smp boolean phdrs; 80100616Smp union etree_union *at; 81100616Smp union etree_union *flags; 82100616Smp } phdr; 83100616Smp struct lang_nocrossref *nocrossref; 84100616Smp struct lang_output_section_phdr_list *section_phdr; 85100616Smp struct bfd_elf_version_deps *deflist; 86100616Smp struct bfd_elf_version_expr *versyms; 87100616Smp struct bfd_elf_version_tree *versnode; 88100616Smp} 89100616Smp 90100616Smp%type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val 91100616Smp%type <etree> opt_exp_without_type 92100616Smp%type <integer> fill_opt 9383098Smp%type <name_list> exclude_name_list 9483098Smp%type <name> memspec_opt casesymlist 95100616Smp%type <name> memspec_at_opt 9683098Smp%type <cname> wildcard_name 97100616Smp%type <wildcard> wildcard_spec 98100616Smp%token <integer> INT 99100616Smp%token <name> NAME LNAME 100100616Smp%type <integer> length 101100616Smp%type <phdr> phdr_qualifiers 102100616Smp%type <nocrossref> nocrossref_list 103100616Smp%type <section_phdr> phdr_opt 104100616Smp%type <integer> opt_nocrossrefs 105195609Smp 106100616Smp%right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ 107195609Smp%right <token> '?' ':' 108195609Smp%left <token> OROR 109195609Smp%left <token> ANDAND 110195609Smp%left <token> '|' 111195609Smp%left <token> '^' 112195609Smp%left <token> '&' 113195609Smp%left <token> EQ NE 114195609Smp%left <token> '<' '>' LE GE 115195609Smp%left <token> LSHIFT RSHIFT 116195609Smp 117100616Smp%left <token> '+' '-' 118100616Smp%left <token> '*' '/' '%' 119100616Smp 120195609Smp%right UNARY 121100616Smp%token END 122100616Smp%left <token> '(' 123100616Smp%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE 124100616Smp%token SECTIONS PHDRS SORT 125100616Smp%token '{' '}' 126100616Smp%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH 127100616Smp%token SIZEOF_HEADERS 128100616Smp%token INCLUDE 129100616Smp%token MEMORY DEFSYMEND 130195609Smp%token NOLOAD DSECT COPY INFO OVERLAY 131100616Smp%token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY 13269408Sache%token <integer> NEXT 133100616Smp%token SIZEOF ADDR LOADADDR MAX_K MIN_K 13469408Sache%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS 13569408Sache%token ORIGIN FILL 13669408Sache%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS 13769408Sache%token ALIGNMOD AT PROVIDE 13869408Sache%type <token> assign_op atype attributes_opt 13969408Sache%type <name> filename 140100616Smp%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K 14169408Sache%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL 14269408Sache%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START 14369408Sache%token <name> VERS_TAG VERS_IDENTIFIER 14469408Sache%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT 14569408Sache%token KEEP 146100616Smp%token EXCLUDE_FILE 147100616Smp%type <versyms> vers_defns 148100616Smp%type <versnode> vers_tag 149100616Smp%type <deflist> verdep 150100616Smp 151100616Smp%% 152100616Smp 153100616Smpfile: 154100616Smp INPUT_SCRIPT script_file 155100616Smp | INPUT_MRI_SCRIPT mri_script_file 156100616Smp | INPUT_VERSION_SCRIPT version_script_file 157100616Smp | INPUT_DEFSYM defsym_expr 158100616Smp ; 159100616Smp 160100616Smp 161100616Smpfilename: NAME; 162100616Smp 163100616Smp 164100616Smpdefsym_expr: 165195609Smp { ldlex_defsym(); } 166100616Smp NAME '=' exp 167100616Smp { 168100616Smp ldlex_popstate(); 169100616Smp lang_add_assignment(exp_assop($3,$2,$4)); 170100616Smp } 171100616Smp 172100616Smp/* SYNTAX WITHIN AN MRI SCRIPT FILE */ 173100616Smpmri_script_file: 174195609Smp { 175100616Smp ldlex_mri_script (); 176100616Smp PUSH_ERROR (_("MRI style script")); 177100616Smp } 178100616Smp mri_script_lines 179100616Smp { 180100616Smp ldlex_popstate (); 181100616Smp mri_draw_tree (); 182100616Smp POP_ERROR (); 183100616Smp } 184100616Smp ; 185100616Smp 186100616Smpmri_script_lines: 187100616Smp mri_script_lines mri_script_command NEWLINE 188195609Smp | 189195609Smp ; 190195609Smp 191195609Smpmri_script_command: 192195609Smp CHIP exp 193195609Smp | CHIP exp ',' exp 194195609Smp | NAME { 195195609Smp einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1); 196195609Smp } 197195609Smp | LIST { 198195609Smp config.map_filename = "-"; 199195609Smp } 200100616Smp | ORDER ordernamelist 201100616Smp | ENDWORD 202100616Smp | PUBLIC NAME '=' exp 203100616Smp { mri_public($2, $4); } 204195609Smp | PUBLIC NAME ',' exp 205100616Smp { mri_public($2, $4); } 206195609Smp | PUBLIC NAME exp 207195609Smp { mri_public($2, $3); } 208195609Smp | FORMAT NAME 209195609Smp { mri_format($2); } 210195609Smp | SECT NAME ',' exp 211195609Smp { mri_output_section($2, $4);} 212195609Smp | SECT NAME exp 213195609Smp { mri_output_section($2, $3);} 214195609Smp | SECT NAME '=' exp 215195609Smp { mri_output_section($2, $4);} 216195609Smp | ALIGN_K NAME '=' exp 217195609Smp { mri_align($2,$4); } 218195609Smp | ALIGN_K NAME ',' exp 219195609Smp { mri_align($2,$4); } 220195609Smp | ALIGNMOD NAME '=' exp 22169408Sache { mri_alignmod($2,$4); } 222195609Smp | ALIGNMOD NAME ',' exp 223195609Smp { mri_alignmod($2,$4); } 22469408Sache | ABSOLUTE mri_abs_name_list 225195609Smp | LOAD mri_load_name_list 226195609Smp | NAMEWORD NAME 227195609Smp { mri_name($2); } 228195609Smp | ALIAS NAME ',' NAME 229195609Smp { mri_alias($2,$4,0);} 230195609Smp | ALIAS NAME ',' INT 231195609Smp { mri_alias($2,0,(int) $4);} 232195609Smp | BASE exp 233195609Smp { mri_base($2); } 234195609Smp | TRUNCATE INT 235195609Smp { mri_truncate((unsigned int) $2); } 236195609Smp | CASE casesymlist 237195609Smp | EXTERN extern_name_list 238195609Smp | INCLUDE filename 239195609Smp { ldfile_open_command_file ($2); } mri_script_lines END 240195609Smp | START NAME 241195609Smp { lang_add_entry ($2, false); } 242195609Smp | 243195609Smp ; 244195609Smp 245195609Smpordernamelist: 246195609Smp ordernamelist ',' NAME { mri_order($3); } 247195609Smp | ordernamelist NAME { mri_order($2); } 248195609Smp | 249195609Smp ; 250195609Smp 251195609Smpmri_load_name_list: 252195609Smp NAME 253195609Smp { mri_load($1); } 254195609Smp | mri_load_name_list ',' NAME { mri_load($3); } 255195609Smp ; 256195609Smp 257195609Smpmri_abs_name_list: 258195609Smp NAME 259195609Smp { mri_only_load($1); } 260195609Smp | mri_abs_name_list ',' NAME 261195609Smp { mri_only_load($3); } 262195609Smp ; 263195609Smp 264195609Smpcasesymlist: 265195609Smp /* empty */ { $$ = NULL; } 266195609Smp | NAME 267195609Smp | casesymlist ',' NAME 26869408Sache ; 26969408Sache 27069408Sacheextern_name_list: 27169408Sache NAME 272195609Smp { ldlang_add_undef ($1); } 273195609Smp | extern_name_list NAME 27483098Smp { ldlang_add_undef ($2); } 27583098Smp | extern_name_list ',' NAME 27683098Smp { ldlang_add_undef ($3); } 27783098Smp ; 27883098Smp 279195609Smpscript_file: 28069408Sache { 28169408Sache ldlex_both(); 282195609Smp } 28369408Sache ifile_list 284100616Smp { 285195609Smp ldlex_popstate(); 28669408Sache } 28769408Sache ; 288195609Smp 289100616Smp 290100616Smpifile_list: 291195609Smp ifile_list ifile_p1 29283098Smp | 29383098Smp ; 294195609Smp 295195609Smp 296195609Smp 297195609Smpifile_p1: 298195609Smp memory 299195609Smp | sections 300195609Smp | phdrs 30169408Sache | startup 30269408Sache | high_level_library 303195609Smp | low_level_library 304195609Smp | floating_point_support 305195609Smp | statement_anywhere 306195609Smp | version 307100616Smp | ';' 30869408Sache | TARGET_K '(' NAME ')' 309195609Smp { lang_add_target($3); } 31083098Smp | SEARCH_DIR '(' filename ')' 31169408Sache { ldfile_add_library_path ($3, false); } 31269408Sache | OUTPUT '(' filename ')' 31369408Sache { lang_add_output($3, 1); } 31469408Sache | OUTPUT_FORMAT '(' NAME ')' 31569408Sache { lang_add_output_format ($3, (char *) NULL, 31669408Sache (char *) NULL, 1); } 317195609Smp | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')' 31883098Smp { lang_add_output_format ($3, $5, $7, 1); } 31969408Sache | OUTPUT_ARCH '(' NAME ')' 320195609Smp { ldfile_set_output_arch($3); } 321195609Smp | FORCE_COMMON_ALLOCATION 322195609Smp { command_line.force_common_definition = true ; } 323195609Smp | INPUT '(' input_list ')' 324195609Smp | GROUP 325100616Smp { lang_enter_group (); } 326195609Smp '(' input_list ')' 327100616Smp { lang_leave_group (); } 328195609Smp | MAP '(' filename ')' 329195609Smp { lang_add_map($3); } 330195609Smp | INCLUDE filename 33169408Sache { ldfile_open_command_file($2); } ifile_list END 33269408Sache | NOCROSSREFS '(' nocrossref_list ')' 333195609Smp { 33469408Sache lang_add_nocrossref ($3); 33569408Sache } 336195609Smp | EXTERN '(' extern_name_list ')' 337231990Smp ; 338231990Smp 339231990Smpinput_list: 340195609Smp NAME 341195609Smp { lang_add_input_file($1,lang_input_file_is_search_file_enum, 342195609Smp (char *)NULL); } 343195609Smp | input_list ',' NAME 344195609Smp { lang_add_input_file($3,lang_input_file_is_search_file_enum, 345195609Smp (char *)NULL); } 346195609Smp | input_list NAME 347195609Smp { lang_add_input_file($2,lang_input_file_is_search_file_enum, 348195609Smp (char *)NULL); } 349195609Smp | LNAME 350195609Smp { lang_add_input_file($1,lang_input_file_is_l_enum, 351195609Smp (char *)NULL); } 352195609Smp | input_list ',' LNAME 353195609Smp { lang_add_input_file($3,lang_input_file_is_l_enum, 354195609Smp (char *)NULL); } 355195609Smp | input_list LNAME 35669408Sache { lang_add_input_file($2,lang_input_file_is_l_enum, 35769408Sache (char *)NULL); } 35869408Sache ; 35969408Sache 36069408Sachesections: 361195609Smp SECTIONS '{' sec_or_group_p1 '}' 36269408Sache ; 36369408Sache 36469408Sachesec_or_group_p1: 36569408Sache sec_or_group_p1 section 36669408Sache | sec_or_group_p1 statement_anywhere 36769408Sache | 36869408Sache ; 36969408Sache 370195609Smpstatement_anywhere: 37169408Sache ENTRY '(' NAME ')' 37269408Sache { lang_add_entry ($3, false); } 373195609Smp | assignment end 37469408Sache ; 375100616Smp 37669408Sache/* The '*' and '?' cases are there because the lexer returns them as 37769408Sache separate tokens rather than as NAME. */ 37869408Sachewildcard_name: 37969408Sache NAME 38069408Sache { 38169408Sache $$ = $1; 38269408Sache } 38369408Sache | '*' 38469408Sache { 385195609Smp $$ = "*"; 38669408Sache } 38769408Sache | '?' 388195609Smp { 38983098Smp $$ = "?"; 39083098Smp } 391100616Smp ; 39283098Smp 39383098Smpwildcard_spec: 39483098Smp wildcard_name 39583098Smp { 39683098Smp $$.name = $1; 39783098Smp $$.sorted = false; 39883098Smp $$.exclude_name_list = NULL; 399195609Smp } 40083098Smp | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name 40183098Smp { 402195609Smp $$.name = $5; 40383098Smp $$.sorted = false; 40483098Smp $$.exclude_name_list = $3; 405195609Smp } 40683098Smp | SORT '(' wildcard_name ')' 40783098Smp { 408195609Smp $$.name = $3; 40983098Smp $$.sorted = true; 41083098Smp $$.exclude_name_list = NULL; 411195609Smp } 41283098Smp | SORT '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')' 41383098Smp { 414195609Smp $$.name = $7; 415195609Smp $$.sorted = true; 416195609Smp $$.exclude_name_list = $5; 417195609Smp } 41869408Sache ; 41969408Sache 420195609Smp 42169408Sache 42269408Sacheexclude_name_list: 423195609Smp exclude_name_list wildcard_name 42469408Sache { 42569408Sache struct name_list *tmp; 426195609Smp tmp = (struct name_list *) xmalloc (sizeof *tmp); 42769408Sache tmp->name = $2; 42869408Sache tmp->next = $1; 429195609Smp $$ = tmp; 43083098Smp } 43169408Sache | 432195609Smp wildcard_name 43369408Sache { 434100616Smp struct name_list *tmp; 43583098Smp tmp = (struct name_list *) xmalloc (sizeof *tmp); 43683098Smp tmp->name = $1; 437100616Smp tmp->next = NULL; 43883098Smp $$ = tmp; 43983098Smp } 44083098Smp ; 44183098Smp 44269408Sachefile_NAME_list: 44369408Sache wildcard_spec 44469408Sache { 44569408Sache lang_add_wild ($1.name, $1.sorted, 44669408Sache current_file.name, 44769408Sache current_file.sorted, 44869408Sache ldgram_had_keep, $1.exclude_name_list); 44969408Sache } 45069408Sache | file_NAME_list opt_comma wildcard_spec 45169408Sache { 45269408Sache lang_add_wild ($3.name, $3.sorted, 45369408Sache current_file.name, 45469408Sache current_file.sorted, 45569408Sache ldgram_had_keep, $3.exclude_name_list); 456195609Smp } 457195609Smp ; 458195609Smp 459195609Smpinput_section_spec_no_keep: 46069408Sache NAME 461195609Smp { 462100616Smp lang_add_wild (NULL, false, $1, false, 463100616Smp ldgram_had_keep, NULL); 464195609Smp } 465195609Smp | '[' 466100616Smp { 467195609Smp current_file.name = NULL; 468195609Smp current_file.sorted = false; 469195609Smp } 470195609Smp file_NAME_list ']' 47169408Sache | wildcard_spec 47269408Sache { 473195609Smp current_file = $1; 47469408Sache /* '*' matches any file name. */ 47569408Sache if (strcmp (current_file.name, "*") == 0) 476195609Smp current_file.name = NULL; 47769408Sache } 47869408Sache '(' file_NAME_list ')' 479195609Smp ; 48069408Sache 48169408Sacheinput_section_spec: 482195609Smp input_section_spec_no_keep 48369408Sache | KEEP '(' 48469408Sache { ldgram_had_keep = true; } 48569408Sache input_section_spec_no_keep ')' 486100616Smp { ldgram_had_keep = false; } 48783098Smp ; 48883098Smp 48983098Smpstatement: 49083098Smp assignment end 49169408Sache | CREATE_OBJECT_SYMBOLS 49283098Smp { 49383098Smp lang_add_attribute(lang_object_symbols_statement_enum); 49483098Smp } 49569408Sache | ';' 49683098Smp | CONSTRUCTORS 49769408Sache { 498195609Smp 49969408Sache lang_add_attribute(lang_constructors_statement_enum); 50069408Sache } 501195609Smp | SORT '(' CONSTRUCTORS ')' 50269408Sache { 50369408Sache constructors_sorted = true; 50469408Sache lang_add_attribute (lang_constructors_statement_enum); 505195609Smp } 50669408Sache | input_section_spec 50769408Sache | length '(' mustbe_exp ')' 508195609Smp { 50969408Sache lang_add_data((int) $1,$3); 51069408Sache } 511195609Smp 51269408Sache | FILL '(' mustbe_exp ')' 51369408Sache { 514195609Smp lang_add_fill 51569408Sache (exp_get_value_int($3, 516195609Smp 0, 517195609Smp "fill value", 518100616Smp lang_first_phase_enum)); 51969408Sache } 520195609Smp ; 521100616Smp 522100616Smpstatement_list: 523100616Smp statement_list statement 524100616Smp | statement 525100616Smp ; 526100616Smp 527100616Smpstatement_list_opt: 528195609Smp /* empty */ 52969408Sache | statement_list 53069408Sache ; 531100616Smp 53283098Smplength: 53369408Sache QUAD 53469408Sache { $$ = $1; } 53569408Sache | SQUAD 53669408Sache { $$ = $1; } 53769408Sache | LONG 53869408Sache { $$ = $1; } 53969408Sache | SHORT 54069408Sache { $$ = $1; } 54169408Sache | BYTE 54269408Sache { $$ = $1; } 543195609Smp ; 544195609Smp 545195609Smpfill_opt: 546195609Smp '=' mustbe_exp 547195609Smp { 548195609Smp $$ = exp_get_value_int($2, 54969408Sache 0, 55069408Sache "fill value", 55169408Sache lang_first_phase_enum); 55269408Sache } 55369408Sache | { $$ = 0; } 554195609Smp ; 555195609Smp 556100616Smp 557100616Smp 55869408Sacheassign_op: 55969408Sache PLUSEQ 56069408Sache { $$ = '+'; } 56169408Sache | MINUSEQ 56269408Sache { $$ = '-'; } 56369408Sache | MULTEQ 56469408Sache { $$ = '*'; } 565100616Smp | DIVEQ 56669408Sache { $$ = '/'; } 56769408Sache | LSHIFTEQ 568195609Smp { $$ = LSHIFT; } 56969408Sache | RSHIFTEQ 57069408Sache { $$ = RSHIFT; } 571195609Smp | ANDEQ 57269408Sache { $$ = '&'; } 57369408Sache | OREQ 574195609Smp { $$ = '|'; } 575100616Smp 57669408Sache ; 577195609Smp 57869408Sacheend: ';' | ',' 57969408Sache ; 580195609Smp 58169408Sache 58269408Sacheassignment: 583195609Smp NAME '=' mustbe_exp 58469408Sache { 58569408Sache lang_add_assignment (exp_assop ($2, $1, $3)); 586195609Smp } 58769408Sache | NAME assign_op mustbe_exp 58869408Sache { 589195609Smp lang_add_assignment (exp_assop ('=', $1, 59069408Sache exp_binop ($2, 591100616Smp exp_nameop (NAME, 59269408Sache $1), 59369408Sache $3))); 59469408Sache } 59583098Smp | PROVIDE '(' NAME '=' mustbe_exp ')' 596100616Smp { 597100616Smp lang_add_assignment (exp_provide ($3, $5)); 598100616Smp } 599100616Smp ; 600100616Smp 601100616Smp 602100616Smpopt_comma: 603100616Smp ',' | ; 604100616Smp 605100616Smp 606100616Smpmemory: 607100616Smp MEMORY '{' memory_spec memory_spec_list '}' 608100616Smp ; 609100616Smp 610100616Smpmemory_spec_list: 611100616Smp memory_spec_list memory_spec 612100616Smp | memory_spec_list ',' memory_spec 613100616Smp | 614100616Smp ; 61569408Sache 61669408Sache 61783098Smpmemory_spec: NAME 61869408Sache { region = lang_memory_region_lookup($1); } 61969408Sache attributes_opt ':' 62069408Sache origin_spec opt_comma length_spec 62169408Sache 62283098Smp ; origin_spec: 62369408Sache ORIGIN '=' mustbe_exp 62483098Smp { region->current = 62583098Smp region->origin = 62669408Sache exp_get_vma($3, 0L,"origin", lang_first_phase_enum); 62769408Sache} 62869408Sache ; 62983098Smp 63069408Sachelength_spec: 63183098Smp LENGTH '=' mustbe_exp 63269408Sache { region->length = exp_get_vma($3, 63369408Sache ~((bfd_vma)0), 63469408Sache "length", 63569408Sache lang_first_phase_enum); 63669408Sache } 63769408Sache ; 63869408Sache 63983098Smpattributes_opt: 64069408Sache /* empty */ 64169408Sache { /* dummy action to avoid bison 1.25 error message */ } 64269408Sache | '(' attributes_list ')' 64369408Sache ; 64469408Sache 645195609Smpattributes_list: 646195609Smp attributes_string 647100616Smp | attributes_list attributes_string 64869408Sache ; 649195609Smp 650195609Smpattributes_string: 651195609Smp NAME 652195609Smp { lang_set_flags (region, $1, 0); } 653195609Smp | '!' NAME 654195609Smp { lang_set_flags (region, $2, 1); } 655195609Smp ; 656195609Smp 657195609Smpstartup: 658195609Smp STARTUP '(' filename ')' 659195609Smp { lang_startup($3); } 660195609Smp ; 661195609Smp 662195609Smphigh_level_library: 663195609Smp HLL '(' high_level_library_NAME_list ')' 664195609Smp | HLL '(' ')' 665195609Smp { ldemul_hll((char *)NULL); } 666195609Smp ; 667195609Smp 668195609Smphigh_level_library_NAME_list: 669195609Smp high_level_library_NAME_list opt_comma filename 67069408Sache { ldemul_hll($3); } 671195609Smp | filename 672100616Smp { ldemul_hll($1); } 673100616Smp 674100616Smp ; 675195609Smp 67669408Sachelow_level_library: 677100616Smp SYSLIB '(' low_level_library_NAME_list ')' 67883098Smp ; low_level_library_NAME_list: 67969408Sache low_level_library_NAME_list opt_comma filename 68069408Sache { ldemul_syslib($3); } 68169408Sache | 68269408Sache ; 68369408Sache 68469408Sachefloating_point_support: 68569408Sache FLOAT 68669408Sache { lang_float(true); } 68769408Sache | NOFLOAT 68869408Sache { lang_float(false); } 68969408Sache ; 69069408Sache 69169408Sachenocrossref_list: 69269408Sache /* empty */ 69369408Sache { 69469408Sache $$ = NULL; 69569408Sache } 69669408Sache | NAME nocrossref_list 69769408Sache { 69869408Sache struct lang_nocrossref *n; 69969408Sache 70069408Sache n = (struct lang_nocrossref *) xmalloc (sizeof *n); 70169408Sache n->name = $1; 70269408Sache n->next = $2; 703195609Smp $$ = n; 704195609Smp } 70569408Sache | NAME ',' nocrossref_list 706195609Smp { 70769408Sache struct lang_nocrossref *n; 70869408Sache 709195609Smp n = (struct lang_nocrossref *) xmalloc (sizeof *n); 71069408Sache n->name = $1; 71169408Sache n->next = $3; 712195609Smp $$ = n; 713100616Smp } 71483098Smp ; 715195609Smp 71669408Sachemustbe_exp: { ldlex_expression(); } 71769408Sache exp 718195609Smp { ldlex_popstate(); $$=$2;} 71969408Sache ; 72069408Sache 721195609Smpexp : 722100616Smp '-' exp %prec UNARY 72369408Sache { $$ = exp_unop('-', $2); } 72469408Sache | '(' exp ')' 72569408Sache { $$ = $2; } 72669408Sache | NEXT '(' exp ')' %prec UNARY 72769408Sache { $$ = exp_unop((int) $1,$3); } 728195609Smp | '!' exp %prec UNARY 72969408Sache { $$ = exp_unop('!', $2); } 73069408Sache | '+' exp %prec UNARY 731195609Smp { $$ = $2; } 73283098Smp | '~' exp %prec UNARY 73369408Sache { $$ = exp_unop('~', $2);} 734195609Smp 73583098Smp | exp '*' exp 73683098Smp { $$ = exp_binop('*', $1, $3); } 73769408Sache | exp '/' exp 73869408Sache { $$ = exp_binop('/', $1, $3); } 73969408Sache | exp '%' exp 740195609Smp { $$ = exp_binop('%', $1, $3); } 74183098Smp | exp '+' exp 74269408Sache { $$ = exp_binop('+', $1, $3); } 743195609Smp | exp '-' exp 74483098Smp { $$ = exp_binop('-' , $1, $3); } 74569408Sache | exp LSHIFT exp 746195609Smp { $$ = exp_binop(LSHIFT , $1, $3); } 74783098Smp | exp RSHIFT exp 74869408Sache { $$ = exp_binop(RSHIFT , $1, $3); } 749195609Smp | exp EQ exp 75069408Sache { $$ = exp_binop(EQ , $1, $3); } 751100616Smp | exp NE exp 752195609Smp { $$ = exp_binop(NE , $1, $3); } 75369408Sache | exp LE exp 75469408Sache { $$ = exp_binop(LE , $1, $3); } 75569408Sache | exp GE exp 756100616Smp { $$ = exp_binop(GE , $1, $3); } 757100616Smp | exp '<' exp 758195609Smp { $$ = exp_binop('<' , $1, $3); } 75969408Sache | exp '>' exp 760100616Smp { $$ = exp_binop('>' , $1, $3); } 761195609Smp | exp '&' exp 76283098Smp { $$ = exp_binop('&' , $1, $3); } 763100616Smp | exp '^' exp 764195609Smp { $$ = exp_binop('^' , $1, $3); } 765100616Smp | exp '|' exp 766100616Smp { $$ = exp_binop('|' , $1, $3); } 767195609Smp | exp '?' exp ':' exp 768195609Smp { $$ = exp_trinop('?' , $1, $3, $5); } 769195609Smp | exp ANDAND exp 770195609Smp { $$ = exp_binop(ANDAND , $1, $3); } 771100616Smp | exp OROR exp 772100616Smp { $$ = exp_binop(OROR , $1, $3); } 77383098Smp | DEFINED '(' NAME ')' 77469408Sache { $$ = exp_nameop(DEFINED, $3); } 775100616Smp | INT 776195609Smp { $$ = exp_intop($1); } 777195609Smp | SIZEOF_HEADERS 778195609Smp { $$ = exp_nameop(SIZEOF_HEADERS,0); } 779195609Smp 780195609Smp | SIZEOF '(' NAME ')' 781195609Smp { $$ = exp_nameop(SIZEOF,$3); } 782100616Smp | ADDR '(' NAME ')' 78383098Smp { $$ = exp_nameop(ADDR,$3); } 784195609Smp | LOADADDR '(' NAME ')' 78569408Sache { $$ = exp_nameop(LOADADDR,$3); } 78669408Sache | ABSOLUTE '(' exp ')' 787195609Smp { $$ = exp_unop(ABSOLUTE, $3); } 78883098Smp | ALIGN_K '(' exp ')' 78983098Smp { $$ = exp_unop(ALIGN_K,$3); } 790195609Smp | BLOCK '(' exp ')' 79169408Sache { $$ = exp_unop(ALIGN_K,$3); } 792195609Smp | NAME 793195609Smp { $$ = exp_nameop(NAME,$1); } 794195609Smp | MAX_K '(' exp ',' exp ')' 795195609Smp { $$ = exp_binop (MAX_K, $3, $5 ); } 796195609Smp | MIN_K '(' exp ',' exp ')' 797195609Smp { $$ = exp_binop (MIN_K, $3, $5 ); } 798195609Smp | ASSERT_K '(' exp ',' NAME ')' 799195609Smp { $$ = exp_assert ($3, $5); } 800195609Smp ; 80169408Sache 80269408Sache 803195609Smpmemspec_at_opt: 804195609Smp AT '>' NAME { $$ = $3; } 80569408Sache | { $$ = "*default*"; } 806195609Smp ; 807195609Smp 808195609Smpopt_at: 809195609Smp AT '(' exp ')' { $$ = $3; } 810195609Smp | { $$ = 0; } 811100616Smp ; 812100616Smp 813195609Smpsection: NAME { ldlex_expression(); } 814231990Smp opt_exp_with_type 815195609Smp opt_at { ldlex_popstate (); ldlex_script (); } 816195609Smp '{' 817195609Smp { 818195609Smp lang_enter_output_section_statement($1, $3, 819231990Smp sectype, 820195609Smp 0, 0, 0, $4); 821195609Smp } 822195609Smp statement_list_opt 823195609Smp '}' { ldlex_popstate (); ldlex_expression (); } 824195609Smp memspec_opt memspec_at_opt phdr_opt fill_opt 825195609Smp { 826195609Smp ldlex_popstate (); 827195609Smp lang_leave_output_section_statement ($14, $11, $13, $12); 828195609Smp } 829195609Smp opt_comma 830195609Smp | OVERLAY 831195609Smp { ldlex_expression (); } 83283098Smp opt_exp_without_type opt_nocrossrefs opt_at 83383098Smp { ldlex_popstate (); ldlex_script (); } 83483098Smp '{' 83583098Smp { 836195609Smp lang_enter_overlay ($3, $5, (int) $4); 837195609Smp } 83883098Smp overlay_section 83983098Smp '}' 840195609Smp { ldlex_popstate (); ldlex_expression (); } 841195609Smp memspec_opt memspec_at_opt phdr_opt fill_opt 842195609Smp { 843195609Smp ldlex_popstate (); 84469408Sache lang_leave_overlay ($15, $12, $14, $13); 84569408Sache } 846195609Smp opt_comma 84769408Sache | /* The GROUP case is just enough to support the gcc 84869408Sache svr3.ifile script. It is not intended to be full 849195609Smp support. I'm not even sure what GROUP is supposed 85069408Sache to mean. */ 851195609Smp GROUP { ldlex_expression (); } 85269408Sache opt_exp_with_type 853195609Smp { 854195609Smp ldlex_popstate (); 855195609Smp lang_add_assignment (exp_assop ('=', ".", $3)); 856195609Smp } 857195609Smp '{' sec_or_group_p1 '}' 858100616Smp ; 859100616Smp 860195609Smptype: 861231990Smp NOLOAD { sectype = noload_section; } 862231990Smp | DSECT { sectype = dsect_section; } 863231990Smp | COPY { sectype = copy_section; } 864231990Smp | INFO { sectype = info_section; } 865231990Smp | OVERLAY { sectype = overlay_section; } 866231990Smp ; 867231990Smp 868231990Smpatype: 869231990Smp '(' type ')' 870231990Smp | /* EMPTY */ { sectype = normal_section; } 871231990Smp | '(' ')' { sectype = normal_section; } 872231990Smp ; 873231990Smp 874231990Smpopt_exp_with_type: 875100616Smp exp atype ':' { $$ = $1; } 876195609Smp | atype ':' { $$ = (etree_type *)NULL; } 877195609Smp | /* The BIND cases are to support the gcc svr3.ifile 878195609Smp script. They aren't intended to implement full 879195609Smp support for the BIND keyword. I'm not even sure 880195609Smp what BIND is supposed to mean. */ 881195609Smp BIND '(' exp ')' atype ':' { $$ = $3; } 882195609Smp | BIND '(' exp ')' BLOCK '(' exp ')' atype ':' 883195609Smp { $$ = $3; } 884195609Smp ; 885195609Smp 886100616Smpopt_exp_without_type: 887195609Smp exp ':' { $$ = $1; } 888195609Smp | ':' { $$ = (etree_type *) NULL; } 889195609Smp ; 890195609Smp 891195609Smpopt_nocrossrefs: 892195609Smp /* empty */ 893195609Smp { $$ = 0; } 894195609Smp | NOCROSSREFS 895195609Smp { $$ = 1; } 896195609Smp ; 897231990Smp 898231990Smpmemspec_opt: 899231990Smp '>' NAME 900231990Smp { $$ = $2; } 901231990Smp | { $$ = "*default*"; } 902231990Smp ; 903231990Smp 904231990Smpphdr_opt: 905231990Smp /* empty */ 906231990Smp { 907231990Smp $$ = NULL; 908100616Smp } 909100616Smp | phdr_opt ':' NAME 910195609Smp { 911195609Smp struct lang_output_section_phdr_list *n; 912195609Smp 913195609Smp n = ((struct lang_output_section_phdr_list *) 914100616Smp xmalloc (sizeof *n)); 915100616Smp n->name = $3; 916195609Smp n->used = false; 917195609Smp n->next = $1; 918100616Smp $$ = n; 919100616Smp } 920100616Smp ; 921195609Smp 922195609Smpoverlay_section: 923100616Smp /* empty */ 924195609Smp | overlay_section 925100616Smp NAME 926100616Smp { 927195609Smp ldlex_script (); 928100616Smp lang_enter_overlay_section ($2); 929100616Smp } 930100616Smp '{' statement_list_opt '}' 931100616Smp { ldlex_popstate (); ldlex_expression (); } 932100616Smp phdr_opt fill_opt 933231990Smp { 934195609Smp ldlex_popstate (); 935100616Smp lang_leave_overlay_section ($9, $8); 936195609Smp } 937195609Smp opt_comma 938195609Smp ; 939195609Smp 940195609Smpphdrs: 941195609Smp PHDRS '{' phdr_list '}' 942231990Smp ; 943231990Smp 944231990Smpphdr_list: 945100616Smp /* empty */ 946100616Smp | phdr_list phdr 947100616Smp ; 948100616Smp 949100616Smpphdr: 950100616Smp NAME { ldlex_expression (); } 951100616Smp phdr_type phdr_qualifiers { ldlex_popstate (); } 952195609Smp ';' 953231990Smp { 954231990Smp lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at, 955195609Smp $4.flags); 956231990Smp } 957231990Smp ; 958231990Smp 959100616Smpphdr_type: 960100616Smp exp 961195609Smp { 962195609Smp $$ = $1; 963195609Smp 964195609Smp if ($1->type.node_class == etree_name 965100616Smp && $1->type.node_code == NAME) 966100616Smp { 967195609Smp const char *s; 968100616Smp unsigned int i; 969100616Smp static const char * const phdr_types[] = 970195609Smp { 971195609Smp "PT_NULL", "PT_LOAD", "PT_DYNAMIC", 972195609Smp "PT_INTERP", "PT_NOTE", "PT_SHLIB", 973195609Smp "PT_PHDR" 974100616Smp }; 975100616Smp 976195609Smp s = $1->name.name; 977195609Smp for (i = 0; 978195609Smp i < sizeof phdr_types / sizeof phdr_types[0]; 979195609Smp i++) 980100616Smp if (strcmp (s, phdr_types[i]) == 0) 981100616Smp { 982100616Smp $$ = exp_intop (i); 983100616Smp break; 98469408Sache } 985195609Smp } 986100616Smp } 98769408Sache ; 98869408Sache 98969408Sachephdr_qualifiers: 99069408Sache /* empty */ 99169408Sache { 99269408Sache memset (&$$, 0, sizeof (struct phdr_info)); 993195609Smp } 994195609Smp | NAME phdr_val phdr_qualifiers 995195609Smp { 996195609Smp $$ = $3; 997195609Smp if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL) 998195609Smp $$.filehdr = true; 999195609Smp else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL) 1000195609Smp $$.phdrs = true; 1001195609Smp else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL) 1002195609Smp $$.flags = $2; 1003195609Smp else 1004195609Smp einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1); 1005195609Smp } 1006195609Smp | AT '(' exp ')' phdr_qualifiers 1007195609Smp { 1008195609Smp $$ = $5; 1009195609Smp $$.at = $3; 1010195609Smp } 1011195609Smp ; 1012195609Smp 1013195609Smpphdr_val: 1014100616Smp /* empty */ 101583098Smp { 101669408Sache $$ = NULL; 101783098Smp } 101869408Sache | '(' exp ')' 101983098Smp { 102069408Sache $$ = $2; 1021195609Smp } 1022195609Smp ; 1023195609Smp 1024100616Smp/* This syntax is used within an external version script file. */ 1025100616Smp 1026100616Smpversion_script_file: 1027100616Smp { 1028100616Smp ldlex_version_file (); 1029100616Smp PUSH_ERROR (_("VERSION script")); 1030195609Smp } 1031100616Smp vers_nodes 103269408Sache { 103369408Sache ldlex_popstate (); 103469408Sache POP_ERROR (); 103569408Sache } 1036100616Smp ; 1037100616Smp 1038100616Smp/* This is used within a normal linker script file. */ 103969408Sache 1040100616Smpversion: 104183098Smp { 1042100616Smp ldlex_version_script (); 104383098Smp } 104469408Sache VERSIONK '{' vers_nodes '}' 104569408Sache { 104669408Sache ldlex_popstate (); 104769408Sache } 1048195609Smp ; 104969408Sache 1050100616Smpvers_nodes: 105169408Sache vers_node 1052195609Smp | vers_nodes vers_node 1053195609Smp ; 1054195609Smp 1055195609Smpvers_node: 1056195609Smp VERS_TAG '{' vers_tag '}' ';' 1057195609Smp { 105869408Sache lang_register_vers_node ($1, $3, NULL); 105969408Sache } 1060195609Smp | VERS_TAG '{' vers_tag '}' verdep ';' 106169408Sache { 106269408Sache lang_register_vers_node ($1, $3, $5); 1063195609Smp } 106469408Sache ; 106569408Sache 106669408Sacheverdep: 106769408Sache VERS_TAG 106869408Sache { 106969408Sache $$ = lang_add_vers_depend (NULL, $1); 1070195609Smp } 107169408Sache | verdep VERS_TAG 107269408Sache { 107369408Sache $$ = lang_add_vers_depend ($1, $2); 1074195609Smp } 1075195609Smp ; 1076195609Smp 1077195609Smpvers_tag: 1078195609Smp /* empty */ 1079195609Smp { 1080195609Smp $$ = lang_new_vers_node (NULL, NULL); 1081195609Smp } 1082195609Smp | vers_defns ';' 1083195609Smp { 108469408Sache $$ = lang_new_vers_node ($1, NULL); 108569408Sache } 108669408Sache | GLOBAL ':' vers_defns ';' 108769408Sache { 1088195609Smp $$ = lang_new_vers_node ($3, NULL); 108969408Sache } 1090195609Smp | LOCAL ':' vers_defns ';' 109169408Sache { 109269408Sache $$ = lang_new_vers_node (NULL, $3); 1093195609Smp } 1094195609Smp | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';' 1095195609Smp { 1096195609Smp $$ = lang_new_vers_node ($3, $7); 1097195609Smp } 1098195609Smp ; 1099195609Smp 1100195609Smpvers_defns: 1101195609Smp VERS_IDENTIFIER 1102195609Smp { 1103195609Smp $$ = lang_new_vers_regex (NULL, $1, ldgram_vers_current_lang); 1104100616Smp } 110569408Sache | vers_defns ';' VERS_IDENTIFIER 1106195609Smp { 110769408Sache $$ = lang_new_vers_regex ($1, $3, ldgram_vers_current_lang); 110869408Sache } 1109195609Smp | EXTERN NAME '{' 111069408Sache { 111169408Sache $<name>$ = ldgram_vers_current_lang; 1112195609Smp ldgram_vers_current_lang = $2; 1113100616Smp } 111469408Sache vers_defns '}' 1115195609Smp { 1116195609Smp ldgram_vers_current_lang = $<name>4; 1117100616Smp } 1118195609Smp ; 111969408Sache 112069408Sache%% 1121195609Smpvoid 112283098Smpyyerror(arg) 112383098Smp const char *arg; 1124195609Smp{ 112569408Sache if (ldfile_assumed_script) 112669408Sache einfo (_("%P:%s: file format not recognized; treating as linker script\n"), 1127195609Smp ldfile_input_filename); 112869408Sache if (error_index > 0 && error_index < ERROR_NAME_MAX) 112969408Sache einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]); 113069408Sache else 113169408Sache einfo ("%P%F:%S: %s\n", arg); 113269408Sache} 113369408Sache