1 /* yyscript.y -- linker script grammar for gold. */ 2 3 /* Copyright (C) 2006-2024 Free Software Foundation, Inc. 4 Written by Ian Lance Taylor <iant@google.com>. 5 6 This file is part of gold. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23 /* This is a bison grammar to parse a subset of the original GNU ld 24 linker script language. */ 25 26 %{ 27 28 #include "config.h" 29 #include "diagnostics.h" 30 31 #include <stddef.h> 32 #include <stdint.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include "script-c.h" 37 38 DIAGNOSTIC_IGNORE_UNUSED_BUT_SET_VARIABLE 39 40 %} 41 42 /* We need to use a pure parser because we might be multi-threaded. 43 We pass some arguments through the parser to the lexer. */ 44 45 %pure-parser 46 47 %parse-param {void* closure} 48 %lex-param {void* closure} 49 50 /* Since we require bison anyhow, we take advantage of it. */ 51 52 %error-verbose 53 54 /* The values associated with tokens. */ 55 56 %union { 57 /* A string. */ 58 struct Parser_string string; 59 /* A number. */ 60 uint64_t integer; 61 /* An expression. */ 62 Expression_ptr expr; 63 /* An output section header. */ 64 struct Parser_output_section_header output_section_header; 65 /* An output section trailer. */ 66 struct Parser_output_section_trailer output_section_trailer; 67 /* A section constraint. */ 68 enum Section_constraint constraint; 69 /* A complete input section specification. */ 70 struct Input_section_spec input_section_spec; 71 /* A list of wildcard specifications, with exclusions. */ 72 struct Wildcard_sections wildcard_sections; 73 /* A single wildcard specification. */ 74 struct Wildcard_section wildcard_section; 75 /* A list of strings. */ 76 String_list_ptr string_list; 77 /* Information for a program header. */ 78 struct Phdr_info phdr_info; 79 /* Used for version scripts and within VERSION {}. */ 80 struct Version_dependency_list* deplist; 81 struct Version_expression_list* versyms; 82 struct Version_tree* versnode; 83 enum Script_section_type section_type; 84 } 85 86 /* Operators, including a precedence table for expressions. */ 87 88 %right PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ 89 %right '?' ':' 90 %left OROR 91 %left ANDAND 92 %left '|' 93 %left '^' 94 %left '&' 95 %left EQ NE 96 %left '<' '>' LE GE 97 %left LSHIFT RSHIFT 98 %left '+' '-' 99 %left '*' '/' '%' 100 101 /* A fake operator used to indicate unary operator precedence. */ 102 %right UNARY 103 104 /* Constants. */ 105 106 %token <string> STRING 107 %token <string> QUOTED_STRING 108 %token <integer> INTEGER 109 110 /* Keywords. This list is taken from ldgram.y and ldlex.l in the old 111 GNU linker, with the keywords which only appear in MRI mode 112 removed. Not all these keywords are actually used in this grammar. 113 In most cases the keyword is recognized as the token name in upper 114 case. The comments indicate where this is not the case. */ 115 116 %token ABSOLUTE 117 %token ADDR 118 %token ALIGN_K /* ALIGN */ 119 %token ALIGNOF 120 %token ASSERT_K /* ASSERT */ 121 %token AS_NEEDED 122 %token AT 123 %token BIND 124 %token BLOCK 125 %token BYTE 126 %token CONSTANT 127 %token CONSTRUCTORS 128 %token COPY 129 %token CREATE_OBJECT_SYMBOLS 130 %token DATA_SEGMENT_ALIGN 131 %token DATA_SEGMENT_END 132 %token DATA_SEGMENT_RELRO_END 133 %token DEFINED 134 %token DSECT 135 %token ENTRY 136 %token EXCLUDE_FILE 137 %token EXTERN 138 %token FILL 139 %token FLOAT 140 %token FORCE_COMMON_ALLOCATION 141 %token GLOBAL /* global */ 142 %token GROUP 143 %token HIDDEN 144 %token HLL 145 %token INCLUDE 146 %token INHIBIT_COMMON_ALLOCATION 147 %token INFO 148 %token INPUT 149 %token KEEP 150 %token LEN 151 %token LENGTH /* LENGTH, l, len */ 152 %token LOADADDR 153 %token LOCAL /* local */ 154 %token LONG 155 %token MAP 156 %token MAX_K /* MAX */ 157 %token MEMORY 158 %token MIN_K /* MIN */ 159 %token NEXT 160 %token NOCROSSREFS 161 %token NOFLOAT 162 %token NOLOAD 163 %token ONLY_IF_RO 164 %token ONLY_IF_RW 165 %token ORG 166 %token ORIGIN /* ORIGIN, o, org */ 167 %token OUTPUT 168 %token OUTPUT_ARCH 169 %token OUTPUT_FORMAT 170 %token OVERLAY 171 %token PHDRS 172 %token PROVIDE 173 %token PROVIDE_HIDDEN 174 %token QUAD 175 %token SEARCH_DIR 176 %token SECTIONS 177 %token SEGMENT_START 178 %token SHORT 179 %token SIZEOF 180 %token SIZEOF_HEADERS /* SIZEOF_HEADERS, sizeof_headers */ 181 %token SORT_BY_ALIGNMENT 182 %token SORT_BY_INIT_PRIORITY 183 %token SORT_BY_NAME 184 %token SPECIAL 185 %token SQUAD 186 %token STARTUP 187 %token SUBALIGN 188 %token SYSLIB 189 %token TARGET_K /* TARGET */ 190 %token TRUNCATE 191 %token VERSIONK /* VERSION */ 192 193 /* Keywords, part 2. These are keywords that are unique to gold, 194 and not present in the old GNU linker. As before, unless the 195 comments say otherwise, the keyword is recognized as the token 196 name in upper case. */ 197 198 %token OPTION 199 200 /* Special tokens used to tell the grammar what type of tokens we are 201 parsing. The token stream always begins with one of these tokens. 202 We do this because version scripts can appear embedded within 203 linker scripts, and because --defsym uses the expression 204 parser. */ 205 %token PARSING_LINKER_SCRIPT 206 %token PARSING_VERSION_SCRIPT 207 %token PARSING_DEFSYM 208 %token PARSING_DYNAMIC_LIST 209 %token PARSING_SECTIONS_BLOCK 210 %token PARSING_SECTION_COMMANDS 211 %token PARSING_MEMORY_DEF 212 213 /* Non-terminal types, where needed. */ 214 215 %type <expr> parse_exp exp 216 %type <expr> opt_at opt_align opt_subalign opt_fill 217 %type <output_section_header> section_header opt_address_and_section_type 218 %type <section_type> section_type 219 %type <output_section_trailer> section_trailer 220 %type <constraint> opt_constraint 221 %type <string_list> opt_phdr 222 %type <integer> data_length 223 %type <input_section_spec> input_section_no_keep 224 %type <wildcard_sections> wildcard_sections 225 %type <wildcard_section> wildcard_file wildcard_section 226 %type <string_list> exclude_names 227 %type <string> wildcard_name 228 %type <integer> phdr_type memory_attr 229 %type <phdr_info> phdr_info 230 %type <versyms> vers_defns 231 %type <versnode> vers_tag 232 %type <deplist> verdep 233 %type <string> string 234 235 %% 236 237 /* Read the special token to see what to read next. */ 238 top: 239 PARSING_LINKER_SCRIPT linker_script 240 | PARSING_VERSION_SCRIPT version_script 241 | PARSING_DEFSYM defsym_expr 242 | PARSING_DYNAMIC_LIST dynamic_list_expr 243 | PARSING_SECTIONS_BLOCK sections_block 244 | PARSING_SECTION_COMMANDS section_cmds 245 | PARSING_MEMORY_DEF memory_defs 246 ; 247 248 /* A file contains a list of commands. */ 249 linker_script: 250 linker_script file_cmd 251 | /* empty */ 252 ; 253 254 /* A command which may appear at top level of a linker script. */ 255 file_cmd: 256 EXTERN '(' extern_name_list ')' 257 | FORCE_COMMON_ALLOCATION 258 { script_set_common_allocation(closure, 1); } 259 | GROUP 260 { script_start_group(closure); } 261 '(' input_list ')' 262 { script_end_group(closure); } 263 | INHIBIT_COMMON_ALLOCATION 264 { script_set_common_allocation(closure, 0); } 265 | INPUT '(' input_list ')' 266 | MEMORY '{' memory_defs '}' 267 | OPTION '(' string ')' 268 { script_parse_option(closure, $3.value, $3.length); } 269 | OUTPUT_FORMAT '(' string ')' 270 { 271 if (!script_check_output_format(closure, $3.value, $3.length, 272 NULL, 0, NULL, 0)) 273 YYABORT; 274 } 275 | OUTPUT_FORMAT '(' string ',' string ',' string ')' 276 { 277 if (!script_check_output_format(closure, $3.value, $3.length, 278 $5.value, $5.length, 279 $7.value, $7.length)) 280 YYABORT; 281 } 282 | PHDRS '{' phdrs_defs '}' 283 | SEARCH_DIR '(' string ')' 284 { script_add_search_dir(closure, $3.value, $3.length); } 285 | SECTIONS '{' 286 { script_start_sections(closure); } 287 sections_block '}' 288 { script_finish_sections(closure); } 289 | TARGET_K '(' string ')' 290 { script_set_target(closure, $3.value, $3.length); } 291 | VERSIONK '{' 292 { script_push_lex_into_version_mode(closure); } 293 version_script '}' 294 { script_pop_lex_mode(closure); } 295 | ENTRY '(' string ')' 296 { script_set_entry(closure, $3.value, $3.length); } 297 | assignment end 298 | ASSERT_K '(' parse_exp ',' string ')' 299 { script_add_assertion(closure, $3, $5.value, $5.length); } 300 | INCLUDE string 301 { script_include_directive(PARSING_LINKER_SCRIPT, closure, 302 $2.value, $2.length); } 303 | ignore_cmd 304 | ';' 305 ; 306 307 /* Top level commands which we ignore. The GNU linker uses these to 308 select the output format, but we don't offer a choice. Ignoring 309 these is more-or-less OK since most scripts simply explicitly 310 choose the default. */ 311 ignore_cmd: 312 OUTPUT_ARCH '(' string ')' 313 ; 314 315 /* A list of external undefined symbols. We put the lexer into 316 expression mode so that commas separate names; this is what the GNU 317 linker does. */ 318 319 extern_name_list: 320 { script_push_lex_into_expression_mode(closure); } 321 extern_name_list_body 322 { script_pop_lex_mode(closure); } 323 ; 324 325 extern_name_list_body: 326 string 327 { script_add_extern(closure, $1.value, $1.length); } 328 | extern_name_list_body string 329 { script_add_extern(closure, $2.value, $2.length); } 330 | extern_name_list_body ',' string 331 { script_add_extern(closure, $3.value, $3.length); } 332 ; 333 334 /* A list of input file names. */ 335 input_list: 336 input_list_element 337 | input_list opt_comma input_list_element 338 ; 339 340 /* An input file name. */ 341 input_list_element: 342 string 343 { script_add_file(closure, $1.value, $1.length); } 344 | '-' STRING 345 { script_add_library(closure, $2.value, $2.length); } 346 | AS_NEEDED 347 { script_start_as_needed(closure); } 348 '(' input_list ')' 349 { script_end_as_needed(closure); } 350 ; 351 352 /* Commands in a SECTIONS block. */ 353 sections_block: 354 sections_block section_block_cmd 355 | /* empty */ 356 ; 357 358 /* A command which may appear within a SECTIONS block. */ 359 section_block_cmd: 360 ENTRY '(' string ')' 361 { script_set_entry(closure, $3.value, $3.length); } 362 | assignment end 363 | ASSERT_K '(' parse_exp ',' string ')' 364 { script_add_assertion(closure, $3, $5.value, $5.length); } 365 | INCLUDE string 366 { script_include_directive(PARSING_SECTIONS_BLOCK, closure, 367 $2.value, $2.length); } 368 | string section_header 369 { script_start_output_section(closure, $1.value, $1.length, &$2); } 370 '{' section_cmds '}' section_trailer 371 { script_finish_output_section(closure, &$7); } 372 ; 373 374 /* The header of an output section in a SECTIONS block--everything 375 after the name. */ 376 section_header: 377 { script_push_lex_into_expression_mode(closure); } 378 opt_address_and_section_type opt_at opt_align opt_subalign 379 { script_pop_lex_mode(closure); } 380 opt_constraint 381 { 382 $$.address = $2.address; 383 $$.section_type = $2.section_type; 384 $$.load_address = $3; 385 $$.align = $4; 386 $$.subalign = $5; 387 $$.constraint = $7; 388 } 389 ; 390 391 /* The optional address followed by the optional section type. This 392 is a separate nonterminal to avoid a shift/reduce conflict on 393 '(' in section_header. */ 394 395 opt_address_and_section_type: 396 ':' 397 { 398 $$.address = NULL; 399 $$.section_type = SCRIPT_SECTION_TYPE_NONE; 400 } 401 | '(' ')' ':' 402 { 403 $$.address = NULL; 404 $$.section_type = SCRIPT_SECTION_TYPE_NONE; 405 } 406 | exp ':' 407 { 408 $$.address = $1; 409 $$.section_type = SCRIPT_SECTION_TYPE_NONE; 410 } 411 | exp '(' ')' ':' 412 { 413 $$.address = $1; 414 $$.section_type = SCRIPT_SECTION_TYPE_NONE; 415 } 416 | '(' section_type ')' ':' 417 { 418 $$.address = NULL; 419 $$.section_type = $2; 420 } 421 | exp '(' section_type ')' ':' 422 { 423 $$.address = $1; 424 $$.section_type = $3; 425 } 426 ; 427 428 /* We only support NOLOAD. */ 429 section_type: 430 NOLOAD 431 { $$ = SCRIPT_SECTION_TYPE_NOLOAD; } 432 | DSECT 433 { 434 yyerror(closure, "DSECT section type is unsupported"); 435 $$ = SCRIPT_SECTION_TYPE_DSECT; 436 } 437 | COPY 438 { 439 yyerror(closure, "COPY section type is unsupported"); 440 $$ = SCRIPT_SECTION_TYPE_COPY; 441 } 442 | INFO 443 { 444 yyerror(closure, "INFO section type is unsupported"); 445 $$ = SCRIPT_SECTION_TYPE_INFO; 446 } 447 | OVERLAY 448 { 449 yyerror(closure, "OVERLAY section type is unsupported"); 450 $$ = SCRIPT_SECTION_TYPE_OVERLAY; 451 } 452 ; 453 454 /* The address at which an output section should be loaded. */ 455 opt_at: 456 /* empty */ 457 { $$ = NULL; } 458 | AT '(' exp ')' 459 { $$ = $3; } 460 ; 461 462 /* The alignment of an output section. */ 463 opt_align: 464 /* empty */ 465 { $$ = NULL; } 466 | ALIGN_K '(' exp ')' 467 { $$ = $3; } 468 ; 469 470 /* The input section alignment within an output section. */ 471 opt_subalign: 472 /* empty */ 473 { $$ = NULL; } 474 | SUBALIGN '(' exp ')' 475 { $$ = $3; } 476 ; 477 478 /* A section constraint. */ 479 opt_constraint: 480 /* empty */ 481 { $$ = CONSTRAINT_NONE; } 482 | ONLY_IF_RO 483 { $$ = CONSTRAINT_ONLY_IF_RO; } 484 | ONLY_IF_RW 485 { $$ = CONSTRAINT_ONLY_IF_RW; } 486 | SPECIAL 487 { $$ = CONSTRAINT_SPECIAL; } 488 ; 489 490 /* The trailer of an output section in a SECTIONS block. */ 491 section_trailer: 492 opt_memspec opt_at_memspec opt_phdr opt_fill opt_comma 493 { 494 $$.fill = $4; 495 $$.phdrs = $3; 496 } 497 ; 498 499 /* A memory specification for an output section. */ 500 opt_memspec: 501 '>' string 502 { script_set_section_region(closure, $2.value, $2.length, 1); } 503 | /* empty */ 504 ; 505 506 /* A memory specification for where to load an output section. */ 507 opt_at_memspec: 508 AT '>' string 509 { script_set_section_region(closure, $3.value, $3.length, 0); } 510 | /* empty */ 511 ; 512 513 /* The program segment an output section should go into. */ 514 opt_phdr: 515 opt_phdr ':' string 516 { $$ = script_string_list_push_back($1, $3.value, $3.length); } 517 | /* empty */ 518 { $$ = NULL; } 519 ; 520 521 /* The value to use to fill an output section. FIXME: This does not 522 handle a string of arbitrary length. */ 523 opt_fill: 524 '=' parse_exp 525 { $$ = $2; } 526 | /* empty */ 527 { $$ = NULL; } 528 ; 529 530 /* Commands which may appear within the description of an output 531 section in a SECTIONS block. */ 532 section_cmds: 533 /* empty */ 534 | section_cmds section_cmd 535 ; 536 537 /* A command which may appear within the description of an output 538 section in a SECTIONS block. */ 539 section_cmd: 540 assignment end 541 | input_section_spec 542 | data_length '(' parse_exp ')' 543 { script_add_data(closure, $1, $3); } 544 | ASSERT_K '(' parse_exp ',' string ')' 545 { script_add_assertion(closure, $3, $5.value, $5.length); } 546 | FILL '(' parse_exp ')' 547 { script_add_fill(closure, $3); } 548 | CONSTRUCTORS 549 { 550 /* The GNU linker uses CONSTRUCTORS for the a.out object 551 file format. It does nothing when using ELF. Since 552 some ELF linker scripts use it although it does 553 nothing, we accept it and ignore it. */ 554 } 555 | SORT_BY_NAME '(' CONSTRUCTORS ')' 556 | INCLUDE string 557 { script_include_directive(PARSING_SECTION_COMMANDS, closure, 558 $2.value, $2.length); } 559 | ';' 560 ; 561 562 /* The length of data which may appear within the description of an 563 output section in a SECTIONS block. */ 564 data_length: 565 QUAD 566 { $$ = QUAD; } 567 | SQUAD 568 { $$ = SQUAD; } 569 | LONG 570 { $$ = LONG; } 571 | SHORT 572 { $$ = SHORT; } 573 | BYTE 574 { $$ = BYTE; } 575 ; 576 577 /* An input section specification. This may appear within the 578 description of an output section in a SECTIONS block. */ 579 input_section_spec: 580 input_section_no_keep 581 { script_add_input_section(closure, &$1, 0); } 582 | KEEP '(' input_section_no_keep ')' 583 { script_add_input_section(closure, &$3, 1); } 584 ; 585 586 /* An input section specification within a KEEP clause. */ 587 input_section_no_keep: 588 string 589 { 590 $$.file.name = $1; 591 $$.file.sort = SORT_WILDCARD_NONE; 592 $$.input_sections.sections = NULL; 593 $$.input_sections.exclude = NULL; 594 } 595 | wildcard_file '(' wildcard_sections ')' 596 { 597 $$.file = $1; 598 $$.input_sections = $3; 599 } 600 ; 601 602 /* A wildcard file specification. */ 603 wildcard_file: 604 wildcard_name 605 { 606 $$.name = $1; 607 $$.sort = SORT_WILDCARD_NONE; 608 } 609 | SORT_BY_NAME '(' wildcard_name ')' 610 { 611 $$.name = $3; 612 $$.sort = SORT_WILDCARD_BY_NAME; 613 } 614 ; 615 616 /* A list of wild card section specifications. */ 617 wildcard_sections: 618 wildcard_sections opt_comma wildcard_section 619 { 620 $$.sections = script_string_sort_list_add($1.sections, &$3); 621 $$.exclude = $1.exclude; 622 } 623 | wildcard_section 624 { 625 $$.sections = script_new_string_sort_list(&$1); 626 $$.exclude = NULL; 627 } 628 | wildcard_sections opt_comma EXCLUDE_FILE '(' exclude_names ')' 629 { 630 $$.sections = $1.sections; 631 $$.exclude = script_string_list_append($1.exclude, $5); 632 } 633 | EXCLUDE_FILE '(' exclude_names ')' 634 { 635 $$.sections = NULL; 636 $$.exclude = $3; 637 } 638 ; 639 640 /* A single wild card specification. */ 641 wildcard_section: 642 wildcard_name 643 { 644 $$.name = $1; 645 $$.sort = SORT_WILDCARD_NONE; 646 } 647 | SORT_BY_NAME '(' wildcard_section ')' 648 { 649 $$.name = $3.name; 650 switch ($3.sort) 651 { 652 case SORT_WILDCARD_NONE: 653 $$.sort = SORT_WILDCARD_BY_NAME; 654 break; 655 case SORT_WILDCARD_BY_NAME: 656 case SORT_WILDCARD_BY_NAME_BY_ALIGNMENT: 657 break; 658 case SORT_WILDCARD_BY_ALIGNMENT: 659 case SORT_WILDCARD_BY_ALIGNMENT_BY_NAME: 660 $$.sort = SORT_WILDCARD_BY_NAME_BY_ALIGNMENT; 661 break; 662 default: 663 abort(); 664 } 665 } 666 | SORT_BY_ALIGNMENT '(' wildcard_section ')' 667 { 668 $$.name = $3.name; 669 switch ($3.sort) 670 { 671 case SORT_WILDCARD_NONE: 672 $$.sort = SORT_WILDCARD_BY_ALIGNMENT; 673 break; 674 case SORT_WILDCARD_BY_ALIGNMENT: 675 case SORT_WILDCARD_BY_ALIGNMENT_BY_NAME: 676 break; 677 case SORT_WILDCARD_BY_NAME: 678 case SORT_WILDCARD_BY_NAME_BY_ALIGNMENT: 679 $$.sort = SORT_WILDCARD_BY_ALIGNMENT_BY_NAME; 680 break; 681 default: 682 abort(); 683 } 684 } 685 | SORT_BY_INIT_PRIORITY '(' wildcard_name ')' 686 { 687 $$.name = $3; 688 $$.sort = SORT_WILDCARD_BY_INIT_PRIORITY; 689 } 690 ; 691 692 /* A list of file names to exclude. */ 693 exclude_names: 694 exclude_names opt_comma wildcard_name 695 { $$ = script_string_list_push_back($1, $3.value, $3.length); } 696 | wildcard_name 697 { $$ = script_new_string_list($1.value, $1.length); } 698 ; 699 700 /* A single wildcard name. We recognize '*' and '?' specially since 701 they are expression tokens. */ 702 wildcard_name: 703 string 704 { $$ = $1; } 705 | '*' 706 { 707 $$.value = "*"; 708 $$.length = 1; 709 } 710 | '?' 711 { 712 $$.value = "?"; 713 $$.length = 1; 714 } 715 ; 716 717 /* A list of MEMORY definitions. */ 718 memory_defs: 719 memory_defs opt_comma memory_def 720 | /* empty */ 721 ; 722 723 /* A single MEMORY definition. */ 724 memory_def: 725 string memory_attr ':' memory_origin '=' parse_exp opt_comma memory_length '=' parse_exp 726 { script_add_memory(closure, $1.value, $1.length, $2, $6, $10); } 727 | 728 INCLUDE string 729 { script_include_directive(PARSING_MEMORY_DEF, closure, 730 $2.value, $2.length); } 731 | 732 ; 733 734 /* The (optional) attributes of a MEMORY region. */ 735 memory_attr: 736 '(' string ')' 737 { $$ = script_parse_memory_attr(closure, $2.value, $2.length, 0); } 738 | /* Inverted attributes. */ 739 '(' '!' string ')' 740 { $$ = script_parse_memory_attr(closure, $3.value, $3.length, 1); } 741 | /* empty */ 742 { $$ = 0; } 743 ; 744 745 memory_origin: 746 ORIGIN 747 | 748 ORG 749 | 750 'o' 751 ; 752 753 memory_length: 754 LENGTH 755 | 756 LEN 757 | 758 'l' 759 ; 760 761 /* A list of program header definitions. */ 762 phdrs_defs: 763 phdrs_defs phdr_def 764 | /* empty */ 765 ; 766 767 /* A program header definition. */ 768 phdr_def: 769 string phdr_type phdr_info ';' 770 { script_add_phdr(closure, $1.value, $1.length, $2, &$3); } 771 ; 772 773 /* A program header type. The GNU linker accepts a general expression 774 here, but that would be a pain because we would have to dig into 775 the expression structure. It's unlikely that anybody uses anything 776 other than a string or a number here, so that is all we expect. */ 777 phdr_type: 778 string 779 { $$ = script_phdr_string_to_type(closure, $1.value, $1.length); } 780 | INTEGER 781 { $$ = $1; } 782 ; 783 784 /* Additional information for a program header. */ 785 phdr_info: 786 /* empty */ 787 { memset(&$$, 0, sizeof(struct Phdr_info)); } 788 | string phdr_info 789 { 790 $$ = $2; 791 if ($1.length == 7 && strncmp($1.value, "FILEHDR", 7) == 0) 792 $$.includes_filehdr = 1; 793 else 794 yyerror(closure, "PHDRS syntax error"); 795 } 796 | PHDRS phdr_info 797 { 798 $$ = $2; 799 $$.includes_phdrs = 1; 800 } 801 | string '(' INTEGER ')' phdr_info 802 { 803 $$ = $5; 804 if ($1.length == 5 && strncmp($1.value, "FLAGS", 5) == 0) 805 { 806 $$.is_flags_valid = 1; 807 $$.flags = $3; 808 } 809 else 810 yyerror(closure, "PHDRS syntax error"); 811 } 812 | AT '(' parse_exp ')' phdr_info 813 { 814 $$ = $5; 815 $$.load_address = $3; 816 } 817 ; 818 819 /* Set a symbol to a value. */ 820 assignment: 821 string '=' parse_exp 822 { script_set_symbol(closure, $1.value, $1.length, $3, 0, 0); } 823 | string PLUSEQ parse_exp 824 { 825 Expression_ptr s = script_exp_string($1.value, $1.length); 826 Expression_ptr e = script_exp_binary_add(s, $3); 827 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 828 } 829 | string MINUSEQ parse_exp 830 { 831 Expression_ptr s = script_exp_string($1.value, $1.length); 832 Expression_ptr e = script_exp_binary_sub(s, $3); 833 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 834 } 835 | string MULTEQ parse_exp 836 { 837 Expression_ptr s = script_exp_string($1.value, $1.length); 838 Expression_ptr e = script_exp_binary_mult(s, $3); 839 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 840 } 841 | string DIVEQ parse_exp 842 { 843 Expression_ptr s = script_exp_string($1.value, $1.length); 844 Expression_ptr e = script_exp_binary_div(s, $3); 845 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 846 } 847 | string LSHIFTEQ parse_exp 848 { 849 Expression_ptr s = script_exp_string($1.value, $1.length); 850 Expression_ptr e = script_exp_binary_lshift(s, $3); 851 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 852 } 853 | string RSHIFTEQ parse_exp 854 { 855 Expression_ptr s = script_exp_string($1.value, $1.length); 856 Expression_ptr e = script_exp_binary_rshift(s, $3); 857 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 858 } 859 | string ANDEQ parse_exp 860 { 861 Expression_ptr s = script_exp_string($1.value, $1.length); 862 Expression_ptr e = script_exp_binary_bitwise_and(s, $3); 863 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 864 } 865 | string OREQ parse_exp 866 { 867 Expression_ptr s = script_exp_string($1.value, $1.length); 868 Expression_ptr e = script_exp_binary_bitwise_or(s, $3); 869 script_set_symbol(closure, $1.value, $1.length, e, 0, 0); 870 } 871 | HIDDEN '(' string '=' parse_exp ')' 872 { script_set_symbol(closure, $3.value, $3.length, $5, 0, 1); } 873 | PROVIDE '(' string '=' parse_exp ')' 874 { script_set_symbol(closure, $3.value, $3.length, $5, 1, 0); } 875 | PROVIDE_HIDDEN '(' string '=' parse_exp ')' 876 { script_set_symbol(closure, $3.value, $3.length, $5, 1, 1); } 877 ; 878 879 /* Parse an expression, putting the lexer into the right mode. */ 880 parse_exp: 881 { script_push_lex_into_expression_mode(closure); } 882 exp 883 { 884 script_pop_lex_mode(closure); 885 $$ = $2; 886 } 887 ; 888 889 /* An expression. */ 890 exp: 891 '(' exp ')' 892 { $$ = $2; } 893 | '-' exp %prec UNARY 894 { $$ = script_exp_unary_minus($2); } 895 | '!' exp %prec UNARY 896 { $$ = script_exp_unary_logical_not($2); } 897 | '~' exp %prec UNARY 898 { $$ = script_exp_unary_bitwise_not($2); } 899 | '+' exp %prec UNARY 900 { $$ = $2; } 901 | exp '*' exp 902 { $$ = script_exp_binary_mult($1, $3); } 903 | exp '/' exp 904 { $$ = script_exp_binary_div($1, $3); } 905 | exp '%' exp 906 { $$ = script_exp_binary_mod($1, $3); } 907 | exp '+' exp 908 { $$ = script_exp_binary_add($1, $3); } 909 | exp '-' exp 910 { $$ = script_exp_binary_sub($1, $3); } 911 | exp LSHIFT exp 912 { $$ = script_exp_binary_lshift($1, $3); } 913 | exp RSHIFT exp 914 { $$ = script_exp_binary_rshift($1, $3); } 915 | exp EQ exp 916 { $$ = script_exp_binary_eq($1, $3); } 917 | exp NE exp 918 { $$ = script_exp_binary_ne($1, $3); } 919 | exp LE exp 920 { $$ = script_exp_binary_le($1, $3); } 921 | exp GE exp 922 { $$ = script_exp_binary_ge($1, $3); } 923 | exp '<' exp 924 { $$ = script_exp_binary_lt($1, $3); } 925 | exp '>' exp 926 { $$ = script_exp_binary_gt($1, $3); } 927 | exp '&' exp 928 { $$ = script_exp_binary_bitwise_and($1, $3); } 929 | exp '^' exp 930 { $$ = script_exp_binary_bitwise_xor($1, $3); } 931 | exp '|' exp 932 { $$ = script_exp_binary_bitwise_or($1, $3); } 933 | exp ANDAND exp 934 { $$ = script_exp_binary_logical_and($1, $3); } 935 | exp OROR exp 936 { $$ = script_exp_binary_logical_or($1, $3); } 937 | exp '?' exp ':' exp 938 { $$ = script_exp_trinary_cond($1, $3, $5); } 939 | INTEGER 940 { $$ = script_exp_integer($1); } 941 | string 942 { $$ = script_symbol(closure, $1.value, $1.length); } 943 | MAX_K '(' exp ',' exp ')' 944 { $$ = script_exp_function_max($3, $5); } 945 | MIN_K '(' exp ',' exp ')' 946 { $$ = script_exp_function_min($3, $5); } 947 | DEFINED '(' string ')' 948 { $$ = script_exp_function_defined($3.value, $3.length); } 949 | SIZEOF_HEADERS 950 { $$ = script_exp_function_sizeof_headers(); } 951 | ALIGNOF '(' string ')' 952 { $$ = script_exp_function_alignof($3.value, $3.length); } 953 | SIZEOF '(' string ')' 954 { $$ = script_exp_function_sizeof($3.value, $3.length); } 955 | ADDR '(' string ')' 956 { $$ = script_exp_function_addr($3.value, $3.length); } 957 | LOADADDR '(' string ')' 958 { $$ = script_exp_function_loadaddr($3.value, $3.length); } 959 | ORIGIN '(' string ')' 960 { $$ = script_exp_function_origin(closure, $3.value, $3.length); } 961 | LENGTH '(' string ')' 962 { $$ = script_exp_function_length(closure, $3.value, $3.length); } 963 | CONSTANT '(' string ')' 964 { $$ = script_exp_function_constant($3.value, $3.length); } 965 | ABSOLUTE '(' exp ')' 966 { $$ = script_exp_function_absolute($3); } 967 | ALIGN_K '(' exp ')' 968 { $$ = script_exp_function_align(script_exp_string(".", 1), $3); } 969 | ALIGN_K '(' exp ',' exp ')' 970 { $$ = script_exp_function_align($3, $5); } 971 | BLOCK '(' exp ')' 972 { $$ = script_exp_function_align(script_exp_string(".", 1), $3); } 973 | DATA_SEGMENT_ALIGN '(' exp ',' exp ')' 974 { 975 script_data_segment_align(closure); 976 $$ = script_exp_function_data_segment_align($3, $5); 977 } 978 | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')' 979 { 980 script_data_segment_relro_end(closure); 981 $$ = script_exp_function_data_segment_relro_end($3, $5); 982 } 983 | DATA_SEGMENT_END '(' exp ')' 984 { $$ = script_exp_function_data_segment_end($3); } 985 | SEGMENT_START '(' string ',' exp ')' 986 { 987 $$ = script_exp_function_segment_start($3.value, $3.length, $5); 988 /* We need to take note of any SEGMENT_START expressions 989 because they change the behaviour of -Ttext, -Tdata and 990 -Tbss options. */ 991 script_saw_segment_start_expression(closure); 992 } 993 | ASSERT_K '(' exp ',' string ')' 994 { $$ = script_exp_function_assert($3, $5.value, $5.length); } 995 ; 996 997 /* Handle the --defsym option. */ 998 defsym_expr: 999 string '=' parse_exp 1000 { script_set_symbol(closure, $1.value, $1.length, $3, 0, 0); } 1001 ; 1002 1003 /* Handle the --dynamic-list option. A dynamic list has the format 1004 { sym1; sym2; extern "C++" { namespace::sym3 }; }; 1005 We store the symbol we see in the "local" list; that is where 1006 Command_line::in_dynamic_list() will look to do its check. 1007 TODO(csilvers): More than one of these brace-lists can appear, and 1008 should just be merged and treated as a single list. */ 1009 dynamic_list_expr: dynamic_list_nodes ; 1010 1011 dynamic_list_nodes: 1012 dynamic_list_node 1013 | dynamic_list_nodes dynamic_list_node 1014 ; 1015 1016 dynamic_list_node: 1017 '{' vers_defns ';' '}' ';' 1018 { script_new_vers_node (closure, NULL, $2); } 1019 ; 1020 1021 /* A version script. */ 1022 version_script: 1023 vers_nodes 1024 ; 1025 1026 vers_nodes: 1027 vers_node 1028 | vers_nodes vers_node 1029 ; 1030 1031 vers_node: 1032 '{' vers_tag '}' ';' 1033 { 1034 script_register_vers_node (closure, NULL, 0, $2, NULL); 1035 } 1036 | string '{' vers_tag '}' ';' 1037 { 1038 script_register_vers_node (closure, $1.value, $1.length, $3, 1039 NULL); 1040 } 1041 | string '{' vers_tag '}' verdep ';' 1042 { 1043 script_register_vers_node (closure, $1.value, $1.length, $3, $5); 1044 } 1045 ; 1046 1047 verdep: 1048 string 1049 { 1050 $$ = script_add_vers_depend (closure, NULL, $1.value, $1.length); 1051 } 1052 | verdep string 1053 { 1054 $$ = script_add_vers_depend (closure, $1, $2.value, $2.length); 1055 } 1056 ; 1057 1058 vers_tag: 1059 /* empty */ 1060 { $$ = script_new_vers_node (closure, NULL, NULL); } 1061 | vers_defns ';' 1062 { $$ = script_new_vers_node (closure, $1, NULL); } 1063 | GLOBAL ':' vers_defns ';' 1064 { $$ = script_new_vers_node (closure, $3, NULL); } 1065 | LOCAL ':' vers_defns ';' 1066 { $$ = script_new_vers_node (closure, NULL, $3); } 1067 | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';' 1068 { $$ = script_new_vers_node (closure, $3, $7); } 1069 ; 1070 1071 /* Here is one of the rare places we care about the distinction 1072 between STRING and QUOTED_STRING. For QUOTED_STRING, we do exact 1073 matching on the pattern, so we pass in true for the exact_match 1074 parameter. For STRING, we do glob matching and pass in false. */ 1075 vers_defns: 1076 STRING 1077 { 1078 $$ = script_new_vers_pattern (closure, NULL, $1.value, 1079 $1.length, 0); 1080 } 1081 | QUOTED_STRING 1082 { 1083 $$ = script_new_vers_pattern (closure, NULL, $1.value, 1084 $1.length, 1); 1085 } 1086 | vers_defns ';' STRING 1087 { 1088 $$ = script_new_vers_pattern (closure, $1, $3.value, 1089 $3.length, 0); 1090 } 1091 | vers_defns ';' QUOTED_STRING 1092 { 1093 $$ = script_new_vers_pattern (closure, $1, $3.value, 1094 $3.length, 1); 1095 } 1096 | /* Push string on the language stack. */ 1097 EXTERN string '{' 1098 { version_script_push_lang (closure, $2.value, $2.length); } 1099 vers_defns opt_semicolon '}' 1100 { 1101 $$ = $5; 1102 version_script_pop_lang(closure); 1103 } 1104 | /* Push string on the language stack. This is more complicated 1105 than the other cases because we need to merge the linked-list 1106 state from the pre-EXTERN defns and the post-EXTERN defns. */ 1107 vers_defns ';' EXTERN string '{' 1108 { version_script_push_lang (closure, $4.value, $4.length); } 1109 vers_defns opt_semicolon '}' 1110 { 1111 $$ = script_merge_expressions ($1, $7); 1112 version_script_pop_lang(closure); 1113 } 1114 | EXTERN // "extern" as a symbol name 1115 { 1116 $$ = script_new_vers_pattern (closure, NULL, "extern", 1117 sizeof("extern") - 1, 1); 1118 } 1119 | vers_defns ';' EXTERN 1120 { 1121 $$ = script_new_vers_pattern (closure, $1, "extern", 1122 sizeof("extern") - 1, 1); 1123 } 1124 ; 1125 1126 /* A string can be either a STRING or a QUOTED_STRING. Almost all the 1127 time we don't care, and we use this rule. */ 1128 string: 1129 STRING 1130 { $$ = $1; } 1131 | QUOTED_STRING 1132 { $$ = $1; } 1133 ; 1134 1135 /* Some statements require a terminator, which may be a semicolon or a 1136 comma. */ 1137 end: 1138 ';' 1139 | ',' 1140 ; 1141 1142 /* An optional semicolon. */ 1143 opt_semicolon: 1144 ';' 1145 | /* empty */ 1146 ; 1147 1148 /* An optional comma. */ 1149 opt_comma: 1150 ',' 1151 | /* empty */ 1152 ; 1153 1154 %% 1155