From 6f897e655a5f18b28b47542d76ac88d0aebcbc5d Mon Sep 17 00:00:00 2001 From: iximeow Date: Fri, 3 Jan 2020 18:31:22 -0800 Subject: match changes in arch to have Resulty decode, instead of Option --- src/display.rs | 14 ++++- src/lib.rs | 194 +++++++++++++++++++++++++++++++-------------------------- src/vex.rs | 143 +++++++++++++++++++++--------------------- test/test.rs | 16 ++--- 4 files changed, 199 insertions(+), 168 deletions(-) diff --git a/src/display.rs b/src/display.rs index 40bf190..dd46055 100644 --- a/src/display.rs +++ b/src/display.rs @@ -6,7 +6,19 @@ use std::fmt; use yaxpeax_arch::{Colorize, ColorSettings, ShowContextual, YaxColors}; use yaxpeax_arch::display::*; -use ::{RegSpec, RegisterBank, Opcode, Operand, InstDecoder, Instruction, Segment, PrefixRex, OperandSpec}; +use ::{RegSpec, RegisterBank, Opcode, Operand, InstDecoder, Instruction, Segment, PrefixRex, OperandSpec, DecodeError}; + +impl fmt::Display for DecodeError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + DecodeError::ExhaustedInput => { write!(f, "exhausted input") }, + DecodeError::InvalidOpcode => { write!(f, "invalid opcode") }, + DecodeError::InvalidOperand => { write!(f, "invalid operand") }, + DecodeError::InvalidPrefixes => { write!(f, "invalid prefixes") }, + DecodeError::TooLong => { write!(f, "too long") }, + } + } +} impl fmt::Display for InstDecoder { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/lib.rs b/src/lib.rs index 2427f4a..0bf93ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1213,6 +1213,28 @@ pub struct Instruction { pub opcode: Opcode, } +impl yaxpeax_arch::Instruction for Instruction { + fn well_defined(&self) -> bool { + // TODO: this is incorrect! + true + } +} + +#[derive(Debug, PartialEq)] +pub enum DecodeError { + ExhaustedInput, + InvalidOpcode, + InvalidOperand, + InvalidPrefixes, + TooLong, +} + +impl yaxpeax_arch::DecodeError for DecodeError { + fn data_exhausted(&self) -> bool { self == &DecodeError::ExhaustedInput } + fn bad_opcode(&self) -> bool { self == &DecodeError::InvalidOpcode } + fn bad_operand(&self) -> bool { self == &DecodeError::InvalidOperand } +} + #[derive(Debug, Copy, Clone, PartialEq)] enum OperandSpec { Nothing, @@ -1266,6 +1288,7 @@ pub struct x86_64; impl Arch for x86_64 { type Address = u64; type Instruction = Instruction; + type DecodeError = DecodeError; type Decoder = InstDecoder; type Operand = Operand; } @@ -1860,7 +1883,7 @@ impl InstDecoder { /// Optionally reject or reinterpret instruction according to the decoder's /// declared extensions. - fn revise_instruction(&self, inst: &mut Instruction) -> Result<(), ()> { + fn revise_instruction(&self, inst: &mut Instruction) -> Result<(), DecodeError> { match inst.opcode { Opcode::TZCNT => { if !self.bmi1() { @@ -1884,7 +1907,7 @@ impl InstDecoder { // via Intel section 5.7, SSE3 Instructions if !self.sse3() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } Opcode::PHADDW | @@ -1906,7 +1929,7 @@ impl InstDecoder { // via Intel section 5.8, SSSE3 Instructions if !self.ssse3() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } Opcode::PMULLD | @@ -1957,7 +1980,7 @@ impl InstDecoder { // via Intel section 5.10, SSE4.1 Instructions if !self.sse4_1() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } Opcode::PCMPESTRI | @@ -1968,7 +1991,7 @@ impl InstDecoder { // via Intel section 5.11, SSE4.2 Instructions if !self.sse4_2() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } Opcode::AESDEC | @@ -1980,14 +2003,14 @@ impl InstDecoder { // via Intel section 5.12. AESNI AND PCLMULQDQ if !self.aesni() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } Opcode::PCLMULQDQ => { // via Intel section 5.12. AESNI AND PCLMULQDQ if !self.pclmulqdq() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } // AVX... @@ -2022,7 +2045,7 @@ impl InstDecoder { Opcode::ENCLU => { if !self.sgx() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } Opcode::VMOVDDUP | @@ -2352,7 +2375,7 @@ impl InstDecoder { // TODO: check a table for these if !self.avx() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } Opcode::VAESDEC | @@ -2364,7 +2387,7 @@ impl InstDecoder { // TODO: check a table for these if !self.avx() || !self.aesni() { inst.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } _ => {} @@ -2386,14 +2409,14 @@ impl Default for InstDecoder { } impl Decoder for InstDecoder { - fn decode>(&self, bytes: T) -> Option { + type Error = DecodeError; + + fn decode>(&self, bytes: T) -> Result { let mut instr = Instruction::invalid(); - match decode_one(self, bytes, &mut instr) { - Some(_) => Some(instr), - None => None - } + decode_one(self, bytes, &mut instr) + .map(|_: ()| instr) } - fn decode_into>(&self, instr: &mut Instruction, bytes: T) -> Option<()> { + fn decode_into>(&self, instr: &mut Instruction, bytes: T) -> Result<(), Self::Error> { decode_one(self, bytes, instr) } } @@ -3145,8 +3168,8 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), ]; -fn read_opcode_660f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { - bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_660f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), DecodeError> { + bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; (OPCODE_660F_MAP[b as usize], b) }) @@ -3426,8 +3449,8 @@ const OPCODE_F20F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), ]; -fn read_opcode_f20f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { - bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_f20f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), DecodeError> { + bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; (OPCODE_F20F_MAP[b as usize], b) }) @@ -3707,8 +3730,8 @@ const OPCODE_F30F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), ]; -fn read_opcode_f30f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { - bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_f30f_map>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), DecodeError> { + bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; (OPCODE_F30F_MAP[b as usize], b) }) @@ -4029,8 +4052,8 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::PADDD), OperandCode::Unsupported), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), ]; -fn read_opcode_0f_map>(bytes_iter: &mut T, length: &mut u8) -> Result { - bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_0f_map>(bytes_iter: &mut T, length: &mut u8) -> Result { + bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; OPCODE_0F_MAP[b as usize] }) @@ -4348,7 +4371,7 @@ const OPCODES: [OpcodeRecord; 256] = [ ]; #[allow(non_snake_case)] -pub(crate) fn read_E>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, length: &mut u8) -> Result { +pub(crate) fn read_E>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, length: &mut u8) -> Result { let bank = width_to_gp_reg_bank(width, instr.prefixes.rex().present()); if modrm >= 0b11000000 { read_modrm_reg(instr, modrm, bank) @@ -4357,7 +4380,7 @@ pub(crate) fn read_E>(bytes_iter: &mut T, instr: &mut Instr } } #[allow(non_snake_case)] -pub(crate) fn read_E_xmm>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { +pub(crate) fn read_E_xmm>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { if modrm >= 0b11000000 { read_modrm_reg(instr, modrm, RegisterBank::X) } else { @@ -4365,7 +4388,7 @@ pub(crate) fn read_E_xmm>(bytes_iter: &mut T, instr: &mut I } } #[allow(non_snake_case)] -pub(crate) fn read_E_ymm>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { +pub(crate) fn read_E_ymm>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { if modrm >= 0b11000000 { read_modrm_reg(instr, modrm, RegisterBank::Y) } else { @@ -4374,20 +4397,16 @@ pub(crate) fn read_E_ymm>(bytes_iter: &mut T, instr: &mut I } #[allow(non_snake_case)] -fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) -> Result { +fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) -> Result { instr.modrm_mmm = RegSpec::from_parts(modrm & 7, instr.prefixes.rex().b(), reg_bank); Ok(OperandSpec::RegMMM) } #[allow(non_snake_case)] -fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { +fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { let modbits = (modrm >> 6); let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q }; - let sibbyte = match bytes_iter.next() { - Some(b) => b, -// None => { unsafe { unreachable_unchecked(); } } - None => { return Err(()); } //Err("Out of bytes".to_string()) - }; + let sibbyte = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; *length += 1; let op_spec = if (sibbyte & 7) == 0b101 { @@ -4476,7 +4495,7 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m } #[allow(non_snake_case)] -fn read_M>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { +fn read_M>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { let modbits = (modrm >> 6); let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q }; let mmm = modrm & 7; @@ -4531,7 +4550,7 @@ fn width_to_gp_reg_bank(width: u8, rex: bool) -> RegisterBank { } } -pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), ()> { +pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), DecodeError> { let mut length = 0u8; let mut alternate_opcode_map: Option = None; // use std::intrinsics::unlikely; @@ -4592,7 +4611,6 @@ pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T escapes_are_prefixes_actually(&mut prefixes, &mut alternate_opcode_map); break record; } else { - println!("prefix: {:02x}, extant prefixes: {:?}", b, prefixes); // some prefix seen after we saw rex, but before the 0f escape or an actual // opcode. so we must forget the rex prefix! // this is to handle sequences like 41660f21cf @@ -4612,7 +4630,7 @@ pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { // rex and then vex is invalid! reject it. instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidPrefixes); } else { instruction.prefixes = prefixes; vex::two_byte_vex(&mut bytes_iter, instruction, length)?; @@ -4626,7 +4644,7 @@ pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { // rex and then vex is invalid! reject it. instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidPrefixes); } else { instruction.prefixes = prefixes; vex::three_byte_vex(&mut bytes_iter, instruction, length)?; @@ -4679,7 +4697,7 @@ pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T }, None => { // unsafe { unreachable_unchecked(); } - return Err(()); + return Err(DecodeError::ExhaustedInput); } } }; @@ -4699,7 +4717,7 @@ pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T } Ok(()) } -pub fn read_operands>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), ()> { +pub fn read_operands>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), DecodeError> { let mut bytes_read = 0; if (operand_code as u8) & 0x40 == 0x40 { instruction.operands[0] = OperandSpec::RegRRR; @@ -4853,7 +4871,7 @@ pub fn read_operands>(decoder: &InstDecoder, mut bytes_iter OperandCode::Eb_R0 => { if (modrm & 0b00111000) != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); // Err("Invalid modr/m for opcode 0xc6".to_owned()); + return Err(DecodeError::InvalidOperand); // Err("Invalid modr/m for opcode 0xc6".to_owned()); } instruction.operands[0] = mem_oper; @@ -4934,7 +4952,7 @@ pub fn read_operands>(decoder: &InstDecoder, mut bytes_iter op @ OperandCode::ModRM_0xc7_Ev_Iv => { if (modrm & 0b00111000) != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); // Err("Invalid modr/m for opcode 0xc7".to_string()); + return Err(DecodeError::InvalidOperand); // Err("Invalid modr/m for opcode 0xc7".to_string()); } instruction.operands[0] = mem_oper; @@ -5115,7 +5133,7 @@ pub fn read_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = mem_oper; instruction.modrm_rrr.bank = RegisterBank::D; if mem_oper != OperandSpec::RegMMM { - return Err(()); + return Err(DecodeError::InvalidOperand); } instruction.modrm_mmm.bank = RegisterBank::MM; instruction.modrm_mmm.num &= 0b111; @@ -5130,7 +5148,7 @@ pub fn read_operands>(decoder: &InstDecoder, mut bytes_iter if instruction.operands[1] == OperandSpec::RegMMM { if op == OperandCode::G_M_xmm { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } else { // fix the register to XMM instruction.modrm_mmm.bank = RegisterBank::X; @@ -5272,7 +5290,7 @@ pub fn read_operands>(decoder: &InstDecoder, mut bytes_iter Ok(()) } -fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), ()> { +fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), DecodeError> { let mut bytes_read = 0; match operand_code { OperandCode::ModRM_0x0f71 => { @@ -5280,7 +5298,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter let modrm = read_modrm(&mut bytes_iter, instruction, length)?; if modrm & 0xc0 != 0xc0 { - return Err(()); + return Err(DecodeError::InvalidOperand); } let r = (modrm >> 3) & 7; @@ -5295,7 +5313,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::PSLLW; } _ => { - return Err(()); + return Err(DecodeError::InvalidOpcode); } } @@ -5309,7 +5327,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter let modrm = read_modrm(&mut bytes_iter, instruction, length)?; if modrm & 0xc0 != 0xc0 { - return Err(()); + return Err(DecodeError::InvalidOperand); } let r = (modrm >> 3) & 7; @@ -5324,7 +5342,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::PSLLD; } _ => { - return Err(()); + return Err(DecodeError::InvalidOpcode); } } @@ -5338,7 +5356,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter let modrm = read_modrm(&mut bytes_iter, instruction, length)?; if modrm & 0xc0 != 0xc0 { - return Err(()); + return Err(DecodeError::InvalidOperand); } let r = (modrm >> 3) & 7; @@ -5350,7 +5368,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::PSLLQ; } _ => { - return Err(()); + return Err(DecodeError::InvalidOpcode); } } @@ -5360,7 +5378,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = OperandSpec::ImmI8; }, OperandCode::ModRM_0x660f38 => { - let op = bytes_iter.next().map(|b| { *length += 1; b }).ok_or(())?; + let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; match op { 0xdb => { instruction.opcode = Opcode::AESIMC; } 0xdc => { instruction.opcode = Opcode::AESENC; } @@ -5369,7 +5387,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter 0xdf => { instruction.opcode = Opcode::AESDECLAST; } _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } }; // all these SO FAR are G_E_xmm @@ -5383,7 +5401,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operand_count = 2; } OperandCode::ModRM_0x660f3a => { - let op = bytes_iter.next().map(|b| { *length += 1; b }).ok_or(())?; + let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; match op { 0xdf => { instruction.opcode = Opcode::AESKEYGENASSIST; @@ -5403,7 +5421,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } }; } @@ -5557,7 +5575,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } OperandCode::ModRM_0x0f18 => { if mem_oper == OperandSpec::RegMMM { - return Err(()); + return Err(DecodeError::InvalidOperand); } let rrr = instruction.modrm_rrr.num & 0b111; instruction.operands[0] = mem_oper; @@ -5573,7 +5591,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = mem_oper; if instruction.operands[1] != OperandSpec::RegMMM { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } instruction.modrm_rrr.bank = RegisterBank::D; instruction.modrm_mmm.bank = RegisterBank::X; @@ -5583,7 +5601,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = mem_oper; if instruction.operands[0] == OperandSpec::RegMMM { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } instruction.modrm_rrr.bank = RegisterBank::X; } @@ -5594,7 +5612,8 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter // check r if ((modrm >> 3) & 7) > 5 { - return Err(()); //Err("Invalid r".to_owned()); + // return Err(()); //Err("Invalid r".to_owned()); + return Err(DecodeError::InvalidOperand); } instruction.modrm_rrr = @@ -5617,7 +5636,8 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter // check r if ((modrm >> 3) & 7) > 5 { - return Err(()); // Err("Invalid r".to_owned()); + // return Err(()); // Err("Invalid r".to_owned()); + return Err(DecodeError::InvalidOperand); } instruction.modrm_rrr = @@ -5682,7 +5702,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } else if r == 7 { instruction.opcode = Opcode::Invalid; instruction.operand_count = 0; - return Err(()); + return Err(DecodeError::InvalidOperand); } else { unreachable!("r <= 8"); } @@ -5715,7 +5735,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter }, _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } else { @@ -5746,7 +5766,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } else { @@ -5780,7 +5800,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } else { @@ -5794,7 +5814,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter if mod_bits == 0b11 { instruction.opcode = Opcode::Invalid; instruction.operand_count = 0; - return Err(()); + return Err(DecodeError::InvalidOperand); } else { instruction.opcode = Opcode::LIDT; instruction.operand_count = 1; @@ -5820,7 +5840,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter _ => { instruction.opcode = Opcode::Invalid; instruction.operand_count = 0; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } else if r == 6 { @@ -5839,7 +5859,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operand_count = 0; } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } else { instruction.opcode = Opcode::INVLPG; @@ -5862,7 +5882,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter match r { // invalid rrr for 0x0fae, mod: 11 0 | 1 | 2 | 3 | 4 => { - return Err(()); + return Err(DecodeError::InvalidOpcode); }, 5 => { instruction.opcode = Opcode::LFENCE; @@ -5871,7 +5891,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter if !decoder.amd_quirks() && !decoder.intel_quirks() { if m != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } } }, @@ -5882,7 +5902,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter if !decoder.amd_quirks() && !decoder.intel_quirks() { if m != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } } }, @@ -5893,7 +5913,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter if !decoder.amd_quirks() && !decoder.intel_quirks() { if m != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } } }, @@ -5921,7 +5941,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter match r { 0 | 1 | 2 | 3 => { instruction.opcode = Opcode::Invalid; - return Err(()); //Err("invalid instruction".to_string()); + return Err(DecodeError::InvalidOpcode); }, 4 => { instruction.opcode = Opcode::BT; @@ -6001,14 +6021,15 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter _ => { instruction.operand_count = 0; instruction.opcode = Opcode::Invalid; - return Err(()); // Err(format!("unsupported operand code: {:?}", operand_code)); +// return Err(()); // Err(format!("unsupported operand code: {:?}", operand_code)); + return Err(DecodeError::InvalidOperand); // unsafe { unreachable_unchecked(); } } }; Ok(()) } -pub fn decode_one<'b, T: IntoIterator>(decoder: &InstDecoder, bytes: T, instr: &'b mut Instruction) -> Option<()> { +pub fn decode_one<'b, T: IntoIterator>(decoder: &InstDecoder, bytes: T, instr: &'b mut Instruction) -> Result<(), DecodeError> { instr.operands = [ OperandSpec::Nothing, OperandSpec::Nothing, @@ -6016,7 +6037,7 @@ pub fn decode_one<'b, T: IntoIterator>(decoder: &InstDecoder, bytes: T, OperandSpec::Nothing, ]; let mut bytes_iter = bytes.into_iter(); - read_instr(decoder, bytes_iter, instr).ok() + read_instr(decoder, bytes_iter, instr) } /* match read_opcode(&mut bytes_iter, instr) { @@ -6045,24 +6066,21 @@ pub fn decode_one<'b, T: IntoIterator>(decoder: &InstDecoder, bytes: T, */ #[inline] -fn read_num>(bytes: &mut T, width: u8) -> Result { +fn read_num>(bytes: &mut T, width: u8) -> Result { let mut result = 0u64; let mut idx = 0; loop { if idx == width { return Ok(result); } - if let Some(byte) = bytes.next() { - result |= (byte as u64) << (idx * 8); - idx += 1; - } else { - return Err(()); - } + let byte = bytes.next().ok_or(DecodeError::ExhaustedInput)?; + result |= (byte as u64) << (idx * 8); + idx += 1; } } #[inline] -fn read_imm_ivq>(bytes: &mut T, width: u8, length: &mut u8) -> Result { +fn read_imm_ivq>(bytes: &mut T, width: u8, length: &mut u8) -> Result { match width { 2 => { *length += 2; @@ -6083,7 +6101,7 @@ fn read_imm_ivq>(bytes: &mut T, width: u8, length: &mut u8) } #[inline] -fn read_imm_signed>(bytes: &mut T, num_width: u8, length: &mut u8) -> Result { +fn read_imm_signed>(bytes: &mut T, num_width: u8, length: &mut u8) -> Result { if num_width == 1 { *length += 1; Ok(read_num(bytes, 1)? as i8 as i64) @@ -6098,7 +6116,7 @@ fn read_imm_signed>(bytes: &mut T, num_width: u8, length: & } #[inline] -fn read_imm_unsigned>(bytes: &mut T, width: u8) -> Result { +fn read_imm_unsigned>(bytes: &mut T, width: u8) -> Result { read_num(bytes, width) } @@ -6136,6 +6154,6 @@ fn imm_width_from_prefixes_64(interpretation: SizeCode, prefixes: Prefixes) -> u } #[inline] -fn read_modrm>(bytes_iter: &mut T, inst: &mut Instruction, length: &mut u8) -> Result { - bytes_iter.next().map(|b| { *length += 1; b }).ok_or(()) +fn read_modrm>(bytes_iter: &mut T, inst: &mut Instruction, length: &mut u8) -> Result { + bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b }) } diff --git a/src/vex.rs b/src/vex.rs index 9d7d109..b59f7d7 100644 --- a/src/vex.rs +++ b/src/vex.rs @@ -1,4 +1,5 @@ use OperandSpec; +use DecodeError; use RegSpec; use RegisterBank; use Instruction; @@ -78,9 +79,9 @@ enum VEXOperandCode { } #[inline(never)] -pub(crate) fn three_byte_vex>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), ()> { - let vex_byte_one = bytes.next().ok_or(())?; - let vex_byte_two = bytes.next().ok_or(())?; +pub(crate) fn three_byte_vex>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> { + let vex_byte_one = bytes.next().ok_or(DecodeError::ExhaustedInput)?; + let vex_byte_two = bytes.next().ok_or(DecodeError::ExhaustedInput)?; let p = vex_byte_two & 0x03; let p = match p { 0x00 => VEXOpcodePrefix::None, @@ -97,7 +98,7 @@ pub(crate) fn three_byte_vex>(bytes: &mut T, instruction: & 0b00011 => VEXOpcodeMap::Map0F3A, _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } }; instruction.vex_reg = RegSpec { @@ -111,8 +112,8 @@ pub(crate) fn three_byte_vex>(bytes: &mut T, instruction: & Ok(()) } -pub(crate) fn two_byte_vex>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), ()> { - let vex_byte = bytes.next().ok_or(())?; +pub(crate) fn two_byte_vex>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> { + let vex_byte = bytes.next().ok_or(DecodeError::ExhaustedInput)?; let p = vex_byte & 0x03; let p = match p { 0x00 => VEXOpcodePrefix::None, @@ -132,7 +133,7 @@ pub(crate) fn two_byte_vex>(bytes: &mut T, instruction: &mu Ok(()) } -fn read_vex_operands>(bytes: &mut T, instruction: &mut Instruction, length: &mut u8, operand_code: VEXOperandCode) -> Result<(), ()> { +fn read_vex_operands>(bytes: &mut T, instruction: &mut Instruction, length: &mut u8, operand_code: VEXOperandCode) -> Result<(), DecodeError> { println!("operand code: {:?}", operand_code); match operand_code { VEXOperandCode::VMOVSS_10 | @@ -177,7 +178,7 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst VEXOperandCode::Ev_G_xmm_imm8 => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = @@ -196,7 +197,7 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst op @ VEXOperandCode::U_G_xmm_imm8 => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = @@ -213,7 +214,7 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst op @ VEXOperandCode::G_E_xmm_imm8 => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = @@ -229,7 +230,7 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst op @ VEXOperandCode::M_G_ymm => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = @@ -245,7 +246,7 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst op @ VEXOperandCode::G_E_ymm => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = @@ -352,8 +353,8 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst } } -fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: &mut T, instruction: &mut Instruction, length: &mut u8, p: VEXOpcodePrefix) -> Result<(), ()> { - let opc = bytes.next().ok_or(())?; +fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: &mut T, instruction: &mut Instruction, length: &mut u8, p: VEXOpcodePrefix) -> Result<(), DecodeError> { + let opc = bytes.next().ok_or(DecodeError::ExhaustedInput)?; let L = instruction.prefixes.vex().l(); println!("reading vex instruction from opcode prefix {:?}, L: {}, opc: {:#x}, map:{:?}", p, L, opc, opcode_map); @@ -372,7 +373,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & // 0x12 => (Opcode::VMOVLPS, ..), 0x13 => (Opcode::VMOVLPS, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), @@ -391,7 +392,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & // 0x16 => (Opcode::VMOVLHPS, ..), 0x17 => (Opcode::VMOVHPS, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), @@ -490,7 +491,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } }, @@ -510,13 +511,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x12 => (Opcode::VMOVLPD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_M_xmm }), 0x13 => (Opcode::VMOVLPD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), @@ -532,13 +533,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x16 => (Opcode::VMOVHPD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_M_xmm }), 0x17 => (Opcode::VMOVHPD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), @@ -687,14 +688,14 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & 0x6E => if instruction.prefixes.vex().w() { (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_xmm_Eq }) } else { (Opcode::VMOVD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_xmm_Ed }) @@ -786,13 +787,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x7E => (Opcode::VMOVD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ed_G_xmm }), 0x7E => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Eq_G_xmm }), @@ -808,13 +809,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0xC4 => (Opcode::VPINSRW, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_xmm_Ew_imm8 }), 0xC5 => (Opcode::VPEXTRW, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::U_G_xmm_imm8 }), @@ -855,7 +856,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0xD6 => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), @@ -883,7 +884,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_V_E_ymm } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0xDD => (Opcode::VPADDUSW, if L { VEXOperandCode::G_V_E_ymm @@ -1002,7 +1003,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0xF7 => (Opcode::VMASKMOVDQU, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), @@ -1043,7 +1044,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } @@ -1112,7 +1113,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } @@ -1150,13 +1151,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & 0x5f => (Opcode::VMAXSS, VEXOperandCode::G_V_E_xmm), 0x6f => (Opcode::VMOVDQU, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), 0x70 => (Opcode::VMOVSHDUP, if L { VEXOperandCode::G_E_ymm_imm8 } else { VEXOperandCode::G_E_xmm_imm8 }), - 0x7e => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { VEXOperandCode::G_E_xmm }), + 0x7e => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), 0x7f => (Opcode::VMOVDQU, if L { VEXOperandCode::E_G_ymm } else { VEXOperandCode::E_G_xmm }), 0xc2 => (Opcode::VCMPSS, VEXOperandCode::G_V_E_xmm_imm8), 0xe6 => (Opcode::VCVTDQ2PD, if L { VEXOperandCode::G_ymm_E_xmm } else { VEXOperandCode::G_xmm_E_xmm }), _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } @@ -1256,7 +1257,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_V_E_xmm } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x17 => (Opcode::VPTEST, if L { VEXOperandCode::G_E_ymm @@ -1277,7 +1278,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_M_ymm } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x1C => (Opcode::VPABSB, if L { VEXOperandCode::G_E_ymm @@ -1388,13 +1389,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_ymm } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x36 => (Opcode::VPERMD, if L { VEXOperandCode::G_V_E_ymm } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x37 => (Opcode::VPCMPGTQ, if L { VEXOperandCode::G_V_E_ymm @@ -1433,7 +1434,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x41 => (Opcode::VPHMINPOSUW, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), @@ -1476,7 +1477,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_ymm } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x78 => (Opcode::VPBROADCASTB, if L { VEXOperandCode::G_E_ymm @@ -1910,43 +1911,43 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }, 0xDB => (Opcode::VAESIMC, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), 0xDC => (Opcode::VAESENC, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm }), 0xDD => (Opcode::VAESENCLAST, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm }), 0xDE => (Opcode::VAESDEC, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm }), 0xDF => (Opcode::VAESDECLAST, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm }), _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } else { // the only VEX* 0f38 instructions have an implied 66 prefix. instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } VEXOpcodeMap::Map0F3A => { @@ -1957,13 +1958,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x01 => (Opcode::VPERMPD, if L { VEXOperandCode::G_E_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x02 => (Opcode::VPBLENDD, if L { VEXOperandCode::G_V_E_ymm @@ -1984,7 +1985,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_V_E_ymm } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x08 => (Opcode::VROUNDPS, if L { VEXOperandCode::G_E_ymm_imm8 @@ -2018,27 +2019,27 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x14 => (Opcode::VPEXTRB, if L || instruction.prefixes.vex().w() { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ev_G_xmm_imm8 }), 0x15 => (Opcode::VPEXTRW, if L || instruction.prefixes.vex().w() { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ev_G_xmm_imm8 }), 0x16 => if instruction.prefixes.vex().w() { (Opcode::VPEXTRQ, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_ymm_imm8 }) } else { (Opcode::VPEXTRD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { // varies on W VEXOperandCode::Ev_G_xmm_imm8 @@ -2046,7 +2047,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }, 0x17 => (Opcode::VEXTRACTPS, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_ymm_imm8 }), @@ -2054,13 +2055,13 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_V_E_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x19 => (Opcode::VEXTRACTF128, if L { VEXOperandCode::E_xmm_G_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x1D => (Opcode::VCVTPS2PH, if L { VEXOperandCode::E_xmm_G_ymm_imm8 @@ -2069,31 +2070,31 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x20 => (Opcode::VPINSRB, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), 0x21 => (Opcode::VINSERTPS, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), 0x22 => (Opcode::VPINSRD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), 0x22 => (Opcode::VPINSRQ, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), 0x38 => (Opcode::VINSERTI128, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::V_ymm_G_ymm_E_xmm_imm8 }), @@ -2101,7 +2102,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::V_xmm_G_ymm_E_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x40 => (Opcode::VDPPS, if L { VEXOperandCode::G_V_E_ymm_imm8 @@ -2110,7 +2111,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x41 => (Opcode::VDPPD, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), @@ -2121,7 +2122,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x44 => (Opcode::VPCLMULQDQ, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), @@ -2129,7 +2130,7 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_V_E_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); }), 0x4A => (Opcode::VBLENDVPS, if L { VEXOperandCode::G_V_E_ymm_ymm4 @@ -2148,31 +2149,31 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & }), 0x62 => (Opcode::VPCMPISTRM, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm_imm8 }), 0x63 => (Opcode::VPCMPISTRI, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm_imm8 }), 0xDF => (Opcode::VAESKEYGENASSIST, if L { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm_imm8 }), _ => { instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } } else { // the only VEX* 0f3a instructions have an implied 66 prefix. instruction.opcode = Opcode::Invalid; - return Err(()); + return Err(DecodeError::InvalidOpcode); } } }; diff --git a/test/test.rs b/test/test.rs index 662d358..96f77be 100644 --- a/test/test.rs +++ b/test/test.rs @@ -9,16 +9,16 @@ use yaxpeax_x86::{Instruction, InstDecoder, decode_one}; fn decode(bytes: &[u8]) -> Option { let mut instr = Instruction::invalid(); match decode_one(&InstDecoder::default(), bytes.iter().map(|x| *x).take(16).collect::>(), &mut instr) { - Some(()) => Some(instr), - None => None + Ok(()) => Some(instr), + _ => None } } fn decode_as(decoder: &InstDecoder, bytes: &[u8]) -> Option { let mut instr = Instruction::invalid(); match decode_one(decoder, bytes.iter().map(|x| *x).take(16).collect::>(), &mut instr) { - Some(()) => Some(instr), - None => None + Ok(()) => Some(instr), + _ => None } } @@ -27,7 +27,7 @@ fn test_invalid(data: &[u8]) { } fn test_invalid_under(decoder: &InstDecoder, data: &[u8]) { - if let Some(inst) = decoder.decode(data.into_iter().cloned()) { + if let Ok(inst) = decoder.decode(data.into_iter().cloned()) { assert_eq!(inst.opcode, yaxpeax_x86::Opcode::Invalid, "decoded {:?} from {:02x?} under decoder {}", inst.opcode, data, decoder); } else { // this is fine @@ -44,7 +44,7 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str write!(hex, "{:02x}", b).unwrap(); } match decoder.decode(data.into_iter().map(|x| *x)) { - Some(instr) => { + Ok(instr) => { let text = format!("{}", instr); assert!( text == expected, @@ -56,8 +56,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str expected ); }, - None => { - assert!(false, "decode error for {} under decoder {}:\n expected: {}\n", hex, decoder, expected); + Err(e) => { + assert!(false, "decode error ({}) for {} under decoder {}:\n expected: {}\n", e, hex, decoder, expected); } } } -- cgit v1.1