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