diff --git a/fuzzers/binary_only/intel_pt_baby_fuzzer/src/main.rs b/fuzzers/binary_only/intel_pt_baby_fuzzer/src/main.rs index 0614a5e9bd..f0fdaed0af 100644 --- a/fuzzers/binary_only/intel_pt_baby_fuzzer/src/main.rs +++ b/fuzzers/binary_only/intel_pt_baby_fuzzer/src/main.rs @@ -122,8 +122,8 @@ pub fn main() { } .build(); - type PTInProcessExecutor<'a, H, I, OT, S, T> = - GenericInProcessExecutor, ()), I, OT, S>; + type PTInProcessExecutor<'a, EM, H, I, OT, S, T, Z> = + GenericInProcessExecutor, ()), I, OT, S, Z>; // Create the executor for an in-process function with just one observer let mut executor = PTInProcessExecutor::with_timeout_generic( tuple_list!(pt_hook), diff --git a/libafl/src/executors/inprocess/inner.rs b/libafl/src/executors/inprocess/inner.rs index f94317e0cd..92e23b750d 100644 --- a/libafl/src/executors/inprocess/inner.rs +++ b/libafl/src/executors/inprocess/inner.rs @@ -1,6 +1,7 @@ use core::{ ffi::c_void, fmt::{self, Debug, Formatter}, + marker::PhantomData, ptr::{self, null, write_volatile}, sync::atomic::{compiler_fence, Ordering}, time::Duration, @@ -33,14 +34,17 @@ use crate::{ }; /// The internal state of `GenericInProcessExecutor`. -pub struct GenericInProcessExecutorInner { +pub struct GenericInProcessExecutorInner { /// The observers, observing each run pub(super) observers: OT, - // Crash and timeout hah + /// Crash and timeout hooks pub(super) hooks: (InProcessHooks, HT), + /// `EM` and `Z` need to be tracked here to remain stable, + /// else we can run into type confusions between [`Self::enter_target`] and [`Self::leave_target`]. + phantom: PhantomData<(EM, Z)>, } -impl Debug for GenericInProcessExecutorInner +impl Debug for GenericInProcessExecutorInner where OT: Debug, { @@ -51,7 +55,7 @@ where } } -impl HasObservers for GenericInProcessExecutorInner { +impl HasObservers for GenericInProcessExecutorInner { type Observers = OT; #[inline] @@ -65,7 +69,7 @@ impl HasObservers for GenericInProcessExecutorInner } } -impl GenericInProcessExecutorInner +impl GenericInProcessExecutorInner where OT: ObserversTuple, { @@ -76,7 +80,7 @@ where /// the code. // TODO: Remove EM and Z from function bound and add it to struct instead to avoid possible type confusion #[inline] - pub unsafe fn enter_target( + pub unsafe fn enter_target( &mut self, fuzzer: &mut Z, state: &mut S, @@ -111,13 +115,7 @@ where /// This function marks the boundary between the fuzzer and the target #[inline] - pub fn leave_target( - &mut self, - _fuzzer: &mut Z, - _state: &mut S, - _mgr: &mut EM, - _input: &I, - ) { + pub fn leave_target(&mut self, _fuzzer: &mut Z, _state: &mut S, _mgr: &mut EM, _input: &I) { unsafe { let data = &raw mut GLOBAL_STATE; @@ -127,14 +125,14 @@ where } } -impl GenericInProcessExecutorInner +impl GenericInProcessExecutorInner where HT: ExecutorHooksTuple, OT: ObserversTuple, S: HasExecutions + HasSolutions, { /// Create a new in mem executor with the default timeout (5 sec) - pub fn generic( + pub fn generic( user_hooks: HT, observers: OT, fuzzer: &mut Z, @@ -150,7 +148,7 @@ where S: HasCurrentTestcase + HasSolutions, Z: HasObjective, { - Self::with_timeout_generic::( + Self::with_timeout_generic::( user_hooks, observers, fuzzer, @@ -162,7 +160,7 @@ where /// Create a new in mem executor with the default timeout and use batch mode(5 sec) #[cfg(all(feature = "std", target_os = "linux"))] - pub fn batched_timeout_generic( + pub fn batched_timeout_generic( user_hooks: HT, observers: OT, fuzzer: &mut Z, @@ -179,7 +177,7 @@ where S: HasCurrentTestcase + HasSolutions, Z: HasObjective, { - let mut me = Self::with_timeout_generic::( + let mut me = Self::with_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, )?; me.hooks_mut().0.timer_mut().batch_mode = true; @@ -194,7 +192,7 @@ where /// * `observers` - the observers observing the target during execution /// /// This may return an error on unix, if signal handler setup fails - pub fn with_timeout_generic( + pub fn with_timeout_generic( user_hooks: HT, observers: OT, _fuzzer: &mut Z, @@ -238,7 +236,11 @@ where *hooks.0.millis_sec_mut() = timeout.as_millis() as i64; } - Ok(Self { observers, hooks }) + Ok(Self { + observers, + hooks, + phantom: PhantomData, + }) } /// The inprocess handlers @@ -254,7 +256,9 @@ where } } -impl HasInProcessHooks for GenericInProcessExecutorInner { +impl HasInProcessHooks + for GenericInProcessExecutorInner +{ /// the timeout handler #[inline] fn inprocess_hooks(&self) -> &InProcessHooks { diff --git a/libafl/src/executors/inprocess/mod.rs b/libafl/src/executors/inprocess/mod.rs index 07e3fa1233..3b77ef59cc 100644 --- a/libafl/src/executors/inprocess/mod.rs +++ b/libafl/src/executors/inprocess/mod.rs @@ -40,29 +40,32 @@ pub mod inner; pub mod stateful; /// The process executor simply calls a target function, as mutable reference to a closure. -pub type InProcessExecutor<'a, H, I, OT, S> = GenericInProcessExecutor; +pub type InProcessExecutor<'a, EM, H, I, OT, S, Z> = + GenericInProcessExecutor; /// The inprocess executor that allows hooks -pub type HookableInProcessExecutor<'a, H, HT, I, OT, S> = - GenericInProcessExecutor; +pub type HookableInProcessExecutor<'a, EM, H, HT, I, OT, S, Z> = + GenericInProcessExecutor; /// The process executor simply calls a target function, as boxed `FnMut` trait object -pub type OwnedInProcessExecutor = GenericInProcessExecutor< +pub type OwnedInProcessExecutor = GenericInProcessExecutor< + EM, dyn FnMut(&I) -> ExitKind, Box ExitKind>, (), I, OT, S, + Z, >; /// The inmem executor simply calls a target function, then returns afterwards. -pub struct GenericInProcessExecutor { +pub struct GenericInProcessExecutor { harness_fn: HB, - inner: GenericInProcessExecutorInner, + inner: GenericInProcessExecutorInner, phantom: PhantomData<(*const H, HB)>, } -impl Debug for GenericInProcessExecutor +impl Debug for GenericInProcessExecutor where OT: Debug, { @@ -75,7 +78,7 @@ where } impl Executor - for GenericInProcessExecutor + for GenericInProcessExecutor where S: HasExecutions, OT: ObserversTuple, @@ -106,7 +109,9 @@ where } } -impl HasObservers for GenericInProcessExecutor { +impl HasObservers + for GenericInProcessExecutor +{ type Observers = OT; #[inline] @@ -120,7 +125,7 @@ impl HasObservers for GenericInProcessExecutor InProcessExecutor<'a, H, I, OT, S> +impl<'a, EM, H, I, OT, S, Z> InProcessExecutor<'a, EM, H, I, OT, S, Z> where H: FnMut(&I) -> ExitKind + Sized, OT: ObserversTuple, @@ -128,7 +133,7 @@ where I: Input, { /// Create a new in mem executor with the default timeout (5 sec) - pub fn new( + pub fn new( harness_fn: &'a mut H, observers: OT, fuzzer: &mut Z, @@ -140,7 +145,7 @@ where OF: Feedback, Z: HasObjective, { - Self::with_timeout_generic::( + Self::with_timeout_generic::( tuple_list!(), harness_fn, observers, @@ -153,7 +158,7 @@ where /// Create a new in mem executor with the default timeout and use batch mode(5 sec) #[cfg(all(feature = "std", target_os = "linux"))] - pub fn batched_timeout( + pub fn batched_timeout( harness_fn: &'a mut H, observers: OT, fuzzer: &mut Z, @@ -166,7 +171,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::batched_timeout_generic::( + let inner = GenericInProcessExecutorInner::batched_timeout_generic::( tuple_list!(), observers, fuzzer, @@ -190,7 +195,7 @@ where /// * `observers` - the observers observing the target during execution /// /// This may return an error on unix, if signal handler setup fails - pub fn with_timeout( + pub fn with_timeout( harness_fn: &'a mut H, observers: OT, fuzzer: &mut Z, @@ -203,7 +208,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::with_timeout_generic::( + let inner = GenericInProcessExecutorInner::with_timeout_generic::( tuple_list!(), observers, fuzzer, @@ -220,7 +225,7 @@ where } } -impl GenericInProcessExecutor +impl GenericInProcessExecutor where H: FnMut(&I) -> ExitKind + Sized, HB: BorrowMut, @@ -230,7 +235,7 @@ where I: Input, { /// Create a new in mem executor with the default timeout (5 sec) - pub fn generic( + pub fn generic( user_hooks: HT, harness_fn: HB, observers: OT, @@ -243,7 +248,7 @@ where OF: Feedback, Z: HasObjective, { - Self::with_timeout_generic::( + Self::with_timeout_generic::( user_hooks, harness_fn, observers, @@ -256,7 +261,7 @@ where /// Create a new in mem executor with the default timeout and use batch mode(5 sec) #[cfg(all(feature = "std", target_os = "linux"))] - pub fn batched_timeout_generic( + pub fn batched_timeout_generic( user_hooks: HT, harness_fn: HB, observers: OT, @@ -271,7 +276,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::batched_timeout_generic::( + let inner = GenericInProcessExecutorInner::batched_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, )?; @@ -290,7 +295,7 @@ where /// * `observers` - the observers observing the target during execution /// /// This may return an error on unix, if signal handler setup fails - pub fn with_timeout_generic( + pub fn with_timeout_generic( user_hooks: HT, harness_fn: HB, observers: OT, @@ -304,7 +309,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::with_timeout_generic::( + let inner = GenericInProcessExecutorInner::with_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, timeout, )?; @@ -349,8 +354,8 @@ pub trait HasInProcessHooks { fn inprocess_hooks_mut(&mut self) -> &mut InProcessHooks; } -impl HasInProcessHooks - for GenericInProcessExecutor +impl HasInProcessHooks + for GenericInProcessExecutor { /// the timeout handler #[inline] diff --git a/libafl/src/executors/inprocess/stateful.rs b/libafl/src/executors/inprocess/stateful.rs index 943afffcae..5efa7cd94c 100644 --- a/libafl/src/executors/inprocess/stateful.rs +++ b/libafl/src/executors/inprocess/stateful.rs @@ -27,34 +27,37 @@ use crate::{ /// The process executor simply calls a target function, as mutable reference to a closure /// The internal state of the executor is made available to the harness. -pub type StatefulInProcessExecutor<'a, ES, H, I, OT, S> = - StatefulGenericInProcessExecutor; +pub type StatefulInProcessExecutor<'a, EM, ES, H, I, OT, S, Z> = + StatefulGenericInProcessExecutor; /// The process executor simply calls a target function, as boxed `FnMut` trait object /// The internal state of the executor is made available to the harness. -pub type OwnedInProcessExecutor = StatefulGenericInProcessExecutor< +pub type OwnedInProcessExecutor = StatefulGenericInProcessExecutor< + EM, + ES, dyn FnMut(&mut ES, &I) -> ExitKind, Box ExitKind>, (), I, OT, S, - ES, + Z, >; /// The inmem executor simply calls a target function, then returns afterwards. /// The harness can access the internal state of the executor. -pub struct StatefulGenericInProcessExecutor { +pub struct StatefulGenericInProcessExecutor { /// The harness function, being executed for each fuzzing loop execution harness_fn: HB, /// The state used as argument of the harness pub exposed_executor_state: ES, /// Inner state of the executor - pub inner: GenericInProcessExecutorInner, + pub inner: GenericInProcessExecutorInner, phantom: PhantomData<(ES, *const H)>, } -impl Debug for StatefulGenericInProcessExecutor +impl Debug + for StatefulGenericInProcessExecutor where OT: Debug, { @@ -67,7 +70,7 @@ where } impl Executor - for StatefulGenericInProcessExecutor + for StatefulGenericInProcessExecutor where H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, HB: BorrowMut, @@ -98,8 +101,8 @@ where } } -impl HasObservers - for StatefulGenericInProcessExecutor +impl HasObservers + for StatefulGenericInProcessExecutor where H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, HB: BorrowMut, @@ -118,7 +121,7 @@ where } } -impl<'a, H, I, OT, S, ES> StatefulInProcessExecutor<'a, ES, H, I, OT, S> +impl<'a, EM, ES, H, I, OT, S, Z> StatefulInProcessExecutor<'a, EM, ES, H, I, OT, S, Z> where H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, OT: ObserversTuple, @@ -126,7 +129,7 @@ where I: Clone + Input, { /// Create a new in mem executor with the default timeout (5 sec) - pub fn new( + pub fn new( harness_fn: &'a mut H, exposed_executor_state: ES, observers: OT, @@ -153,7 +156,7 @@ where /// Create a new in mem executor with the default timeout and use batch mode(5 sec) #[cfg(all(feature = "std", target_os = "linux"))] - pub fn batched_timeout( + pub fn batched_timeout( harness_fn: &'a mut H, exposed_executor_state: ES, observers: OT, @@ -167,7 +170,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::batched_timeout_generic::( + let inner = GenericInProcessExecutorInner::batched_timeout_generic::( tuple_list!(), observers, fuzzer, @@ -192,7 +195,7 @@ where /// * `observers` - the observers observing the target during execution /// /// This may return an error on unix, if signal handler setup fails - pub fn with_timeout( + pub fn with_timeout( harness_fn: &'a mut H, exposed_executor_state: ES, observers: OT, @@ -206,7 +209,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::with_timeout_generic::( + let inner = GenericInProcessExecutorInner::with_timeout_generic::( tuple_list!(), observers, fuzzer, @@ -224,7 +227,9 @@ where } } -impl StatefulGenericInProcessExecutor { +impl + StatefulGenericInProcessExecutor +{ /// The executor state given to the harness pub fn exposed_executor_state(&self) -> &ES { &self.exposed_executor_state @@ -236,7 +241,8 @@ impl StatefulGenericInProcessExecutor StatefulGenericInProcessExecutor +impl + StatefulGenericInProcessExecutor where H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized, HB: BorrowMut, @@ -246,7 +252,7 @@ where S: HasExecutions + HasSolutions + HasCurrentTestcase, { /// Create a new in mem executor with the default timeout (5 sec) - pub fn generic( + pub fn generic( user_hooks: HT, harness_fn: HB, exposed_executor_state: ES, @@ -275,7 +281,7 @@ where /// Create a new in mem executor with the default timeout and use batch mode(5 sec) #[cfg(all(feature = "std", target_os = "linux"))] #[expect(clippy::too_many_arguments)] - pub fn batched_timeout_generic( + pub fn batched_timeout_generic( user_hooks: HT, harness_fn: HB, exposed_executor_state: ES, @@ -290,7 +296,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::batched_timeout_generic::( + let inner = GenericInProcessExecutorInner::batched_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, exec_tmout, )?; @@ -311,7 +317,7 @@ where /// /// This may return an error on unix, if signal handler setup fails #[expect(clippy::too_many_arguments)] - pub fn with_timeout_generic( + pub fn with_timeout_generic( user_hooks: HT, harness_fn: HB, exposed_executor_state: ES, @@ -326,7 +332,7 @@ where OF: Feedback, Z: HasObjective, { - let inner = GenericInProcessExecutorInner::with_timeout_generic::( + let inner = GenericInProcessExecutorInner::with_timeout_generic::( user_hooks, observers, fuzzer, state, event_mgr, timeout, )?; @@ -363,8 +369,8 @@ where } } -impl HasInProcessHooks - for StatefulGenericInProcessExecutor +impl HasInProcessHooks + for StatefulGenericInProcessExecutor { /// the timeout handler #[inline] diff --git a/libafl/src/executors/inprocess_fork/stateful.rs b/libafl/src/executors/inprocess_fork/stateful.rs index f6a206bf20..306d0caaec 100644 --- a/libafl/src/executors/inprocess_fork/stateful.rs +++ b/libafl/src/executors/inprocess_fork/stateful.rs @@ -27,7 +27,7 @@ use crate::{ pub type StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z> = StatefulGenericInProcessForkExecutor<'a, EM, ES, H, (), I, OT, S, SP, Z>; -impl<'a, H, I, OT, S, SP, ES, EM, Z> StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z> +impl<'a, H, I, OT, S, SP, EM, ES, Z> StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z> where OT: ObserversTuple, SP: ShMemProvider, @@ -68,7 +68,7 @@ pub struct StatefulGenericInProcessForkExecutor<'a, EM, ES, H, HT, I, OT, S, SP, pub inner: GenericInProcessForkExecutorInner, } -impl Debug +impl Debug for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z> where HT: Debug, @@ -131,7 +131,7 @@ where } } -impl<'a, H, HT, I, OT, S, SP, ES, EM, Z> +impl<'a, H, HT, I, OT, S, SP, EM, ES, Z> StatefulGenericInProcessForkExecutor<'a, EM, ES, H, HT, I, OT, S, SP, Z> where HT: ExecutorHooksTuple, @@ -178,7 +178,7 @@ where } } -impl HasObservers +impl HasObservers for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z> { type Observers = OT; diff --git a/libafl_frida/src/executor.rs b/libafl_frida/src/executor.rs index bfc9b80a4b..882968b9d7 100644 --- a/libafl_frida/src/executor.rs +++ b/libafl_frida/src/executor.rs @@ -29,8 +29,8 @@ use crate::helper::{FridaInstrumentationHelper, FridaRuntimeTuple}; use crate::windows_hooks::initialize; /// The [`FridaInProcessExecutor`] is an [`Executor`] that executes the target in the same process, usinig [`frida`](https://frida.re/) for binary-only instrumentation. -pub struct FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> { - base: InProcessExecutor<'a, H, I, OT, S>, +pub struct FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> { + base: InProcessExecutor<'a, EM, H, I, OT, S, Z>, /// `thread_id` for the Stalker thread_id: Option, /// Frida's dynamic rewriting engine @@ -42,7 +42,8 @@ pub struct FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> { _phantom: PhantomData<&'b u8>, } -impl Debug for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC> +impl Debug + for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z> where OT: Debug, { @@ -56,7 +57,7 @@ where } impl Executor - for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC> + for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z> where H: FnMut(&I) -> ExitKind, S: HasExecutions, @@ -111,7 +112,9 @@ where } } -impl HasObservers for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC> { +impl HasObservers + for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z> +{ type Observers = OT; #[inline] fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> { @@ -124,15 +127,15 @@ impl HasObservers for FridaInProcessExecutor<'_, '_, '_, H, } } -impl<'a, 'b, 'c, H, I, OT, RT, S> - FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, NopTargetBytesConverter> +impl<'a, 'b, 'c, EM, H, I, OT, RT, S, Z> + FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, NopTargetBytesConverter, Z> where RT: FridaRuntimeTuple, { /// Creates a new [`FridaInProcessExecutor`]. pub fn new( gum: &'a Gum, - base: InProcessExecutor<'a, H, I, OT, S>, + base: InProcessExecutor<'a, EM, H, I, OT, S, Z>, helper: &'c mut FridaInstrumentationHelper<'b, RT>, ) -> Self { FridaInProcessExecutor::with_target_bytes_converter( @@ -147,7 +150,7 @@ where /// Creates a new [`FridaInProcessExecutor`] tracking the given `thread_id`. pub fn on_thread( gum: &'a Gum, - base: InProcessExecutor<'a, H, I, OT, S>, + base: InProcessExecutor<'a, EM, H, I, OT, S, Z>, helper: &'c mut FridaInstrumentationHelper<'b, RT>, thread_id: u32, ) -> Self { @@ -161,14 +164,15 @@ where } } -impl<'a, 'b, 'c, H, I, OT, RT, S, TC> FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> +impl<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> + FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> where RT: FridaRuntimeTuple, { /// Creates a new [`FridaInProcessExecutor`]. pub fn with_target_bytes_converter( gum: &'a Gum, - base: InProcessExecutor<'a, H, I, OT, S>, + base: InProcessExecutor<'a, EM, H, I, OT, S, Z>, helper: &'c mut FridaInstrumentationHelper<'b, RT>, thread_id: Option, target_bytes_converter: TC, @@ -221,8 +225,8 @@ where } #[cfg(windows)] -impl<'a, 'b, 'c, H, I, OT, RT, S, TC> HasInProcessHooks - for FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> +impl<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> HasInProcessHooks + for FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> where H: FnMut(&I) -> ExitKind, S: HasSolutions + HasCurrentTestcase + HasExecutions, diff --git a/libafl_qemu/src/executor.rs b/libafl_qemu/src/executor.rs index 8cc884ec12..3abc2f6e8e 100644 --- a/libafl_qemu/src/executor.rs +++ b/libafl_qemu/src/executor.rs @@ -42,11 +42,11 @@ use crate::EmulatorModules; use crate::Qemu; use crate::{command::CommandManager, modules::EmulatorModuleTuple, Emulator, EmulatorDriver}; -type EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> = - StatefulInProcessExecutor<'a, Emulator, H, I, OT, S>; +type EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> = + StatefulInProcessExecutor<'a, EM, Emulator, H, I, OT, S, Z>; -pub struct QemuExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> { - inner: EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM>, +pub struct QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> { + inner: EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>, first_exec: bool, } @@ -133,7 +133,8 @@ pub unsafe fn inproc_qemu_timeout_handler( } } -impl Debug for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM> +impl Debug + for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> where OT: Debug, { @@ -144,7 +145,8 @@ where } } -impl<'a, C, CM, ED, ET, H, I, OT, S, SM> QemuExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> +impl<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> + QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> where ET: EmulatorModuleTuple, H: FnMut(&mut Emulator, &mut S, &I) -> ExitKind, @@ -152,7 +154,7 @@ where OT: ObserversTuple, S: Unpin + HasExecutions + HasSolutions + HasCurrentTestcase, { - pub fn new( + pub fn new( emulator: Emulator, harness_fn: &'a mut H, observers: OT, @@ -207,7 +209,7 @@ where } inner.inprocess_hooks_mut().timeout_handler = inproc_qemu_timeout_handler::< - StatefulInProcessExecutor<'a, Emulator, H, I, OT, S>, + StatefulInProcessExecutor<'a, EM, Emulator, H, I, OT, S, Z>, EM, ET, I, @@ -222,7 +224,7 @@ where }) } - pub fn inner(&self) -> &EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> { + pub fn inner(&self) -> &EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> { &self.inner } @@ -233,13 +235,13 @@ where pub fn inner_mut( &mut self, - ) -> &mut EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> { + ) -> &mut EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> { &mut self.inner } } impl Executor - for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM> + for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> where C: Clone, CM: CommandManager, @@ -279,8 +281,8 @@ where } } -impl HasObservers - for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM> +impl HasObservers + for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> where ET: EmulatorModuleTuple, H: FnMut(&mut Emulator, &mut S, &I) -> ExitKind,