aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-01-03 18:31:22 -0800
committeriximeow <me@iximeow.net>2020-01-12 16:10:14 -0800
commit6f897e655a5f18b28b47542d76ac88d0aebcbc5d (patch)
tree4c464e9801e4976360b4d86fa3bfff3f7794b0e4
parente5c38434423e3f0e936c6b9718063866b3e3347c (diff)
match changes in arch to have Resulty decode, instead of Option
-rw-r--r--src/display.rs14
-rw-r--r--src/lib.rs194
-rw-r--r--src/vex.rs143
-rw-r--r--test/test.rs16
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<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 })
}
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<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);
}
}
};
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<Instruction> {
let mut instr = Instruction::invalid();
match decode_one(&InstDecoder::default(), bytes.iter().map(|x| *x).take(16).collect::<Vec<u8>>(), &mut instr) {
- Some(()) => Some(instr),
- None => None
+ Ok(()) => Some(instr),
+ _ => None
}
}
fn decode_as(decoder: &InstDecoder, bytes: &[u8]) -> Option<Instruction> {
let mut instr = Instruction::invalid();
match decode_one(decoder, bytes.iter().map(|x| *x).take(16).collect::<Vec<u8>>(), &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);
}
}
}