From 0c3ef986fad0644de3fd982f79c0c3c9affaef40 Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Sat, 5 Dec 2020 22:48:37 +0000 Subject: [PATCH] hypervisor: emulator: rewrite MOV emulation with get/set_op Signed-off-by: Wei Liu --- .../src/arch/x86/emulator/instructions/mov.rs | 108 ++++++++---------- 1 file changed, 47 insertions(+), 61 deletions(-) diff --git a/hypervisor/src/arch/x86/emulator/instructions/mov.rs b/hypervisor/src/arch/x86/emulator/instructions/mov.rs index 44322b72c..1b3beb11d 100644 --- a/hypervisor/src/arch/x86/emulator/instructions/mov.rs +++ b/hypervisor/src/arch/x86/emulator/instructions/mov.rs @@ -17,7 +17,6 @@ extern crate iced_x86; use crate::arch::emulator::{EmulationError, PlatformEmulator}; use crate::arch::x86::emulator::instructions::*; use crate::arch::x86::Exception; -use std::mem; macro_rules! mov_rm_r { ($bound:ty) => { @@ -27,27 +26,18 @@ macro_rules! mov_rm_r { state: &mut T, platform: &mut dyn PlatformEmulator, ) -> Result<(), EmulationError> { - let src_reg_value = state - .read_reg(insn.op1_register()) + let src_reg_value = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform) .map_err(EmulationError::PlatformEmulationError)?; - match insn.op0_kind() { - OpKind::Register => state - .write_reg(insn.op0_register(), src_reg_value) - .map_err(EmulationError::PlatformEmulationError)?, - - OpKind::Memory => { - let addr = memory_operand_address(insn, state, true) - .map_err(EmulationError::PlatformEmulationError)?; - let src_reg_value_type: $bound = src_reg_value as $bound; - - platform - .write_memory(addr, &src_reg_value_type.to_le_bytes()) - .map_err(EmulationError::PlatformEmulationError)? - } - - k => return Err(EmulationError::InvalidOperand(anyhow!("{:?}", k))), - } + set_op( + &insn, + 0, + std::mem::size_of::<$bound>(), + state, + platform, + src_reg_value, + ) + .map_err(EmulationError::PlatformEmulationError)?; state.set_ip(insn.ip()); @@ -57,29 +47,25 @@ macro_rules! mov_rm_r { } macro_rules! mov_rm_imm { - ($type:tt) => { + ($bound:ty) => { fn emulate( &self, insn: &Instruction, state: &mut T, platform: &mut dyn PlatformEmulator, ) -> Result<(), EmulationError> { - let imm = imm_op!($type, insn); + let imm = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform) + .map_err(EmulationError::PlatformEmulationError)?; - match insn.op0_kind() { - OpKind::Register => state - .write_reg(insn.op0_register(), imm as u64) - .map_err(EmulationError::PlatformEmulationError)?, - OpKind::Memory => { - let addr = memory_operand_address(insn, state, true) - .map_err(EmulationError::PlatformEmulationError)?; - - platform - .write_memory(addr, &imm.to_le_bytes()) - .map_err(EmulationError::PlatformEmulationError)? - } - k => return Err(EmulationError::InvalidOperand(anyhow!("{:?}", k))), - } + set_op( + &insn, + 0, + std::mem::size_of::<$bound>(), + state, + platform, + imm, + ) + .map_err(EmulationError::PlatformEmulationError)?; state.set_ip(insn.ip()); @@ -96,28 +82,19 @@ macro_rules! mov_r_rm { state: &mut T, platform: &mut dyn PlatformEmulator, ) -> Result<(), EmulationError> { - let src_value: $bound = match insn.op1_kind() { - OpKind::Register => state - .read_reg(insn.op1_register()) - .map_err(EmulationError::PlatformEmulationError)? - as $bound, - OpKind::Memory => { - let target_address = memory_operand_address(insn, state, false) - .map_err(EmulationError::PlatformEmulationError)?; - let mut memory: [u8; mem::size_of::<$bound>()] = [0; mem::size_of::<$bound>()]; - platform - .read_memory(target_address, &mut memory) - .map_err(EmulationError::PlatformEmulationError)?; - <$bound>::from_le_bytes(memory) - } - - k => return Err(EmulationError::InvalidOperand(anyhow!("{:?}", k))), - }; - - state - .write_reg(insn.op0_register(), src_value as u64) + let src_value = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform) .map_err(EmulationError::PlatformEmulationError)?; + set_op( + &insn, + 0, + std::mem::size_of::<$bound>(), + state, + platform, + src_value, + ) + .map_err(EmulationError::PlatformEmulationError)?; + state.set_ip(insn.ip()); Ok(()) @@ -126,17 +103,26 @@ macro_rules! mov_r_rm { } macro_rules! mov_r_imm { - ($type:tt) => { + ($bound:ty) => { fn emulate( &self, insn: &Instruction, state: &mut T, - _platform: &mut dyn PlatformEmulator, + platform: &mut dyn PlatformEmulator, ) -> Result<(), EmulationError> { - state - .write_reg(insn.op0_register(), imm_op!($type, insn) as u64) + let imm = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform) .map_err(EmulationError::PlatformEmulationError)?; + set_op( + &insn, + 0, + std::mem::size_of::<$bound>(), + state, + platform, + imm, + ) + .map_err(EmulationError::PlatformEmulationError)?; + state.set_ip(insn.ip()); Ok(()) @@ -216,7 +202,7 @@ impl InstructionHandler for Mov_rm32_r32 { pub struct Mov_rm64_imm32; impl InstructionHandler for Mov_rm64_imm32 { - mov_rm_imm!(u32tou64); + mov_rm_imm!(u32); } pub struct Mov_rm64_r64;