diff --git a/hypervisor/Cargo.toml b/hypervisor/Cargo.toml index 8f1538188..aab06ec87 100644 --- a/hypervisor/Cargo.toml +++ b/hypervisor/Cargo.toml @@ -28,7 +28,7 @@ features = ["elf", "bzimage"] [dependencies.iced-x86] version = "1.9.1" default-features = false -features = ["std", "decoder", "op_code_info", "instr_info"] +features = ["std", "decoder", "op_code_info", "instr_info", "fast_fmt"] [dev-dependencies] env_logger = "0.8.2" diff --git a/hypervisor/src/arch/emulator/mod.rs b/hypervisor/src/arch/emulator/mod.rs index 3bcd81c70..fb02d222f 100644 --- a/hypervisor/src/arch/emulator/mod.rs +++ b/hypervisor/src/arch/emulator/mod.rs @@ -76,6 +76,9 @@ pub enum EmulationError { #[error("Platform emulation error: {0}")] PlatformEmulationError(PlatformError), + + #[error(transparent)] + EmulationError(#[from] anyhow::Error), } /// The PlatformEmulator trait emulates a guest platform. diff --git a/hypervisor/src/arch/x86/emulator/instructions/mod.rs b/hypervisor/src/arch/x86/emulator/instructions/mod.rs index aeb1a4574..ecdec16ea 100644 --- a/hypervisor/src/arch/x86/emulator/instructions/mod.rs +++ b/hypervisor/src/arch/x86/emulator/instructions/mod.rs @@ -114,3 +114,16 @@ macro_rules! insn_add { $insn_map.add_insn(Code::$code, Box::new($mnemonic::$code {})); }; } + +macro_rules! insn_format { + ($insn:ident) => {{ + let mut output = String::new(); + let mut formatter = FastFormatter::new(); + formatter + .options_mut() + .set_space_after_operand_separator(true); + formatter.format(&$insn, &mut output); + + output + }}; +} diff --git a/hypervisor/src/arch/x86/emulator/mod.rs b/hypervisor/src/arch/x86/emulator/mod.rs index 457c0114e..2a820ad00 100644 --- a/hypervisor/src/arch/x86/emulator/mod.rs +++ b/hypervisor/src/arch/x86/emulator/mod.rs @@ -12,6 +12,7 @@ use crate::arch::x86::regs::*; use crate::arch::x86::*; use crate::arch::x86::{Exception, SegmentRegisterOps}; use crate::x86_64::{SegmentRegister, SpecialRegisters, StandardRegisters}; +use anyhow::Context; use iced_x86::*; #[macro_use] @@ -551,7 +552,8 @@ impl<'a, T: CpuStateManager> Emulator<'a, T> { decoder.decode_out(&mut insn); if decoder.last_error() != DecoderError::None { return Err(EmulationError::InstructionFetchingError(anyhow!( - "{:#x?}", insn + "{:#x?}", + insn_format!(insn) ))); } @@ -563,9 +565,15 @@ impl<'a, T: CpuStateManager> Emulator<'a, T> { .instructions .get(&insn.code()) .ok_or_else(|| { - EmulationError::UnsupportedInstruction(anyhow!("{:?}", insn.mnemonic())) + EmulationError::UnsupportedInstruction(anyhow!( + "{:#x?} {:?} {:?}", + insn_format!(insn), + insn.mnemonic(), + insn.code() + )) })? - .emulate(&insn, &mut state, self.platform)?; + .emulate(&insn, &mut state, self.platform) + .context(anyhow!("Failed to emulate {:#x?}", insn_format!(insn)))?; last_decoded_ip = decoder.ip(); num_insn_emulated += 1;