From b8d48013c03336d605411956a6fb80140f1947f1 Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Wed, 3 Jan 2024 20:10:20 +0100 Subject: [PATCH] updated QEMU. Adapted emu.rs to fit new interface. (#1774) * updated QEMU. Adapted emu.rs to fit new interface. * format --- libafl_qemu/libafl_qemu_build/src/build.rs | 2 +- .../src/x86_64_stub_bindings.rs | 468 ++++++++++-------- libafl_qemu/src/emu.rs | 4 +- 3 files changed, 258 insertions(+), 216 deletions(-) diff --git a/libafl_qemu/libafl_qemu_build/src/build.rs b/libafl_qemu/libafl_qemu_build/src/build.rs index dd8e611b05..a852b1f84f 100644 --- a/libafl_qemu/libafl_qemu_build/src/build.rs +++ b/libafl_qemu/libafl_qemu_build/src/build.rs @@ -8,7 +8,7 @@ use which::which; const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge"; const QEMU_DIRNAME: &str = "qemu-libafl-bridge"; -const QEMU_REVISION: &str = "c92d7c2ef66811278e8d665d4aec57661c980186"; +const QEMU_REVISION: &str = "51abe6fbcc34a7a8f6a19f4dea219e6a05ccb15f"; fn build_dep_check(tools: &[&str]) { for tool in tools { diff --git a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs index bfc3f44b98..f7f904f13e 100644 --- a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs +++ b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs @@ -144,6 +144,107 @@ fn bindgen_test_layout___sigset_t() { ); } #[repr(C)] +#[derive(Copy, Clone)] +pub union __atomic_wide_counter { + pub __value64: ::std::os::raw::c_ulonglong, + pub __value32: __atomic_wide_counter__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct __atomic_wide_counter__bindgen_ty_1 { + pub __low: ::std::os::raw::c_uint, + pub __high: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout___atomic_wide_counter__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit<__atomic_wide_counter__bindgen_ty_1> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__atomic_wide_counter__bindgen_ty_1>(), + 8usize, + concat!("Size of: ", stringify!(__atomic_wide_counter__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::<__atomic_wide_counter__bindgen_ty_1>(), + 4usize, + concat!( + "Alignment of ", + stringify!(__atomic_wide_counter__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__low) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__atomic_wide_counter__bindgen_ty_1), + "::", + stringify!(__low) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__high) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__atomic_wide_counter__bindgen_ty_1), + "::", + stringify!(__high) + ) + ); +} +#[test] +fn bindgen_test_layout___atomic_wide_counter() { + const UNINIT: ::std::mem::MaybeUninit<__atomic_wide_counter> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__atomic_wide_counter>(), + 8usize, + concat!("Size of: ", stringify!(__atomic_wide_counter)) + ); + assert_eq!( + ::std::mem::align_of::<__atomic_wide_counter>(), + 8usize, + concat!("Alignment of ", stringify!(__atomic_wide_counter)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__value64) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__atomic_wide_counter), + "::", + stringify!(__value64) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__value32) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__atomic_wide_counter), + "::", + stringify!(__value32) + ) + ); +} +impl Default for __atomic_wide_counter { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for __atomic_wide_counter { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "__atomic_wide_counter {{ union }}") + } +} +#[repr(C)] #[derive(Debug, Copy, Clone)] pub struct __pthread_internal_list { pub __prev: *mut __pthread_internal_list, @@ -314,222 +415,14 @@ impl Default for __pthread_mutex_s { #[repr(C)] #[derive(Copy, Clone)] pub struct __pthread_cond_s { - pub __bindgen_anon_1: __pthread_cond_s__bindgen_ty_1, - pub __bindgen_anon_2: __pthread_cond_s__bindgen_ty_2, + pub __wseq: __atomic_wide_counter, + pub __g1_start: __atomic_wide_counter, pub __g_refs: [::std::os::raw::c_uint; 2usize], pub __g_size: [::std::os::raw::c_uint; 2usize], pub __g1_orig_size: ::std::os::raw::c_uint, pub __wrefs: ::std::os::raw::c_uint, pub __g_signals: [::std::os::raw::c_uint; 2usize], } -#[repr(C)] -#[derive(Copy, Clone)] -pub union __pthread_cond_s__bindgen_ty_1 { - pub __wseq: ::std::os::raw::c_ulonglong, - pub __wseq32: __pthread_cond_s__bindgen_ty_1__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct __pthread_cond_s__bindgen_ty_1__bindgen_ty_1 { - pub __low: ::std::os::raw::c_uint, - pub __high: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit<__pthread_cond_s__bindgen_ty_1__bindgen_ty_1> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_1__bindgen_ty_1>(), - 8usize, - concat!( - "Size of: ", - stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_1__bindgen_ty_1>(), - 4usize, - concat!( - "Alignment of ", - stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__low) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(__low) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__high) as usize - ptr as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(__high) - ) - ); -} -#[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit<__pthread_cond_s__bindgen_ty_1> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_1>(), - 8usize, - concat!("Size of: ", stringify!(__pthread_cond_s__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_1>(), - 8usize, - concat!("Alignment of ", stringify!(__pthread_cond_s__bindgen_ty_1)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__wseq) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1), - "::", - stringify!(__wseq) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__wseq32) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_1), - "::", - stringify!(__wseq32) - ) - ); -} -impl Default for __pthread_cond_s__bindgen_ty_1 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -impl ::std::fmt::Debug for __pthread_cond_s__bindgen_ty_1 { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "__pthread_cond_s__bindgen_ty_1 {{ union }}") - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union __pthread_cond_s__bindgen_ty_2 { - pub __g1_start: ::std::os::raw::c_ulonglong, - pub __g1_start32: __pthread_cond_s__bindgen_ty_2__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct __pthread_cond_s__bindgen_ty_2__bindgen_ty_1 { - pub __low: ::std::os::raw::c_uint, - pub __high: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_2__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit<__pthread_cond_s__bindgen_ty_2__bindgen_ty_1> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_2__bindgen_ty_1>(), - 8usize, - concat!( - "Size of: ", - stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_2__bindgen_ty_1>(), - 4usize, - concat!( - "Alignment of ", - stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__low) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(__low) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__high) as usize - ptr as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2__bindgen_ty_1), - "::", - stringify!(__high) - ) - ); -} -#[test] -fn bindgen_test_layout___pthread_cond_s__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit<__pthread_cond_s__bindgen_ty_2> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<__pthread_cond_s__bindgen_ty_2>(), - 8usize, - concat!("Size of: ", stringify!(__pthread_cond_s__bindgen_ty_2)) - ); - assert_eq!( - ::std::mem::align_of::<__pthread_cond_s__bindgen_ty_2>(), - 8usize, - concat!("Alignment of ", stringify!(__pthread_cond_s__bindgen_ty_2)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__g1_start) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2), - "::", - stringify!(__g1_start) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__g1_start32) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__pthread_cond_s__bindgen_ty_2), - "::", - stringify!(__g1_start32) - ) - ); -} -impl Default for __pthread_cond_s__bindgen_ty_2 { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -impl ::std::fmt::Debug for __pthread_cond_s__bindgen_ty_2 { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "__pthread_cond_s__bindgen_ty_2 {{ union }}") - } -} #[test] fn bindgen_test_layout___pthread_cond_s() { const UNINIT: ::std::mem::MaybeUninit<__pthread_cond_s> = ::std::mem::MaybeUninit::uninit(); @@ -544,6 +437,26 @@ fn bindgen_test_layout___pthread_cond_s() { 8usize, concat!("Alignment of ", stringify!(__pthread_cond_s)) ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__wseq) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__pthread_cond_s), + "::", + stringify!(__wseq) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__g1_start) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__pthread_cond_s), + "::", + stringify!(__g1_start) + ) + ); assert_eq!( unsafe { ::std::ptr::addr_of!((*ptr).__g_refs) as usize - ptr as usize }, 16usize, @@ -606,7 +519,7 @@ impl Default for __pthread_cond_s { } impl ::std::fmt::Debug for __pthread_cond_s { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write ! (f , "__pthread_cond_s {{ __bindgen_anon_1: {:?}, __bindgen_anon_2: {:?}, __g_refs: {:?}, __g_size: {:?}, __g1_orig_size: {:?}, __wrefs: {:?}, __g_signals: {:?} }}" , self . __bindgen_anon_1 , self . __bindgen_anon_2 , self . __g_refs , self . __g_size , self . __g1_orig_size , self . __wrefs , self . __g_signals) + write ! (f , "__pthread_cond_s {{ __wseq: {:?}, __g1_start: {:?}, __g_refs: {:?}, __g_size: {:?}, __g1_orig_size: {:?}, __wrefs: {:?}, __g_signals: {:?} }}" , self . __wseq , self . __g1_start , self . __g_refs , self . __g_size , self . __g1_orig_size , self . __wrefs , self . __g_signals) } } pub type pthread_t = ::std::os::raw::c_ulong; @@ -4629,6 +4542,47 @@ impl Default for CPUTLBDescFast { } } } +pub const ShutdownCause_SHUTDOWN_CAUSE_NONE: ShutdownCause = ShutdownCause(0); +pub const ShutdownCause_SHUTDOWN_CAUSE_HOST_ERROR: ShutdownCause = ShutdownCause(1); +pub const ShutdownCause_SHUTDOWN_CAUSE_HOST_QMP_QUIT: ShutdownCause = ShutdownCause(2); +pub const ShutdownCause_SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET: ShutdownCause = ShutdownCause(3); +pub const ShutdownCause_SHUTDOWN_CAUSE_HOST_SIGNAL: ShutdownCause = ShutdownCause(4); +pub const ShutdownCause_SHUTDOWN_CAUSE_HOST_UI: ShutdownCause = ShutdownCause(5); +pub const ShutdownCause_SHUTDOWN_CAUSE_GUEST_SHUTDOWN: ShutdownCause = ShutdownCause(6); +pub const ShutdownCause_SHUTDOWN_CAUSE_GUEST_RESET: ShutdownCause = ShutdownCause(7); +pub const ShutdownCause_SHUTDOWN_CAUSE_GUEST_PANIC: ShutdownCause = ShutdownCause(8); +pub const ShutdownCause_SHUTDOWN_CAUSE_SUBSYSTEM_RESET: ShutdownCause = ShutdownCause(9); +pub const ShutdownCause_SHUTDOWN_CAUSE_SNAPSHOT_LOAD: ShutdownCause = ShutdownCause(10); +pub const ShutdownCause_SHUTDOWN_CAUSE__MAX: ShutdownCause = ShutdownCause(11); +impl ::std::ops::BitOr for ShutdownCause { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + ShutdownCause(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for ShutdownCause { + #[inline] + fn bitor_assign(&mut self, rhs: ShutdownCause) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for ShutdownCause { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + ShutdownCause(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for ShutdownCause { + #[inline] + fn bitand_assign(&mut self, rhs: ShutdownCause) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ShutdownCause(pub ::std::os::raw::c_uint); #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TCGCPUOps { @@ -12038,9 +11992,13 @@ extern "C" { extern "C" { pub fn libafl_qemu_remove_breakpoint(pc: target_ulong) -> ::std::os::raw::c_int; } -pub const libafl_exit_reason_kind_BREAKPOINT: libafl_exit_reason_kind = libafl_exit_reason_kind(0); +extern "C" { + pub fn libafl_qemu_trigger_breakpoint(cpu: *mut CPUState); +} +pub const libafl_exit_reason_kind_INTERNAL: libafl_exit_reason_kind = libafl_exit_reason_kind(0); +pub const libafl_exit_reason_kind_BREAKPOINT: libafl_exit_reason_kind = libafl_exit_reason_kind(1); pub const libafl_exit_reason_kind_SYNC_BACKDOOR: libafl_exit_reason_kind = - libafl_exit_reason_kind(1); + libafl_exit_reason_kind(2); impl ::std::ops::BitOr for libafl_exit_reason_kind { type Output = Self; #[inline] @@ -12121,6 +12079,57 @@ fn bindgen_test_layout_libafl_exit_reason_sync_backdoor() { ); } #[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libafl_exit_reason_internal { + pub cause: ShutdownCause, + pub signal: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_libafl_exit_reason_internal() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(libafl_exit_reason_internal)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(libafl_exit_reason_internal)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).cause) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libafl_exit_reason_internal), + "::", + stringify!(cause) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).signal) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libafl_exit_reason_internal), + "::", + stringify!(signal) + ) + ); +} +impl Default for libafl_exit_reason_internal { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] #[derive(Copy, Clone)] pub struct libafl_exit_reason { pub kind: libafl_exit_reason_kind, @@ -12131,6 +12140,7 @@ pub struct libafl_exit_reason { #[repr(C)] #[derive(Copy, Clone)] pub union libafl_exit_reason__bindgen_ty_1 { + pub internal: libafl_exit_reason_internal, pub breakpoint: libafl_exit_reason_breakpoint, pub backdoor: libafl_exit_reason_sync_backdoor, } @@ -12152,6 +12162,16 @@ fn bindgen_test_layout_libafl_exit_reason__bindgen_ty_1() { stringify!(libafl_exit_reason__bindgen_ty_1) ) ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).internal) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libafl_exit_reason__bindgen_ty_1), + "::", + stringify!(internal) + ) + ); assert_eq!( unsafe { ::std::ptr::addr_of!((*ptr).breakpoint) as usize - ptr as usize }, 0usize, @@ -12272,6 +12292,14 @@ extern "C" { extern "C" { pub fn libafl_sync_exit_cpu(); } +extern "C" { + pub fn libafl_exit_request_internal( + cpu: *mut CPUState, + pc: u64, + cause: ShutdownCause, + signal: ::std::os::raw::c_int, + ); +} extern "C" { pub fn libafl_exit_request_sync_backdoor(cpu: *mut CPUState, pc: target_ulong); } @@ -13446,7 +13474,7 @@ extern "C" { pub fn libafl_qemu_edge_hook_set_jit( num: usize, jit: ::std::option::Option usize>, - ); + ) -> bool; } extern "C" { pub fn libafl_add_block_hook( @@ -13464,6 +13492,12 @@ extern "C" { invalidate: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } +extern "C" { + pub fn libafl_qemu_block_hook_set_jit( + num: usize, + jit: ::std::option::Option usize>, + ) -> bool; +} extern "C" { pub fn libafl_add_read_hook( gen: ::std::option::Option u64>, @@ -13625,6 +13659,12 @@ extern "C" { extern "C" { pub fn libafl_jit_trace_edge_single(data: u64, id: u64) -> usize; } +extern "C" { + pub fn libafl_jit_trace_block_hitcount(data: u64, id: u64) -> usize; +} +extern "C" { + pub fn libafl_jit_trace_block_single(data: u64, id: u64) -> usize; +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct kvm_dirty_gfn { diff --git a/libafl_qemu/src/emu.rs b/libafl_qemu/src/emu.rs index 439a2b42ce..002563ac37 100644 --- a/libafl_qemu/src/emu.rs +++ b/libafl_qemu/src/emu.rs @@ -980,7 +980,7 @@ impl Emulator { envp.as_ptr() as *const *const u8, ); libc::atexit(qemu_cleanup_atexit); - libafl_qemu_sys::syx_snapshot_init(); + libafl_qemu_sys::syx_snapshot_init(true); } } Ok(Emulator { _private: () }) @@ -1544,6 +1544,7 @@ impl Emulator { unsafe { libafl_qemu_sys::syx_snapshot_new( track, + true, libafl_qemu_sys::DeviceSnapshotKind_DEVICE_SNAPSHOT_ALL, null_mut(), ) @@ -1561,6 +1562,7 @@ impl Emulator { unsafe { libafl_qemu_sys::syx_snapshot_new( track, + true, device_filter.enum_id(), device_filter.devices(&mut v), )