comparison lib/MC/MCParser/COFFAsmParser.cpp @ 121:803732b1fca8

LLVM 5.0
author kono
date Fri, 27 Oct 2017 17:07:41 +0900
parents 1172e4bd9c6f
children
comparison
equal deleted inserted replaced
120:1172e4bd9c6f 121:803732b1fca8
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 9
10 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/ADT/StringSwitch.h" 11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/ADT/Triple.h"
12 #include "llvm/ADT/Twine.h" 13 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmInfo.h" 14 #include "llvm/BinaryFormat/COFF.h"
14 #include "llvm/MC/MCContext.h" 15 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCExpr.h" 16 #include "llvm/MC/MCDirectives.h"
16 #include "llvm/MC/MCObjectFileInfo.h" 17 #include "llvm/MC/MCObjectFileInfo.h"
17 #include "llvm/MC/MCParser/MCAsmLexer.h" 18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
18 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 20 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
19 #include "llvm/MC/MCRegisterInfo.h" 21 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSectionCOFF.h" 22 #include "llvm/MC/MCSectionCOFF.h"
21 #include "llvm/MC/MCStreamer.h" 23 #include "llvm/MC/MCStreamer.h"
22 #include "llvm/Support/COFF.h" 24 #include "llvm/MC/SectionKind.h"
25 #include "llvm/Support/SMLoc.h"
26 #include <cassert>
27 #include <cstdint>
28 #include <limits>
29 #include <utility>
30
23 using namespace llvm; 31 using namespace llvm;
24 32
25 namespace { 33 namespace {
26 34
27 class COFFAsmParser : public MCAsmParserExtension { 35 class COFFAsmParser : public MCAsmParserExtension {
96 COFF::IMAGE_SCN_CNT_CODE 104 COFF::IMAGE_SCN_CNT_CODE
97 | COFF::IMAGE_SCN_MEM_EXECUTE 105 | COFF::IMAGE_SCN_MEM_EXECUTE
98 | COFF::IMAGE_SCN_MEM_READ, 106 | COFF::IMAGE_SCN_MEM_READ,
99 SectionKind::getText()); 107 SectionKind::getText());
100 } 108 }
109
101 bool ParseSectionDirectiveData(StringRef, SMLoc) { 110 bool ParseSectionDirectiveData(StringRef, SMLoc) {
102 return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 111 return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
103 COFF::IMAGE_SCN_MEM_READ | 112 COFF::IMAGE_SCN_MEM_READ |
104 COFF::IMAGE_SCN_MEM_WRITE, 113 COFF::IMAGE_SCN_MEM_WRITE,
105 SectionKind::getData()); 114 SectionKind::getData());
106 } 115 }
116
107 bool ParseSectionDirectiveBSS(StringRef, SMLoc) { 117 bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
108 return ParseSectionSwitch(".bss", 118 return ParseSectionSwitch(".bss",
109 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA 119 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
110 | COFF::IMAGE_SCN_MEM_READ 120 | COFF::IMAGE_SCN_MEM_READ
111 | COFF::IMAGE_SCN_MEM_WRITE, 121 | COFF::IMAGE_SCN_MEM_WRITE,
139 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc); 149 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
140 150
141 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except); 151 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
142 bool ParseSEHRegisterNumber(unsigned &RegNo); 152 bool ParseSEHRegisterNumber(unsigned &RegNo);
143 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc); 153 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
154
144 public: 155 public:
145 COFFAsmParser() {} 156 COFFAsmParser() = default;
146 }; 157 };
147 158
148 } // end annonomous namespace. 159 } // end annonomous namespace.
149 160
150 static SectionKind computeSectionKind(unsigned Flags) { 161 static SectionKind computeSectionKind(unsigned Flags) {
275 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) 286 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
276 .Case(".weak", MCSA_Weak) 287 .Case(".weak", MCSA_Weak)
277 .Default(MCSA_Invalid); 288 .Default(MCSA_Invalid);
278 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); 289 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
279 if (getLexer().isNot(AsmToken::EndOfStatement)) { 290 if (getLexer().isNot(AsmToken::EndOfStatement)) {
280 for (;;) { 291 while (true) {
281 StringRef Name; 292 StringRef Name;
282 293
283 if (getParser().parseIdentifier(Name)) 294 if (getParser().parseIdentifier(Name))
284 return TokError("expected identifier in directive"); 295 return TokError("expected identifier in directive");
285 296
453 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { 464 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
454 StringRef SymbolID; 465 StringRef SymbolID;
455 if (getParser().parseIdentifier(SymbolID)) 466 if (getParser().parseIdentifier(SymbolID))
456 return TokError("expected identifier in directive"); 467 return TokError("expected identifier in directive");
457 468
458 if (getLexer().isNot(AsmToken::EndOfStatement)) 469 int64_t Offset = 0;
459 return TokError("unexpected token in directive"); 470 SMLoc OffsetLoc;
471 if (getLexer().is(AsmToken::Plus)) {
472 OffsetLoc = getLexer().getLoc();
473 if (getParser().parseAbsoluteExpression(Offset))
474 return true;
475 }
476
477 if (getLexer().isNot(AsmToken::EndOfStatement))
478 return TokError("unexpected token in directive");
479
480 if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max())
481 return Error(
482 OffsetLoc,
483 "invalid '.secrel32' directive offset, can't be less "
484 "than zero or greater than std::numeric_limits<uint32_t>::max()");
460 485
461 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); 486 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
462 487
463 Lex(); 488 Lex();
464 getStreamer().EmitCOFFSecRel32(Symbol); 489 getStreamer().EmitCOFFSecRel32(Symbol, Offset);
465 return false; 490 return false;
466 } 491 }
467 492
468 bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) { 493 bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
469 StringRef SymbolID; 494 StringRef SymbolID;
541 return TokError("unexpected token in directive"); 566 return TokError("unexpected token in directive");
542 567
543 return false; 568 return false;
544 } 569 }
545 570
546 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { 571 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
547 StringRef SymbolID; 572 StringRef SymbolID;
548 if (getParser().parseIdentifier(SymbolID)) 573 if (getParser().parseIdentifier(SymbolID))
549 return true; 574 return true;
550 575
551 if (getLexer().isNot(AsmToken::EndOfStatement)) 576 if (getLexer().isNot(AsmToken::EndOfStatement))
552 return TokError("unexpected token in directive"); 577 return TokError("unexpected token in directive");
553 578
554 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); 579 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
555 580
556 Lex(); 581 Lex();
557 getStreamer().EmitWinCFIStartProc(Symbol); 582 getStreamer().EmitWinCFIStartProc(Symbol, Loc);
558 return false; 583 return false;
559 } 584 }
560 585
561 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) { 586 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
562 Lex(); 587 Lex();
563 getStreamer().EmitWinCFIEndProc(); 588 getStreamer().EmitWinCFIEndProc(Loc);
564 return false; 589 return false;
565 } 590 }
566 591
567 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) { 592 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
568 Lex(); 593 Lex();
569 getStreamer().EmitWinCFIStartChained(); 594 getStreamer().EmitWinCFIStartChained(Loc);
570 return false; 595 return false;
571 } 596 }
572 597
573 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) { 598 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
574 Lex(); 599 Lex();
575 getStreamer().EmitWinCFIEndChained(); 600 getStreamer().EmitWinCFIEndChained(Loc);
576 return false; 601 return false;
577 } 602 }
578 603
579 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) { 604 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
580 StringRef SymbolID; 605 StringRef SymbolID;
581 if (getParser().parseIdentifier(SymbolID)) 606 if (getParser().parseIdentifier(SymbolID))
582 return true; 607 return true;
583 608
584 if (getLexer().isNot(AsmToken::Comma)) 609 if (getLexer().isNot(AsmToken::Comma))
596 return TokError("unexpected token in directive"); 621 return TokError("unexpected token in directive");
597 622
598 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID); 623 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
599 624
600 Lex(); 625 Lex();
601 getStreamer().EmitWinEHHandler(handler, unwind, except); 626 getStreamer().EmitWinEHHandler(handler, unwind, except, Loc);
602 return false; 627 return false;
603 } 628 }
604 629
605 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) { 630 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
606 Lex(); 631 Lex();
607 getStreamer().EmitWinEHHandlerData(); 632 getStreamer().EmitWinEHHandlerData();
608 return false; 633 return false;
609 } 634 }
610 635
611 bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) { 636 bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc Loc) {
612 unsigned Reg = 0; 637 unsigned Reg = 0;
613 if (ParseSEHRegisterNumber(Reg)) 638 if (ParseSEHRegisterNumber(Reg))
614 return true; 639 return true;
615 640
616 if (getLexer().isNot(AsmToken::EndOfStatement)) 641 if (getLexer().isNot(AsmToken::EndOfStatement))
617 return TokError("unexpected token in directive"); 642 return TokError("unexpected token in directive");
618 643
619 Lex(); 644 Lex();
620 getStreamer().EmitWinCFIPushReg(Reg); 645 getStreamer().EmitWinCFIPushReg(Reg, Loc);
621 return false; 646 return false;
622 } 647 }
623 648
624 bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) { 649 bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc Loc) {
625 unsigned Reg = 0; 650 unsigned Reg = 0;
626 int64_t Off; 651 int64_t Off;
627 if (ParseSEHRegisterNumber(Reg)) 652 if (ParseSEHRegisterNumber(Reg))
628 return true; 653 return true;
629 if (getLexer().isNot(AsmToken::Comma)) 654 if (getLexer().isNot(AsmToken::Comma))
630 return TokError("you must specify a stack pointer offset"); 655 return TokError("you must specify a stack pointer offset");
631 656
632 Lex(); 657 Lex();
633 SMLoc startLoc = getLexer().getLoc();
634 if (getParser().parseAbsoluteExpression(Off)) 658 if (getParser().parseAbsoluteExpression(Off))
635 return true; 659 return true;
636 660
637 if (Off & 0x0F) 661 if (getLexer().isNot(AsmToken::EndOfStatement))
638 return Error(startLoc, "offset is not a multiple of 16"); 662 return TokError("unexpected token in directive");
639 663
640 if (getLexer().isNot(AsmToken::EndOfStatement)) 664 Lex();
641 return TokError("unexpected token in directive"); 665 getStreamer().EmitWinCFISetFrame(Reg, Off, Loc);
642 666 return false;
643 Lex(); 667 }
644 getStreamer().EmitWinCFISetFrame(Reg, Off); 668
645 return false; 669 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
646 }
647
648 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
649 int64_t Size; 670 int64_t Size;
650 SMLoc startLoc = getLexer().getLoc();
651 if (getParser().parseAbsoluteExpression(Size)) 671 if (getParser().parseAbsoluteExpression(Size))
652 return true; 672 return true;
653 673
654 if (Size & 7) 674 if (getLexer().isNot(AsmToken::EndOfStatement))
655 return Error(startLoc, "size is not a multiple of 8"); 675 return TokError("unexpected token in directive");
656 676
657 if (getLexer().isNot(AsmToken::EndOfStatement)) 677 Lex();
658 return TokError("unexpected token in directive"); 678 getStreamer().EmitWinCFIAllocStack(Size, Loc);
659 679 return false;
660 Lex(); 680 }
661 getStreamer().EmitWinCFIAllocStack(Size); 681
662 return false; 682 bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc Loc) {
663 }
664
665 bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
666 unsigned Reg = 0; 683 unsigned Reg = 0;
667 int64_t Off; 684 int64_t Off;
668 if (ParseSEHRegisterNumber(Reg)) 685 if (ParseSEHRegisterNumber(Reg))
669 return true; 686 return true;
670 if (getLexer().isNot(AsmToken::Comma)) 687 if (getLexer().isNot(AsmToken::Comma))
671 return TokError("you must specify an offset on the stack"); 688 return TokError("you must specify an offset on the stack");
672 689
673 Lex(); 690 Lex();
674 SMLoc startLoc = getLexer().getLoc();
675 if (getParser().parseAbsoluteExpression(Off)) 691 if (getParser().parseAbsoluteExpression(Off))
676 return true; 692 return true;
677 693
678 if (Off & 7)
679 return Error(startLoc, "size is not a multiple of 8");
680
681 if (getLexer().isNot(AsmToken::EndOfStatement)) 694 if (getLexer().isNot(AsmToken::EndOfStatement))
682 return TokError("unexpected token in directive"); 695 return TokError("unexpected token in directive");
683 696
684 Lex(); 697 Lex();
685 // FIXME: Err on %xmm* registers 698 // FIXME: Err on %xmm* registers
686 getStreamer().EmitWinCFISaveReg(Reg, Off); 699 getStreamer().EmitWinCFISaveReg(Reg, Off, Loc);
687 return false; 700 return false;
688 } 701 }
689 702
690 // FIXME: This method is inherently x86-specific. It should really be in the 703 // FIXME: This method is inherently x86-specific. It should really be in the
691 // x86 backend. 704 // x86 backend.
692 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) { 705 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc Loc) {
693 unsigned Reg = 0; 706 unsigned Reg = 0;
694 int64_t Off; 707 int64_t Off;
695 if (ParseSEHRegisterNumber(Reg)) 708 if (ParseSEHRegisterNumber(Reg))
696 return true; 709 return true;
697 if (getLexer().isNot(AsmToken::Comma)) 710 if (getLexer().isNot(AsmToken::Comma))
698 return TokError("you must specify an offset on the stack"); 711 return TokError("you must specify an offset on the stack");
699 712
700 Lex(); 713 Lex();
701 SMLoc startLoc = getLexer().getLoc();
702 if (getParser().parseAbsoluteExpression(Off)) 714 if (getParser().parseAbsoluteExpression(Off))
703 return true; 715 return true;
704 716
705 if (getLexer().isNot(AsmToken::EndOfStatement)) 717 if (getLexer().isNot(AsmToken::EndOfStatement))
706 return TokError("unexpected token in directive"); 718 return TokError("unexpected token in directive");
707 719
708 if (Off & 0x0F)
709 return Error(startLoc, "offset is not a multiple of 16");
710
711 Lex(); 720 Lex();
712 // FIXME: Err on non-%xmm* registers 721 // FIXME: Err on non-%xmm* registers
713 getStreamer().EmitWinCFISaveXMM(Reg, Off); 722 getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc);
714 return false; 723 return false;
715 } 724 }
716 725
717 bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) { 726 bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc Loc) {
718 bool Code = false; 727 bool Code = false;
719 StringRef CodeID; 728 StringRef CodeID;
720 if (getLexer().is(AsmToken::At)) { 729 if (getLexer().is(AsmToken::At)) {
721 SMLoc startLoc = getLexer().getLoc(); 730 SMLoc startLoc = getLexer().getLoc();
722 Lex(); 731 Lex();
729 738
730 if (getLexer().isNot(AsmToken::EndOfStatement)) 739 if (getLexer().isNot(AsmToken::EndOfStatement))
731 return TokError("unexpected token in directive"); 740 return TokError("unexpected token in directive");
732 741
733 Lex(); 742 Lex();
734 getStreamer().EmitWinCFIPushFrame(Code); 743 getStreamer().EmitWinCFIPushFrame(Code, Loc);
735 return false; 744 return false;
736 } 745 }
737 746
738 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) { 747 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
739 Lex(); 748 Lex();
740 getStreamer().EmitWinCFIEndProlog(); 749 getStreamer().EmitWinCFIEndProlog(Loc);
741 return false; 750 return false;
742 } 751 }
743 752
744 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) { 753 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
745 StringRef identifier; 754 StringRef identifier;
802 811
803 MCAsmParserExtension *createCOFFAsmParser() { 812 MCAsmParserExtension *createCOFFAsmParser() {
804 return new COFFAsmParser; 813 return new COFFAsmParser;
805 } 814 }
806 815
807 } 816 } // end namespace llvm