1/* A YACC grammar to parse a superset of the AT&T linker scripting language. 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 4 Free Software Foundation, Inc. 5 Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com). 6 7 This file is part of the GNU Binutils. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22 MA 02110-1301, USA. */ 23 24%{ 25/* 26 27 */ 28 29#define DONTDECLARE_MALLOC 30 31#include "sysdep.h" 32#include "bfd.h" 33#include "bfdlink.h" 34#include "ld.h" 35#include "ldexp.h" 36#include "ldver.h" 37#include "ldlang.h" 38#include "ldfile.h" 39#include "ldemul.h" 40#include "ldmisc.h" 41#include "ldmain.h" 42#include "mri.h" 43#include "ldctor.h" 44#include "ldlex.h" 45 46#ifndef YYDEBUG 47#define YYDEBUG 1 48#endif 49 50static enum section_type sectype; 51static lang_memory_region_type *region; 52 53bfd_boolean ldgram_had_keep = FALSE; 54char *ldgram_vers_current_lang = NULL; 55 56#define ERROR_NAME_MAX 20 57static char *error_names[ERROR_NAME_MAX]; 58static int error_index; 59#define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++; 60#define POP_ERROR() error_index--; 61%} 62%union { 63 bfd_vma integer; 64 struct big_int 65 { 66 bfd_vma integer; 67 char *str; 68 } bigint; 69 fill_type *fill; 70 char *name; 71 const char *cname; 72 struct wildcard_spec wildcard; 73 struct wildcard_list *wildcard_list; 74 struct name_list *name_list; 75 int token; 76 union etree_union *etree; 77 struct phdr_info 78 { 79 bfd_boolean filehdr; 80 bfd_boolean phdrs; 81 union etree_union *at; 82 union etree_union *flags; 83 } phdr; 84 struct lang_nocrossref *nocrossref; 85 struct lang_output_section_phdr_list *section_phdr; 86 struct bfd_elf_version_deps *deflist; 87 struct bfd_elf_version_expr *versyms; 88 struct bfd_elf_version_tree *versnode; 89} 90 91%type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val 92%type <etree> opt_exp_without_type opt_subalign opt_align 93%type <fill> fill_opt fill_exp 94%type <name_list> exclude_name_list 95%type <wildcard_list> file_NAME_list 96%type <name> memspec_opt casesymlist 97%type <name> memspec_at_opt 98%type <cname> wildcard_name 99%type <wildcard> wildcard_spec 100%token <bigint> INT 101%token <name> NAME LNAME 102%type <integer> length 103%type <phdr> phdr_qualifiers 104%type <nocrossref> nocrossref_list 105%type <section_phdr> phdr_opt 106%type <integer> opt_nocrossrefs 107 108%right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ 109%right <token> '?' ':' 110%left <token> OROR 111%left <token> ANDAND 112%left <token> '|' 113%left <token> '^' 114%left <token> '&' 115%left <token> EQ NE 116%left <token> '<' '>' LE GE 117%left <token> LSHIFT RSHIFT 118 119%left <token> '+' '-' 120%left <token> '*' '/' '%' 121 122%right UNARY 123%token END 124%left <token> '(' 125%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE 126%token SECTIONS PHDRS INSERT_K AFTER BEFORE 127%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END 128%token SORT_BY_NAME SORT_BY_ALIGNMENT 129%token '{' '}' 130%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH 131%token INHIBIT_COMMON_ALLOCATION 132%token SEGMENT_START 133%token INCLUDE 134%token MEMORY 135%token REGION_ALIAS 136%token LD_FEATURE 137%token NOLOAD DSECT COPY INFO OVERLAY 138%token DEFINED TARGET_K SEARCH_DIR MAP ENTRY 139%token <integer> NEXT 140%token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K 141%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS 142%token ORIGIN FILL 143%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS 144%token ALIGNMOD AT SUBALIGN PROVIDE PROVIDE_HIDDEN AS_NEEDED 145%type <token> assign_op atype attributes_opt sect_constraint 146%type <name> filename 147%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K 148%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL 149%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START 150%token <name> VERS_TAG VERS_IDENTIFIER 151%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT 152%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL 153%token EXCLUDE_FILE 154%token CONSTANT 155%type <versyms> vers_defns 156%type <versnode> vers_tag 157%type <deflist> verdep 158%token INPUT_DYNAMIC_LIST 159 160%% 161 162file: 163 INPUT_SCRIPT script_file 164 | INPUT_MRI_SCRIPT mri_script_file 165 | INPUT_VERSION_SCRIPT version_script_file 166 | INPUT_DYNAMIC_LIST dynamic_list_file 167 | INPUT_DEFSYM defsym_expr 168 ; 169 170 171filename: NAME; 172 173 174defsym_expr: 175 { ldlex_defsym(); } 176 NAME '=' exp 177 { 178 ldlex_popstate(); 179 lang_add_assignment (exp_defsym ($2, $4)); 180 } 181 ; 182 183/* SYNTAX WITHIN AN MRI SCRIPT FILE */ 184mri_script_file: 185 { 186 ldlex_mri_script (); 187 PUSH_ERROR (_("MRI style script")); 188 } 189 mri_script_lines 190 { 191 ldlex_popstate (); 192 mri_draw_tree (); 193 POP_ERROR (); 194 } 195 ; 196 197mri_script_lines: 198 mri_script_lines mri_script_command NEWLINE 199 | 200 ; 201 202mri_script_command: 203 CHIP exp 204 | CHIP exp ',' exp 205 | NAME { 206 einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1); 207 } 208 | LIST { 209 config.map_filename = "-"; 210 } 211 | ORDER ordernamelist 212 | ENDWORD 213 | PUBLIC NAME '=' exp 214 { mri_public($2, $4); } 215 | PUBLIC NAME ',' exp 216 { mri_public($2, $4); } 217 | PUBLIC NAME exp 218 { mri_public($2, $3); } 219 | FORMAT NAME 220 { mri_format($2); } 221 | SECT NAME ',' exp 222 { mri_output_section($2, $4);} 223 | SECT NAME exp 224 { mri_output_section($2, $3);} 225 | SECT NAME '=' exp 226 { mri_output_section($2, $4);} 227 | ALIGN_K NAME '=' exp 228 { mri_align($2,$4); } 229 | ALIGN_K NAME ',' exp 230 { mri_align($2,$4); } 231 | ALIGNMOD NAME '=' exp 232 { mri_alignmod($2,$4); } 233 | ALIGNMOD NAME ',' exp 234 { mri_alignmod($2,$4); } 235 | ABSOLUTE mri_abs_name_list 236 | LOAD mri_load_name_list 237 | NAMEWORD NAME 238 { mri_name($2); } 239 | ALIAS NAME ',' NAME 240 { mri_alias($2,$4,0);} 241 | ALIAS NAME ',' INT 242 { mri_alias ($2, 0, (int) $4.integer); } 243 | BASE exp 244 { mri_base($2); } 245 | TRUNCATE INT 246 { mri_truncate ((unsigned int) $2.integer); } 247 | CASE casesymlist 248 | EXTERN extern_name_list 249 | INCLUDE filename 250 { ldlex_script (); ldfile_open_command_file($2); } 251 mri_script_lines END 252 { ldlex_popstate (); } 253 | START NAME 254 { lang_add_entry ($2, FALSE); } 255 | 256 ; 257 258ordernamelist: 259 ordernamelist ',' NAME { mri_order($3); } 260 | ordernamelist NAME { mri_order($2); } 261 | 262 ; 263 264mri_load_name_list: 265 NAME 266 { mri_load($1); } 267 | mri_load_name_list ',' NAME { mri_load($3); } 268 ; 269 270mri_abs_name_list: 271 NAME 272 { mri_only_load($1); } 273 | mri_abs_name_list ',' NAME 274 { mri_only_load($3); } 275 ; 276 277casesymlist: 278 /* empty */ { $$ = NULL; } 279 | NAME 280 | casesymlist ',' NAME 281 ; 282 283/* Parsed as expressions so that commas separate entries */ 284extern_name_list: 285 { ldlex_expression (); } 286 extern_name_list_body 287 { ldlex_popstate (); } 288 289extern_name_list_body: 290 NAME 291 { ldlang_add_undef ($1, FALSE); } 292 | extern_name_list_body NAME 293 { ldlang_add_undef ($2, FALSE); } 294 | extern_name_list_body ',' NAME 295 { ldlang_add_undef ($3, FALSE); } 296 ; 297 298script_file: 299 { ldlex_both(); } 300 ifile_list 301 { ldlex_popstate(); } 302 ; 303 304ifile_list: 305 ifile_list ifile_p1 306 | 307 ; 308 309 310ifile_p1: 311 memory 312 | sections 313 | phdrs 314 | startup 315 | high_level_library 316 | low_level_library 317 | floating_point_support 318 | statement_anywhere 319 | version 320 | ';' 321 | TARGET_K '(' NAME ')' 322 { lang_add_target($3); } 323 | SEARCH_DIR '(' filename ')' 324 { ldfile_add_library_path ($3, FALSE); } 325 | OUTPUT '(' filename ')' 326 { lang_add_output($3, 1); } 327 | OUTPUT_FORMAT '(' NAME ')' 328 { lang_add_output_format ($3, (char *) NULL, 329 (char *) NULL, 1); } 330 | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')' 331 { lang_add_output_format ($3, $5, $7, 1); } 332 | OUTPUT_ARCH '(' NAME ')' 333 { ldfile_set_output_arch ($3, bfd_arch_unknown); } 334 | FORCE_COMMON_ALLOCATION 335 { command_line.force_common_definition = TRUE ; } 336 | INHIBIT_COMMON_ALLOCATION 337 { command_line.inhibit_common_definition = TRUE ; } 338 | INPUT '(' input_list ')' 339 | GROUP 340 { lang_enter_group (); } 341 '(' input_list ')' 342 { lang_leave_group (); } 343 | MAP '(' filename ')' 344 { lang_add_map($3); } 345 | INCLUDE filename 346 { ldlex_script (); ldfile_open_command_file($2); } 347 ifile_list END 348 { ldlex_popstate (); } 349 | NOCROSSREFS '(' nocrossref_list ')' 350 { 351 lang_add_nocrossref ($3); 352 } 353 | EXTERN '(' extern_name_list ')' 354 | INSERT_K AFTER NAME 355 { lang_add_insert ($3, 0); } 356 | INSERT_K BEFORE NAME 357 { lang_add_insert ($3, 1); } 358 | REGION_ALIAS '(' NAME ',' NAME ')' 359 { lang_memory_region_alias ($3, $5); } 360 | LD_FEATURE '(' NAME ')' 361 { lang_ld_feature ($3); } 362 ; 363 364input_list: 365 NAME 366 { lang_add_input_file($1,lang_input_file_is_search_file_enum, 367 (char *)NULL); } 368 | input_list ',' NAME 369 { lang_add_input_file($3,lang_input_file_is_search_file_enum, 370 (char *)NULL); } 371 | input_list NAME 372 { lang_add_input_file($2,lang_input_file_is_search_file_enum, 373 (char *)NULL); } 374 | LNAME 375 { lang_add_input_file($1,lang_input_file_is_l_enum, 376 (char *)NULL); } 377 | input_list ',' LNAME 378 { lang_add_input_file($3,lang_input_file_is_l_enum, 379 (char *)NULL); } 380 | input_list LNAME 381 { lang_add_input_file($2,lang_input_file_is_l_enum, 382 (char *)NULL); } 383 | AS_NEEDED '(' 384 { $<integer>$ = add_DT_NEEDED_for_regular; add_DT_NEEDED_for_regular = TRUE; } 385 input_list ')' 386 { add_DT_NEEDED_for_regular = $<integer>3; } 387 | input_list ',' AS_NEEDED '(' 388 { $<integer>$ = add_DT_NEEDED_for_regular; add_DT_NEEDED_for_regular = TRUE; } 389 input_list ')' 390 { add_DT_NEEDED_for_regular = $<integer>5; } 391 | input_list AS_NEEDED '(' 392 { $<integer>$ = add_DT_NEEDED_for_regular; add_DT_NEEDED_for_regular = TRUE; } 393 input_list ')' 394 { add_DT_NEEDED_for_regular = $<integer>4; } 395 ; 396 397sections: 398 SECTIONS '{' sec_or_group_p1 '}' 399 ; 400 401sec_or_group_p1: 402 sec_or_group_p1 section 403 | sec_or_group_p1 statement_anywhere 404 | 405 ; 406 407statement_anywhere: 408 ENTRY '(' NAME ')' 409 { lang_add_entry ($3, FALSE); } 410 | assignment end 411 | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')' 412 { ldlex_popstate (); 413 lang_add_assignment (exp_assert ($4, $6)); } 414 ; 415 416/* The '*' and '?' cases are there because the lexer returns them as 417 separate tokens rather than as NAME. */ 418wildcard_name: 419 NAME 420 { 421 $$ = $1; 422 } 423 | '*' 424 { 425 $$ = "*"; 426 } 427 | '?' 428 { 429 $$ = "?"; 430 } 431 ; 432 433wildcard_spec: 434 wildcard_name 435 { 436 $$.name = $1; 437 $$.sorted = none; 438 $$.exclude_name_list = NULL; 439 } 440 | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name 441 { 442 $$.name = $5; 443 $$.sorted = none; 444 $$.exclude_name_list = $3; 445 } 446 | SORT_BY_NAME '(' wildcard_name ')' 447 { 448 $$.name = $3; 449 $$.sorted = by_name; 450 $$.exclude_name_list = NULL; 451 } 452 | SORT_BY_ALIGNMENT '(' wildcard_name ')' 453 { 454 $$.name = $3; 455 $$.sorted = by_alignment; 456 $$.exclude_name_list = NULL; 457 } 458 | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' 459 { 460 $$.name = $5; 461 $$.sorted = by_name_alignment; 462 $$.exclude_name_list = NULL; 463 } 464 | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')' 465 { 466 $$.name = $5; 467 $$.sorted = by_name; 468 $$.exclude_name_list = NULL; 469 } 470 | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')' 471 { 472 $$.name = $5; 473 $$.sorted = by_alignment_name; 474 $$.exclude_name_list = NULL; 475 } 476 | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' 477 { 478 $$.name = $5; 479 $$.sorted = by_alignment; 480 $$.exclude_name_list = NULL; 481 } 482 | SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')' 483 { 484 $$.name = $7; 485 $$.sorted = by_name; 486 $$.exclude_name_list = $5; 487 } 488 ; 489 490exclude_name_list: 491 exclude_name_list wildcard_name 492 { 493 struct name_list *tmp; 494 tmp = (struct name_list *) xmalloc (sizeof *tmp); 495 tmp->name = $2; 496 tmp->next = $1; 497 $$ = tmp; 498 } 499 | 500 wildcard_name 501 { 502 struct name_list *tmp; 503 tmp = (struct name_list *) xmalloc (sizeof *tmp); 504 tmp->name = $1; 505 tmp->next = NULL; 506 $$ = tmp; 507 } 508 ; 509 510file_NAME_list: 511 file_NAME_list opt_comma wildcard_spec 512 { 513 struct wildcard_list *tmp; 514 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); 515 tmp->next = $1; 516 tmp->spec = $3; 517 $$ = tmp; 518 } 519 | 520 wildcard_spec 521 { 522 struct wildcard_list *tmp; 523 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); 524 tmp->next = NULL; 525 tmp->spec = $1; 526 $$ = tmp; 527 } 528 ; 529 530input_section_spec_no_keep: 531 NAME 532 { 533 struct wildcard_spec tmp; 534 tmp.name = $1; 535 tmp.exclude_name_list = NULL; 536 tmp.sorted = none; 537 lang_add_wild (&tmp, NULL, ldgram_had_keep); 538 } 539 | '[' file_NAME_list ']' 540 { 541 lang_add_wild (NULL, $2, ldgram_had_keep); 542 } 543 | wildcard_spec '(' file_NAME_list ')' 544 { 545 lang_add_wild (&$1, $3, ldgram_had_keep); 546 } 547 ; 548 549input_section_spec: 550 input_section_spec_no_keep 551 | KEEP '(' 552 { ldgram_had_keep = TRUE; } 553 input_section_spec_no_keep ')' 554 { ldgram_had_keep = FALSE; } 555 ; 556 557statement: 558 assignment end 559 | CREATE_OBJECT_SYMBOLS 560 { 561 lang_add_attribute(lang_object_symbols_statement_enum); 562 } 563 | ';' 564 | CONSTRUCTORS 565 { 566 567 lang_add_attribute(lang_constructors_statement_enum); 568 } 569 | SORT_BY_NAME '(' CONSTRUCTORS ')' 570 { 571 constructors_sorted = TRUE; 572 lang_add_attribute (lang_constructors_statement_enum); 573 } 574 | input_section_spec 575 | length '(' mustbe_exp ')' 576 { 577 lang_add_data ((int) $1, $3); 578 } 579 580 | FILL '(' fill_exp ')' 581 { 582 lang_add_fill ($3); 583 } 584 | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')' end 585 { ldlex_popstate (); 586 lang_add_assignment (exp_assert ($4, $6)); } 587 | INCLUDE filename 588 { ldlex_script (); ldfile_open_command_file($2); } 589 statement_list_opt END 590 { ldlex_popstate (); } 591 ; 592 593statement_list: 594 statement_list statement 595 | statement 596 ; 597 598statement_list_opt: 599 /* empty */ 600 | statement_list 601 ; 602 603length: 604 QUAD 605 { $$ = $1; } 606 | SQUAD 607 { $$ = $1; } 608 | LONG 609 { $$ = $1; } 610 | SHORT 611 { $$ = $1; } 612 | BYTE 613 { $$ = $1; } 614 ; 615 616fill_exp: 617 mustbe_exp 618 { 619 $$ = exp_get_fill ($1, 0, "fill value"); 620 } 621 ; 622 623fill_opt: 624 '=' fill_exp 625 { $$ = $2; } 626 | { $$ = (fill_type *) 0; } 627 ; 628 629assign_op: 630 PLUSEQ 631 { $$ = '+'; } 632 | MINUSEQ 633 { $$ = '-'; } 634 | MULTEQ 635 { $$ = '*'; } 636 | DIVEQ 637 { $$ = '/'; } 638 | LSHIFTEQ 639 { $$ = LSHIFT; } 640 | RSHIFTEQ 641 { $$ = RSHIFT; } 642 | ANDEQ 643 { $$ = '&'; } 644 | OREQ 645 { $$ = '|'; } 646 647 ; 648 649end: ';' | ',' 650 ; 651 652 653assignment: 654 NAME '=' mustbe_exp 655 { 656 lang_add_assignment (exp_assign ($1, $3)); 657 } 658 | NAME assign_op mustbe_exp 659 { 660 lang_add_assignment (exp_assign ($1, 661 exp_binop ($2, 662 exp_nameop (NAME, 663 $1), 664 $3))); 665 } 666 | PROVIDE '(' NAME '=' mustbe_exp ')' 667 { 668 lang_add_assignment (exp_provide ($3, $5, FALSE)); 669 } 670 | PROVIDE_HIDDEN '(' NAME '=' mustbe_exp ')' 671 { 672 lang_add_assignment (exp_provide ($3, $5, TRUE)); 673 } 674 ; 675 676 677opt_comma: 678 ',' | ; 679 680 681memory: 682 MEMORY '{' memory_spec_list_opt '}' 683 ; 684 685memory_spec_list_opt: memory_spec_list | ; 686 687memory_spec_list: 688 memory_spec_list opt_comma memory_spec 689 | memory_spec 690 ; 691 692 693memory_spec: NAME 694 { region = lang_memory_region_lookup ($1, TRUE); } 695 attributes_opt ':' 696 origin_spec opt_comma length_spec 697 {} 698 | INCLUDE filename 699 { ldlex_script (); ldfile_open_command_file($2); } 700 memory_spec_list_opt END 701 { ldlex_popstate (); } 702 ; 703 704origin_spec: 705 ORIGIN '=' mustbe_exp 706 { 707 region->origin = exp_get_vma ($3, 0, "origin"); 708 region->current = region->origin; 709 } 710 ; 711 712length_spec: 713 LENGTH '=' mustbe_exp 714 { 715 region->length = exp_get_vma ($3, -1, "length"); 716 } 717 ; 718 719attributes_opt: 720 /* empty */ 721 { /* dummy action to avoid bison 1.25 error message */ } 722 | '(' attributes_list ')' 723 ; 724 725attributes_list: 726 attributes_string 727 | attributes_list attributes_string 728 ; 729 730attributes_string: 731 NAME 732 { lang_set_flags (region, $1, 0); } 733 | '!' NAME 734 { lang_set_flags (region, $2, 1); } 735 ; 736 737startup: 738 STARTUP '(' filename ')' 739 { lang_startup($3); } 740 ; 741 742high_level_library: 743 HLL '(' high_level_library_NAME_list ')' 744 | HLL '(' ')' 745 { ldemul_hll((char *)NULL); } 746 ; 747 748high_level_library_NAME_list: 749 high_level_library_NAME_list opt_comma filename 750 { ldemul_hll($3); } 751 | filename 752 { ldemul_hll($1); } 753 754 ; 755 756low_level_library: 757 SYSLIB '(' low_level_library_NAME_list ')' 758 ; low_level_library_NAME_list: 759 low_level_library_NAME_list opt_comma filename 760 { ldemul_syslib($3); } 761 | 762 ; 763 764floating_point_support: 765 FLOAT 766 { lang_float(TRUE); } 767 | NOFLOAT 768 { lang_float(FALSE); } 769 ; 770 771nocrossref_list: 772 /* empty */ 773 { 774 $$ = NULL; 775 } 776 | NAME nocrossref_list 777 { 778 struct lang_nocrossref *n; 779 780 n = (struct lang_nocrossref *) xmalloc (sizeof *n); 781 n->name = $1; 782 n->next = $2; 783 $$ = n; 784 } 785 | NAME ',' nocrossref_list 786 { 787 struct lang_nocrossref *n; 788 789 n = (struct lang_nocrossref *) xmalloc (sizeof *n); 790 n->name = $1; 791 n->next = $3; 792 $$ = n; 793 } 794 ; 795 796mustbe_exp: { ldlex_expression (); } 797 exp 798 { ldlex_popstate (); $$=$2;} 799 ; 800 801exp : 802 '-' exp %prec UNARY 803 { $$ = exp_unop ('-', $2); } 804 | '(' exp ')' 805 { $$ = $2; } 806 | NEXT '(' exp ')' %prec UNARY 807 { $$ = exp_unop ((int) $1,$3); } 808 | '!' exp %prec UNARY 809 { $$ = exp_unop ('!', $2); } 810 | '+' exp %prec UNARY 811 { $$ = $2; } 812 | '~' exp %prec UNARY 813 { $$ = exp_unop ('~', $2);} 814 815 | exp '*' exp 816 { $$ = exp_binop ('*', $1, $3); } 817 | exp '/' exp 818 { $$ = exp_binop ('/', $1, $3); } 819 | exp '%' exp 820 { $$ = exp_binop ('%', $1, $3); } 821 | exp '+' exp 822 { $$ = exp_binop ('+', $1, $3); } 823 | exp '-' exp 824 { $$ = exp_binop ('-' , $1, $3); } 825 | exp LSHIFT exp 826 { $$ = exp_binop (LSHIFT , $1, $3); } 827 | exp RSHIFT exp 828 { $$ = exp_binop (RSHIFT , $1, $3); } 829 | exp EQ exp 830 { $$ = exp_binop (EQ , $1, $3); } 831 | exp NE exp 832 { $$ = exp_binop (NE , $1, $3); } 833 | exp LE exp 834 { $$ = exp_binop (LE , $1, $3); } 835 | exp GE exp 836 { $$ = exp_binop (GE , $1, $3); } 837 | exp '<' exp 838 { $$ = exp_binop ('<' , $1, $3); } 839 | exp '>' exp 840 { $$ = exp_binop ('>' , $1, $3); } 841 | exp '&' exp 842 { $$ = exp_binop ('&' , $1, $3); } 843 | exp '^' exp 844 { $$ = exp_binop ('^' , $1, $3); } 845 | exp '|' exp 846 { $$ = exp_binop ('|' , $1, $3); } 847 | exp '?' exp ':' exp 848 { $$ = exp_trinop ('?' , $1, $3, $5); } 849 | exp ANDAND exp 850 { $$ = exp_binop (ANDAND , $1, $3); } 851 | exp OROR exp 852 { $$ = exp_binop (OROR , $1, $3); } 853 | DEFINED '(' NAME ')' 854 { $$ = exp_nameop (DEFINED, $3); } 855 | INT 856 { $$ = exp_bigintop ($1.integer, $1.str); } 857 | SIZEOF_HEADERS 858 { $$ = exp_nameop (SIZEOF_HEADERS,0); } 859 860 | ALIGNOF '(' NAME ')' 861 { $$ = exp_nameop (ALIGNOF,$3); } 862 | SIZEOF '(' NAME ')' 863 { $$ = exp_nameop (SIZEOF,$3); } 864 | ADDR '(' NAME ')' 865 { $$ = exp_nameop (ADDR,$3); } 866 | LOADADDR '(' NAME ')' 867 { $$ = exp_nameop (LOADADDR,$3); } 868 | CONSTANT '(' NAME ')' 869 { $$ = exp_nameop (CONSTANT,$3); } 870 | ABSOLUTE '(' exp ')' 871 { $$ = exp_unop (ABSOLUTE, $3); } 872 | ALIGN_K '(' exp ')' 873 { $$ = exp_unop (ALIGN_K,$3); } 874 | ALIGN_K '(' exp ',' exp ')' 875 { $$ = exp_binop (ALIGN_K,$3,$5); } 876 | DATA_SEGMENT_ALIGN '(' exp ',' exp ')' 877 { $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); } 878 | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')' 879 { $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); } 880 | DATA_SEGMENT_END '(' exp ')' 881 { $$ = exp_unop (DATA_SEGMENT_END, $3); } 882 | SEGMENT_START '(' NAME ',' exp ')' 883 { /* The operands to the expression node are 884 placed in the opposite order from the way 885 in which they appear in the script as 886 that allows us to reuse more code in 887 fold_binary. */ 888 $$ = exp_binop (SEGMENT_START, 889 $5, 890 exp_nameop (NAME, $3)); } 891 | BLOCK '(' exp ')' 892 { $$ = exp_unop (ALIGN_K,$3); } 893 | NAME 894 { $$ = exp_nameop (NAME,$1); } 895 | MAX_K '(' exp ',' exp ')' 896 { $$ = exp_binop (MAX_K, $3, $5 ); } 897 | MIN_K '(' exp ',' exp ')' 898 { $$ = exp_binop (MIN_K, $3, $5 ); } 899 | ASSERT_K '(' exp ',' NAME ')' 900 { $$ = exp_assert ($3, $5); } 901 | ORIGIN '(' NAME ')' 902 { $$ = exp_nameop (ORIGIN, $3); } 903 | LENGTH '(' NAME ')' 904 { $$ = exp_nameop (LENGTH, $3); } 905 ; 906 907 908memspec_at_opt: 909 AT '>' NAME { $$ = $3; } 910 | { $$ = 0; } 911 ; 912 913opt_at: 914 AT '(' exp ')' { $$ = $3; } 915 | { $$ = 0; } 916 ; 917 918opt_align: 919 ALIGN_K '(' exp ')' { $$ = $3; } 920 | { $$ = 0; } 921 ; 922 923opt_subalign: 924 SUBALIGN '(' exp ')' { $$ = $3; } 925 | { $$ = 0; } 926 ; 927 928sect_constraint: 929 ONLY_IF_RO { $$ = ONLY_IF_RO; } 930 | ONLY_IF_RW { $$ = ONLY_IF_RW; } 931 | SPECIAL { $$ = SPECIAL; } 932 | { $$ = 0; } 933 ; 934 935section: NAME { ldlex_expression(); } 936 opt_exp_with_type 937 opt_at 938 opt_align 939 opt_subalign { ldlex_popstate (); ldlex_script (); } 940 sect_constraint 941 '{' 942 { 943 lang_enter_output_section_statement($1, $3, 944 sectype, 945 $5, $6, $4, $8); 946 } 947 statement_list_opt 948 '}' { ldlex_popstate (); ldlex_expression (); } 949 memspec_opt memspec_at_opt phdr_opt fill_opt 950 { 951 ldlex_popstate (); 952 lang_leave_output_section_statement ($17, $14, $16, $15); 953 } 954 opt_comma 955 {} 956 | OVERLAY 957 { ldlex_expression (); } 958 opt_exp_without_type opt_nocrossrefs opt_at opt_subalign 959 { ldlex_popstate (); ldlex_script (); } 960 '{' 961 { 962 lang_enter_overlay ($3, $6); 963 } 964 overlay_section 965 '}' 966 { ldlex_popstate (); ldlex_expression (); } 967 memspec_opt memspec_at_opt phdr_opt fill_opt 968 { 969 ldlex_popstate (); 970 lang_leave_overlay ($5, (int) $4, 971 $16, $13, $15, $14); 972 } 973 opt_comma 974 | /* The GROUP case is just enough to support the gcc 975 svr3.ifile script. It is not intended to be full 976 support. I'm not even sure what GROUP is supposed 977 to mean. */ 978 GROUP { ldlex_expression (); } 979 opt_exp_with_type 980 { 981 ldlex_popstate (); 982 lang_add_assignment (exp_assign (".", $3)); 983 } 984 '{' sec_or_group_p1 '}' 985 | INCLUDE filename 986 { ldlex_script (); ldfile_open_command_file($2); } 987 sec_or_group_p1 END 988 { ldlex_popstate (); } 989 ; 990 991type: 992 NOLOAD { sectype = noload_section; } 993 | DSECT { sectype = noalloc_section; } 994 | COPY { sectype = noalloc_section; } 995 | INFO { sectype = noalloc_section; } 996 | OVERLAY { sectype = noalloc_section; } 997 ; 998 999atype: 1000 '(' type ')' 1001 | /* EMPTY */ { sectype = normal_section; } 1002 | '(' ')' { sectype = normal_section; } 1003 ; 1004 1005opt_exp_with_type: 1006 exp atype ':' { $$ = $1; } 1007 | atype ':' { $$ = (etree_type *)NULL; } 1008 | /* The BIND cases are to support the gcc svr3.ifile 1009 script. They aren't intended to implement full 1010 support for the BIND keyword. I'm not even sure 1011 what BIND is supposed to mean. */ 1012 BIND '(' exp ')' atype ':' { $$ = $3; } 1013 | BIND '(' exp ')' BLOCK '(' exp ')' atype ':' 1014 { $$ = $3; } 1015 ; 1016 1017opt_exp_without_type: 1018 exp ':' { $$ = $1; } 1019 | ':' { $$ = (etree_type *) NULL; } 1020 ; 1021 1022opt_nocrossrefs: 1023 /* empty */ 1024 { $$ = 0; } 1025 | NOCROSSREFS 1026 { $$ = 1; } 1027 ; 1028 1029memspec_opt: 1030 '>' NAME 1031 { $$ = $2; } 1032 | { $$ = DEFAULT_MEMORY_REGION; } 1033 ; 1034 1035phdr_opt: 1036 /* empty */ 1037 { 1038 $$ = NULL; 1039 } 1040 | phdr_opt ':' NAME 1041 { 1042 struct lang_output_section_phdr_list *n; 1043 1044 n = ((struct lang_output_section_phdr_list *) 1045 xmalloc (sizeof *n)); 1046 n->name = $3; 1047 n->used = FALSE; 1048 n->next = $1; 1049 $$ = n; 1050 } 1051 ; 1052 1053overlay_section: 1054 /* empty */ 1055 | overlay_section 1056 NAME 1057 { 1058 ldlex_script (); 1059 lang_enter_overlay_section ($2); 1060 } 1061 '{' statement_list_opt '}' 1062 { ldlex_popstate (); ldlex_expression (); } 1063 phdr_opt fill_opt 1064 { 1065 ldlex_popstate (); 1066 lang_leave_overlay_section ($9, $8); 1067 } 1068 opt_comma 1069 ; 1070 1071phdrs: 1072 PHDRS '{' phdr_list '}' 1073 ; 1074 1075phdr_list: 1076 /* empty */ 1077 | phdr_list phdr 1078 ; 1079 1080phdr: 1081 NAME { ldlex_expression (); } 1082 phdr_type phdr_qualifiers { ldlex_popstate (); } 1083 ';' 1084 { 1085 lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at, 1086 $4.flags); 1087 } 1088 ; 1089 1090phdr_type: 1091 exp 1092 { 1093 $$ = $1; 1094 1095 if ($1->type.node_class == etree_name 1096 && $1->type.node_code == NAME) 1097 { 1098 const char *s; 1099 unsigned int i; 1100 static const char * const phdr_types[] = 1101 { 1102 "PT_NULL", "PT_LOAD", "PT_DYNAMIC", 1103 "PT_INTERP", "PT_NOTE", "PT_SHLIB", 1104 "PT_PHDR", "PT_TLS" 1105 }; 1106 1107 s = $1->name.name; 1108 for (i = 0; 1109 i < sizeof phdr_types / sizeof phdr_types[0]; 1110 i++) 1111 if (strcmp (s, phdr_types[i]) == 0) 1112 { 1113 $$ = exp_intop (i); 1114 break; 1115 } 1116 if (i == sizeof phdr_types / sizeof phdr_types[0]) 1117 { 1118 if (strcmp (s, "PT_GNU_EH_FRAME") == 0) 1119 $$ = exp_intop (0x6474e550); 1120 else if (strcmp (s, "PT_GNU_STACK") == 0) 1121 $$ = exp_intop (0x6474e551); 1122 else 1123 { 1124 einfo (_("\ 1125%X%P:%S: unknown phdr type `%s' (try integer literal)\n"), 1126 s); 1127 $$ = exp_intop (0); 1128 } 1129 } 1130 } 1131 } 1132 ; 1133 1134phdr_qualifiers: 1135 /* empty */ 1136 { 1137 memset (&$$, 0, sizeof (struct phdr_info)); 1138 } 1139 | NAME phdr_val phdr_qualifiers 1140 { 1141 $$ = $3; 1142 if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL) 1143 $$.filehdr = TRUE; 1144 else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL) 1145 $$.phdrs = TRUE; 1146 else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL) 1147 $$.flags = $2; 1148 else 1149 einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1); 1150 } 1151 | AT '(' exp ')' phdr_qualifiers 1152 { 1153 $$ = $5; 1154 $$.at = $3; 1155 } 1156 ; 1157 1158phdr_val: 1159 /* empty */ 1160 { 1161 $$ = NULL; 1162 } 1163 | '(' exp ')' 1164 { 1165 $$ = $2; 1166 } 1167 ; 1168 1169dynamic_list_file: 1170 { 1171 ldlex_version_file (); 1172 PUSH_ERROR (_("dynamic list")); 1173 } 1174 dynamic_list_nodes 1175 { 1176 ldlex_popstate (); 1177 POP_ERROR (); 1178 } 1179 ; 1180 1181dynamic_list_nodes: 1182 dynamic_list_node 1183 | dynamic_list_nodes dynamic_list_node 1184 ; 1185 1186dynamic_list_node: 1187 '{' dynamic_list_tag '}' ';' 1188 ; 1189 1190dynamic_list_tag: 1191 vers_defns ';' 1192 { 1193 lang_append_dynamic_list ($1); 1194 } 1195 ; 1196 1197/* This syntax is used within an external version script file. */ 1198 1199version_script_file: 1200 { 1201 ldlex_version_file (); 1202 PUSH_ERROR (_("VERSION script")); 1203 } 1204 vers_nodes 1205 { 1206 ldlex_popstate (); 1207 POP_ERROR (); 1208 } 1209 ; 1210 1211/* This is used within a normal linker script file. */ 1212 1213version: 1214 { 1215 ldlex_version_script (); 1216 } 1217 VERSIONK '{' vers_nodes '}' 1218 { 1219 ldlex_popstate (); 1220 } 1221 ; 1222 1223vers_nodes: 1224 vers_node 1225 | vers_nodes vers_node 1226 ; 1227 1228vers_node: 1229 '{' vers_tag '}' ';' 1230 { 1231 lang_register_vers_node (NULL, $2, NULL); 1232 } 1233 | VERS_TAG '{' vers_tag '}' ';' 1234 { 1235 lang_register_vers_node ($1, $3, NULL); 1236 } 1237 | VERS_TAG '{' vers_tag '}' verdep ';' 1238 { 1239 lang_register_vers_node ($1, $3, $5); 1240 } 1241 ; 1242 1243verdep: 1244 VERS_TAG 1245 { 1246 $$ = lang_add_vers_depend (NULL, $1); 1247 } 1248 | verdep VERS_TAG 1249 { 1250 $$ = lang_add_vers_depend ($1, $2); 1251 } 1252 ; 1253 1254vers_tag: 1255 /* empty */ 1256 { 1257 $$ = lang_new_vers_node (NULL, NULL); 1258 } 1259 | vers_defns ';' 1260 { 1261 $$ = lang_new_vers_node ($1, NULL); 1262 } 1263 | GLOBAL ':' vers_defns ';' 1264 { 1265 $$ = lang_new_vers_node ($3, NULL); 1266 } 1267 | LOCAL ':' vers_defns ';' 1268 { 1269 $$ = lang_new_vers_node (NULL, $3); 1270 } 1271 | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';' 1272 { 1273 $$ = lang_new_vers_node ($3, $7); 1274 } 1275 ; 1276 1277vers_defns: 1278 VERS_IDENTIFIER 1279 { 1280 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, FALSE); 1281 } 1282 | NAME 1283 { 1284 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, TRUE); 1285 } 1286 | vers_defns ';' VERS_IDENTIFIER 1287 { 1288 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, FALSE); 1289 } 1290 | vers_defns ';' NAME 1291 { 1292 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, TRUE); 1293 } 1294 | vers_defns ';' EXTERN NAME '{' 1295 { 1296 $<name>$ = ldgram_vers_current_lang; 1297 ldgram_vers_current_lang = $4; 1298 } 1299 vers_defns opt_semicolon '}' 1300 { 1301 struct bfd_elf_version_expr *pat; 1302 for (pat = $7; pat->next != NULL; pat = pat->next); 1303 pat->next = $1; 1304 $$ = $7; 1305 ldgram_vers_current_lang = $<name>6; 1306 } 1307 | EXTERN NAME '{' 1308 { 1309 $<name>$ = ldgram_vers_current_lang; 1310 ldgram_vers_current_lang = $2; 1311 } 1312 vers_defns opt_semicolon '}' 1313 { 1314 $$ = $5; 1315 ldgram_vers_current_lang = $<name>4; 1316 } 1317 | GLOBAL 1318 { 1319 $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang, FALSE); 1320 } 1321 | vers_defns ';' GLOBAL 1322 { 1323 $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang, FALSE); 1324 } 1325 | LOCAL 1326 { 1327 $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang, FALSE); 1328 } 1329 | vers_defns ';' LOCAL 1330 { 1331 $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang, FALSE); 1332 } 1333 | EXTERN 1334 { 1335 $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang, FALSE); 1336 } 1337 | vers_defns ';' EXTERN 1338 { 1339 $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, FALSE); 1340 } 1341 ; 1342 1343opt_semicolon: 1344 /* empty */ 1345 | ';' 1346 ; 1347 1348%% 1349void 1350yyerror(arg) 1351 const char *arg; 1352{ 1353 if (ldfile_assumed_script) 1354 einfo (_("%P:%s: file format not recognized; treating as linker script\n"), 1355 ldfile_input_filename); 1356 if (error_index > 0 && error_index < ERROR_NAME_MAX) 1357 einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]); 1358 else 1359 einfo ("%P%F:%S: %s\n", arg); 1360} 1361