From 3955891035024f9d2a3b6fb26f5b7b81f5294c0a Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh <aquynh@gmail.com> Date: Sun, 22 May 2016 16:32:28 +0800 Subject: [PATCH] propagate error from encodeInstruction() back to ks_asm(). this fixes an issue in #9 --- llvm/include/llvm/MC/MCCodeEmitter.h | 3 +- llvm/include/llvm/MC/MCELFStreamer.h | 2 +- llvm/include/llvm/MC/MCObjectStreamer.h | 4 +- llvm/include/llvm/MC/MCStreamer.h | 2 +- llvm/lib/MC/MCAssembler.cpp | 6 +- llvm/lib/MC/MCELFStreamer.cpp | 8 ++- llvm/lib/MC/MCObjectStreamer.cpp | 13 ++-- llvm/lib/MC/MCStreamer.cpp | 3 +- .../AArch64/AsmParser/AArch64AsmParser.cpp | 7 +- .../MCTargetDesc/AArch64MCCodeEmitter.cpp | 7 +- .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 +- .../ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 8 ++- .../Hexagon/AsmParser/HexagonAsmParser.cpp | 3 +- .../MCTargetDesc/HexagonMCCodeEmitter.cpp | 5 +- .../MCTargetDesc/HexagonMCCodeEmitter.h | 3 +- .../MCTargetDesc/HexagonMCELFStreamer.h | 2 +- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 4 +- .../Mips/MCTargetDesc/MipsELFStreamer.h | 2 +- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 5 +- .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 3 +- .../Target/PowerPC/AsmParser/PPCAsmParser.cpp | 4 +- .../PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp | 5 +- .../Target/Sparc/AsmParser/SparcAsmParser.cpp | 4 +- .../Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp | 9 ++- .../SystemZ/AsmParser/SystemZAsmParser.cpp | 4 +- .../MCTargetDesc/SystemZMCCodeEmitter.cpp | 9 ++- .../X86/AsmParser/X86AsmInstrumentation.cpp | 9 +-- .../X86/AsmParser/X86AsmInstrumentation.h | 5 +- .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 32 ++++++--- .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 72 +++++++++++++------ 30 files changed, 166 insertions(+), 81 deletions(-) diff --git a/llvm/include/llvm/MC/MCCodeEmitter.h b/llvm/include/llvm/MC/MCCodeEmitter.h index f9ca2ad..ac1fed1 100644 --- a/llvm/include/llvm/MC/MCCodeEmitter.h +++ b/llvm/include/llvm/MC/MCCodeEmitter.h @@ -38,7 +38,8 @@ public: /// stream \p OS. virtual void encodeInstruction(MCInst &Inst, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const = 0; + const MCSubtargetInfo &STI, + unsigned int &KsError) const = 0; }; } // End llvm namespace diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index ebe439e..f5f5e68 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -85,7 +85,7 @@ public: private: bool isBundleLocked() const; void EmitInstToFragment(MCInst &Inst, const MCSubtargetInfo &) override; - void EmitInstToData(MCInst &Inst, const MCSubtargetInfo &) override; + void EmitInstToData(MCInst &Inst, const MCSubtargetInfo &, unsigned int &KsError) override; void fixSymbolsInTLSFixups(const MCExpr *expr); diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 7ecc137..d29a7a2 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -40,7 +40,7 @@ class MCObjectStreamer : public MCStreamer { bool EmitDebugFrame; SmallVector<MCSymbol *, 2> PendingLabels; - virtual void EmitInstToData(MCInst &Inst, const MCSubtargetInfo&) = 0; + virtual void EmitInstToData(MCInst &Inst, const MCSubtargetInfo&, unsigned int &KsError) = 0; void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; @@ -97,7 +97,7 @@ public: void EmitSLEB128Value(const MCExpr *Value) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; - void EmitInstruction(MCInst &Inst, const MCSubtargetInfo& STI) override; + void EmitInstruction(MCInst &Inst, const MCSubtargetInfo& STI, unsigned int &KsError) override; /// \brief Emit an instruction to a special fragment, because this instruction /// can change its size during relaxation. diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 262c9ba..e9d301a 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -720,7 +720,7 @@ public: } /// \brief Emit the given \p Instruction into the current section. - virtual void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI); + virtual void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI, unsigned int &KsError); /// \brief Set the bundle alignment mode from now on in the section. /// The argument is the power of 2 to which the alignment is set. The diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 6184a1f..006f7b5 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -716,7 +716,8 @@ bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F, } bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, - MCRelaxableFragment &F) { + MCRelaxableFragment &F) +{ if (!fragmentNeedsRelaxation(&F, Layout)) return false; @@ -735,7 +736,8 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, SmallVector<MCFixup, 4> Fixups; SmallString<256> Code; raw_svector_ostream VecOS(Code); - getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo()); + unsigned int KsError; + getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo(), KsError); // Update the fragment. F.setInst(Relaxed); diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index c881e14..3445f02 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -472,12 +472,16 @@ void MCELFStreamer::EmitInstToFragment(MCInst &Inst, } void MCELFStreamer::EmitInstToData(MCInst &Inst, - const MCSubtargetInfo &STI) { + const MCSubtargetInfo &STI, + unsigned int &KsError) +{ MCAssembler &Assembler = getAssembler(); SmallVector<MCFixup, 4> Fixups; SmallString<256> Code; raw_svector_ostream VecOS(Code); - Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI, KsError); + if (KsError) + return; for (unsigned i = 0, e = Fixups.size(); i != e; ++i) fixSymbolsInTLSFixups(Fixups[i].getValue()); diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 4335af9..6fe19f2 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -238,8 +238,10 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { } void MCObjectStreamer::EmitInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) { // qq - MCStreamer::EmitInstruction(Inst, STI); + const MCSubtargetInfo &STI, + unsigned int &KsError) +{ + MCStreamer::EmitInstruction(Inst, STI, KsError); MCSection *Sec = getCurrentSectionOnly(); Sec->setHasInstructions(true); @@ -252,7 +254,7 @@ void MCObjectStreamer::EmitInstruction(MCInst &Inst, // If this instruction doesn't need relaxation, just emit it as data. MCAssembler &Assembler = getAssembler(); if (!Assembler.getBackend().mayNeedRelaxation(Inst)) { - EmitInstToData(Inst, STI); + EmitInstToData(Inst, STI, KsError); return; } @@ -267,7 +269,7 @@ void MCObjectStreamer::EmitInstruction(MCInst &Inst, getAssembler().getBackend().relaxInstruction(Inst, Relaxed); while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); - EmitInstToData(Relaxed, STI); + EmitInstToData(Relaxed, STI, KsError); return; } @@ -287,8 +289,9 @@ void MCObjectStreamer::EmitInstToFragment(MCInst &Inst, SmallString<128> Code; raw_svector_ostream VecOS(Code); + unsigned int KsError; getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(), - STI); + STI, KsError); IF->getContents().append(Code.begin(), Code.end()); } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index e9e765f..ac51eaf 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -662,7 +662,8 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) { } void MCStreamer::EmitInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) { + const MCSubtargetInfo &STI, + unsigned int &KsError) { // Scan for values. for (unsigned i = Inst.getNumOperands(); i--;) if (Inst.getOperand(i).isExpr()) diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index d94ad5e..391f411 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -4103,8 +4103,8 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return true; Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); - return false; + Out.EmitInstruction(Inst, getSTI(), ErrorCode); + return (ErrorCode != 0); } case Match_MissingFeature: { assert(ErrorInfo && "Unknown missing feature!"); @@ -4316,7 +4316,8 @@ bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) { Inst.setOpcode(AArch64::TLSDESCCALL); Inst.addOperand(MCOperand::createExpr(Expr)); - getParser().getStreamer().EmitInstruction(Inst, getSTI()); + unsigned int KsError; + getParser().getStreamer().EmitInstruction(Inst, getSTI(), KsError); return false; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp index 3d0991b..4ac87dd 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp @@ -174,7 +174,8 @@ public: void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override; + const MCSubtargetInfo &STI, + unsigned int &KsError) const override; unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const; @@ -573,7 +574,9 @@ unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue, void AArch64MCCodeEmitter::encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { + const MCSubtargetInfo &STI, + unsigned int &KsError) const { + KsError = 0; if (MI.getOpcode() == AArch64::TLSDESCCALL) { // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the // following (BLR) instruction. It doesn't emit any code itself so it diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index f02ecef..f0cbb64 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -8712,9 +8712,9 @@ bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return false; Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); + Out.EmitInstruction(Inst, getSTI(), ErrorCode); Address = Inst.getAddress(); // keystone update address - return false; + return ErrorCode != 0; case Match_MissingFeature: { ErrorCode = KS_ERR_ASM_ARM_MISSINGFEATURE; return true; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 6652fc4..78ccc6e 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -436,7 +436,8 @@ public: void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override; + const MCSubtargetInfo &STI, + unsigned int &KsError) const override; }; } // end anonymous namespace @@ -1704,7 +1705,10 @@ getShiftRight64Imm(const MCInst &MI, unsigned Op, void ARMMCCodeEmitter:: encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { // qq + const MCSubtargetInfo &STI, + unsigned int &KsError) const +{ + KsError = 0; // Pseudo instructions don't get encoded. const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); uint64_t TSFlags = Desc.TSFlags; diff --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp index ef829da..103c90c 100644 --- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp +++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp @@ -700,7 +700,8 @@ bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) { // Empty packets are valid yet aren't emitted return false; } - Out.EmitInstruction(MCB, getSTI()); + unsigned int KsError; + Out.EmitInstruction(MCB, getSTI(), KsError); } else { // If compounding and duplexing didn't reduce the size below // 4 or less we have a packet that is too big. diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index e1f6bac..720b94a 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -64,7 +64,10 @@ uint32_t HexagonMCCodeEmitter::parseBits(size_t Instruction, size_t Last, void HexagonMCCodeEmitter::encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - MCSubtargetInfo const &STI) const { + MCSubtargetInfo const &STI, + unsigned int &KsError) const +{ + KsError = 0; MCInst &HMB = const_cast<MCInst &>(MI); assert(HexagonMCInstrInfo::isBundle(HMB)); diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h index 51fa44a..64cdc04 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h @@ -46,7 +46,8 @@ public: void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - MCSubtargetInfo const &STI) const override; + MCSubtargetInfo const &STI, + unsigned int &KsError) const override; void EncodeSingleInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h index 08a2882..13d46c8 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h @@ -28,7 +28,7 @@ public: MCII(createHexagonMCInstrInfo()) {} virtual void EmitInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) override; + const MCSubtargetInfo &STI, unsigned int &KsError) override; void EmitSymbol(const MCInst &Inst); void HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 054de29..76140fe 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -3641,8 +3641,8 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, if (processInstruction(Inst, IDLoc, Instructions)) return true; for (unsigned i = 0; i < Instructions.size(); i++) - Out.EmitInstruction(Instructions[i], getSTI()); - return false; + Out.EmitInstruction(Instructions[i], getSTI(), ErrorCode); + return ErrorCode != 0; } case Match_MissingFeature: Error(IDLoc, "instruction requires a CPU feature not currently enabled"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h index 7c9926e..f54646c 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h @@ -46,7 +46,7 @@ public: /// \p Inst is actually emitted. For example, we can inspect the operands and /// gather sufficient information that allows us to reason about the register /// usage for the translation unit. - void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI) override; + void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI, unsigned int &KsError) override; /// Overriding this function allows us to record all labels that should be /// marked as microMIPS. Based on this data marking is done in diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index a72c287..2e9f7e8 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -147,9 +147,10 @@ void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, void MipsMCCodeEmitter:: encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const + const MCSubtargetInfo &STI, + unsigned int &KsError) const { - + KsError = 0; // Non-pseudo instructions that get changed for direct object // only based on operand values. // If this list of instructions get much longer we will move diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 203c131..8201e91 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -53,7 +53,8 @@ public: void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override; + const MCSubtargetInfo &STI, + unsigned int &KsError) const override; // getBinaryCodeForInstr - TableGen'erated function for getting the // binary encoding for an instruction. diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 18e40ec..3dad04f 100644 --- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -1206,8 +1206,8 @@ bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, // Post-process instructions (typically extended mnemonics) ProcessInstruction(Inst, Operands); Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); - return false; + Out.EmitInstruction(Inst, getSTI(), ErrorCode); + return (ErrorCode != 0); case Match_MissingFeature: // return Error(IDLoc, "instruction use requires an option to be enabled"); ErrorCode = KS_ERR_ASM_PPC_MISSINGFEATURE; diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index cca9ad8..27c8367 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -98,12 +98,15 @@ public: const MCSubtargetInfo &STI) const; void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override { + const MCSubtargetInfo &STI, + unsigned int &KsError) const override { unsigned Opcode = MI.getOpcode(); const MCInstrDesc &Desc = MCII.get(Opcode); uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); + KsError = 0; + // Output the constant in big/little endian byte order. unsigned Size = Desc.getSize(); switch (Size) { diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index 1f5f911..ad13ab6 100644 --- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -530,9 +530,9 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, } for (MCInst &I : Instructions) { - Out.EmitInstruction(I, getSTI()); + Out.EmitInstruction(I, getSTI(), ErrorCode); } - return false; + return (ErrorCode != 0); } case Match_MissingFeature: diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp index 7ce2c17..a59a542 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp @@ -42,7 +42,8 @@ public: void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override; + const MCSubtargetInfo &STI, + unsigned int &KsError) const override; // getBinaryCodeForInstr - TableGen'erated function for getting the // binary encoding for an instruction. @@ -80,9 +81,13 @@ MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, void SparcMCCodeEmitter::encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { + const MCSubtargetInfo &STI, + unsigned int &KsError) const +{ unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); + KsError = 0; + if (Ctx.getAsmInfo()->isLittleEndian()) { // Output the bits in little-endian byte order. support::endian::Writer<support::little>(OS).write<uint32_t>(Bits); diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index 601b257..9fd2db5 100644 --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -823,8 +823,8 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, switch (MatchResult) { case Match_Success: Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); - return false; + Out.EmitInstruction(Inst, getSTI(), ErrorCode); + return (ErrorCode != 0); case Match_MissingFeature: { #if 0 diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp index b27bf86..e481911 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp @@ -39,7 +39,8 @@ public: // OVerride MCCodeEmitter. void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override; + const MCSubtargetInfo &STI, + unsigned int &KsError) const override; private: // Automatically generated by TableGen. @@ -122,9 +123,13 @@ MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII, void SystemZMCCodeEmitter:: encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { + const MCSubtargetInfo &STI, + unsigned int &KsError) const +{ uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); unsigned Size = MCII.get(MI.getOpcode()).getSize(); + + KsError = 0; // Big-endian insertion of Size bytes. unsigned ShiftValue = (Size * 8) - 8; for (unsigned I = 0; I != Size; ++I) { diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp index 944669e..c802224 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp @@ -101,13 +101,14 @@ X86AsmInstrumentation::~X86AsmInstrumentation() {} void X86AsmInstrumentation::InstrumentAndEmitInstruction( MCInst &Inst, OperandVector &Operands, MCContext &Ctx, - const MCInstrInfo &MII, MCStreamer &Out) { - EmitInstruction(Out, Inst); + const MCInstrInfo &MII, MCStreamer &Out, unsigned int &KsError) { + EmitInstruction(Out, Inst, KsError); } void X86AsmInstrumentation::EmitInstruction(MCStreamer &Out, - MCInst &Inst) { - Out.EmitInstruction(Inst, *STI); + MCInst &Inst, + unsigned int &KsError) { + Out.EmitInstruction(Inst, *STI, KsError); } unsigned X86AsmInstrumentation::GetFrameRegGeneric(const MCContext &Ctx, diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h index 3552e3b..2a6e2e6 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h +++ b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h @@ -44,7 +44,8 @@ public: virtual void InstrumentAndEmitInstruction( MCInst &Inst, SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand> > &Operands, - MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out); + MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out, + unsigned int &KsError); protected: friend X86AsmInstrumentation * @@ -56,7 +57,7 @@ protected: unsigned GetFrameRegGeneric(const MCContext &Ctx, MCStreamer &Out); - void EmitInstruction(MCStreamer &Out, MCInst &Inst); + void EmitInstruction(MCStreamer &Out, MCInst &Inst, unsigned int &KsError); const MCSubtargetInfo *&STI; diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index de54729..815e88e 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -785,7 +785,8 @@ private: /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds /// instrumentation around Inst. - void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out); + void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out, + unsigned int &KsError); bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, @@ -1853,6 +1854,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand(StringRef Mnem, unsi bool PtrInOperand = false; unsigned Size = getIntelMemOperandSize(Tok.getString()); + //printf(">> Intel Op Size = %u\n", Size); if (Size) { Parser.Lex(); // Eat operand size (e.g., byte, word). if (KsSyntax == KS_OPT_SYNTAX_NASM) { @@ -2655,9 +2657,9 @@ bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { static const char *getSubtargetFeatureName(uint64_t Val); void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands, - MCStreamer &Out) { + MCStreamer &Out, unsigned int &KsError) { Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(), - MII, Out); + MII, Out, KsError); } bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, @@ -2691,8 +2693,9 @@ void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, MCInst Inst; Inst.setOpcode(X86::WAIT); Inst.setLoc(IDLoc); + unsigned int KsError = 0; if (!MatchingInlineAsm) - EmitInstruction(Inst, Operands, Out); + EmitInstruction(Inst, Operands, Out, KsError); Operands[0] = X86Operand::CreateToken(Repl, IDLoc); } } @@ -2744,8 +2747,11 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, ; Inst.setLoc(IDLoc); - if (!MatchingInlineAsm) - EmitInstruction(Inst, Operands, Out); + if (!MatchingInlineAsm) { + EmitInstruction(Inst, Operands, Out, ErrorCode); + if (ErrorCode) + return true; + } Opcode = Inst.getOpcode(); return false; case Match_MissingFeature: @@ -2801,8 +2807,11 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, std::count(std::begin(Match), std::end(Match), Match_Success); if (NumSuccessfulMatches == 1) { Inst.setLoc(IDLoc); - if (!MatchingInlineAsm) - EmitInstruction(Inst, Operands, Out); + if (!MatchingInlineAsm) { + EmitInstruction(Inst, Operands, Out, ErrorCode); + if (ErrorCode) + return true; + } Opcode = Inst.getOpcode(); return false; } @@ -3008,8 +3017,11 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, while (processInstruction(Inst, Operands)) ; Inst.setLoc(IDLoc); - if (!MatchingInlineAsm) - EmitInstruction(Inst, Operands, Out); + if (!MatchingInlineAsm) { + EmitInstruction(Inst, Operands, Out, ErrorCode); + if (ErrorCode) + return true; + } Opcode = Inst.getOpcode(); return false; } else if (NumSuccessfulMatches > 1) { diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index c2b6867..b09ba33 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -24,6 +24,8 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/Support/raw_ostream.h" +#include <keystone/keystone.h> + using namespace llvm; #define DEBUG_TYPE "mccodeemitter" @@ -123,6 +125,7 @@ public: unsigned ImmSize, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, + unsigned int &KsError, int ImmOffset = 0) const; inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode, @@ -151,7 +154,7 @@ public: void encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override; + const MCSubtargetInfo &STI, unsigned int &KsError) const override; void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, const MCInst &MI, const MCInstrDesc &Desc, @@ -290,12 +293,34 @@ static bool HasSecRelSymbolRef(const MCExpr *Expr) { return false; } +// return false if Imm value is invalid for a given size +static bool validImmRange(uint64_t Imm, unsigned int Size) +{ + switch(Size) { + default: + return true; + case 1: + return (Imm <= 0xff); + case 2: + return (Imm <= 0xffff); + case 4: + return (Imm <= 0xffffffff); + } + +} + void X86MCCodeEmitter:: EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, - SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const { + SmallVectorImpl<MCFixup> &Fixups, unsigned int &KsError, int ImmOffset) const +{ + KsError = 0; const MCExpr *Expr = nullptr; if (DispOp.isImm()) { + if (!validImmRange(DispOp.getImm(), Size)) { + KsError = KS_ERR_ASM_INVALIDOPERAND; + return; + } // If this is a simple integer displacement that doesn't require a // relocation, emit it now. if (FixupKind != FK_PCRel_1 && @@ -372,6 +397,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); unsigned BaseReg = Base.getReg(); bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX; + unsigned int KsError; // Handle %rip relative addressing. if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode @@ -395,7 +421,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0; EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), - CurByte, OS, Fixups, -ImmSize); + CurByte, OS, Fixups, KsError, -ImmSize); return; } @@ -448,7 +474,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, } // Use the [REG]+disp8 form, including for [BP] which cannot be encoded. EmitByte(ModRMByte(1, RegOpcodeField, RMfield), CurByte, OS); - EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); + EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, KsError); return; } // This is the [REG]+disp16 case. @@ -459,7 +485,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, } // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases. - EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups); + EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups, KsError); return; } @@ -480,7 +506,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, if (BaseReg == 0) { // [disp32] in X86-32 mode EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); - EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups); + EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups, KsError); return; } @@ -497,7 +523,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, if (Disp.isImm()) { if (!HasEVEX && isDisp8(Disp.getImm())) { EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); - EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); + EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, KsError); return; } // Try EVEX compressed 8-bit displacement first; if failed, fall back to @@ -506,7 +532,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) { EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS); EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, - CDisp8 - Disp.getImm()); + KsError, CDisp8 - Disp.getImm()); return; } } @@ -514,7 +540,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // Otherwise, emit the most general non-SIB encoding: [REG+disp32] EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS); EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), - CurByte, OS, Fixups); + CurByte, OS, Fixups, KsError); return; } @@ -588,10 +614,10 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // Do we need to output a displacement? if (ForceDisp8) - EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, ImmOffset); + EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, KsError, ImmOffset); else if (ForceDisp32 || Disp.getImm() != 0) EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), - CurByte, OS, Fixups); + CurByte, OS, Fixups, KsError); } /// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix @@ -1178,12 +1204,14 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, void X86MCCodeEmitter:: encodeInstruction(MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const + const MCSubtargetInfo &STI, unsigned int &KsError) const { unsigned Opcode = MI.getOpcode(); const MCInstrDesc &Desc = MCII.get(Opcode); uint64_t TSFlags = Desc.TSFlags; + KsError = 0; + // Pseudo instructions don't get encoded. if ((TSFlags & X86II::FormMask) == X86II::Pseudo) return; @@ -1319,7 +1347,7 @@ encodeInstruction(MCInst &MI, raw_ostream &OS, EmitByte(BaseOpcode, CurByte, OS); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - CurByte, OS, Fixups); + CurByte, OS, Fixups, KsError); ++CurOp; // skip segment operand break; case X86II::RawFrmImm8: @@ -1327,18 +1355,18 @@ encodeInstruction(MCInst &MI, raw_ostream &OS, EmitByte(BaseOpcode, CurByte, OS); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - CurByte, OS, Fixups); + CurByte, OS, Fixups, KsError); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte, - OS, Fixups); + OS, Fixups, KsError); break; case X86II::RawFrmImm16: //printf(">> gg\n"); EmitByte(BaseOpcode, CurByte, OS); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - CurByte, OS, Fixups); + CurByte, OS, Fixups, KsError); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte, - OS, Fixups); + OS, Fixups, KsError); break; case X86II::AddRegFrm: @@ -1534,16 +1562,20 @@ encodeInstruction(MCInst &MI, raw_ostream &OS, RegNum |= Val; } } + //printf(">> uu\n"); EmitImmediate(MCOperand::createImm(RegNum), MI.getLoc(), 1, FK_Data_1, - CurByte, OS, Fixups); + CurByte, OS, Fixups, KsError); } else { + //printf(">> vv\n"); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - CurByte, OS, Fixups); + CurByte, OS, Fixups, KsError); + if (KsError) + break; } } - if (TSFlags & X86II::Has3DNow0F0FOpcode) + if (KsError == 0 && TSFlags & X86II::Has3DNow0F0FOpcode) EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS); #ifndef NDEBUG -- GitLab