mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-21 23:41:15 +00:00
x86 emulator: add Mov_moffs_AX & Mov_AX_moffs (16,32,64)
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
This commit is contained in:
parent
fe97785a9f
commit
442ac9056c
@ -239,6 +239,36 @@ impl<T: CpuStateManager> InstructionHandler<T> for Movzx_r64_rm16 {
|
|||||||
movzx!(u64, u16);
|
movzx!(u64, u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Mov_moffs16_AX;
|
||||||
|
impl<T: CpuStateManager> InstructionHandler<T> for Mov_moffs16_AX {
|
||||||
|
movzx!(u16, u16);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mov_AX_moffs16;
|
||||||
|
impl<T: CpuStateManager> InstructionHandler<T> for Mov_AX_moffs16 {
|
||||||
|
movzx!(u16, u16);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mov_moffs32_EAX;
|
||||||
|
impl<T: CpuStateManager> InstructionHandler<T> for Mov_moffs32_EAX {
|
||||||
|
movzx!(u32, u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mov_EAX_moffs32;
|
||||||
|
impl<T: CpuStateManager> InstructionHandler<T> for Mov_EAX_moffs32 {
|
||||||
|
movzx!(u32, u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mov_moffs64_RAX;
|
||||||
|
impl<T: CpuStateManager> InstructionHandler<T> for Mov_moffs64_RAX {
|
||||||
|
movzx!(u64, u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mov_RAX_moffs64;
|
||||||
|
impl<T: CpuStateManager> InstructionHandler<T> for Mov_RAX_moffs64 {
|
||||||
|
movzx!(u64, u64);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(unused_mut)]
|
#![allow(unused_mut)]
|
||||||
@ -617,4 +647,123 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(eax, value as u64);
|
assert_eq!(eax, value as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
// movabs ax, ds:0x1337
|
||||||
|
// movabs eax, ds:0x1337
|
||||||
|
// movabs rax, ds:0x1337
|
||||||
|
fn test_mov_memoff_ax() {
|
||||||
|
let test_inputs: [(Register, &[u8]); 3] = [
|
||||||
|
(Register::AX, &[0x66, 0xa1]),
|
||||||
|
(Register::EAX, &[0xa1]),
|
||||||
|
(Register::RAX, &[0x48, 0xa1]),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Constructs the instruction with the provided inputs and emulates it.
|
||||||
|
fn helper(register: Register, instruction_prefix: &[u8]) {
|
||||||
|
let mem_addr: u64 = 0x1337;
|
||||||
|
let mem_value: u64 = 0x13371337deadbeef;
|
||||||
|
let ip: u64 = 0x1000;
|
||||||
|
let cpu_id = 0;
|
||||||
|
|
||||||
|
let mut instruction_bytes = Vec::new();
|
||||||
|
// instruction prefix with specified register
|
||||||
|
instruction_bytes.extend(instruction_prefix);
|
||||||
|
// 64-bit memory operand
|
||||||
|
instruction_bytes.extend([
|
||||||
|
mem_addr.to_le_bytes()[0],
|
||||||
|
mem_addr.to_le_bytes()[1],
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let memory: [u8; 8] = mem_value.to_le_bytes();
|
||||||
|
let mut vmm = MockVmm::new(ip, vec![], Some((mem_addr, &memory)));
|
||||||
|
assert!(vmm.emulate_first_insn(cpu_id, &instruction_bytes).is_ok());
|
||||||
|
|
||||||
|
let ax: u64 = vmm.cpu_state(cpu_id).unwrap().read_reg(register).unwrap();
|
||||||
|
|
||||||
|
match register {
|
||||||
|
Register::AX => {
|
||||||
|
assert_eq!(ax as u16, mem_value as u16);
|
||||||
|
}
|
||||||
|
Register::EAX => {
|
||||||
|
assert_eq!(ax as u32, mem_value as u32);
|
||||||
|
}
|
||||||
|
Register::RAX => {
|
||||||
|
assert_eq!(ax, mem_value);
|
||||||
|
}
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (register, instruction_prefix) in test_inputs {
|
||||||
|
helper(register, instruction_prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
// movabs ds:0x1337, ax
|
||||||
|
// movabs ds:0x1337, eax
|
||||||
|
// movabs ds:0x1337, rax
|
||||||
|
fn test_mov_ax_memoff() {
|
||||||
|
let test_inputs: [(Register, &[u8]); 3] = [
|
||||||
|
(Register::AX, &[0x66, 0xa3]),
|
||||||
|
(Register::EAX, &[0xa3]),
|
||||||
|
(Register::RAX, &[0x48, 0xa3]),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Constructs the instruction with the provided inputs and emulates it.
|
||||||
|
fn helper(register: Register, instruction_prefix: &[u8]) {
|
||||||
|
let mem_addr: u64 = 0x1337;
|
||||||
|
let ax: u64 = 0x13371337deadbeef;
|
||||||
|
let ip: u64 = 0x1000;
|
||||||
|
let cpu_id = 0;
|
||||||
|
|
||||||
|
let mut instruction_bytes = Vec::new();
|
||||||
|
// instruction prefix with specified register
|
||||||
|
instruction_bytes.extend(instruction_prefix);
|
||||||
|
// 64-bit memory operand
|
||||||
|
instruction_bytes.extend([
|
||||||
|
mem_addr.to_le_bytes()[0],
|
||||||
|
mem_addr.to_le_bytes()[1],
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
let mut vmm = MockVmm::new(ip, vec![(Register::RAX, ax)], None);
|
||||||
|
assert!(vmm.emulate_first_insn(cpu_id, &instruction_bytes).is_ok());
|
||||||
|
|
||||||
|
match register {
|
||||||
|
Register::AX => {
|
||||||
|
let mut memory: [u8; 2] = [0; 2];
|
||||||
|
vmm.read_memory(mem_addr, &mut memory).unwrap();
|
||||||
|
assert_eq!(u16::from_le_bytes(memory), ax as u16);
|
||||||
|
}
|
||||||
|
Register::EAX => {
|
||||||
|
let mut memory: [u8; 4] = [0; 4];
|
||||||
|
vmm.read_memory(mem_addr, &mut memory).unwrap();
|
||||||
|
assert_eq!(u32::from_le_bytes(memory), ax as u32);
|
||||||
|
}
|
||||||
|
Register::RAX => {
|
||||||
|
let mut memory: [u8; 8] = [0; 8];
|
||||||
|
vmm.read_memory(mem_addr, &mut memory).unwrap();
|
||||||
|
assert_eq!(u64::from_le_bytes(memory), ax);
|
||||||
|
}
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (register, instruction_prefix) in test_inputs {
|
||||||
|
helper(register, instruction_prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,6 +524,13 @@ impl<'a, T: CpuStateManager> Emulator<'a, T> {
|
|||||||
(mov, Movzx_r64_rm8),
|
(mov, Movzx_r64_rm8),
|
||||||
(mov, Movzx_r32_rm16),
|
(mov, Movzx_r32_rm16),
|
||||||
(mov, Movzx_r64_rm16),
|
(mov, Movzx_r64_rm16),
|
||||||
|
// MOV MOFFS
|
||||||
|
(mov, Mov_moffs16_AX),
|
||||||
|
(mov, Mov_AX_moffs16),
|
||||||
|
(mov, Mov_moffs32_EAX),
|
||||||
|
(mov, Mov_EAX_moffs32),
|
||||||
|
(mov, Mov_moffs64_RAX),
|
||||||
|
(mov, Mov_RAX_moffs64),
|
||||||
// MOVS
|
// MOVS
|
||||||
(movs, Movsd_m32_m32),
|
(movs, Movsd_m32_m32),
|
||||||
(movs, Movsw_m16_m16),
|
(movs, Movsw_m16_m16),
|
||||||
|
@ -36,7 +36,7 @@ pub mod kvm;
|
|||||||
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
|
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
|
||||||
pub mod mshv;
|
pub mod mshv;
|
||||||
|
|
||||||
/// Hypevisor related module
|
/// Hypervisor related module
|
||||||
mod hypervisor;
|
mod hypervisor;
|
||||||
|
|
||||||
/// Vm related module
|
/// Vm related module
|
||||||
|
Loading…
Reference in New Issue
Block a user