diff options
-rw-r--r-- | src/display.rs | 5 | ||||
-rw-r--r-- | src/lib.rs | 152 | ||||
-rw-r--r-- | src/vex.rs | 428 | ||||
-rw-r--r-- | test/test.rs | 7 |
4 files changed, 360 insertions, 232 deletions
diff --git a/src/display.rs b/src/display.rs index dd46055..bea5340 100644 --- a/src/display.rs +++ b/src/display.rs @@ -16,6 +16,7 @@ impl fmt::Display for DecodeError { DecodeError::InvalidOperand => { write!(f, "invalid operand") }, DecodeError::InvalidPrefixes => { write!(f, "invalid prefixes") }, DecodeError::TooLong => { write!(f, "too long") }, + DecodeError::IncompleteDecoder => { write!(f, "the decoder is incomplete") }, } } } @@ -641,7 +642,6 @@ impl fmt::Display for Opcode { &Opcode::ENCLU => write!(f, "enclu"), &Opcode::RDPKRU => write!(f, "rdpkru"), &Opcode::WRPKRU => write!(f, "wrpkru"), - &Opcode::VMOVUPS => write!(f, "vmovups"), &Opcode::VADDPD => write!(f, "vaddpd"), &Opcode::VADDPS => write!(f, "vaddps"), &Opcode::VADDSUBPD => write!(f, "vaddsubpd"), @@ -1617,7 +1617,6 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::MOVQ2DQ | Opcode::MOVSHDUP | Opcode::MOVUPS | - Opcode::VMOVUPS | Opcode::PEXTRW | Opcode::PINSRW | Opcode::MOV | @@ -1908,7 +1907,7 @@ impl <T: std::fmt::Write> ShowContextual<u64, [Option<String>], T> for Instructi &OperandSpec::RegMMM => { write!(out, ", ")?; } - x @ _ => { + _ => { write!(out, ", byte ")?; if let Some(prefix) = self.segment_override_for_op(1) { write!(out, "{}:", prefix)?; @@ -1227,6 +1227,7 @@ pub enum DecodeError { InvalidOperand, InvalidPrefixes, TooLong, + IncompleteDecoder, } impl yaxpeax_arch::DecodeError for DecodeError { @@ -1235,6 +1236,7 @@ impl yaxpeax_arch::DecodeError for DecodeError { fn bad_operand(&self) -> bool { self == &DecodeError::InvalidOperand } } +#[allow(non_camel_case_types)] #[derive(Debug, Copy, Clone, PartialEq)] enum OperandSpec { Nothing, @@ -2390,7 +2392,13 @@ impl InstDecoder { return Err(DecodeError::InvalidOpcode); } } - _ => {} + other => { + if !self.bmi1() { + if BMI1.contains(&other) { + return Err(DecodeError::InvalidOpcode); + } + } + } } Ok(()) } @@ -2585,6 +2593,7 @@ pub struct PrefixVex { bits: u8, } +#[allow(dead_code)] impl PrefixVex { #[inline] fn b(&self) -> bool { (self.bits & 0x01) == 0x01 } @@ -4404,7 +4413,7 @@ fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) -> #[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, DecodeError> { - let modbits = (modrm >> 6); + let modbits = modrm >> 6; let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q }; let sibbyte = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; *length += 1; @@ -4460,7 +4469,7 @@ fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m } } } else { - instr.modrm_mmm = RegSpec::from_parts((sibbyte & 7), instr.prefixes.rex().b(), addr_width); + instr.modrm_mmm = RegSpec::from_parts(sibbyte & 7, instr.prefixes.rex().b(), addr_width); let disp = if modbits == 0b00 { 0 @@ -4496,14 +4505,11 @@ 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, DecodeError> { - let modbits = (modrm >> 6); + let modbits = modrm >> 6; let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q }; let mmm = modrm & 7; let op_spec = if mmm == 4 { return read_sib(bytes_iter, instr, modrm, length); -// let (ss, index, base) = octets_of(sibbyte); - -// println!("scale: {:b}, index: {:b}, base: {:b}", ss, index, base); } else if mmm == 5 && modbits == 0b00 { *length += 4; let disp = read_num(bytes_iter, 4)? as i32; @@ -4696,7 +4702,6 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T } }, None => { -// unsafe { unreachable_unchecked(); } return Err(DecodeError::ExhaustedInput); } } @@ -4718,7 +4723,6 @@ 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<(), DecodeError> { - let mut bytes_read = 0; if (operand_code as u8) & 0x40 == 0x40 { instruction.operands[0] = OperandSpec::RegRRR; } @@ -4744,8 +4748,8 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr = RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present()); instruction.imm = - read_imm_unsigned(&mut bytes_iter, 1)?; - bytes_read = 1; + read_imm_unsigned(&mut bytes_iter, 1, length)?; + *length += 1; instruction.operands[1] = OperandSpec::ImmU8; instruction.operand_count = 2; } else { @@ -4762,7 +4766,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank); instruction.imm = read_imm_ivq(&mut bytes_iter, opwidth, length)?; - bytes_read = opwidth; + *length += opwidth; instruction.operands[1] = match opwidth { 1 => OperandSpec::ImmI8, 2 => OperandSpec::ImmI16, @@ -4798,7 +4802,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter bank = RegisterBank::B; } }; - modrm = read_modrm(&mut bytes_iter, instruction, length)?; + modrm = read_modrm(&mut bytes_iter, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), bank); @@ -4893,7 +4897,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 }; let imm = read_num(&mut bytes_iter, addr_width)?; *length += addr_width; - bytes_read = addr_width; instruction.modrm_rrr = RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()); instruction.disp = imm; @@ -4920,7 +4923,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 }; let imm = read_num(&mut bytes_iter, addr_width)?; *length += addr_width; - bytes_read = addr_width; instruction.disp = imm; instruction.operands[0] = if instruction.prefixes.address_size() { OperandSpec::DispU32 @@ -4932,12 +4934,12 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; } - op @ OperandCode::ModRM_0x80_Eb_Ib | - op @ OperandCode::ModRM_0x81_Ev_Ivs => { + _op @ OperandCode::ModRM_0x80_Eb_Ib | + _op @ OperandCode::ModRM_0x81_Ev_Ivs => { instruction.operands[0] = mem_oper; let numwidth = if opwidth == 8 { 4 } else { opwidth }; instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64; - bytes_read = numwidth; + *length = numwidth; instruction.opcode = base_opcode_map((modrm >> 3) & 7); instruction.operands[1] = match opwidth { 1 => OperandSpec::ImmI8, @@ -4948,8 +4950,8 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter }; instruction.operand_count = 2; }, - op @ OperandCode::ModRM_0xc6_Eb_Ib | - op @ OperandCode::ModRM_0xc7_Ev_Iv => { + _op @ OperandCode::ModRM_0xc6_Eb_Ib | + _op @ OperandCode::ModRM_0xc7_Ev_Iv => { if (modrm & 0b00111000) != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); // Err("Invalid modr/m for opcode 0xc7".to_string()); @@ -4959,7 +4961,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::MOV; let numwidth = if opwidth == 8 { 4 } else { opwidth }; instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64; - bytes_read = numwidth; instruction.operands[1] = match opwidth { 1 => OperandSpec::ImmI8, 2 => OperandSpec::ImmI16, @@ -4996,16 +4997,15 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } instruction.operand_count = 2; }, - op @ OperandCode::ModRM_0xf6 | - op @ OperandCode::ModRM_0xf7 => { + _op @ OperandCode::ModRM_0xf6 | + _op @ OperandCode::ModRM_0xf7 => { instruction.operands[0] = mem_oper; instruction.operand_count = 1; - match ((modrm >> 3) & 7) { + match (modrm >> 3) & 7 { 0 | 1 => { instruction.opcode = Opcode::TEST; let numwidth = if opwidth == 8 { 4 } else { opwidth }; instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64; - bytes_read = numwidth; instruction.operands[1] = match opwidth { 1 => OperandSpec::ImmI8, 2 => OperandSpec::ImmI16, @@ -5069,8 +5069,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } OperandCode::Gv_Eb => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; - bytes_read = 1; + let modrm = read_modrm(&mut bytes_iter, length)?; instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 1, length)?; instruction.modrm_rrr = @@ -5079,8 +5078,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter }, OperandCode::Gv_Ew => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; - bytes_read = 1; + let modrm = read_modrm(&mut bytes_iter, length)?; instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; instruction.modrm_rrr = @@ -5089,8 +5087,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter }, OperandCode::Gdq_Ed => { let opwidth = 8; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; - bytes_read = 1; + let modrm = read_modrm(&mut bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4 /* opwidth */, length)?; @@ -5109,8 +5106,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operand_count = 2; }, OperandCode::E_G_xmm => { - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; - bytes_read = 1; + let modrm = read_modrm(&mut bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); instruction.operands[0] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; @@ -5156,8 +5152,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } }, OperandCode::G_E_mm_Ib => { - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; - bytes_read = 1; + let modrm = read_modrm(&mut bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; @@ -5170,8 +5165,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operand_count = 3; }, OperandCode::G_mm_Ew_Ib => { - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; - bytes_read = 1; + let modrm = read_modrm(&mut bytes_iter, length)?; // println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m); instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; @@ -5192,7 +5186,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter RegSpec::al(); instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - bytes_read = 1; instruction.operands[1] = OperandSpec::ImmI8; instruction.operand_count = 2; } @@ -5203,7 +5196,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter RegSpec::gp_from_parts(0, false, opwidth, false); instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64; - bytes_read = numwidth; instruction.operands[1] = match opwidth { 2 => OperandSpec::ImmI16, 4 => OperandSpec::ImmI32, @@ -5215,8 +5207,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter OperandCode::Ivs => { let opwidth = imm_width_from_prefixes_64(SizeCode::vd, instruction.prefixes); instruction.imm = - read_imm_unsigned(&mut bytes_iter, opwidth)?; - bytes_read = opwidth; + read_imm_unsigned(&mut bytes_iter, opwidth, length)?; instruction.operands[0] = match opwidth { 2 => OperandSpec::ImmI16, 4 => OperandSpec::ImmI32, @@ -5229,7 +5220,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = mem_oper; instruction.opcode = base_opcode_map((modrm >> 3) & 7); instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - bytes_read = 2; instruction.operands[1] = OperandSpec::ImmI8; instruction.operand_count = 2; }, @@ -5264,7 +5254,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operand_count = 3; } OperandCode::Ev_Gv_Ib => { - let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; instruction.imm = @@ -5273,7 +5262,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operand_count = 3; } OperandCode::Ev_Gv_CL => { - let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; instruction.operands[2] = OperandSpec::CL; @@ -5291,12 +5279,11 @@ 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<(), DecodeError> { - let mut bytes_read = 0; match operand_code { OperandCode::ModRM_0x0f71 => { instruction.operand_count = 2; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; if modrm & 0xc0 != 0xc0 { return Err(DecodeError::InvalidOperand); } @@ -5325,7 +5312,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter OperandCode::ModRM_0x0f72 => { instruction.operand_count = 2; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; if modrm & 0xc0 != 0xc0 { return Err(DecodeError::InvalidOperand); } @@ -5354,7 +5341,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter OperandCode::ModRM_0x0f73 => { instruction.operand_count = 2; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; if modrm & 0xc0 != 0xc0 { return Err(DecodeError::InvalidOperand); } @@ -5391,7 +5378,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } }; // all these SO FAR are G_E_xmm - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); @@ -5407,7 +5394,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::AESKEYGENASSIST; // read operands right here right now - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); @@ -5415,7 +5402,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; instruction.imm = - read_imm_unsigned(&mut bytes_iter, 1)?; + read_imm_unsigned(&mut bytes_iter, 1, length)?; instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; } @@ -5607,8 +5594,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } OperandCode::Ew_Sw => { let opwidth = 2; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; - bytes_read = 1; + let modrm = read_modrm(&mut bytes_iter, length)?; // check r if ((modrm >> 3) & 7) > 5 { @@ -5631,8 +5617,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } }, OperandCode::Sw_Ew => { - let opwidth = 2; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; // check r if ((modrm >> 3) & 7) > 5 { @@ -5674,14 +5659,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } OperandCode::Iw => { instruction.imm = - read_imm_unsigned(&mut bytes_iter, 2)?; - bytes_read = 2; + read_imm_unsigned(&mut bytes_iter, 2, length)?; instruction.operands[0] = OperandSpec::ImmU16; instruction.operand_count = 1; } OperandCode::ModRM_0x0f00 => { instruction.operand_count = 1; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; let r = (modrm >> 3) & 7; if r == 0 { instruction.opcode = Opcode::SLDT; @@ -5710,7 +5694,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } OperandCode::ModRM_0x0f01 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; let r = (modrm >> 3) & 7; if r == 0 { let mod_bits = modrm >> 6; @@ -5810,7 +5794,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } else if r == 3 { let mod_bits = modrm >> 6; - let m = modrm & 7; if mod_bits == 0b11 { instruction.opcode = Opcode::Invalid; instruction.operand_count = 0; @@ -5871,7 +5854,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } OperandCode::ModRM_0x0fae => { - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; let r = (modrm >> 3) & 7; let mod_bits = modrm >> 6; @@ -5936,7 +5919,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } OperandCode::ModRM_0x0fba => { let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; let r = (modrm >> 3) & 7; match r { 0 | 1 | 2 | 3 => { @@ -5963,7 +5946,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - bytes_read += 2; instruction.operands[1] = OperandSpec::ImmI8; instruction.operand_count = 2; } @@ -5986,7 +5968,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter _ => unsafe { unreachable_unchecked() } }; - let modrm = read_modrm(&mut bytes_iter, instruction, length)?; + let modrm = read_modrm(&mut bytes_iter, length)?; let mut m = modrm & 7; let mut r = (modrm >> 3) & 7; if instruction.prefixes.rex().r() { @@ -6023,7 +6005,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::Invalid; // return Err(()); // Err(format!("unsupported operand code: {:?}", operand_code)); return Err(DecodeError::InvalidOperand); - // unsafe { unreachable_unchecked(); } } }; Ok(()) @@ -6036,34 +6017,9 @@ pub fn decode_one<'b, T: IntoIterator<Item=u8>>(decoder: &InstDecoder, bytes: T, OperandSpec::Nothing, OperandSpec::Nothing, ]; - let mut bytes_iter = bytes.into_iter(); + let bytes_iter = bytes.into_iter(); read_instr(decoder, bytes_iter, instr) } -/* - match read_opcode(&mut bytes_iter, instr) { - Some(operand_code) => { - match read_operands(&mut bytes_iter, instr, operand_code) { - Ok(()) => { - Some(()) - }, - Err(_reason) => { -// panic!("Decode error on operand: {:?}", reason); - // println!("Invalid instruction: {}", reason); -// return Instruction::invalid() - None - } - } - } -// Err(_reason) => { - None => { -// panic!("Decode error on opcode: {:?}", reason); - // println!("Invalid instruction: {}", reason); -// return Instruction::invalid() - None - } - } -} -*/ #[inline] fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> { @@ -6116,13 +6072,11 @@ 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, DecodeError> { - read_num(bytes, width) -} - -#[inline] -fn octets_of(byte: u8) -> (u8, u8, u8) { - (byte >> 6 & 0b11, (byte >> 3) & 0b111, byte & 0b111) +fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u64, DecodeError> { + read_num(bytes, width).map(|res| { + *length += width; + res + }) } #[inline] @@ -6154,6 +6108,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, DecodeError> { +fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<u8, DecodeError> { bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b }) } @@ -25,9 +25,16 @@ enum VEXOpcodePrefix { PrefixF2, } +#[allow(non_camel_case_types)] #[derive(Debug)] enum VEXOperandCode { Nothing, + VPS_71, + VPS_71_L, + VPS_72, + VPS_72_L, + VPS_73, + VPS_73_L, VMOVSS_10, VMOVSD_10, VMOVSD_11, @@ -107,7 +114,7 @@ pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: & }; instruction.prefixes.vex_from_c4(vex_byte_one, vex_byte_two); - read_vex_instruction(m, bytes, instruction, &mut length, p); + read_vex_instruction(m, bytes, instruction, &mut length, p)?; instruction.length = length; Ok(()) } @@ -128,7 +135,7 @@ pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mu }; instruction.prefixes.vex_from_c5(vex_byte); - read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p); + read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p)?; instruction.length = length; Ok(()) } @@ -136,9 +143,201 @@ pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mu 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::VPS_71 => { + let modrm = read_modrm(bytes, length)?; + match (modrm >> 3) & 0b111 { + 0b010 => { + instruction.opcode = Opcode::VPSRLW; + } + 0b100 => { + instruction.opcode = Opcode::VPSRAW; + } + 0b110 => { + instruction.opcode = Opcode::VPSLLW; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + /* + 0x71 => (Opcode::VPSLLW, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x71 => (Opcode::VPSRAW, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x71 => (Opcode::VPSRLW, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_ymm + }), + */ + Err(DecodeError::IncompleteDecoder) // :) + } + VEXOperandCode::VPS_71_L => { + let modrm = read_modrm(bytes, length)?; + match (modrm >> 3) & 0b111 { + 0b010 => { + instruction.opcode = Opcode::VPSRLW; + } + 0b100 => { + instruction.opcode = Opcode::VPSRAW; + } + 0b110 => { + instruction.opcode = Opcode::VPSLLW; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + /* + 0x71 => (Opcode::VPSLLW, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x71 => (Opcode::VPSRAW, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x71 => (Opcode::VPSRLW, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_ymm + }), + */ + Err(DecodeError::IncompleteDecoder) // :) + } + VEXOperandCode::VPS_72 => { + let modrm = read_modrm(bytes, length)?; + match (modrm >> 3) & 0b111 { + 0b010 => { + instruction.opcode = Opcode::VPSRLD; + } + 0b100 => { + instruction.opcode = Opcode::VPSRAD; + } + 0b110 => { + instruction.opcode = Opcode::VPSLLD; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + /* + 0x72 => (Opcode::VPSLLD, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x72 => (Opcode::VPSRAD, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x72 => (Opcode::VPSRLD, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + */ + Err(DecodeError::IncompleteDecoder) // :) + } + VEXOperandCode::VPS_72_L => { + let modrm = read_modrm(bytes, length)?; + match (modrm >> 3) & 0b111 { + 0b010 => { + instruction.opcode = Opcode::VPSRLD; + } + 0b100 => { + instruction.opcode = Opcode::VPSRAD; + } + 0b110 => { + instruction.opcode = Opcode::VPSLLD; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + /* + 0x72 => (Opcode::VPSLLD, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x72 => (Opcode::VPSRAD, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + 0x72 => (Opcode::VPSRLD, if L { + VEXOperandCode::G_E_ymm_imm8 + } else { + VEXOperandCode::G_E_ymm_imm8 + }), + */ + Err(DecodeError::IncompleteDecoder) // :) + } + VEXOperandCode::VPS_73 => { + let modrm = read_modrm(bytes, length)?; + match (modrm >> 3) & 0b111 { + 0b010 => { + instruction.opcode = Opcode::VPSRLQ; + } + 0b011 => { + instruction.opcode = Opcode::VPSRLDQ; + } + 0b110 => { + instruction.opcode = Opcode::VPSLLQ; + } + 0b111 => { + instruction.opcode = Opcode::VPSLLDQ; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + // VEXOperandCode::G_E_xmm_imm8 ? this is reg1, reg2, imm8, but r is used for + // picking the opcode. is one of these actually the vex reg? + Err(DecodeError::IncompleteDecoder) // :) + } + VEXOperandCode::VPS_73_L => { + let modrm = read_modrm(bytes, length)?; + match (modrm >> 3) & 0b111 { + 0b000 | + 0b001 | + 0b100 | + 0b101 => { + return Err(DecodeError::InvalidOpcode); + } + 0b010 => { + instruction.opcode = Opcode::VPSRLQ; + } + 0b011 => { + instruction.opcode = Opcode::VPSRLDQ; + } + 0b110 => { + instruction.opcode = Opcode::VPSLLQ; + } + 0b111 => { + instruction.opcode = Opcode::VPSLLDQ; + } + _ => { + unreachable!("r is only three bits"); + } + } + // VEXOperandCode::G_E_ymm_imm8 ? this is reg1, reg2, imm8, but r is used for + // picking the opcode. is one of these actually the vex reg? + Err(DecodeError::IncompleteDecoder) // :) + } VEXOperandCode::VMOVSS_10 | VEXOperandCode::VMOVSD_10 => { - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; @@ -156,7 +355,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst }, VEXOperandCode::VMOVSS_11 | VEXOperandCode::VMOVSD_11 => { - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; @@ -180,26 +379,26 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E(bytes, instruction, modrm, 8, length)?; instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; instruction.operands[2] = OperandSpec::ImmU8; - instruction.imm = read_imm_unsigned(bytes, 1)?; + instruction.imm = read_imm_unsigned(bytes, 1, length)?; Ok(()) }, - op @ VEXOperandCode::E_G_xmm | - op @ VEXOperandCode::U_G_xmm | - op @ VEXOperandCode::M_G_xmm | - op @ VEXOperandCode::E_G_xmm_imm8 | - op @ VEXOperandCode::U_G_xmm_imm8 => { + _op @ VEXOperandCode::E_G_xmm | + _op @ VEXOperandCode::U_G_xmm | + _op @ VEXOperandCode::M_G_xmm | + _op @ VEXOperandCode::E_G_xmm_imm8 | + _op @ VEXOperandCode::U_G_xmm_imm8 => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; @@ -208,15 +407,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst Ok(()) } - op @ VEXOperandCode::G_M_xmm | - op @ VEXOperandCode::G_U_xmm | - op @ VEXOperandCode::G_E_xmm | - op @ VEXOperandCode::G_E_xmm_imm8 => { + _op @ VEXOperandCode::G_M_xmm | + _op @ VEXOperandCode::G_U_xmm | + _op @ VEXOperandCode::G_E_xmm | + _op @ VEXOperandCode::G_E_xmm_imm8 => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; @@ -225,14 +424,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst Ok(()) } - op @ VEXOperandCode::E_G_ymm | - op @ VEXOperandCode::U_G_ymm | - op @ VEXOperandCode::M_G_ymm => { + _op @ VEXOperandCode::E_G_ymm | + _op @ VEXOperandCode::U_G_ymm | + _op @ VEXOperandCode::M_G_ymm => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; @@ -241,14 +440,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst Ok(()) } - op @ VEXOperandCode::G_M_ymm | - op @ VEXOperandCode::G_U_ymm | - op @ VEXOperandCode::G_E_ymm => { + _op @ VEXOperandCode::G_M_ymm | + _op @ VEXOperandCode::G_U_ymm | + _op @ VEXOperandCode::G_E_ymm => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; @@ -256,9 +455,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[1] = mem_oper; Ok(()) } - op @ VEXOperandCode::G_V_E_ymm | - op @ VEXOperandCode::G_V_M_ymm => { - let modrm = read_modrm(bytes, instruction, length)?; + _op @ VEXOperandCode::G_V_E_ymm | + _op @ VEXOperandCode::G_V_M_ymm => { + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); instruction.vex_reg.bank = RegisterBank::Y; @@ -268,9 +467,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[2] = mem_oper; Ok(()) } - op @ VEXOperandCode::E_V_G_ymm | - op @ VEXOperandCode::M_V_G_ymm => { - let modrm = read_modrm(bytes, instruction, length)?; + _op @ VEXOperandCode::E_V_G_ymm | + _op @ VEXOperandCode::M_V_G_ymm => { + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); instruction.vex_reg.bank = RegisterBank::Y; @@ -280,9 +479,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[2] = OperandSpec::RegRRR; Ok(()) } - op @ VEXOperandCode::G_V_M_xmm | - op @ VEXOperandCode::G_V_E_xmm => { - let modrm = read_modrm(bytes, instruction, length)?; + _op @ VEXOperandCode::G_V_M_xmm | + _op @ VEXOperandCode::G_V_E_xmm => { + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; @@ -292,9 +491,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst Ok(()) } - op @ VEXOperandCode::E_V_G_xmm | - op @ VEXOperandCode::M_V_G_xmm => { - let modrm = read_modrm(bytes, instruction, length)?; + _op @ VEXOperandCode::E_V_G_xmm | + _op @ VEXOperandCode::M_V_G_xmm => { + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; @@ -305,7 +504,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst } VEXOperandCode::G_Ex_V_xmm => { - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; @@ -316,7 +515,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst Ok(()) } VEXOperandCode::G_Ey_V_ymm => { - let modrm = read_modrm(bytes, instruction, length)?; + let modrm = read_modrm(bytes, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; @@ -329,7 +528,6 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst } VEXOperandCode::E_xmm_G_ymm_imm8 | - VEXOperandCode::Ev_G_xmm_imm8 | VEXOperandCode::G_E_ymm_imm8 | VEXOperandCode::G_xmm_E_xmm | VEXOperandCode::G_xmm_E_ymm | @@ -347,7 +545,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst VEXOperandCode::G_xmm_Eq | VEXOperandCode::G_V_ymm_E_xmm | VEXOperandCode::G_V_xmm_Ew_imm8 => { - Ok(()) // :) + Err(DecodeError::IncompleteDecoder) // :) } } @@ -355,6 +553,9 @@ 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<(), DecodeError> { let opc = bytes.next().ok_or(DecodeError::ExhaustedInput)?; + + // the name of this bit is `L` in the documentation, so use the same name here. + #[allow(non_snake_case)] let L = instruction.prefixes.vex().l(); println!("reading vex instruction from opcode prefix {:?}, L: {}, opc: {:#x}, map:{:?}", p, L, opc, opcode_map); @@ -710,55 +911,20 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_E_xmm_imm8 }), - 0x71 => (Opcode::VPSLLW, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_ymm_imm8 - }), - 0x71 => (Opcode::VPSRAW, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_ymm_imm8 - }), - 0x71 => (Opcode::VPSRLW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }), - 0x72 => (Opcode::VPSLLD, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_ymm_imm8 - }), - 0x72 => (Opcode::VPSRAD, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_ymm_imm8 - }), - 0x72 => (Opcode::VPSRLD, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_ymm_imm8 - }), - 0x73 => (Opcode::VPSLLDQ, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_ymm_imm8 - }), - 0x73 => (Opcode::VPSLLQ, if L { - VEXOperandCode::G_E_ymm_imm8 + 0x71 => (Opcode::Invalid, if L { + VEXOperandCode::VPS_71_L } else { - VEXOperandCode::G_E_ymm_imm8 + VEXOperandCode::VPS_71 }), - 0x73 => (Opcode::VPSRLDQ, if L { - VEXOperandCode::G_E_ymm_imm8 + 0x72 => (Opcode::Invalid, if L { + VEXOperandCode::VPS_72_L } else { - VEXOperandCode::G_E_ymm_imm8 + VEXOperandCode::VPS_72 }), - 0x73 => (Opcode::VPSRLQ, if L { - VEXOperandCode::G_E_ymm_imm8 + 0x73 => (Opcode::Invalid, if L { + VEXOperandCode::VPS_73_L } else { - VEXOperandCode::G_E_ymm_imm8 + VEXOperandCode::VPS_73 }), 0x74 => (Opcode::VPCMPEQB, if L { VEXOperandCode::G_V_E_ymm @@ -785,18 +951,21 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_V_E_xmm }), - 0x7E => (Opcode::VMOVD, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::Ed_G_xmm - }), - 0x7E => (Opcode::VMOVQ, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); + 0x7E => if instruction.prefixes.vex().w() { + (Opcode::VMOVQ, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::Eq_G_xmm + }) } else { - VEXOperandCode::Eq_G_xmm - }), + (Opcode::VMOVD, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::Ed_G_xmm + }) + } 0x7F => (Opcode::VMOVDQA, if L { VEXOperandCode::E_G_ymm } else { @@ -1438,31 +1607,37 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_E_xmm }), - 0x45 => (Opcode::VPSRLVD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x45 => (Opcode::VPSRLVQ, if L { - VEXOperandCode::G_V_E_ymm + 0x45 => if instruction.prefixes.vex().w() { + (Opcode::VPSRLVQ, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }) } else { - VEXOperandCode::G_V_E_xmm - }), + (Opcode::VPSRLVD, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }) + }, 0x46 => (Opcode::VPSRAVD, if L { VEXOperandCode::G_V_E_ymm } else { VEXOperandCode::G_V_E_xmm }), - 0x47 => (Opcode::VPSLLVD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x47 => (Opcode::VPSLLVQ, if L { - VEXOperandCode::G_V_E_ymm + 0x47 => if instruction.prefixes.vex().w() { + (Opcode::VPSLLVQ, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }) } else { - VEXOperandCode::G_V_E_xmm - }), + (Opcode::VPSLLVD, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }) + }, 0x58 => (Opcode::VPBROADCASTD, if L { VEXOperandCode::G_E_ymm } else { @@ -2080,18 +2255,21 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_V_E_xmm_imm8 }), - 0x22 => (Opcode::VPINSRD, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0x22 => (Opcode::VPINSRQ, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); + 0x22 => if instruction.prefixes.vex().w() { + (Opcode::VPINSRQ, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_V_E_xmm_imm8 + }) } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), + (Opcode::VPINSRD, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_V_E_xmm_imm8 + }) + }, 0x38 => (Opcode::VINSERTI128, if L { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); diff --git a/test/test.rs b/test/test.rs index 96f77be..7726bb7 100644 --- a/test/test.rs +++ b/test/test.rs @@ -6,6 +6,7 @@ use std::fmt::Write; use yaxpeax_arch::Decoder; use yaxpeax_x86::{Instruction, InstDecoder, decode_one}; +#[allow(dead_code)] 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) { @@ -14,6 +15,7 @@ fn decode(bytes: &[u8]) -> Option<Instruction> { } } +#[allow(dead_code)] 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) { @@ -105,11 +107,6 @@ fn test_aesni() { test_invalid_under(&InstDecoder::minimal(), bytes); } - fn test_instr_invalid(bytes: &[u8]) { - test_invalid_under(&InstDecoder::minimal().with_aesni(), bytes); - test_invalid_under(&InstDecoder::default(), bytes); - } - test_instr(&[0x66, 0x0f, 0x38, 0xdb, 0x0f], "aesimc xmm1, [rdi]"); test_instr(&[0x66, 0x4f, 0x0f, 0x38, 0xdb, 0xcf], "aesimc xmm9, xmm15"); |