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