From a4b6304bd0df5fbab311a037d7c04b1ecbef7b14 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 3 Jul 2021 10:17:17 -0700 Subject: port over x86_64 improvements to x86_32 --- src/long_mode/mod.rs | 4 +++ src/protected_mode/mod.rs | 69 ++++++++++++++--------------------------------- 2 files changed, 24 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 125716f..254ccc7 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -9133,6 +9133,10 @@ fn unlikely_operands::Address, { + if instruction.prefixes.rep() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOperand); + } + let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes); let modrm = read_modrm(words)?; let r = (modrm >> 3) & 7; diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 46321d1..b7387d9 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -7141,7 +7141,6 @@ fn read_operands::Address, ::Address, ::Address, ::Address, ::Address, ::Address, ::Address, { if is_reg { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { instruction.opcode = Opcode::CMPXCHG8B; @@ -8150,7 +8146,6 @@ fn unlikely_operands::Address, { if is_reg { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { instruction.opcode = Opcode::CMPXCHG8B; @@ -8208,7 +8203,6 @@ fn unlikely_operands::Address, { if is_reg { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { instruction.opcode = Opcode::CMPXCHG8B; @@ -8253,7 +8247,6 @@ fn unlikely_operands::Address, { if is_reg { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { instruction.mem_size = 8; @@ -8262,7 +8255,6 @@ fn unlikely_operands::Address, { if is_reg { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { instruction.mem_size = 63; @@ -8271,7 +8263,6 @@ fn unlikely_operands::Address, { if is_reg { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { instruction.mem_size = 63; @@ -8280,7 +8271,6 @@ fn unlikely_operands::Address, { if is_reg { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { instruction.mem_size = 63; @@ -8304,7 +8294,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } }; @@ -8356,6 +8345,10 @@ fn unlikely_operands::Address, { + if instruction.prefixes.rep() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOperand); + } + instruction.operand_count = 2; let modrm = read_modrm(words)?; @@ -8757,7 +8750,6 @@ fn unlikely_operands::Address, { if instruction.operands[1] != OperandSpec::RegMMM { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } instruction.regs[0].bank = RegisterBank::D; @@ -8774,7 +8766,6 @@ fn unlikely_operands::Address, ::Address, ::Address, { + if instruction.prefixes.rep() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOperand); + } + let opwidth = if instruction.prefixes.operand_size() { 2 } else { @@ -8950,7 +8943,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -8981,7 +8973,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -9006,7 +8997,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -9043,7 +9033,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -9106,7 +9095,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; return Err(DecodeError::InvalidOperand); @@ -9161,7 +9149,6 @@ fn unlikely_operands::Address, ::Address, ::Address, ::Address, { - instruction.opcode = Opcode::Invalid; instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; return Err(DecodeError::InvalidOpcode); @@ -9243,7 +9227,6 @@ fn unlikely_operands::Address, ::Address, ::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } }; @@ -9321,7 +9302,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } }; @@ -9345,7 +9325,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -9408,7 +9387,6 @@ fn unlikely_operands::Address, { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -9446,7 +9424,6 @@ fn unlikely_operands::Address, ::Address, ::Address, ::Address, > 3) & 7; match r { 0 | 1 | 2 | 3 => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }, 4 => { @@ -9728,7 +9702,7 @@ fn unlikely_operands::Address, { - return decode_x87(decoder, words, instruction, operand_code); + return decode_x87(words, instruction, operand_code); } OperandCode::M_Gv => { // `lea` operands (`Gv_M`) opportunistically reject a register form of `mmm` early, but @@ -9775,14 +9749,13 @@ fn unlikely_operands::Address, ::Address, ::Word>>(_decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction, operand_code: OperandCode) -> Result<(), DecodeError> { +fn decode_x87::Address, ::Word>>(words: &mut T, instruction: &mut Instruction, operand_code: OperandCode) -> Result<(), DecodeError> { #[allow(non_camel_case_types)] enum OperandCodeX87 { Est, @@ -10304,21 +10277,19 @@ fn decode_x87::Address, ::Address, ::Word>>(bytes: &mut T, width: u8) -> Result { match width { - 1 => { bytes.next().map(|x| x as u32).ok().ok_or(DecodeError::ExhaustedInput) } + 1 => { bytes.next().ok().ok_or(DecodeError::ExhaustedInput).map(|x| x as u32) } 2 => { - bytes.next().and_then(|b0| { - bytes.next().map(|b1| u16::from_le_bytes([b0, b1]) as u32) - }).ok().ok_or(DecodeError::ExhaustedInput) + let mut buf = [0u8; 2]; + bytes.next_n(&mut buf).ok().ok_or(DecodeError::ExhaustedInput)?; + Ok(u16::from_le_bytes(buf) as u32) } 4 => { - bytes.next() - .and_then(|b0| bytes.next().map(|b1| (b0, b1))) - .and_then(|(b0, b1)| bytes.next().map(|b2| (b0, b1, b2))) - .and_then(|(b0, b1, b2)| bytes.next().map(|b3| u32::from_le_bytes([b0, b1, b2, b3]))) - .ok().ok_or(DecodeError::ExhaustedInput) + let mut buf = [0u8; 4]; + bytes.next_n(&mut buf).ok().ok_or(DecodeError::ExhaustedInput)?; + Ok(u32::from_le_bytes(buf) as u32) } _ => { - panic!("unsupported read size"); + unsafe { unreachable_unchecked(); } } } } -- cgit v1.1