From f6ea2e4cb44c80ab19a92e6216d14223daf5841f Mon Sep 17 00:00:00 2001 From: iximeow Date: Mon, 13 Jan 2020 20:12:43 -0800 Subject: test that instruction lengths are correct fix several instances of incorrect instruction lengths * immediates for `mov reg, imm` and some other instructions were double-counted * lengths for vex prefixes were wrong all over the place --- src/lib.rs | 3 --- src/vex.rs | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 9409ca9..500d59d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4757,7 +4757,6 @@ fn read_operands>(decoder: &InstDecoder, mut bytes_iter: T, RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present()); instruction.imm = read_imm_unsigned(&mut bytes_iter, 1, length)?; - *length += 1; instruction.operands[1] = OperandSpec::ImmU8; instruction.operand_count = 2; } else { @@ -4774,7 +4773,6 @@ fn read_operands>(decoder: &InstDecoder, mut bytes_iter: T, RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank); instruction.imm = read_imm_ivq(&mut bytes_iter, opwidth, length)?; - *length += opwidth; instruction.operands[1] = match opwidth { 1 => OperandSpec::ImmI8, 2 => OperandSpec::ImmI16, @@ -4947,7 +4945,6 @@ fn read_operands>(decoder: &InstDecoder, mut bytes_iter: T, 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; - *length = numwidth; instruction.opcode = base_opcode_map((modrm >> 3) & 7); instruction.operands[1] = match opwidth { 1 => OperandSpec::ImmI8, diff --git a/src/vex.rs b/src/vex.rs index 99cee01..8a7434f 100644 --- a/src/vex.rs +++ b/src/vex.rs @@ -89,6 +89,7 @@ enum VEXOperandCode { pub(crate) fn three_byte_vex>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> { let vex_byte_one = bytes.next().ok_or(DecodeError::ExhaustedInput)?; let vex_byte_two = bytes.next().ok_or(DecodeError::ExhaustedInput)?; + length += 2; let p = vex_byte_two & 0x03; let p = match p { 0x00 => VEXOpcodePrefix::None, @@ -121,6 +122,7 @@ pub(crate) fn three_byte_vex>(bytes: &mut T, instruction: & pub(crate) fn two_byte_vex>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> { let vex_byte = bytes.next().ok_or(DecodeError::ExhaustedInput)?; + length += 1; let p = vex_byte & 0x03; let p = match p { 0x00 => VEXOpcodePrefix::None, @@ -553,6 +555,7 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: &mut T, instruction: &mut Instruction, length: &mut u8, p: VEXOpcodePrefix) -> Result<(), DecodeError> { let opc = bytes.next().ok_or(DecodeError::ExhaustedInput)?; + *length += 1; // the name of this bit is `L` in the documentation, so use the same name here. #[allow(non_snake_case)] -- cgit v1.1