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