ScriptParser.yy revision 87f34658dec9097d987d254a990ea7f311bfc95f
1/*===- ScriptParser.yy ----------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===*/ 9 10%{ 11/* C/C++ Declarations */ 12#include <mcld/Script/ScriptReader.h> 13#include <mcld/Script/ScriptScanner.h> 14#include <mcld/Script/Operand.h> 15#include <mcld/Script/Operator.h> 16#include <mcld/Script/Assignment.h> 17#include <mcld/Script/RpnExpr.h> 18#include <mcld/Script/FileToken.h> 19#include <mcld/Script/NameSpec.h> 20#include <mcld/Script/WildcardPattern.h> 21#include <mcld/Support/MsgHandling.h> 22using namespace mcld; 23 24#undef yylex 25#define yylex m_ScriptScanner.lex 26%} 27 28%code requires { 29#include <mcld/Script/StrToken.h> 30#include <mcld/Script/StringList.h> 31#include <mcld/Script/OutputSectDesc.h> 32#include <mcld/Script/InputSectDesc.h> 33#include <llvm/Support/DataTypes.h> 34 35using namespace mcld; 36 37} 38 39%pure-parser 40%require "2.4" 41%skeleton "glr.cc" 42%defines "ScriptParser.h" 43%debug 44%error-verbose 45%define namespace "mcld" 46%define "parser_class_name" "ScriptParser" 47%parse-param { const class LinkerConfig& m_LDConfig } 48%parse-param { class ScriptFile& m_ScriptFile } 49%parse-param { class ScriptScanner& m_ScriptScanner } 50%parse-param { class GroupReader& m_GroupReader} 51%lex-param { const class ScriptFile& m_ScriptFile } 52 53%locations 54%initial-action 55{ 56 /* Initialize the initial location. */ 57 @$.begin.filename = @$.end.filename = &(m_ScriptFile.name()); 58} 59 60%start script_file 61 62%union { 63 const std::string* string; 64 uint64_t integer; 65 RpnExpr* rpn_expr; 66 StrToken* str_token; 67 StringList* str_tokens; 68 OutputSectDesc::Prolog output_prolog; 69 OutputSectDesc::Type output_type; 70 OutputSectDesc::Constraint output_constraint; 71 OutputSectDesc::Epilog output_epilog; 72 WildcardPattern* wildcard; 73 InputSectDesc::Spec input_spec; 74} 75 76%token END 0 /* EOF */ 77%token <string> STRING LNAMESPEC 78%token <integer> INTEGER 79 80/* Initial states */ 81%token LINKER_SCRIPT DEFSYM VERSION_SCRIPT DYNAMIC_LIST 82 83/* Entry point */ 84%token ENTRY 85/* File Commands */ 86%token INCLUDE 87%token INPUT 88%token GROUP 89%token AS_NEEDED 90%token OUTPUT 91%token SEARCH_DIR 92%token STARTUP 93/* Format Commands */ 94%token OUTPUT_FORMAT 95%token TARGET 96/* Misc Commands */ 97%token ASSERT 98%token EXTERN 99%token FORCE_COMMON_ALLOCATION 100%token INHIBIT_COMMON_ALLOCATION 101%token INSERT 102%token NOCROSSREFS 103%token OUTPUT_ARCH 104%token LD_FEATURE 105/* Assignments */ 106%token HIDDEN 107%token PROVIDE 108%token PROVIDE_HIDDEN 109/* SECTIONS Command */ 110%token SECTIONS 111/* MEMORY Command */ 112%token MEMORY 113/* PHDRS Command */ 114%token PHDRS 115/* Builtin Functions */ 116%token ABSOLUTE 117%token ADDR 118%token ALIGN 119%token ALIGNOF 120%token BLOCK 121%token DATA_SEGMENT_ALIGN 122%token DATA_SEGMENT_END 123%token DATA_SEGMENT_RELRO_END 124%token DEFINED 125%token LENGTH 126%token LOADADDR 127%token MAX 128%token MIN 129%token NEXT 130%token ORIGIN 131%token SEGMENT_START 132%token SIZEOF 133%token SIZEOF_HEADERS 134%token CONSTANT 135/* Symbolic Constants */ 136%token MAXPAGESIZE 137%token COMMONPAGESIZE 138/* Input Section Description */ 139%token EXCLUDE_FILE 140%token COMMON 141%token KEEP 142%token SORT_BY_NAME 143%token SORT_BY_ALIGNMENT 144%token SORT_NONE 145%token SORT_BY_INIT_PRIORITY 146/* Output Section Data */ 147%token BYTE 148%token SHORT 149%token LONG 150%token QUAD 151%token SQUAD 152%token FILL 153/* Output Section Discarding */ 154%token DISCARD 155/* Output Section Keywords */ 156%token CREATE_OBJECT_SYMBOLS 157%token CONSTRUCTORS 158/* Output Section Attributes */ 159/* Output Section Type */ 160%token NOLOAD 161%token DSECT 162%token COPY 163%token INFO 164%token OVERLAY 165/* Output Section LMA */ 166%token AT 167/* Forced Input Alignment */ 168%token SUBALIGN 169/* Output Section Constraint */ 170%token ONLY_IF_RO 171%token ONLY_IF_RW 172/* Operators are listed top to bottem, in ascending order */ 173%left ',' 174%right '=' ADD_ASSIGN SUB_ASSIGN MUL_ASSIGN DIV_ASSIGN AND_ASSIGN OR_ASSIGN LS_ASSIGN RS_ASSIGN 175%right '?' ':' 176%left LOGICAL_OR 177%left LOGICAL_AND 178%left '|' 179%left '^' 180%left '&' 181%left EQ NE 182%left '<' LE '>' GE 183%left LSHIFT RSHIFT 184%left '+' '-' 185%left '*' '/' '%' 186%right UNARY_PLUS UNARY_MINUS '!' '~' 187 188%type <integer> exp 189%type <string> string symbol opt_region opt_lma_region wildcard_pattern 190%type <rpn_expr> script_exp opt_lma opt_align opt_subalign opt_fill 191%type <str_token> input phdr 192%type <str_tokens> input_list opt_phdr opt_exclude_files input_sect_wildcard_patterns 193%type <output_prolog> output_desc_prolog opt_vma_and_type 194%type <output_type> opt_type type 195%type <output_constraint> opt_constraint 196%type <output_epilog> output_desc_epilog 197%type <wildcard> wildcard_file wildcard_section 198%type <input_spec> input_sect_spec 199 200%% 201 202script_file : LINKER_SCRIPT 203 { m_ScriptScanner.setLexState(ScriptFile::LDScript); } 204 linker_script 205 { m_ScriptScanner.popLexState(); } 206 ; 207 208linker_script : linker_script script_command 209 | /* Empty */ 210 ; 211 212script_command : entry_command 213 | output_format_command 214 | group_command 215 | output_command 216 | search_dir_command 217 | output_arch_command 218 | assert_command 219 | symbol_assignment 220 | sections_command 221 | ';' 222 ; 223 224entry_command : ENTRY '(' STRING ')' 225 { m_ScriptFile.addEntryPoint(*$3); } 226 ; 227 228output_format_command : OUTPUT_FORMAT '(' STRING ')' 229 { m_ScriptFile.addOutputFormatCmd(*$3); } 230 | OUTPUT_FORMAT '(' STRING ',' STRING ',' STRING ')' 231 { m_ScriptFile.addOutputFormatCmd(*$3, *$5, *$7); } 232 ; 233 234group_command : GROUP '(' input_list ')' 235 { m_ScriptFile.addGroupCmd(*$3, m_GroupReader, m_LDConfig); } 236 ; 237 238search_dir_command : SEARCH_DIR '(' STRING ')' 239 { m_ScriptFile.addSearchDirCmd(*$3); } 240 ; 241 242output_command : OUTPUT '(' STRING ')' 243 { m_ScriptFile.addOutputCmd(*$3); } 244 ; 245 246output_arch_command : OUTPUT_ARCH '(' STRING ')' 247 { m_ScriptFile.addOutputArchCmd(*$3); } 248 ; 249 250assert_command : ASSERT '(' script_exp ',' string ')' 251 { m_ScriptFile.addAssertCmd(*$3, *$5); } 252 ; 253 254input_list : { m_ScriptFile.createStringList(); } 255 inputs 256 { $$ = m_ScriptFile.getCurrentStringList(); } 257 ; 258 259inputs : input 260 { m_ScriptFile.getCurrentStringList()->push_back($1); } 261 | inputs input 262 { m_ScriptFile.getCurrentStringList()->push_back($2); } 263 | inputs ',' input 264 { m_ScriptFile.getCurrentStringList()->push_back($3); } 265 | AS_NEEDED '(' 266 { m_ScriptFile.setAsNeeded(true); } 267 inputs ')' 268 { m_ScriptFile.setAsNeeded(false); } 269 | inputs AS_NEEDED '(' 270 { m_ScriptFile.setAsNeeded(true); } 271 inputs ')' 272 { m_ScriptFile.setAsNeeded(false); } 273 | inputs ',' AS_NEEDED '(' 274 { m_ScriptFile.setAsNeeded(true); } 275 inputs ')' 276 { m_ScriptFile.setAsNeeded(false); } 277 ; 278 279input : string 280 { $$ = FileToken::create(*$1, m_ScriptFile.asNeeded()); } 281 | LNAMESPEC 282 { $$ = NameSpec::create(*$1, m_ScriptFile.asNeeded()); } 283 ; 284 285/* 286 SECTIONS 287 { 288 sections-command 289 sections-command 290 ... 291 } 292*/ 293sections_command : SECTIONS 294 { m_ScriptFile.enterSectionsCmd(); } 295 '{' sect_commands '}' 296 { m_ScriptFile.leaveSectionsCmd(); } 297 ; 298 299sect_commands : sect_commands sect_cmd 300 | /* Empty */ 301 ; 302 303/* 304Each sections-command may of be one of the following: 305 306an ENTRY command (see Entry command) 307a symbol assignment (see Assignments) 308an output section description 309an overlay description 310*/ 311sect_cmd : entry_command 312 | symbol_assignment 313 | output_sect_desc 314 ; 315 316/* 317The full description of an output section looks like this: 318 319 section [address] [(type)] : 320 [AT(lma)] 321 [ALIGN(section_align)] 322 [SUBALIGN(subsection_align)] 323 [constraint] 324 { 325 output-section-command 326 output-section-command 327 ... 328 } [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp] 329*/ 330output_sect_desc : string output_desc_prolog 331 { m_ScriptFile.enterOutputSectDesc(*$1, $2); } 332 '{' 333 output_sect_commands 334 '}' output_desc_epilog 335 { m_ScriptFile.leaveOutputSectDesc($7); } 336 ; 337 338output_desc_prolog : { 339 m_ScriptScanner.setLexState(ScriptFile::Expression); 340 /* create exp for vma */ 341 m_ScriptFile.createRpnExpr(); 342 } 343 opt_vma_and_type 344 { m_ScriptScanner.popLexState(); } 345 ':' 346 opt_lma opt_align opt_subalign opt_constraint 347 { 348 $$.m_pVMA = $2.m_pVMA; 349 $$.m_Type = $2.m_Type; 350 $$.m_pLMA = $5; 351 $$.m_pAlign = $6; 352 $$.m_pSubAlign = $7; 353 $$.m_Constraint = $8; 354 } 355 ; 356 357output_sect_commands : output_sect_commands output_sect_cmd 358 | /* Empty */ 359 ; 360 361output_desc_epilog : opt_region opt_lma_region opt_phdr opt_fill 362 { 363 $$.m_pRegion = $1; 364 $$.m_pLMARegion = $2; 365 $$.m_pPhdrs = $3; 366 $$.m_pFillExp = $4; 367 } 368 ; 369 370/* Output Section Attributes */ 371opt_vma_and_type : exp opt_type 372 { 373 $$.m_pVMA = m_ScriptFile.getCurrentRpnExpr(); 374 $$.m_Type = $2; 375 } 376 | opt_type 377 { 378 $$.m_pVMA = NULL; 379 $$.m_Type = $1; 380 } 381 ; 382 383opt_type : '(' type ')' 384 { $$ = $2; } 385 | '(' ')' 386 { $$ = OutputSectDesc::LOAD; } 387 | /* Empty */ 388 { $$ = OutputSectDesc::LOAD; } 389 ; 390 391type : NOLOAD 392 { $$ = OutputSectDesc::NOLOAD; } 393 | DSECT 394 { $$ = OutputSectDesc::DSECT; } 395 | COPY 396 { $$ = OutputSectDesc::COPY; } 397 | INFO 398 { $$ = OutputSectDesc::INFO; } 399 | OVERLAY 400 { $$ = OutputSectDesc::OVERLAY; } 401 ; 402 403opt_lma : AT '(' script_exp ')' 404 { $$ = $3; } 405 | /* Empty */ 406 { $$ = NULL; } 407 ; 408 409/* Forced Output Alignment */ 410opt_align : ALIGN '(' script_exp ')' 411 { $$ = $3; } 412 | /* Empty */ 413 { $$ = NULL; } 414 ; 415 416/* Forced Input Alignment */ 417opt_subalign : SUBALIGN '(' script_exp ')' 418 { $$ = $3; } 419 | /* Empty */ 420 { $$ = NULL; } 421 ; 422 423opt_constraint : ONLY_IF_RO 424 { $$ = OutputSectDesc::ONLY_IF_RO; } 425 | ONLY_IF_RW 426 { $$ = OutputSectDesc::ONLY_IF_RW; } 427 | /* Empty */ 428 { $$ = OutputSectDesc::NO_CONSTRAINT; } 429 ; 430 431opt_region : '>' string 432 { $$ = $2; } 433 | /* Empty */ 434 { $$ = NULL; } 435 ; 436 437opt_lma_region : AT '>' string 438 { $$ = $3; } 439 | /* Empty */ 440 { $$ = NULL; } 441 ; 442 443opt_phdr : { m_ScriptFile.createStringList(); } 444 phdrs 445 { $$ = m_ScriptFile.getCurrentStringList(); } 446 ; 447 448phdrs : phdrs ':' phdr 449 { m_ScriptFile.getCurrentStringList()->push_back($3); } 450 | /* Empty */ 451 ; 452 453phdr : string 454 { $$ = StrToken::create(*$1); } 455 ; 456 457opt_fill : '=' script_exp 458 { $$ = $2; } 459 | /* Empty */ 460 { $$ = NULL; } 461 ; 462 463/* 464Each output-section-command may be one of the following: 465 466a symbol assignment (see Assignments) 467an input section description (see Input Section) 468data values to include directly (see Output Section Data) 469a special output section keyword (see Output Section Keywords) 470*/ 471output_sect_cmd : symbol_assignment 472 | input_sect_desc 473 | output_sect_data 474 | output_sect_keyword 475 | ';' 476 ; 477 478input_sect_desc : input_sect_spec 479 { m_ScriptFile.addInputSectDesc(InputSectDesc::NoKeep, $1); } 480 | KEEP '(' input_sect_spec ')' 481 { m_ScriptFile.addInputSectDesc(InputSectDesc::Keep, $3); } 482 ; 483 484input_sect_spec : string 485 { 486 $$.m_pWildcardFile = 487 WildcardPattern::create(*$1, WildcardPattern::SORT_NONE); 488 $$.m_pExcludeFiles = NULL; 489 $$.m_pWildcardSections = NULL; 490 } 491 | wildcard_file '(' opt_exclude_files input_sect_wildcard_patterns ')' 492 { 493 $$.m_pWildcardFile = $1; 494 $$.m_pExcludeFiles = $3; 495 $$.m_pWildcardSections = $4; 496 } 497 ; 498 499wildcard_file : wildcard_pattern 500 { $$ = WildcardPattern::create(*$1, WildcardPattern::SORT_NONE); } 501 | SORT_BY_NAME '(' wildcard_pattern ')' 502 { $$ = WildcardPattern::create(*$3, WildcardPattern::SORT_BY_NAME); } 503 ; 504 505wildcard_pattern : string 506 { $$ = $1; } 507 | '*' 508 { $$ = &m_ScriptFile.createParserStr("*", 1); } 509 | '?' 510 { $$ = &m_ScriptFile.createParserStr("?", 1); } 511 ; 512 513opt_exclude_files : EXCLUDE_FILE '(' 514 { m_ScriptFile.createStringList(); } 515 exclude_files ')' 516 { $$ = m_ScriptFile.getCurrentStringList(); } 517 | /* Empty */ 518 { $$ = NULL; } 519 ; 520 521exclude_files : exclude_files wildcard_pattern 522 { 523 m_ScriptFile.getCurrentStringList()->push_back( 524 WildcardPattern::create(*$2, WildcardPattern::SORT_NONE)); 525 } 526 | wildcard_pattern 527 { 528 m_ScriptFile.getCurrentStringList()->push_back( 529 WildcardPattern::create(*$1, WildcardPattern::SORT_NONE)); 530 } 531 ; 532 533input_sect_wildcard_patterns : { m_ScriptFile.createStringList(); } 534 wildcard_sections 535 { $$ = m_ScriptFile.getCurrentStringList(); } 536 ; 537 538wildcard_sections : wildcard_sections wildcard_section 539 { 540 m_ScriptFile.getCurrentStringList()->push_back($2); 541 } 542 | wildcard_section 543 { 544 m_ScriptFile.getCurrentStringList()->push_back($1); 545 } 546 ; 547 548wildcard_section : wildcard_pattern 549 { $$ = WildcardPattern::create(*$1, WildcardPattern::SORT_NONE); } 550 | SORT_NONE '(' wildcard_pattern ')' 551 { $$ = WildcardPattern::create(*$3, WildcardPattern::SORT_NONE); } 552 | SORT_BY_NAME '(' wildcard_pattern ')' 553 { $$ = WildcardPattern::create(*$3, WildcardPattern::SORT_BY_NAME); } 554 | SORT_BY_ALIGNMENT '(' wildcard_pattern ')' 555 { $$ = WildcardPattern::create(*$3, WildcardPattern::SORT_BY_ALIGNMENT); } 556 | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_pattern ')' ')' 557 { $$ = WildcardPattern::create(*$5, WildcardPattern::SORT_BY_NAME_ALIGNMENT); } 558 | SORT_BY_ALIGNMENT '('SORT_BY_NAME '(' wildcard_pattern ')' ')' 559 { $$ = WildcardPattern::create(*$5, WildcardPattern::SORT_BY_ALIGNMENT_NAME); } 560 | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_pattern ')' ')' 561 { $$ = WildcardPattern::create(*$5, WildcardPattern::SORT_BY_NAME); } 562 | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_pattern ')' ')' 563 { $$ = WildcardPattern::create(*$5, WildcardPattern::SORT_BY_ALIGNMENT); } 564 | SORT_BY_INIT_PRIORITY '(' wildcard_pattern ')' 565 { $$ = WildcardPattern::create(*$3, WildcardPattern::SORT_BY_INIT_PRIORITY); } 566 ; 567 568output_sect_data : BYTE '(' script_exp ')' 569 | SHORT '(' script_exp ')' 570 | LONG '(' script_exp ')' 571 | QUAD '(' script_exp ')' 572 | SQUAD '(' script_exp ')' 573 ; 574 575output_sect_keyword : CREATE_OBJECT_SYMBOLS 576 | CONSTRUCTORS 577 | SORT_BY_NAME '(' CONSTRUCTORS ')' 578 ; 579 580symbol_assignment : symbol '=' script_exp ';' 581 { m_ScriptFile.addAssignment(*$1, *$3); } 582 | symbol ADD_ASSIGN exp ';' 583 | symbol SUB_ASSIGN exp ';' 584 | symbol MUL_ASSIGN exp ';' 585 | symbol DIV_ASSIGN exp ';' 586 | symbol AND_ASSIGN exp ';' 587 | symbol OR_ASSIGN exp ';' 588 | symbol LS_ASSIGN exp ';' 589 | symbol RS_ASSIGN exp ';' 590 | HIDDEN '(' symbol '=' script_exp ')' ';' 591 { 592 m_ScriptFile.addAssignment(*$3, *$5, 593 Assignment::HIDDEN); 594 } 595 | PROVIDE '(' symbol '=' script_exp ')' ';' 596 { 597 m_ScriptFile.addAssignment(*$3, *$5, 598 Assignment::PROVIDE); 599 } 600 | PROVIDE_HIDDEN '(' symbol '=' script_exp ')' ';' 601 { 602 m_ScriptFile.addAssignment(*$3, *$5, 603 Assignment::PROVIDE_HIDDEN); 604 } 605 ; 606 607script_exp : { 608 m_ScriptScanner.setLexState(ScriptFile::Expression); 609 m_ScriptFile.createRpnExpr(); 610 } 611 exp 612 { 613 m_ScriptScanner.popLexState(); 614 $$ = m_ScriptFile.getCurrentRpnExpr(); 615 } 616 ; 617 618exp : '(' exp ')' 619 { 620 $$ = $2; 621 } 622 | '+' exp %prec UNARY_PLUS 623 { 624 m_ScriptFile.getCurrentRpnExpr()->push_back( 625 &Operator::create<Operator::UNARY_PLUS>()); 626 $$ = $2 + 1; 627 } 628 | '-' exp %prec UNARY_MINUS 629 { 630 m_ScriptFile.getCurrentRpnExpr()->push_back( 631 &Operator::create<Operator::UNARY_MINUS>()); 632 $$ = $2 + 1; 633 } 634 | '!' exp 635 { 636 m_ScriptFile.getCurrentRpnExpr()->push_back( 637 &Operator::create<Operator::LOGICAL_NOT>()); 638 $$ = $2 + 1; 639 } 640 | '~' exp 641 { 642 m_ScriptFile.getCurrentRpnExpr()->push_back( 643 &Operator::create<Operator::BITWISE_NOT>()); 644 $$ = $2 + 1; 645 } 646 | exp '*' exp 647 { 648 m_ScriptFile.getCurrentRpnExpr()->push_back( 649 &Operator::create<Operator::MUL>()); 650 $$ = $1 + $3 + 1; 651 } 652 | exp '/' exp 653 { 654 m_ScriptFile.getCurrentRpnExpr()->push_back( 655 &Operator::create<Operator::DIV>()); 656 $$ = $1 + $3 + 1; 657 } 658 | exp '%' exp 659 { 660 m_ScriptFile.getCurrentRpnExpr()->push_back( 661 &Operator::create<Operator::MOD>()); 662 $$ = $1 + $3 + 1; 663 } 664 | exp '+' exp 665 { 666 m_ScriptFile.getCurrentRpnExpr()->push_back( 667 &Operator::create<Operator::ADD>()); 668 $$ = $1 + $3 + 1; 669 } 670 | exp '-' exp 671 { 672 m_ScriptFile.getCurrentRpnExpr()->push_back( 673 &Operator::create<Operator::SUB>()); 674 $$ = $1 + $3 + 1; 675 } 676 | exp LSHIFT exp 677 { 678 m_ScriptFile.getCurrentRpnExpr()->push_back( 679 &Operator::create<Operator::LSHIFT>()); 680 $$ = $1 + $3 + 1; 681 } 682 | exp RSHIFT exp 683 { 684 m_ScriptFile.getCurrentRpnExpr()->push_back( 685 &Operator::create<Operator::RSHIFT>()); 686 $$ = $1 + $3 + 1; 687 } 688 | exp '<' exp 689 { 690 m_ScriptFile.getCurrentRpnExpr()->push_back( 691 &Operator::create<Operator::LT>()); 692 $$ = $1 + $3 + 1; 693 } 694 | exp LE exp 695 { 696 m_ScriptFile.getCurrentRpnExpr()->push_back( 697 &Operator::create<Operator::LE>()); 698 $$ = $1 + $3 + 1; 699 } 700 | exp '>' exp 701 { 702 m_ScriptFile.getCurrentRpnExpr()->push_back( 703 &Operator::create<Operator::GT>()); 704 $$ = $1 + $3 + 1; 705 } 706 | exp GE exp 707 { 708 m_ScriptFile.getCurrentRpnExpr()->push_back( 709 &Operator::create<Operator::GE>()); 710 $$ = $1 + $3 + 1; 711 } 712 | exp EQ exp 713 { 714 m_ScriptFile.getCurrentRpnExpr()->push_back( 715 &Operator::create<Operator::EQ>()); 716 $$ = $1 + $3 + 1; 717 } 718 | exp NE exp 719 { 720 m_ScriptFile.getCurrentRpnExpr()->push_back( 721 &Operator::create<Operator::NE>()); 722 $$ = $1 + $3 + 1; 723 } 724 | exp '&' exp 725 { 726 m_ScriptFile.getCurrentRpnExpr()->push_back( 727 &Operator::create<Operator::BITWISE_AND>()); 728 $$ = $1 + $3 + 1; 729 } 730 | exp '^' exp 731 { 732 m_ScriptFile.getCurrentRpnExpr()->push_back( 733 &Operator::create<Operator::BITWISE_XOR>()); 734 $$ = $1 + $3 + 1; 735 } 736 | exp '|' exp 737 { 738 m_ScriptFile.getCurrentRpnExpr()->push_back( 739 &Operator::create<Operator::BITWISE_OR>()); 740 $$ = $1 + $3 + 1; 741 } 742 | exp LOGICAL_AND exp 743 { 744 m_ScriptFile.getCurrentRpnExpr()->push_back( 745 &Operator::create<Operator::LOGICAL_AND>()); 746 $$ = $1 + $3 + 1; 747 } 748 | exp LOGICAL_OR exp 749 { 750 m_ScriptFile.getCurrentRpnExpr()->push_back( 751 &Operator::create<Operator::LOGICAL_OR>()); 752 $$ = $1 + $3 + 1; 753 } 754 | exp '?' exp ':' exp 755 { 756 m_ScriptFile.getCurrentRpnExpr()->push_back( 757 &Operator::create<Operator::TERNARY_IF>()); 758 $$ = $1 + $3 + $5 + 1; 759 } 760 | ABSOLUTE '(' exp ')' 761 { 762 m_ScriptFile.getCurrentRpnExpr()->push_back( 763 &Operator::create<Operator::ABSOLUTE>()); 764 $$ = $3 + 1; 765 } 766 | ADDR '(' string ')' 767 { 768 m_ScriptFile.getCurrentRpnExpr()->push_back(SectOperand::create(*$3)); 769 m_ScriptFile.getCurrentRpnExpr()->push_back( 770 &Operator::create<Operator::ADDR>()); 771 $$ = 2; 772 } 773 | ALIGN '(' exp ')' 774 { 775 RpnExpr::iterator pos = m_ScriptFile.getCurrentRpnExpr()->begin() + 776 m_ScriptFile.getCurrentRpnExpr()->size() - $3; 777 m_ScriptFile.getCurrentRpnExpr()->insert(pos, SymOperand::create(".")); 778 m_ScriptFile.getCurrentRpnExpr()->push_back( 779 &Operator::create<Operator::ALIGN>()); 780 $$ = $3 + 2; 781 } 782 | ALIGN '(' exp ',' exp ')' 783 { 784 m_ScriptFile.getCurrentRpnExpr()->push_back( 785 &Operator::create<Operator::ALIGN>()); 786 $$ = $3 + $5 + 1; 787 } 788 | ALIGNOF '(' string ')' 789 { 790 m_ScriptFile.getCurrentRpnExpr()->push_back(SectOperand::create(*$3)); 791 m_ScriptFile.getCurrentRpnExpr()->push_back( 792 &Operator::create<Operator::ALIGNOF>()); 793 $$ = 2; 794 } 795 | BLOCK '(' exp ')' 796 { 797 RpnExpr::iterator pos = m_ScriptFile.getCurrentRpnExpr()->begin() + 798 m_ScriptFile.getCurrentRpnExpr()->size() - $3; 799 m_ScriptFile.getCurrentRpnExpr()->insert(pos, SymOperand::create(".")); 800 m_ScriptFile.getCurrentRpnExpr()->push_back( 801 &Operator::create<Operator::ALIGN>()); 802 $$ = $3 + 2; 803 } 804 | DATA_SEGMENT_ALIGN 805 { 806 m_ScriptFile.getCurrentRpnExpr()->push_back(SymOperand::create(".")); 807 } 808 '(' exp ',' exp ')' 809 { 810 m_ScriptFile.getCurrentRpnExpr()->push_back( 811 &Operator::create<Operator::DATA_SEGMENT_ALIGN>()); 812 $$ = $4 + $6 + 2; 813 } 814 | DATA_SEGMENT_END '(' exp ')' 815 { 816 m_ScriptFile.getCurrentRpnExpr()->push_back( 817 &Operator::create<Operator::DATA_SEGMENT_END>()); 818 $$ = $3 + 1; 819 } 820 | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')' 821 { 822 m_ScriptFile.getCurrentRpnExpr()->push_back( 823 &Operator::create<Operator::DATA_SEGMENT_RELRO_END>()); 824 $$ = $3 + $5 + 1; 825 } 826 | DEFINED '(' symbol ')' 827 { 828 m_ScriptFile.getCurrentRpnExpr()->push_back(SymOperand::create(*$3)); 829 m_ScriptFile.getCurrentRpnExpr()->push_back( 830 &Operator::create<Operator::DEFINED>()); 831 $$ = 2; 832 } 833 | LENGTH '(' string ')' 834 { 835 /* TODO */ 836 } 837 | LOADADDR '(' string ')' 838 { 839 m_ScriptFile.getCurrentRpnExpr()->push_back(SectOperand::create(*$3)); 840 m_ScriptFile.getCurrentRpnExpr()->push_back( 841 &Operator::create<Operator::LOADADDR>()); 842 $$ = 2; 843 } 844 | MAX '(' exp ',' exp ')' 845 { 846 m_ScriptFile.getCurrentRpnExpr()->push_back( 847 &Operator::create<Operator::MAX>()); 848 $$ = $3 + $5 + 1; 849 } 850 | MIN '(' exp ',' exp ')' 851 { 852 m_ScriptFile.getCurrentRpnExpr()->push_back( 853 &Operator::create<Operator::MIN>()); 854 $$ = $3 + $5 + 1; 855 } 856 | NEXT '(' exp ')' 857 { 858 m_ScriptFile.getCurrentRpnExpr()->push_back( 859 &Operator::create<Operator::NEXT>()); 860 $$ = $3 + 1; 861 } 862 | ORIGIN '(' string ')' 863 { 864 /* TODO */ 865 } 866 | SEGMENT_START '(' string 867 { 868 m_ScriptFile.getCurrentRpnExpr()->push_back(SectOperand::create(*$3)); 869 } 870 ',' exp ')' 871 { 872 m_ScriptFile.getCurrentRpnExpr()->push_back( 873 &Operator::create<Operator::SEGMENT_START>()); 874 $$ = $6 + 2; 875 } 876 | SIZEOF '(' string ')' 877 { 878 m_ScriptFile.getCurrentRpnExpr()->push_back(SectOperand::create(*$3)); 879 m_ScriptFile.getCurrentRpnExpr()->push_back( 880 &Operator::create<Operator::SIZEOF>()); 881 $$ = 2; 882 } 883 | SIZEOF_HEADERS 884 { 885 m_ScriptFile.getCurrentRpnExpr()->push_back( 886 &Operator::create<Operator::SIZEOF_HEADERS>()); 887 $$ = 1; 888 } 889 | CONSTANT '(' MAXPAGESIZE ')' 890 { 891 m_ScriptFile.getCurrentRpnExpr()->push_back( 892 &Operator::create<Operator::MAXPAGESIZE>()); 893 $$ = 1; 894 } 895 | CONSTANT '(' COMMONPAGESIZE')' 896 { 897 m_ScriptFile.getCurrentRpnExpr()->push_back( 898 &Operator::create<Operator::COMMONPAGESIZE>()); 899 $$ = 1; 900 } 901 | INTEGER 902 { 903 m_ScriptFile.getCurrentRpnExpr()->push_back(IntOperand::create($1)); 904 $$ = 1; 905 } 906 | symbol 907 { 908 m_ScriptFile.getCurrentRpnExpr()->push_back(SymOperand::create(*$1)); 909 $$ = 1; 910 } 911 ; 912 913symbol : STRING 914 { $$ = $1; } 915 ; 916 917string : STRING 918 { $$ = $1; } 919 | '"' STRING '"' 920 { $$ = $2; } 921 ; 922 923%% 924 925void mcld::ScriptParser::error(const mcld::ScriptParser::location_type& pLoc, 926 const std::string &pMsg) 927{ 928 position last = pLoc.end - 1; 929 std::string filename = "NaN"; 930 if (last.filename != NULL) 931 filename = *last.filename; 932 933 mcld::error(diag::err_syntax_error) 934 << filename << last.line << last.column << pMsg; 935} 936 937