blob: 3bda9bccfa50d0dcedfe23da3e96f26b010cfcf3 [file] [log] [blame]
Stephen Hines87f34652014-02-14 18:00:16 -08001/*===- 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 */
Stephen Hines37b74a32014-11-26 18:48:20 -080012#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"
Stephen Hines87f34652014-02-14 18:00:16 -080022using namespace mcld;
23
24#undef yylex
25#define yylex m_ScriptScanner.lex
26%}
27
28%code requires {
Stephen Hines37b74a32014-11-26 18:48:20 -080029#include "mcld/Script/StrToken.h"
30#include "mcld/Script/StringList.h"
31#include "mcld/Script/OutputSectDesc.h"
32#include "mcld/Script/InputSectDesc.h"
Stephen Hines87f34652014-02-14 18:00:16 -080033#include <llvm/Support/DataTypes.h>
34
35using namespace mcld;
36
37}
38
Stephen Hines87f34652014-02-14 18:00:16 -080039%require "2.4"
40%skeleton "glr.cc"
Tim Murray3a2e3002014-04-25 14:33:27 -070041/*
42 * BEGIN android-removed: prevent bison from generating the header in current directory
Stephen Hines87f34652014-02-14 18:00:16 -080043%defines "ScriptParser.h"
Tim Murray3a2e3002014-04-25 14:33:27 -070044 * END android-removed
45 */
Stephen Hines87f34652014-02-14 18:00:16 -080046%debug
Dan Willemsen1ee66002019-12-30 11:21:15 -080047%define parse.error verbose
48%define api.namespace {mcld}
49%define api.parser.class {ScriptParser}
Stephen Hines87f34652014-02-14 18:00:16 -080050%parse-param { const class LinkerConfig& m_LDConfig }
51%parse-param { class ScriptFile& m_ScriptFile }
52%parse-param { class ScriptScanner& m_ScriptScanner }
Stephen Hines37b74a32014-11-26 18:48:20 -080053%parse-param { class ObjectReader& m_ObjectReader}
54%parse-param { class ArchiveReader& m_ArchiveReader}
55%parse-param { class DynObjReader& m_DynObjReader}
Stephen Hines87f34652014-02-14 18:00:16 -080056%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
Stephen Hines37b74a32014-11-26 18:48:20 -0800221 | input_command
Stephen Hines87f34652014-02-14 18:00:16 -0800222 | 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
Stephen Hines37b74a32014-11-26 18:48:20 -0800245input_command : INPUT '(' input_list ')'
246 {
247 m_ScriptFile.addInputCmd(*$3, m_ObjectReader, m_ArchiveReader,
248 m_DynObjReader, m_LDConfig);
249 }
250 ;
251
Stephen Hines87f34652014-02-14 18:00:16 -0800252search_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