diff options
| author | iximeow <me@iximeow.net> | 2020-01-03 18:31:22 -0800 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2020-01-12 16:10:14 -0800 | 
| commit | 6f897e655a5f18b28b47542d76ac88d0aebcbc5d (patch) | |
| tree | 4c464e9801e4976360b4d86fa3bfff3f7794b0e4 /src | |
| parent | e5c38434423e3f0e936c6b9718063866b3e3347c (diff) | |
match changes in arch to have Resulty decode, instead of Option
Diffstat (limited to 'src')
| -rw-r--r-- | src/display.rs | 14 | ||||
| -rw-r--r-- | src/lib.rs | 194 | ||||
| -rw-r--r-- | src/vex.rs | 143 | 
3 files changed, 191 insertions, 160 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 { @@ -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<Instruction> for InstDecoder { -    fn decode<T: IntoIterator<Item=u8>>(&self, bytes: T) -> Option<Instruction> { +    type Error = DecodeError; + +    fn decode<T: IntoIterator<Item=u8>>(&self, bytes: T) -> Result<Instruction, Self::Error> {          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<T: IntoIterator<Item=u8>>(&self, instr: &mut Instruction, bytes: T) -> Option<()> { +    fn decode_into<T: IntoIterator<Item=u8>>(&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<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { -    bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_660f_map<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { -    bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_f20f_map<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<(OpcodeRecord, u8), ()> { -    bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_f30f_map<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<OpcodeRecord, ()> { -    bytes_iter.next().ok_or(()).map(|b| { +fn read_opcode_0f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<OpcodeRecord, DecodeError> { +    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<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, length: &mut u8) -> Result<OperandSpec, ()> { +pub(crate) fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {      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<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instr      }  }  #[allow(non_snake_case)] -pub(crate) fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, ()> { +pub(crate) fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {      if modrm >= 0b11000000 {          read_modrm_reg(instr, modrm, RegisterBank::X)      } else { @@ -4365,7 +4388,7 @@ pub(crate) fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut I      }  }  #[allow(non_snake_case)] -pub(crate) fn read_E_ymm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, ()> { +pub(crate) fn read_E_ymm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {      if modrm >= 0b11000000 {          read_modrm_reg(instr, modrm, RegisterBank::Y)      } else { @@ -4374,20 +4397,16 @@ pub(crate) fn read_E_ymm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut I  }  #[allow(non_snake_case)] -fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) -> Result<OperandSpec, ()> { +fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) -> Result<OperandSpec, DecodeError> {      instr.modrm_mmm = RegSpec::from_parts(modrm & 7, instr.prefixes.rex().b(), reg_bank);      Ok(OperandSpec::RegMMM)  }  #[allow(non_snake_case)] -fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, ()> { +fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {      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<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m  }  #[allow(non_snake_case)] -fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, ()> { +fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {      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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), ()> { +pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), DecodeError> {      let mut length = 0u8;      let mut alternate_opcode_map: Option<OpcodeMap> = None;  //    use std::intrinsics::unlikely; @@ -4592,7 +4611,6 @@ pub fn read_instr<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T              },              None => {  //                unsafe { unreachable_unchecked(); } -                return Err(()); +                return Err(DecodeError::ExhaustedInput);              }          }      }; @@ -4699,7 +4717,7 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T      }      Ok(())  } -pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), ()> { +pub fn read_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter      Ok(())  } -fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), ()> { +fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                      instruction.opcode = Opcode::PSLLW;                  }                  _ => { -                    return Err(()); +                    return Err(DecodeError::InvalidOpcode);                  }              } @@ -5309,7 +5327,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                      instruction.opcode = Opcode::PSLLD;                  }                  _ => { -                    return Err(()); +                    return Err(DecodeError::InvalidOpcode);                  }              } @@ -5338,7 +5356,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                      instruction.opcode = Opcode::PSLLQ;                  }                  _ => { -                    return Err(()); +                    return Err(DecodeError::InvalidOpcode);                  }              } @@ -5360,7 +5378,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  }                  _ => {                      instruction.opcode = Opcode::Invalid; -                    return Err(()); +                    return Err(DecodeError::InvalidOpcode);                  }              };          } @@ -5557,7 +5575,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                          },                          _ => {                              instruction.opcode = Opcode::Invalid; -                            return Err(()); +                            return Err(DecodeError::InvalidOpcode);                          }                      }                  } else { @@ -5746,7 +5766,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                          }                          _ => {                              instruction.opcode = Opcode::Invalid; -                            return Err(()); +                            return Err(DecodeError::InvalidOpcode);                          }                      }                  } else { @@ -5780,7 +5800,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                          }                          _ => {                              instruction.opcode = Opcode::Invalid; -                            return Err(()); +                            return Err(DecodeError::InvalidOpcode);                          }                      }                  } else { @@ -5794,7 +5814,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<Item=u8>>(decoder: &InstDecoder, bytes: T, instr: &'b mut Instruction) -> Option<()> { +pub fn decode_one<'b, T: IntoIterator<Item=u8>>(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<Item=u8>>(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<Item=u8>>(decoder: &InstDecoder, bytes: T,  */  #[inline] -fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, ()> { +fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {      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<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u64, ()> { +fn read_imm_ivq<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u64, DecodeError> {      match width {          2 => {              *length += 2; @@ -6083,7 +6101,7 @@ fn read_imm_ivq<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8)  }  #[inline] -fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, length: &mut u8) -> Result<i64, ()> { +fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, length: &mut u8) -> Result<i64, DecodeError> {      if num_width == 1 {          *length += 1;          Ok(read_num(bytes, 1)? as i8 as i64) @@ -6098,7 +6116,7 @@ fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, length: &  }  #[inline] -fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, ()> { +fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {      read_num(bytes, width)  } @@ -6136,6 +6154,6 @@ fn imm_width_from_prefixes_64(interpretation: SizeCode, prefixes: Prefixes) -> u  }  #[inline] -fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, inst: &mut Instruction, length: &mut u8) -> Result<u8, ()> { -    bytes_iter.next().map(|b| { *length += 1; b }).ok_or(()) +fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, inst: &mut Instruction, length: &mut u8) -> Result<u8, DecodeError> { +    bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })  } @@ -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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &      Ok(())  } -pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), ()> { -    let vex_byte = bytes.next().ok_or(())?; +pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mu      Ok(())  } -fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Instruction, length: &mut u8, operand_code: VEXOperandCode) -> Result<(), ()> { +fn read_vex_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst      }  } -fn read_vex_instruction<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          }),                          _ => {                              instruction.opcode = Opcode::Invalid; -                            return Err(()); +                            return Err(DecodeError::InvalidOpcode);                          }                      }                  }, @@ -510,13 +511,13 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          }),                          _ => {                              instruction.opcode = Opcode::Invalid; -                            return Err(()); +                            return Err(DecodeError::InvalidOpcode);                          }                      }                  } @@ -1112,7 +1113,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          }),                          _ => {                              instruction.opcode = Opcode::Invalid; -                            return Err(()); +                            return Err(DecodeError::InvalidOpcode);                          }                      }                  } @@ -1150,13 +1151,13 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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);              }          }      }; | 
