diff options
-rw-r--r-- | src/lib.rs | 339 |
1 files changed, 171 insertions, 168 deletions
@@ -2089,7 +2089,7 @@ const OPCODES: [OpcodeRecord; 256] = [ ]; #[allow(non_snake_case)] -fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize, width: u8) -> Option<()> { +fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize, width: u8) -> Result<(), ()> { let bank = width_to_gp_reg_bank(width, instr.prefixes.rex().present()); if modrm >= 0b11000000 { read_modrm_reg(bytes_iter, instr, modrm, result, bank) @@ -2098,7 +2098,7 @@ fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, mod } } #[allow(non_snake_case)] -fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Option<()> { +fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Result<(), ()> { if modrm >= 0b11000000 { read_modrm_reg(bytes_iter, instr, modrm, result, RegisterBank::X) } else { @@ -2107,28 +2107,28 @@ fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, } #[allow(non_snake_case)] -fn read_modrm_reg<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize, reg_bank: RegisterBank) -> Option<()> { +fn read_modrm_reg<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize, reg_bank: RegisterBank) -> Result<(), ()> { instr.operands[result] = Operand::Register(RegSpec::from_parts(modrm & 7, instr.prefixes.rex().b(), reg_bank)); - Some(()) + Ok(()) } #[allow(non_snake_case)] -fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Option<()> { +fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Result<(), ()> { let modbits = (modrm >> 6); let addr_width = if instr.prefixes.address_size() { 4 } else { 8 }; let sibbyte = match bytes_iter.next() { Some(b) => b, - None => { return None; } //Err("Out of bytes".to_string()) + None => { return Err(()); } //Err("Out of bytes".to_string()) }; instr.length += 1; instr.operands[result] = if (sibbyte & 7) == 0b101 { let disp = if modbits == 0b00 { - read_num(bytes_iter, 4, &mut instr.length) as i32 + read_num(bytes_iter, 4, &mut instr.length)? as i32 } else if modbits == 0b01 { - read_num(bytes_iter, 1, &mut instr.length) as i8 as i32 + read_num(bytes_iter, 1, &mut instr.length)? as i8 as i32 } else { - read_num(bytes_iter, 4, &mut instr.length) as i32 + read_num(bytes_iter, 4, &mut instr.length)? as i32 }; if ((sibbyte >> 3) & 7) == 0b100 { @@ -2182,9 +2182,9 @@ fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m let disp = if modbits == 0b00 { 0 } else if modbits == 0b01 { - read_num(bytes_iter, 1, &mut instr.length) as i8 as i32 + read_num(bytes_iter, 1, &mut instr.length)? as i8 as i32 } else { - read_num(bytes_iter, 4, &mut instr.length) as i32 + read_num(bytes_iter, 4, &mut instr.length)? as i32 }; if ((sibbyte >> 3) & 7) == 0b100 { @@ -2212,11 +2212,11 @@ fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m } } }; - Some(()) + Ok(()) } #[allow(non_snake_case)] -fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Option<()> { +fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Result<(), ()> { let modbits = (modrm >> 6); let addr_width = if instr.prefixes.address_size() { 4 } else { 8 }; let mmm = modrm & 7; @@ -2228,7 +2228,7 @@ fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, mod // println!("scale: {:b}, index: {:b}, base: {:b}", ss, index, base); } else if mmm == 5 && modbits == 0b00 { - let disp = read_num(bytes_iter, 4, &mut instr.length); + let disp = read_num(bytes_iter, 4, &mut instr.length)?; Operand::RegDisp( if addr_width == 8 { RegSpec::rip() } else { RegSpec::eip() }, disp as i32 @@ -2240,14 +2240,14 @@ fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, mod Operand::RegDeref(reg) } else { let disp = if modbits == 0b01 { - read_num(bytes_iter, 1, &mut instr.length) as i8 as i32 + read_num(bytes_iter, 1, &mut instr.length)? as i8 as i32 } else { - read_num(bytes_iter, 4, &mut instr.length) as i32 + read_num(bytes_iter, 4, &mut instr.length)? as i32 }; Operand::RegDisp(reg, disp) } }; - Some(()) + Ok(()) } #[inline] @@ -2261,7 +2261,7 @@ fn width_to_gp_reg_bank(width: u8, rex: bool) -> RegisterBank { } } -pub fn read_instr<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction) -> Option<()> { +pub fn read_instr<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), ()> { let mut alternate_opcode_map: Option<OpcodeMap> = None; // use std::intrinsics::unlikely; instruction.prefixes = Prefixes::new(0); @@ -2298,7 +2298,7 @@ pub fn read_instr<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Ins } { break record; } else { - return None; + return Err(()); } }, 0x26 => { @@ -2350,46 +2350,46 @@ pub fn read_instr<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Ins }, None => { // unsafe { unreachable_unchecked(); } - return None; + return Err(()); } } }; read_operands(bytes_iter, instruction, record.1) } -pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode) -> Option<()> { +pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode) -> Result<(), ()> { if operand_code == OperandCode::Gv_Ev { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); - read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 1, opwidth)?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); } else if operand_code == OperandCode::Ev_Gv { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.operands[1] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); } else if operand_code == OperandCode::Gb_Eb { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 1, opwidth)?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); } else if operand_code == OperandCode::Eb_Gb { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.operands[1] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); } else if operand_code == OperandCode::Jbs { // TODO: arch width (8 in 64, 4 in 32, 2 in 16) instruction.operands = [ - read_imm_signed(&mut bytes_iter, 1, 8, &mut instruction.length).unwrap(), + read_imm_signed(&mut bytes_iter, 1, 8, &mut instruction.length)?, Operand::Nothing ]; } else { @@ -2442,21 +2442,21 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut */ OperandCode::Eb_R0 => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; if (modrm & 0b00111000) != 0 { instruction.opcode = Opcode::Invalid; - return None; // Err("Invalid modr/m for opcode 0xc6".to_owned()); + return Err(()); // Err("Invalid modr/m for opcode 0xc6".to_owned()); } - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; }, OperandCode::AL_Ob => { let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 }; // stupid RCT thing: let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 }; let opwidth = 1; - let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length); + let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?; instruction.operands = [ Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())), if instruction.prefixes.address_size() { @@ -2471,7 +2471,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut // stupid RCT thing: let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 }; let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length); + let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?; instruction.operands = [ Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())), if instruction.prefixes.address_size() { @@ -2486,7 +2486,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut // stupid RCT thing: let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 }; let opwidth = 1; - let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length); + let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?; instruction.operands = [ if instruction.prefixes.address_size() { Operand::DisplacementU32(imm as u32) @@ -2501,7 +2501,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut // stupid RCT thing: let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 }; let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length); + let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?; instruction.operands = [ if instruction.prefixes.address_size() { Operand::DisplacementU32(imm as u32) @@ -2513,100 +2513,100 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } OperandCode::ModRM_0x80_Eb_Ib => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); - let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8; + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; + let num = read_num(&mut bytes_iter, 1, &mut instruction.length)? as i8; instruction.opcode = base_opcode_map((modrm >> 3) & 7); instruction.operands[1] = Operand::ImmediateI8(num); }, OperandCode::ModRM_0x81_Ev_Ivs => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); - let imm = read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, &mut instruction.length).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; + let imm = read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, &mut instruction.length)?; instruction.opcode = base_opcode_map((modrm >> 3) & 7); instruction.operands[1] = imm; }, OperandCode::ModRM_0xc0_Eb_Ib => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); - let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8; + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; + let num = read_num(&mut bytes_iter, 1, &mut instruction.length)? as i8; instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone(); instruction.operands[1] = Operand::ImmediateI8(num); }, OperandCode::ModRM_0xc1_Ev_Ib => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); - let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8; + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; + let num = read_num(&mut bytes_iter, 1, &mut instruction.length)? as i8; instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone(); instruction.operands[1] = Operand::ImmediateI8(num); }, OperandCode::ModRM_0xc6_Eb_Ib => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); - let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8; + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; + let num = read_num(&mut bytes_iter, 1, &mut instruction.length)? as i8; if (modrm & 0b00111000) != 0 { instruction.opcode = Opcode::Invalid; - return None; // Err("Invalid modr/m for opcode 0xc6".to_owned()); + return Err(()); // Err("Invalid modr/m for opcode 0xc6".to_owned()); } instruction.opcode = Opcode::MOV; instruction.operands[1] = Operand::ImmediateI8(num); }, OperandCode::ModRM_0xc7_Ev_Iv => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; if (modrm & 0b00111000) != 0 { instruction.opcode = Opcode::Invalid; - return None; // Err("Invalid modr/m for opcode 0xc7".to_string()); + return Err(()); // Err("Invalid modr/m for opcode 0xc7".to_string()); } - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.opcode = Opcode::MOV; - instruction.operands[1] = read_imm_unsigned(&mut bytes_iter, opwidth, &mut instruction.length).unwrap(); + instruction.operands[1] = read_imm_unsigned(&mut bytes_iter, opwidth, &mut instruction.length)?; }, OperandCode::ModRM_0xd0_Eb_1 => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone(); instruction.operands[1] = Operand::ImmediateI8(1); }, OperandCode::ModRM_0xd1_Ev_1 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone(); instruction.operands[1] = Operand::ImmediateI8(1); }, OperandCode::ModRM_0xd3_Ev_CL => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let (mod_bits, r, m) = octets_of(modrm); - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; let opcode = BITWISE_OPCODE_MAP[r as usize].clone(); instruction.opcode = opcode; instruction.operands[1] = Operand::Register(RegSpec::cl()); } OperandCode::ModRM_0xf6 => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; match (modrm >> 3) & 7 { 0 | 1 => { instruction.opcode = Opcode::TEST; - instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, opwidth, &mut instruction.length).unwrap(); + instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, opwidth, &mut instruction.length)?; }, 2 => { instruction.opcode = Opcode::NOT; @@ -2633,13 +2633,13 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut }, OperandCode::ModRM_0xf7 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; match ((modrm >> 3) & 7) { 0 | 1 => { instruction.opcode = Opcode::TEST; let numwidth = if opwidth == 8 { 4 } else { opwidth }; - instruction.operands[1] = read_imm_signed(&mut bytes_iter, numwidth, opwidth, &mut instruction.length).unwrap(); + instruction.operands[1] = read_imm_signed(&mut bytes_iter, numwidth, opwidth, &mut instruction.length)?; }, 2 => { instruction.opcode = Opcode::NOT; @@ -2666,9 +2666,9 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut }, OperandCode::ModRM_0xfe_Eb => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.opcode = [ Opcode::INC, Opcode::DEC, @@ -2683,9 +2683,9 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } OperandCode::ModRM_0xff_Ev => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; let opcode = [ Opcode::INC, Opcode::DEC, @@ -2701,51 +2701,51 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } OperandCode::Ev => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.operands[1] = Operand::Nothing; }, OperandCode::Gb_Eb_Ib => { let opwidth = 1; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let (mod_bits, r, m) = octets_of(modrm); let mut ext = vec![Operand::Nothing; 2]; // TODO panic!("oh no, a mul!"); -// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0]).unwrap(); +// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0])?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); read_imm_signed(&mut bytes_iter, 1, 1, &mut instruction.length).map(|imm| { ext[1] = imm; instruction.operands[1] = Operand::Many(ext); - }).unwrap() + })? } OperandCode::Gv_Eb => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 1, opwidth)?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); }, OperandCode::Gv_Ew => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; - read_E(&mut bytes_iter, instruction, modrm, 1, 2).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 1, 2)?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); }, OperandCode::Ew_Sw => { let opwidth = 2; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; // check r if ((modrm >> 3) & 7) > 5 { - return None; //Err("Invalid r".to_owned()); + return Err(()); //Err("Invalid r".to_owned()); } instruction.operands[1] = @@ -2756,16 +2756,16 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut instruction.operands[0] = Operand::Register(RegSpec { bank: RegisterBank::W, num: modrm & 7}); } else { - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; } }, OperandCode::Sw_Ew => { let opwidth = 2; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; // check r if ((modrm >> 3) & 7) > 5 { - return None; // Err("Invalid r".to_owned()); + return Err(()); // Err("Invalid r".to_owned()); } instruction.operands[0] = @@ -2776,57 +2776,57 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut instruction.operands[1] = Operand::Register(RegSpec { bank: RegisterBank::W, num: modrm & 7}); } else { - read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 1, opwidth)?; } }, OperandCode::Gdq_Ed => { let opwidth = 8; - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); - read_E(&mut bytes_iter, instruction, modrm, 1, 4 /* opwidth */).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 1, 4 /* opwidth */)?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); }, OperandCode::Gv_M => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); - read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 1, opwidth)?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); }, OperandCode::Gv_Ev_Iv => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let (mod_bits, r, m) = octets_of(modrm); let mut ext = vec![Operand::Nothing; 2]; // TODO panic!("oh no, a mul!"); -// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0]).unwrap(); +// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0])?; instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, &mut instruction.length).map(|imm| { ext[1] = imm; instruction.operands[1] = Operand::Many(ext); - }).unwrap() + })? } OperandCode::E_G_xmm => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); - read_E_xmm(&mut bytes_iter, instruction, modrm, 0).unwrap(); + read_E_xmm(&mut bytes_iter, instruction, modrm, 0)?; instruction.operands[1] = Operand::Register(RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X)); }, OperandCode::G_E_xmm => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); - read_E_xmm(&mut bytes_iter, instruction, modrm, 1).unwrap(); + read_E_xmm(&mut bytes_iter, instruction, modrm, 1)?; instruction.operands[0] = Operand::Register(RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X)); }, @@ -2842,7 +2842,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); instruction.operands = [ Operand::Register(RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())), - read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap() + read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length)? ]; }, OperandCode::AL_Ib => { @@ -2850,7 +2850,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut let numwidth = 1; instruction.operands = [ Operand::Register(RegSpec::al()), - read_imm_signed(&mut bytes_iter, numwidth, opwidth, &mut instruction.length).unwrap() + read_imm_signed(&mut bytes_iter, numwidth, opwidth, &mut instruction.length)? ]; } OperandCode::AX_Ivd => { @@ -2858,7 +2858,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut let numwidth = if opwidth == 8 { 4 } else { opwidth }; instruction.operands = [ Operand::Register(RegSpec::gp_from_parts(0, false, opwidth, false)), - read_imm_signed(&mut bytes_iter, numwidth, opwidth, &mut instruction.length).unwrap() + read_imm_signed(&mut bytes_iter, numwidth, opwidth, &mut instruction.length)? ]; } op @ OperandCode::Zb_Ib_R0 | @@ -2872,35 +2872,35 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut let reg = (op as u8) - (OperandCode::Zb_Ib_R0 as u8); instruction.operands = [ Operand::Register(RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())), - read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap() + read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length)? ]; }, OperandCode::Iw => { instruction.operands = [ - read_imm_unsigned(&mut bytes_iter, 2, &mut instruction.length).unwrap(), + read_imm_unsigned(&mut bytes_iter, 2, &mut instruction.length)?, Operand::Nothing ]; } OperandCode::Ibs => { instruction.operands = [ - read_imm_signed(&mut bytes_iter, 1, 8, &mut instruction.length).unwrap(), + read_imm_signed(&mut bytes_iter, 1, 8, &mut instruction.length)?, Operand::Nothing ]; }, OperandCode::Ivs => { let opwidth = imm_width_from_prefixes_64(SizeCode::vd, &instruction.prefixes); instruction.operands = [ - read_imm_unsigned(&mut bytes_iter, opwidth, &mut instruction.length).unwrap(), + read_imm_unsigned(&mut bytes_iter, opwidth, &mut instruction.length)?, Operand::Nothing ]; }, OperandCode::ModRM_0x83_Ev_Ibs => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; instruction.opcode = base_opcode_map((modrm >> 3) & 7); - instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, opwidth, &mut instruction.length).unwrap(); + instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, opwidth, &mut instruction.length)?; }, op @ OperandCode::Zv_R0 | op @ OperandCode::Zv_R1 | @@ -2919,11 +2919,11 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut ), Operand::Nothing]; }, OperandCode::Jvds => { - let offset = read_num(&mut bytes_iter, 4, &mut instruction.length); + let offset = read_num(&mut bytes_iter, 4, &mut instruction.length)?; instruction.operands = [Operand::ImmediateI32(offset as i32), Operand::Nothing]; } OperandCode::ModRM_0x0f00 => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let r = (modrm >> 3) & 7; if r == 0 { instruction.opcode = Opcode::SLDT; @@ -2946,19 +2946,19 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } else if r == 6 { instruction.opcode = Opcode::JMPE; instruction.operands = [Operand::Nothing, Operand::Nothing]; - return Some(()); + return Ok(()); } else if r == 7 { instruction.opcode = Opcode::Invalid; instruction.operands = [Operand::Nothing, Operand::Nothing]; - return Some(()); + return Ok(()); } else { unreachable!("r <= 8"); } - read_E(&mut bytes_iter, instruction, modrm, 0, 2).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, 2)?; } OperandCode::ModRM_0x0f01 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let r = (modrm >> 3) & 7; if r == 0 { let mod_bits = modrm >> 6; @@ -2968,7 +2968,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } else { instruction.opcode = Opcode::SGDT; instruction.operands[1] = Operand::Nothing; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; } } else if r == 1 { let mod_bits = modrm >> 6; @@ -2980,7 +2980,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } else { instruction.opcode = Opcode::SIDT; instruction.operands[1] = Operand::Nothing; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; } } else if r == 2 { let mod_bits = modrm >> 6; @@ -2992,7 +2992,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } else { instruction.opcode = Opcode::LGDT; instruction.operands[1] = Operand::Nothing; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; } } else if r == 3 { let mod_bits = modrm >> 6; @@ -3004,20 +3004,20 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } else { instruction.opcode = Opcode::LIDT; instruction.operands[1] = Operand::Nothing; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; } } else if r == 4 { // TODO: this permits storing only to word-size registers - // spec suggets this might do something different for f.ex rdi.unwrap() + // spec suggets this might do something different for f.ex rdi? instruction.opcode = Opcode::SMSW; instruction.operands[1] = Operand::Nothing; - read_E(&mut bytes_iter, instruction, modrm, 0, 2).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, 2)?; } else if r == 5 { panic!("Unsupported instruction: 0x0f01 with modrm: __ 101 ___"); } else if r == 6 { instruction.opcode = Opcode::LMSW; instruction.operands[1] = Operand::Nothing; - read_E(&mut bytes_iter, instruction, modrm, 0, 2).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, 2)?; } else if r == 7 { let mod_bits = modrm >> 6; let m = modrm & 7; @@ -3030,25 +3030,25 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut instruction.operands = [Operand::Nothing, Operand::Nothing]; } else { // panic!("Unsupported instruction: 0x0f01 with modrm: 11 110 r >= 2"); - return None; // Err("unsupported 0x0f01 variant".to_string()) + return Err(()); // Err("unsupported 0x0f01 variant".to_string()) } } else { instruction.opcode = Opcode::INVLPG; instruction.operands[1] = Operand::Nothing; - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; } } else { unreachable!("r <= 8"); } } OperandCode::ModRM_0x0fae => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let r = (modrm >> 3) & 7; let mod_bits = modrm >> 6; match r { 0 => { if mod_bits == 0b11 { - return None; // Err("Invalid mod bits".to_owned()) + return Err(()); // Err("Invalid mod bits".to_owned()) } else { instruction.opcode = Opcode::FXSAVE; instruction.operands[1] = Operand::Nothing; @@ -3056,7 +3056,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } 1 => { if mod_bits == 0b11 { - return None; // Err("Invalid mod bits".to_owned()); + return Err(()); // Err("Invalid mod bits".to_owned()); } else { instruction.opcode = Opcode::FXRSTOR; instruction.operands[1] = Operand::Nothing; @@ -3064,7 +3064,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } 2 => { if mod_bits == 0b11 { - return None; // Err("Invalid mod bits".to_owned()); + return Err(()); // Err("Invalid mod bits".to_owned()); } else { instruction.opcode = Opcode::LDMXCSR; instruction.operands[1] = Operand::Nothing; @@ -3072,7 +3072,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } 3 => { if mod_bits == 0b11 { - return None; //Err("Invalid mod bits".to_owned()); + return Err(()); //Err("Invalid mod bits".to_owned()); } else { instruction.opcode = Opcode::STMXCSR; instruction.operands[1] = Operand::Nothing; @@ -3080,7 +3080,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } 4 => { if mod_bits == 0b11 { - return None; //Err("Invalid mod bits".to_owned()); + return Err(()); //Err("Invalid mod bits".to_owned()); } else { instruction.opcode = Opcode::XSAVE; instruction.operands[1] = Operand::Nothing; @@ -3099,9 +3099,9 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut if mod_bits == 0b11 { instruction.opcode = Opcode::MFENCE; instruction.operands = [Operand::Nothing, Operand::Nothing]; - return Some(()); + return Ok(()); } else { - // TODO: radare reports this, but i'm not sure.unwrap() + // TODO: radare reports this, but i'm not sure? instruction.opcode = Opcode::XSAVEOPT; instruction.operands[1] = Operand::Nothing; } @@ -3110,25 +3110,25 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut if mod_bits == 0b11 { instruction.opcode = Opcode::SFENCE; instruction.operands = [Operand::Nothing, Operand::Nothing]; - return Some(()); + return Ok(()); } else { - // TODO: radare reports this, but i'm not sure.unwrap() + // TODO: radare reports this, but i'm not sure? instruction.opcode = Opcode::CLFLUSH; instruction.operands[1] = Operand::Nothing; } } _ => { unreachable!("r < 6"); } } - read_E(&mut bytes_iter, instruction, modrm, 0, 8).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, 8)?; } OperandCode::ModRM_0x0fba => { let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let r = (modrm >> 3) & 7; match r { 0 | 1 | 2 | 3 => { instruction.opcode = Opcode::Invalid; - return None; //Err("invalid instruction".to_string()); + return Err(()); //Err("invalid instruction".to_string()); }, 4 => { instruction.opcode = Opcode::BT; @@ -3147,13 +3147,13 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut } } - read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap(); + read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?; - instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, 1, &mut instruction.length).unwrap(); + instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, 1, &mut instruction.length)?; } OperandCode::Rq_Cq_0 => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let mut m = modrm & 7; let mut r = (modrm >> 3) & 7; if instruction.prefixes.rex().r() { @@ -3168,7 +3168,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut ]; } OperandCode::Rq_Dq_0 => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let mut m = modrm & 7; let mut r = (modrm >> 3) & 7; if instruction.prefixes.rex().r() { @@ -3183,7 +3183,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut ]; } OperandCode::Cq_Rq_0 => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let mut m = modrm & 7; let mut r = (modrm >> 3) & 7; if instruction.prefixes.rex().r() { @@ -3198,7 +3198,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut ]; } OperandCode::Dq_Rq_0 => { - let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?; let mut m = modrm & 7; let mut r = (modrm >> 3) & 7; if instruction.prefixes.rex().r() { @@ -3227,19 +3227,19 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut _ => { instruction.operands = [Operand::Nothing, Operand::Nothing]; instruction.opcode = Opcode::Invalid; - return None; // Err(format!("unsupported operand code: {:.unwrap()}", operand_code)); + return Err(()); // Err(format!("unsupported operand code: {:?}", operand_code)); // unsafe { unreachable_unchecked(); } } }; } - Some(()) + Ok(()) } pub fn decode_one<'b, T: IntoIterator<Item=u8>>(bytes: T, instr: &'b mut Instruction) -> Option<()> { let mut bytes_iter = bytes.into_iter(); instr.length = 0; - read_instr(bytes_iter, instr) + read_instr(bytes_iter, instr).ok() } /* match read_opcode(&mut bytes_iter, instr) { @@ -3268,31 +3268,34 @@ pub fn decode_one<'b, T: IntoIterator<Item=u8>>(bytes: T, instr: &'b mut Instruc */ #[inline] -fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> u64 { +fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u64, ()> { let mut result = 0u64; let mut idx = 0; loop { if idx == width { - return result; + return Ok(result); + } + if let Some(byte) = bytes.next() { + *length += 1; + result |= (byte as u64) << (idx * 8); + idx += 1; + } else { + return Err(()); } - let byte = bytes.next().unwrap(); - *length += 1; - 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<Operand, String> { +fn read_imm_ivq<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<Operand, ()> { match width { 2 => { - Ok(Operand::ImmediateU16(read_num(bytes, 2, length) as u16)) + Ok(Operand::ImmediateU16(read_num(bytes, 2, length)? as u16)) }, 4 => { - Ok(Operand::ImmediateU32(read_num(bytes, 4, length) as u32)) + Ok(Operand::ImmediateU32(read_num(bytes, 4, length)? as u32)) }, 8 => { - Ok(Operand::ImmediateU64(read_num(bytes, 8, length) as u64)) + Ok(Operand::ImmediateU64(read_num(bytes, 8, length)? as u64)) }, _ => { unsafe { unreachable_unchecked(); } @@ -3301,12 +3304,12 @@ 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, extend_to: u8, length: &mut u8) -> Result<Operand, String> { +fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, extend_to: u8, length: &mut u8) -> Result<Operand, ()> { let num = match num_width { - 1 => read_num(bytes, 1, length) as i8 as i64, - 2 => read_num(bytes, 2, length) as i16 as i64, - 4 => read_num(bytes, 4, length) as i32 as i64, - 8 => read_num(bytes, 4, length) as i32 as i64, + 1 => read_num(bytes, 1, length)? as i8 as i64, + 2 => read_num(bytes, 2, length)? as i16 as i64, + 4 => read_num(bytes, 4, length)? as i32 as i64, + 8 => read_num(bytes, 4, length)? as i32 as i64, _ => { unsafe { unreachable_unchecked() } } }; @@ -3320,19 +3323,19 @@ fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, extend_to } #[inline] -fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<Operand, String> { +fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<Operand, ()> { match width { 1 => { - Ok(Operand::ImmediateU8(read_num(bytes, 1, length) as u8)) + Ok(Operand::ImmediateU8(read_num(bytes, 1, length)? as u8)) }, 2 => { - Ok(Operand::ImmediateU16(read_num(bytes, 2, length) as u16)) + Ok(Operand::ImmediateU16(read_num(bytes, 2, length)? as u16)) }, 4 => { - Ok(Operand::ImmediateU32(read_num(bytes, 4, length) as u32)) + Ok(Operand::ImmediateU32(read_num(bytes, 4, length)? as u32)) }, 8 => { - Ok(Operand::ImmediateU64(read_num(bytes, 4, length) as u64)) + Ok(Operand::ImmediateU64(read_num(bytes, 4, length)? as u64)) } _ => { unsafe { unreachable_unchecked(); } @@ -3374,12 +3377,12 @@ fn imm_width_from_prefixes_64(interpretation: SizeCode, prefixes: &Prefixes) -> } #[inline] -fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<u8, String> { +fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<u8, ()> { let modrm = match bytes_iter.next() { Some(b) => b, // TODO: ... None => { - return Err("Out of bytes".to_string()); + return Err(()); } }; *length += 1; |