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