diff --git a/bindings/nodejs/consts/keystone.js b/bindings/nodejs/consts/keystone.js index 3bd3f554a98479d559cde2f5b5f2a90d6b858a8f..3b9f9409bc560c86e7d6c5104b79a050bcd6815c 100644 --- a/bindings/nodejs/consts/keystone.js +++ b/bindings/nodejs/consts/keystone.js @@ -70,6 +70,7 @@ module.exports.ERR_ASM_ESC_OCTAL = 153 module.exports.ERR_ASM_ESC_SEQUENCE = 154 module.exports.ERR_ASM_ESC_STR = 155 module.exports.ERR_ASM_TOKEN_INVALID = 156 +module.exports.ERR_ASM_INSN_UNSUPPORTED = 157 module.exports.ERR_ASM_INVALIDOPERAND = 512 module.exports.ERR_ASM_MISSINGFEATURE = 513 module.exports.ERR_ASM_MNEMONICFAIL = 514 diff --git a/bindings/python/keystone/keystone_const.py b/bindings/python/keystone/keystone_const.py index a737859ed6428c7b8b422bb98510177470ec012d..82d04a6d06ca58042b13df98a848727f1f9fa96e 100644 --- a/bindings/python/keystone/keystone_const.py +++ b/bindings/python/keystone/keystone_const.py @@ -70,6 +70,7 @@ KS_ERR_ASM_ESC_OCTAL = 153 KS_ERR_ASM_ESC_SEQUENCE = 154 KS_ERR_ASM_ESC_STR = 155 KS_ERR_ASM_TOKEN_INVALID = 156 +KS_ERR_ASM_INSN_UNSUPPORTED = 157 KS_ERR_ASM_INVALIDOPERAND = 512 KS_ERR_ASM_MISSINGFEATURE = 513 KS_ERR_ASM_MNEMONICFAIL = 514 diff --git a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb index 1d45192c213012a558813d966ca7be8eb8af024b..19ebc855b3361d3fd15bec96fcbdf3c14ad0088f 100644 --- a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb +++ b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb @@ -72,6 +72,7 @@ module Keystone KS_ERR_ASM_ESC_SEQUENCE = 154 KS_ERR_ASM_ESC_STR = 155 KS_ERR_ASM_TOKEN_INVALID = 156 + KS_ERR_ASM_INSN_UNSUPPORTED = 157 KS_ERR_ASM_INVALIDOPERAND = 512 KS_ERR_ASM_MISSINGFEATURE = 513 KS_ERR_ASM_MNEMONICFAIL = 514 diff --git a/include/keystone/keystone.h b/include/keystone/keystone.h index f9e5aff4bba8fc0079e015170cecd09c2af2e313..1e4f085a4ff8eec68056ba381b2aaf7d6db8d5bb 100644 --- a/include/keystone/keystone.h +++ b/include/keystone/keystone.h @@ -126,6 +126,7 @@ typedef enum ks_err { KS_ERR_ASM_ESC_SEQUENCE, // invalid escape sequence (unrecognized character) KS_ERR_ASM_ESC_STR, // broken escape string KS_ERR_ASM_TOKEN_INVALID, // invalid token + KS_ERR_ASM_INSN_UNSUPPORTED, // this instruction is unsupported in this mode // generic input assembly errors - architecture specific KS_ERR_ASM_INVALIDOPERAND = KS_ERR_ASM_ARCH, diff --git a/llvm/keystone/ks.cpp b/llvm/keystone/ks.cpp index 35c7527f2b33ab6dedaec00a39e75820b7eeb4bc..b0209a7dfbf0803a6397cfacc4984df73191e52a 100644 --- a/llvm/keystone/ks.cpp +++ b/llvm/keystone/ks.cpp @@ -124,6 +124,10 @@ const char *ks_strerror(ks_err code) return "Invalid escape string (KS_ERR_ASM_ESC_STR)"; case KS_ERR_ASM_TOKEN_INVALID: // invalid token from input assembly return "Invalid input token (KS_ERR_ASM_TOKEN_INVALID)"; + case KS_ERR_ASM_INSN_UNSUPPORTED: + return "Instruction is unsupported in this mode (KS_ERR_ASM_INSN_UNSUPPORTED)"; + case KS_ERR_ASM_DIRECTIVE_UNKNOWN: + return "Unknown directive (KS_ERR_ASM_DIRECTIVE_UNKNOWN)"; } } diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 0be48c3fdfb9a5f59fd9c089ede75c368065cd15..2309c8ae99c371fc5128a0869fc18d48126a16ee 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1290,14 +1290,26 @@ encodeInstruction(MCInst &MI, raw_ostream &OS, } else if (MemoryOperand < 0) { need_address_override = false; } else if (is64BitMode(STI)) { - assert(!Is16BitMemOperand(MI, MemoryOperand, STI)); + //assert(!Is16BitMemOperand(MI, MemoryOperand, STI)); + if (Is16BitMemOperand(MI, MemoryOperand, STI)) { + KsError = KS_ERR_ASM_INSN_UNSUPPORTED; + return; + } need_address_override = Is32BitMemOperand(MI, MemoryOperand); } else if (is32BitMode(STI)) { - assert(!Is64BitMemOperand(MI, MemoryOperand)); + //assert(!Is64BitMemOperand(MI, MemoryOperand)); + if (Is64BitMemOperand(MI, MemoryOperand)) { + KsError = KS_ERR_ASM_INSN_UNSUPPORTED; + return; + } need_address_override = Is16BitMemOperand(MI, MemoryOperand, STI); } else { - assert(is16BitMode(STI)); - assert(!Is64BitMemOperand(MI, MemoryOperand)); + //assert(is16BitMode(STI)); + //assert(!Is64BitMemOperand(MI, MemoryOperand)); + if (!is16BitMode(STI) || Is64BitMemOperand(MI, MemoryOperand)) { + KsError = KS_ERR_ASM_INSN_UNSUPPORTED; + return; + } need_address_override = !Is16BitMemOperand(MI, MemoryOperand, STI); } @@ -1323,10 +1335,16 @@ encodeInstruction(MCInst &MI, raw_ostream &OS, case X86II::RawFrmDstSrc: { //printf(">> aa\n"); unsigned siReg = MI.getOperand(1).getReg(); - assert(((siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) || - (siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) || - (siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) && - "SI and DI register sizes do not match"); + //assert(((siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) || + // (siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) || + // (siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) && + // "SI and DI register sizes do not match"); + if (!(siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) && + !(siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) && + !(siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) { + KsError = KS_ERR_ASM_INSN_UNSUPPORTED; + return; + } // Emit segment override opcode prefix as needed (not for %ds). if (MI.getOperand(2).getReg() != X86::DS) EmitSegmentOverridePrefix(CurByte, 2, MI, OS); @@ -1572,7 +1590,11 @@ encodeInstruction(MCInst &MI, raw_ostream &OS, const MCOperand &MIMM = MI.getOperand(CurOp++); if (MIMM.isImm()) { unsigned Val = MIMM.getImm(); - assert(Val < 16 && "Immediate operand value out of range"); + // assert(Val < 16 && "Immediate operand value out of range"); + if (Val >= 16) { + KsError = KS_ERR_ASM_INSN_UNSUPPORTED; + return; + } RegNum |= Val; } }