diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index ce35f07106dd80832938b90d9a90f23d1b08ef78..bee57b8c5e3958a9df6bf3ceb466c93bf061ee9b 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -159,7 +159,7 @@ private: InfixOperatorStack.push_back(Op); } - int64_t execute() { + int64_t execute(unsigned int &KsError) { // qq // Push any remaining operators onto the postfix stack. while (!InfixOperatorStack.empty()) { InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val(); @@ -176,7 +176,12 @@ private: if (Op.first == IC_IMM || Op.first == IC_REGISTER) { OperandStack.push_back(Op); } else { - assert (OperandStack.size() > 1 && "Too few operands."); + //assert (OperandStack.size() > 1 && "Too few operands."); + if (OperandStack.size() <= 1) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } int64_t Val; ICToken Op2 = OperandStack.pop_back_val(); ICToken Op1 = OperandStack.pop_back_val(); @@ -193,52 +198,92 @@ private: OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; case IC_MULTIPLY: - assert (Op1.first == IC_IMM && Op2.first == IC_IMM && - "Multiply operation with an immediate and a register!"); + //assert (Op1.first == IC_IMM && Op2.first == IC_IMM && + // "Multiply operation with an immediate and a register!"); + if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } Val = Op1.second * Op2.second; OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; case IC_DIVIDE: - assert (Op1.first == IC_IMM && Op2.first == IC_IMM && - "Divide operation with an immediate and a register!"); - assert (Op2.second != 0 && "Division by zero!"); + //assert (Op1.first == IC_IMM && Op2.first == IC_IMM && + // "Divide operation with an immediate and a register!"); + //assert (Op2.second != 0 && "Division by zero!"); + if (!(Op1.first == IC_IMM && Op2.first == IC_IMM) || Op2.second == 0) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } Val = Op1.second / Op2.second; OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; case IC_OR: - assert (Op1.first == IC_IMM && Op2.first == IC_IMM && - "Or operation with an immediate and a register!"); + //assert (Op1.first == IC_IMM && Op2.first == IC_IMM && + // "Or operation with an immediate and a register!"); + if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } Val = Op1.second | Op2.second; OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; case IC_XOR: - assert(Op1.first == IC_IMM && Op2.first == IC_IMM && - "Xor operation with an immediate and a register!"); + //assert(Op1.first == IC_IMM && Op2.first == IC_IMM && + // "Xor operation with an immediate and a register!"); + if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } Val = Op1.second ^ Op2.second; OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; case IC_AND: - assert (Op1.first == IC_IMM && Op2.first == IC_IMM && - "And operation with an immediate and a register!"); + //assert (Op1.first == IC_IMM && Op2.first == IC_IMM && + // "And operation with an immediate and a register!"); + if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } Val = Op1.second & Op2.second; OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; case IC_LSHIFT: - assert (Op1.first == IC_IMM && Op2.first == IC_IMM && - "Left shift operation with an immediate and a register!"); + //assert (Op1.first == IC_IMM && Op2.first == IC_IMM && + // "Left shift operation with an immediate and a register!"); + if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } Val = Op1.second << Op2.second; OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; case IC_RSHIFT: - assert (Op1.first == IC_IMM && Op2.first == IC_IMM && - "Right shift operation with an immediate and a register!"); + //assert (Op1.first == IC_IMM && Op2.first == IC_IMM && + // "Right shift operation with an immediate and a register!"); + if (!(Op1.first == IC_IMM && Op2.first == IC_IMM)) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } Val = Op1.second >> Op2.second; OperandStack.push_back(std::make_pair(IC_IMM, Val)); break; } } } - assert (OperandStack.size() == 1 && "Expected a single result."); + //assert (OperandStack.size() == 1 && "Expected a single result."); + if (OperandStack.size() != 1) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + // return a dummy value + return 0; + } return OperandStack.pop_back_val().second; } }; @@ -285,7 +330,7 @@ private: unsigned getScale() { return Scale; } const MCExpr *getSym() { return Sym; } StringRef getSymName() { return SymName; } - int64_t getImm() { return Imm + IC.execute(); } + int64_t getImm(unsigned int &KsError) { return Imm + IC.execute(KsError); } bool isValidEndState() { return State == IES_RBRAC || State == IES_INTEGER; } @@ -704,22 +749,22 @@ private: std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst); bool VerifyAndAdjustOperands(OperandVector &OrigOperands, OperandVector &FinalOperands); - std::unique_ptr<X86Operand> ParseOperand(StringRef Mnem); + std::unique_ptr<X86Operand> ParseOperand(StringRef Mnem, unsigned int &KsError); std::unique_ptr<X86Operand> ParseATTOperand(); - std::unique_ptr<X86Operand> ParseIntelOperand(StringRef Mnem); + std::unique_ptr<X86Operand> ParseIntelOperand(StringRef Mnem, unsigned int &KsError); std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator(); bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp); std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind); std::unique_ptr<X86Operand> - ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size); + ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size, unsigned int &KsError); std::unique_ptr<X86Operand> - ParseIntelMemOperand(StringRef Mnem, int64_t ImmDisp, SMLoc StartLoc, unsigned Size); + ParseIntelMemOperand(StringRef Mnem, int64_t ImmDisp, SMLoc StartLoc, unsigned Size, unsigned int &KsError); std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End); bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End); std::unique_ptr<X86Operand> ParseIntelBracExpression(unsigned SegReg, SMLoc Start, int64_t ImmDisp, - unsigned Size); + unsigned Size, unsigned int &KsError); bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info, bool IsUnevaluatedOperand, SMLoc &End); @@ -1144,9 +1189,9 @@ bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands, return false; } -std::unique_ptr<X86Operand> X86AsmParser::ParseOperand(StringRef Mnem) { +std::unique_ptr<X86Operand> X86AsmParser::ParseOperand(StringRef Mnem, unsigned int &KsError) { if (isParsingIntelSyntax()) - return ParseIntelOperand(Mnem); + return ParseIntelOperand(Mnem, KsError); return ParseATTOperand(); } @@ -1418,7 +1463,7 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) std::unique_ptr<X86Operand> X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start, - int64_t ImmDisp, unsigned Size) { + int64_t ImmDisp, unsigned Size, unsigned int &KsError) { MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc(); @@ -1451,12 +1496,12 @@ X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start, Disp = Sym; if (isParsingInlineAsm()) RewriteIntelBracExpression(*InstInfo->AsmRewrites, SM.getSymName(), - ImmDisp, SM.getImm(), BracLoc, StartInBrac, + ImmDisp, SM.getImm(KsError), BracLoc, StartInBrac, End); } - if (SM.getImm() || !Disp) { - const MCExpr *Imm = MCConstantExpr::create(SM.getImm(), getContext()); + if (SM.getImm(KsError) || !Disp) { + const MCExpr *Imm = MCConstantExpr::create(SM.getImm(KsError), getContext()); if (Disp) Disp = MCBinaryExpr::createAdd(Disp, Imm, getContext()); else @@ -1553,7 +1598,7 @@ bool X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val, /// \brief Parse intel style segment override. std::unique_ptr<X86Operand> X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, - unsigned Size) { + unsigned Size, unsigned int &KsError) { MCAsmParser &Parser = getParser(); assert(SegReg != 0 && "Tried to parse a segment override without a segment!"); const AsmToken &Tok = Parser.getTok(); // Eat colon. @@ -1581,7 +1626,7 @@ X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, } if (getLexer().is(AsmToken::LBrac)) - return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size); + return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size, KsError); const MCExpr *Val; SMLoc End; @@ -1642,7 +1687,7 @@ X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) { std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(StringRef Mnem, int64_t ImmDisp, SMLoc Start, - unsigned Size) + unsigned Size, unsigned int &KsError) { MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); @@ -1650,7 +1695,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand(StringRef Mnem, // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ]. if (getLexer().is(AsmToken::LBrac)) - return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size); + return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size, KsError); assert(ImmDisp == 0); const MCExpr *Val; @@ -1785,7 +1830,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) { return X86Operand::CreateImm(Imm, Start, End); } -std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand(StringRef Mnem) +std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand(StringRef Mnem, unsigned int &KsError) { MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); @@ -1833,7 +1878,11 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand(StringRef Mnem) if (ParseIntelExpression(SM, End)) return nullptr; - int64_t Imm = SM.getImm(); + int64_t Imm = SM.getImm(KsError); + if (KsError) { + return nullptr; + } + if (isParsingInlineAsm()) { unsigned Len = Tok.getLoc().getPointer() - Start.getPointer(); if (StartTok.getString().size() == Len) @@ -1870,7 +1919,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand(StringRef Mnem) "before bracketed expr."); // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ]. - return ParseIntelMemOperand(Mnem, Imm, Start, Size); + return ParseIntelMemOperand(Mnem, Imm, Start, Size, KsError); } // rounding mode token @@ -1894,11 +1943,11 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand(StringRef Mnem) return X86Operand::CreateReg(RegNo, Start, End); } - return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size); + return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size, KsError); } // Memory operand. - return ParseIntelMemOperand(Mnem, /*Disp=*/0, Start, Size); + return ParseIntelMemOperand(Mnem, /*Disp=*/0, Start, Size, KsError); } std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() @@ -1990,8 +2039,9 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands, return true; } else { // Parse mask register {%k1} + unsigned int KsError; Operands.push_back(X86Operand::CreateToken("{", consumedToken)); - if (std::unique_ptr<X86Operand> Op = ParseOperand("")) { + if (std::unique_ptr<X86Operand> Op = ParseOperand("", KsError)) { Operands.push_back(std::move(Op)); if (!getLexer().is(AsmToken::RCurly)) return !ErrorAndEatStatement(getLexer().getLoc(), @@ -2351,7 +2401,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // Read the operands. while(1) { - if (std::unique_ptr<X86Operand> Op = ParseOperand(Name)) { + if (std::unique_ptr<X86Operand> Op = ParseOperand(Name, ErrorCode)) { Operands.push_back(std::move(Op)); if (!HandleAVX512Operand(Operands, *Operands.back())) return true;