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