mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-03-07 17:26:14 +00:00
hypervisor: emulator: rewrite MOV emulation with get/set_op
Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
parent
53c3b00fb0
commit
0c3ef986fa
@ -17,7 +17,6 @@ extern crate iced_x86;
|
|||||||
use crate::arch::emulator::{EmulationError, PlatformEmulator};
|
use crate::arch::emulator::{EmulationError, PlatformEmulator};
|
||||||
use crate::arch::x86::emulator::instructions::*;
|
use crate::arch::x86::emulator::instructions::*;
|
||||||
use crate::arch::x86::Exception;
|
use crate::arch::x86::Exception;
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
macro_rules! mov_rm_r {
|
macro_rules! mov_rm_r {
|
||||||
($bound:ty) => {
|
($bound:ty) => {
|
||||||
@ -27,27 +26,18 @@ macro_rules! mov_rm_r {
|
|||||||
state: &mut T,
|
state: &mut T,
|
||||||
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
||||||
) -> Result<(), EmulationError<Exception>> {
|
) -> Result<(), EmulationError<Exception>> {
|
||||||
let src_reg_value = state
|
let src_reg_value = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform)
|
||||||
.read_reg(insn.op1_register())
|
|
||||||
.map_err(EmulationError::PlatformEmulationError)?;
|
.map_err(EmulationError::PlatformEmulationError)?;
|
||||||
|
|
||||||
match insn.op0_kind() {
|
set_op(
|
||||||
OpKind::Register => state
|
&insn,
|
||||||
.write_reg(insn.op0_register(), src_reg_value)
|
0,
|
||||||
.map_err(EmulationError::PlatformEmulationError)?,
|
std::mem::size_of::<$bound>(),
|
||||||
|
state,
|
||||||
OpKind::Memory => {
|
platform,
|
||||||
let addr = memory_operand_address(insn, state, true)
|
src_reg_value,
|
||||||
.map_err(EmulationError::PlatformEmulationError)?;
|
)
|
||||||
let src_reg_value_type: $bound = src_reg_value as $bound;
|
.map_err(EmulationError::PlatformEmulationError)?;
|
||||||
|
|
||||||
platform
|
|
||||||
.write_memory(addr, &src_reg_value_type.to_le_bytes())
|
|
||||||
.map_err(EmulationError::PlatformEmulationError)?
|
|
||||||
}
|
|
||||||
|
|
||||||
k => return Err(EmulationError::InvalidOperand(anyhow!("{:?}", k))),
|
|
||||||
}
|
|
||||||
|
|
||||||
state.set_ip(insn.ip());
|
state.set_ip(insn.ip());
|
||||||
|
|
||||||
@ -57,29 +47,25 @@ macro_rules! mov_rm_r {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! mov_rm_imm {
|
macro_rules! mov_rm_imm {
|
||||||
($type:tt) => {
|
($bound:ty) => {
|
||||||
fn emulate(
|
fn emulate(
|
||||||
&self,
|
&self,
|
||||||
insn: &Instruction,
|
insn: &Instruction,
|
||||||
state: &mut T,
|
state: &mut T,
|
||||||
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
||||||
) -> Result<(), EmulationError<Exception>> {
|
) -> Result<(), EmulationError<Exception>> {
|
||||||
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() {
|
set_op(
|
||||||
OpKind::Register => state
|
&insn,
|
||||||
.write_reg(insn.op0_register(), imm as u64)
|
0,
|
||||||
.map_err(EmulationError::PlatformEmulationError)?,
|
std::mem::size_of::<$bound>(),
|
||||||
OpKind::Memory => {
|
state,
|
||||||
let addr = memory_operand_address(insn, state, true)
|
platform,
|
||||||
.map_err(EmulationError::PlatformEmulationError)?;
|
imm,
|
||||||
|
)
|
||||||
platform
|
.map_err(EmulationError::PlatformEmulationError)?;
|
||||||
.write_memory(addr, &imm.to_le_bytes())
|
|
||||||
.map_err(EmulationError::PlatformEmulationError)?
|
|
||||||
}
|
|
||||||
k => return Err(EmulationError::InvalidOperand(anyhow!("{:?}", k))),
|
|
||||||
}
|
|
||||||
|
|
||||||
state.set_ip(insn.ip());
|
state.set_ip(insn.ip());
|
||||||
|
|
||||||
@ -96,28 +82,19 @@ macro_rules! mov_r_rm {
|
|||||||
state: &mut T,
|
state: &mut T,
|
||||||
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
||||||
) -> Result<(), EmulationError<Exception>> {
|
) -> Result<(), EmulationError<Exception>> {
|
||||||
let src_value: $bound = match insn.op1_kind() {
|
let src_value = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform)
|
||||||
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)
|
|
||||||
.map_err(EmulationError::PlatformEmulationError)?;
|
.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());
|
state.set_ip(insn.ip());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -126,17 +103,26 @@ macro_rules! mov_r_rm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! mov_r_imm {
|
macro_rules! mov_r_imm {
|
||||||
($type:tt) => {
|
($bound:ty) => {
|
||||||
fn emulate(
|
fn emulate(
|
||||||
&self,
|
&self,
|
||||||
insn: &Instruction,
|
insn: &Instruction,
|
||||||
state: &mut T,
|
state: &mut T,
|
||||||
_platform: &mut dyn PlatformEmulator<CpuState = T>,
|
platform: &mut dyn PlatformEmulator<CpuState = T>,
|
||||||
) -> Result<(), EmulationError<Exception>> {
|
) -> Result<(), EmulationError<Exception>> {
|
||||||
state
|
let imm = get_op(&insn, 1, std::mem::size_of::<$bound>(), state, platform)
|
||||||
.write_reg(insn.op0_register(), imm_op!($type, insn) as u64)
|
|
||||||
.map_err(EmulationError::PlatformEmulationError)?;
|
.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());
|
state.set_ip(insn.ip());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -216,7 +202,7 @@ impl<T: CpuStateManager> InstructionHandler<T> for Mov_rm32_r32 {
|
|||||||
|
|
||||||
pub struct Mov_rm64_imm32;
|
pub struct Mov_rm64_imm32;
|
||||||
impl<T: CpuStateManager> InstructionHandler<T> for Mov_rm64_imm32 {
|
impl<T: CpuStateManager> InstructionHandler<T> for Mov_rm64_imm32 {
|
||||||
mov_rm_imm!(u32tou64);
|
mov_rm_imm!(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Mov_rm64_r64;
|
pub struct Mov_rm64_r64;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user