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