No Uses* for Observers (#2568)

* first

* Round 2

* Round 3

* Round 4

* Round 5

* Round 6

* Round 7

* Round 8

* clp

* from windows

* roll back

* baby building

* doc

* no deref

* frida

* api

* a

* impl HasLen

* libafl-fuzz and fmt

* asan error

* Cargo toml

* who cares abotu freebsd seriously?????

* aaaa

* qemu stuf

* fixing what i can fix

* nyx

* more for qemu stuf

* fixup libfuzzer

* fix baby swap

* AsIterMut

* UsesObservers eliminated

---------

Co-authored-by: Your Name <you@example.com>
Co-authored-by: Addison Crump <addison.crump@cispa.de>
This commit is contained in:
Dongjia "toka" Zhang 2024-10-01 17:51:09 +02:00 committed by GitHub
parent 173aeddbcc
commit a212d66afe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
90 changed files with 972 additions and 2093 deletions

View File

@ -544,36 +544,3 @@ jobs:
# run: clang -v
#- name: Windows Test
# run: C:\Rust\.cargo\bin\cargo.exe test --verbose
freebsd:
runs-on: ubuntu-22.04
name: Simple build in FreeBSD
steps:
- uses: actions/checkout@v4
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v1
with:
usesh: true
sync: rsync
copyback: false
mem: 2048
release: 13.2
prepare: |
pkg install -y curl bash sudo llvm16
curl https://sh.rustup.rs -sSf | sh -s -- -y
run: |
freebsd-version
. "$HOME/.cargo/env"
rustup toolchain install nightly
export LLVM_CONFIG=/usr/local/bin/llvm-config16
pwd
ls -lah
echo "local/bin"
ls -lah /usr/local/bin/
which llvm-config
chmod +x ./scripts/clippy.sh
bash ./scripts/shmem_limits_fbsd.sh
bash ./scripts/clippy.sh
cargo test

View File

@ -60,7 +60,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<PacketData, S>,
{
self.len = input.length;
Ok(false)

View File

@ -21,9 +21,7 @@ use libafl::{
havoc_mutations, token_mutations::I2SRandReplace, tokens_mutations, StdMOptMutator,
StdScheduledMutator, Tokens,
},
observers::{
CanTrack, HitcountsMapObserver, StdCmpValuesObserver, StdMapObserver, TimeObserver,
},
observers::{CanTrack, HitcountsMapObserver, StdCmpObserver, StdMapObserver, TimeObserver},
schedulers::{
powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler,
},
@ -353,7 +351,7 @@ fn fuzz(
cmplog_shmem.write_to_env("__AFL_CMPLOG_SHM_ID").unwrap();
let cmpmap = unsafe { OwnedRefMut::<AFLppCmpLogMap>::from_shmem(&mut cmplog_shmem) };
let cmplog_observer = StdCmpValuesObserver::new("cmplog", cmpmap, true);
let cmplog_observer = StdCmpObserver::new("cmplog", cmpmap, true);
let cmplog_executor = ForkserverExecutor::builder()
.program(exec)

View File

@ -237,6 +237,7 @@ where
+ HasExecutions
+ HasNamedMetadata
+ Stoppable,
E::Observers: MatchNameRef,
O: MapObserver,
C: AsRef<O> + Named,
<Z as HasScheduler>::Scheduler: HasQueueCycles,

View File

@ -118,10 +118,10 @@ where
state: &mut S,
_manager: &mut EM,
_observers: &OT,
testcase: &mut Testcase<<S>::Input>,
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
(self.func)(state, testcase, &self.out_dir)?;

View File

@ -113,10 +113,10 @@ where
state: &mut S,
_manager: &mut EM,
_observers: &OT,
testcase: &mut Testcase<<S>::Input>,
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
if self.should_run() {

View File

@ -62,7 +62,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
if !self.done_loading_seeds {
match exit_kind {
@ -101,7 +101,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
self.inner

View File

@ -74,6 +74,7 @@ where
) -> Result<(), Error>
where
E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<E::Input, E::State>,
CS: Scheduler<E::Input, E::State> + RemovableScheduler<E::Input, E::State>,
EM: EventFirer<State = E::State>,
Z: HasScheduler<Scheduler = CS, State = E::State>,

View File

@ -38,7 +38,7 @@ use crate::{
executors::{Executor, HasObservers},
fuzzer::{EvaluatorObservers, ExecutionProcessor},
inputs::{Input, NopInput, UsesInput},
observers::{ObserversTuple, TimeObserver, UsesObservers},
observers::{ObserversTuple, TimeObserver},
state::{HasExecutions, HasLastReportTime, NopState, State, Stoppable, UsesState},
Error, HasMetadata,
};
@ -324,7 +324,7 @@ where
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
where
OT: ObserversTuple<Self::State> + Serialize,
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
{
const SERIALIZE_TIME_FACTOR: u32 = 4; // twice as much as the normal llmp em's value cuz it does this job twice.
const SERIALIZE_PERCENTAGE_THRESHOLD: usize = 80;
@ -370,8 +370,9 @@ impl<E, EM, EMH, S, SP, Z> EventProcessor<E, Z> for CentralizedEventManager<EM,
where
EM: AdaptiveSerializer + EventProcessor<E, Z> + EventFirer + HasEventManagerId,
EMH: EventManagerHooksTuple<EM::State>,
E: HasObservers<State = Self::State> + Executor<Self, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<Self, Z, State = Self::State>,
E::Observers:
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
S: State,
Self::State: HasExecutions + HasMetadata,
@ -403,8 +404,9 @@ where
impl<E, EM, EMH, S, SP, Z> EventManager<E, Z> for CentralizedEventManager<EM, EMH, S, SP>
where
E: HasObservers<State = Self::State> + Executor<Self, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<Self, Z, State = Self::State>,
E::Observers:
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
EM: AdaptiveSerializer + EventManager<E, Z>,
EM::State: HasExecutions + HasMetadata + HasLastReportTime,
@ -528,8 +530,9 @@ where
executor: &mut E,
) -> Result<usize, Error>
where
E: Executor<Self, Z> + HasObservers<State = <Self as UsesState>::State>,
<E as UsesObservers>::Observers: Serialize,
E: Executor<Self, Z, State = <Self as UsesState>::State> + HasObservers,
E::Observers:
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
<Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata,
for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = <Self as UsesState>::State>
@ -577,7 +580,9 @@ where
event: Event<<<Self as UsesState>::State as UsesInput>::Input>,
) -> Result<(), Error>
where
E: Executor<Self, Z> + HasObservers<State = <Self as UsesState>::State>,
E: Executor<Self, Z, State = <Self as UsesState>::State> + HasObservers,
E::Observers:
ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State> + Serialize,
<Self as UsesState>::State: UsesInput + HasExecutions + HasMetadata,
for<'a> E::Observers: Deserialize<'a> + Serialize,
Z: ExecutionProcessor<State = <Self as UsesState>::State>

View File

@ -39,7 +39,7 @@ use crate::{
executors::{Executor, HasObservers},
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
inputs::{NopInput, UsesInput},
observers::{ObserversTuple, TimeObserver, UsesObservers},
observers::{ObserversTuple, TimeObserver},
state::{HasExecutions, HasImported, HasLastReportTime, NopState, State, UsesState},
Error, HasMetadata,
};
@ -403,8 +403,8 @@ where
event: Event<S::Input>,
) -> Result<(), Error>
where
E: Executor<Self, Z> + HasObservers<State = S>,
<E as UsesObservers>::Observers: Serialize,
E: Executor<Self, Z, State = S> + HasObservers,
E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers> + Evaluator<E, Self>,
{
@ -553,7 +553,7 @@ where
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
where
OT: ObserversTuple<Self::State> + Serialize,
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
{
const SERIALIZE_TIME_FACTOR: u32 = 2;
const SERIALIZE_PERCENTAGE_THRESHOLD: usize = 80;
@ -585,10 +585,10 @@ where
impl<E, EMH, S, SP, Z> EventProcessor<E, Z> for LlmpEventManager<EMH, S, SP>
where
EMH: EventManagerHooksTuple<S>,
<E as UsesObservers>::Observers: Serialize,
S: State + HasExecutions + HasMetadata + HasImported,
SP: ShMemProvider,
E: HasObservers<State = S> + Executor<Self, Z>,
E: HasObservers + Executor<Self, Z, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers> + Evaluator<E, Self>,
{
@ -636,8 +636,8 @@ where
impl<E, EMH, S, SP, Z> EventManager<E, Z> for LlmpEventManager<EMH, S, SP>
where
E: HasObservers<State = S> + Executor<Self, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<Self, Z, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,

View File

@ -293,7 +293,7 @@ where
event: Event<DI>,
) -> Result<(), Error>
where
E: Executor<EM, Z> + HasObservers<State = S>,
E: Executor<EM, Z, State = S> + HasObservers,
EM: UsesState<State = S> + EventFirer,
for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers>,
@ -347,7 +347,7 @@ where
manager: &mut EM,
) -> Result<usize, Error>
where
E: Executor<EM, Z> + HasObservers<State = S>,
E: Executor<EM, Z, State = S> + HasObservers,
EM: UsesState<State = S> + EventFirer,
for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers>,

View File

@ -49,7 +49,7 @@ use crate::{
fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor},
inputs::UsesInput,
monitors::Monitor,
observers::{ObserversTuple, TimeObserver, UsesObservers},
observers::{ObserversTuple, TimeObserver},
state::{HasExecutions, HasImported, HasLastReportTime, State, UsesState},
Error, HasMetadata,
};
@ -149,7 +149,7 @@ where
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
where
OT: ObserversTuple<Self::State> + Serialize,
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
{
self.llmp_mgr.serialize_observers(observers)
}
@ -204,8 +204,8 @@ where
#[cfg(feature = "std")]
impl<E, EMH, S, SP, Z> EventProcessor<E, Z> for LlmpRestartingEventManager<EMH, S, SP>
where
E: HasObservers<State = S> + Executor<LlmpEventManager<EMH, S, SP>, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<LlmpEventManager<EMH, S, SP>, Z, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasImported,
@ -228,8 +228,8 @@ where
#[cfg(feature = "std")]
impl<E, EMH, S, SP, Z> EventManager<E, Z> for LlmpRestartingEventManager<EMH, S, SP>
where
E: HasObservers<State = S> + Executor<LlmpEventManager<EMH, S, SP>, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<LlmpEventManager<EMH, S, SP>, Z, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,

View File

@ -437,7 +437,7 @@ pub trait EventFirer: UsesState {
/// Serialize all observers for this type and manager
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
where
OT: ObserversTuple<Self::State> + Serialize,
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize,
{
Ok(Some(postcard::to_allocvec(observers)?))
}
@ -757,7 +757,7 @@ where
#[inline]
fn serialize_observers<OT>(&mut self, observers: &OT) -> Result<Option<Vec<u8>>, Error>
where
OT: ObserversTuple<Self::State> + Serialize,
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize,
{
self.inner.serialize_observers(observers)
}
@ -893,7 +893,7 @@ pub trait AdaptiveSerializer {
percentage_threshold: usize,
) -> Result<Option<Vec<u8>>, Error>
where
OT: ObserversTuple<S> + Serialize,
OT: ObserversTuple<S::Input, S> + Serialize,
S: UsesInput,
{
match self.time_ref() {

View File

@ -53,7 +53,7 @@ use crate::{
fuzzer::{EvaluatorObservers, ExecutionProcessor},
inputs::{Input, UsesInput},
monitors::Monitor,
observers::UsesObservers,
observers::ObserversTuple,
state::{HasExecutions, HasImported, HasLastReportTime, State, UsesState},
Error, HasMetadata,
};
@ -611,8 +611,8 @@ where
event: Event<S::Input>,
) -> Result<(), Error>
where
E: Executor<Self, Z> + HasObservers<State = S>,
<E as UsesObservers>::Observers: Serialize,
E: Executor<Self, Z, State = S> + HasObservers,
E::Observers: Serialize + ObserversTuple<S::Input, S>,
for<'a> E::Observers: Deserialize<'a>,
Z: ExecutionProcessor<State = S> + EvaluatorObservers<E::Observers>,
{
@ -751,8 +751,8 @@ where
impl<E, EMH, S, Z> EventProcessor<E, Z> for TcpEventManager<EMH, S>
where
E: HasObservers<State = S> + Executor<Self, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<Self, Z, State = S>,
E::Observers: Serialize + ObserversTuple<S::Input, S>,
for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasImported,
@ -825,8 +825,8 @@ where
impl<E, EMH, S, Z> EventManager<E, Z> for TcpEventManager<EMH, S>
where
E: HasObservers<State = S> + Executor<Self, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<Self, Z, State = S>,
E::Observers: Serialize + ObserversTuple<S::Input, S>,
for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,
@ -970,9 +970,9 @@ where
#[cfg(feature = "std")]
impl<E, EMH, S, SP, Z> EventProcessor<E, Z> for TcpRestartingEventManager<EMH, S, SP>
where
E: HasObservers<State = S> + Executor<TcpEventManager<EMH, S>, Z>,
E: HasObservers + Executor<TcpEventManager<EMH, S>, Z, State = S>,
for<'a> E::Observers: Deserialize<'a>,
<E as UsesObservers>::Observers: Serialize,
E::Observers: ObserversTuple<S::Input, S> + Serialize,
EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasImported,
SP: ShMemProvider + 'static,
@ -990,8 +990,8 @@ where
#[cfg(feature = "std")]
impl<E, EMH, S, SP, Z> EventManager<E, Z> for TcpRestartingEventManager<EMH, S, SP>
where
E: HasObservers<State = S> + Executor<TcpEventManager<EMH, S>, Z>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + Executor<TcpEventManager<EMH, S>, Z, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize,
for<'a> E::Observers: Deserialize<'a>,
EMH: EventManagerHooksTuple<S>,
S: State + HasExecutions + HasMetadata + HasLastReportTime + HasImported,

View File

@ -7,7 +7,6 @@ use libafl_bolts::tuples::RefIndexable;
use crate::{
executors::{Executor, ExitKind, HasObservers},
observers::UsesObservers,
state::{HasExecutions, UsesState},
Error,
};
@ -68,17 +67,12 @@ where
type State = A::State;
}
impl<A, B> UsesObservers for CombinedExecutor<A, B>
where
A: UsesObservers,
{
type Observers = A::Observers;
}
impl<A, B> HasObservers for CombinedExecutor<A, B>
where
A: HasObservers,
{
type Observers = A::Observers;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.primary.observers()

View File

@ -28,7 +28,7 @@ use crate::executors::{Executor, ExitKind};
use crate::{
executors::HasObservers,
inputs::{HasTargetBytes, UsesInput},
observers::{ObserversTuple, StdErrObserver, StdOutObserver, UsesObservers},
observers::{ObserversTuple, StdErrObserver, StdOutObserver},
state::{HasExecutions, State, UsesState},
std::borrow::ToOwned,
};
@ -214,7 +214,7 @@ where
EM: UsesState<State = S>,
S: State + HasExecutions,
T: CommandConfigurator<S::Input> + Debug,
OT: Debug + MatchName + ObserversTuple<S>,
OT: Debug + MatchName + ObserversTuple<S::Input, S>,
Z: UsesState<State = S>,
{
fn run_target(
@ -290,20 +290,14 @@ where
type State = S;
}
impl<OT, S, T> UsesObservers for CommandExecutor<OT, S, T>
where
OT: ObserversTuple<S>,
S: State,
{
type Observers = OT;
}
impl<OT, S, T> HasObservers for CommandExecutor<OT, S, T>
where
S: State,
T: Debug,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
type Observers = OT;
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
RefIndexable::from(&self.observers)
}
@ -483,7 +477,7 @@ impl CommandExecutorBuilder {
observers: OT,
) -> Result<CommandExecutor<OT, S, StdCommandConfigurator>, Error>
where
OT: MatchName + ObserversTuple<S>,
OT: MatchName + ObserversTuple<S::Input, S>,
S: UsesInput,
S::Input: Input + HasTargetBytes,
{

View File

@ -3,7 +3,12 @@
//! It wraps two executors that will be run after each other with the same input.
//! In comparison to the [`crate::executors::CombinedExecutor`] it also runs the secondary executor in `run_target`.
//!
use core::{cell::UnsafeCell, fmt::Debug, ptr};
use core::{
cell::UnsafeCell,
fmt::Debug,
ops::{Deref, DerefMut},
ptr,
};
use libafl_bolts::{
ownedref::OwnedMutPtr,
@ -12,10 +17,11 @@ use libafl_bolts::{
use serde::{Deserialize, Serialize};
use crate::{
corpus::Corpus,
executors::{Executor, ExitKind, HasObservers},
inputs::UsesInput,
observers::{DifferentialObserversTuple, ObserversTuple, UsesObservers},
state::UsesState,
observers::{DifferentialObserversTuple, ObserversTuple},
state::{HasCorpus, UsesState},
Error,
};
@ -33,9 +39,7 @@ impl<A, B, DOT, OTA, OTB> DiffExecutor<A, B, DOT, OTA, OTB> {
where
A: UsesState + HasObservers<Observers = OTA>,
B: UsesState<State = <Self as UsesState>::State> + HasObservers<Observers = OTB>,
DOT: DifferentialObserversTuple<OTA, OTB, <Self as UsesState>::State>,
OTA: ObserversTuple<<Self as UsesState>::State>,
OTB: ObserversTuple<<Self as UsesState>::State>,
DOT: DifferentialObserversTuple<OTA, OTB, A::Input, A::State>,
{
Self {
primary,
@ -64,7 +68,11 @@ where
A: Executor<EM, Z> + HasObservers,
B: Executor<EM, Z, State = <Self as UsesState>::State> + HasObservers,
EM: UsesState<State = <Self as UsesState>::State>,
DOT: DifferentialObserversTuple<A::Observers, B::Observers, <Self as UsesState>::State>,
<A as HasObservers>::Observers:
ObserversTuple<<<A as UsesState>::State as UsesInput>::Input, <A as UsesState>::State>,
<B as HasObservers>::Observers:
ObserversTuple<<<A as UsesState>::State as UsesInput>::Input, <A as UsesState>::State>,
DOT: DifferentialObserversTuple<A::Observers, B::Observers, A::Input, A::State> + MatchName,
Z: UsesState<State = <Self as UsesState>::State>,
{
fn run_target(
@ -123,34 +131,35 @@ pub struct ProxyObserversTuple<A, B, DOT> {
differential: DOT,
}
impl<A, B, DOT, S> ObserversTuple<S> for ProxyObserversTuple<A, B, DOT>
impl<A, B, DOT, I, S> ObserversTuple<I, S> for ProxyObserversTuple<A, B, DOT>
where
A: ObserversTuple<S>,
B: ObserversTuple<S>,
DOT: DifferentialObserversTuple<A, B, S>,
S: UsesInput,
A: ObserversTuple<I, S>,
B: ObserversTuple<I, S>,
DOT: DifferentialObserversTuple<A, B, I, S> + MatchName,
S: HasCorpus,
S::Corpus: Corpus<Input = I>,
{
fn pre_exec_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec_all(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.differential.pre_exec_all(state, input)
}
fn post_exec_all(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error> {
self.differential.post_exec_all(state, input, exit_kind)
}
fn pre_exec_child_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec_child_all(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.differential.pre_exec_child_all(state, input)
}
fn post_exec_child_all(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error> {
self.differential
@ -158,6 +167,20 @@ where
}
}
impl<A, B, DOT> Deref for ProxyObserversTuple<A, B, DOT> {
type Target = DOT;
fn deref(&self) -> &Self::Target {
&self.differential
}
}
impl<A, B, DOT> DerefMut for ProxyObserversTuple<A, B, DOT> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.differential
}
}
impl<A, B, DOT> MatchName for ProxyObserversTuple<A, B, DOT>
where
A: MatchName,
@ -194,17 +217,6 @@ impl<A, B, DOT> ProxyObserversTuple<A, B, DOT> {
}
}
impl<A, B, DOT, OTA, OTB> UsesObservers for DiffExecutor<A, B, DOT, OTA, OTB>
where
A: HasObservers<Observers = OTA>,
B: HasObservers<Observers = OTB, State = <Self as UsesState>::State>,
OTA: ObserversTuple<<Self as UsesState>::State>,
OTB: ObserversTuple<<Self as UsesState>::State>,
DOT: DifferentialObserversTuple<OTA, OTB, <Self as UsesState>::State>,
{
type Observers = ProxyObserversTuple<OTA, OTB, DOT>;
}
impl<A, B, DOT, OTA, OTB> UsesState for DiffExecutor<A, B, DOT, OTA, OTB>
where
A: UsesState,
@ -214,12 +226,14 @@ where
impl<A, B, DOT, OTA, OTB> HasObservers for DiffExecutor<A, B, DOT, OTA, OTB>
where
A: HasObservers<Observers = OTA>,
B: HasObservers<Observers = OTB, State = <Self as UsesState>::State>,
OTA: ObserversTuple<<Self as UsesState>::State>,
OTB: ObserversTuple<<Self as UsesState>::State>,
DOT: DifferentialObserversTuple<OTA, OTB, <Self as UsesState>::State>,
A: UsesState + HasObservers<Observers = OTA>,
B: UsesState<State = <Self as UsesState>::State> + HasObservers<Observers = OTB>,
DOT: DifferentialObserversTuple<OTA, OTB, A::Input, A::State> + MatchName,
OTA: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
OTB: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
{
type Observers = ProxyObserversTuple<OTA, OTB, DOT>;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
unsafe {

View File

@ -42,7 +42,7 @@ use crate::{
executors::{Executor, ExitKind, HasObservers},
inputs::{HasTargetBytes, Input, UsesInput},
mutators::Tokens,
observers::{MapObserver, Observer, ObserversTuple, UsesObservers},
observers::{MapObserver, Observer, ObserversTuple},
state::{HasExecutions, State, UsesState},
Error,
};
@ -592,7 +592,7 @@ impl ForkserverExecutor<(), (), UnixShMemProvider> {
impl<OT, S, SP> ForkserverExecutor<OT, S, SP>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput,
SP: ShMemProvider,
{
@ -664,7 +664,7 @@ where
#[allow(clippy::pedantic)]
pub fn build<OT, S>(&mut self, observers: OT) -> Result<ForkserverExecutor<OT, S, SP>, Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput,
S::Input: Input + HasTargetBytes,
SP: ShMemProvider,
@ -729,8 +729,8 @@ where
) -> Result<ForkserverExecutor<(A, OT), S, SP>, Error>
where
MO: MapObserver + Truncate, // TODO maybe enforce Entry = u8 for the cov map
A: Observer<S> + AsRef<MO> + AsMut<MO>,
OT: ObserversTuple<S> + Prepend<MO>,
A: Observer<S::Input, S> + AsMut<MO>,
OT: ObserversTuple<S::Input, S> + Prepend<MO>,
S: UsesInput,
S::Input: Input + HasTargetBytes,
SP: ShMemProvider,
@ -1355,7 +1355,7 @@ impl<'a> Default for ForkserverExecutorBuilder<'a, UnixShMemProvider> {
impl<EM, OT, S, SP, Z> Executor<EM, Z> for ForkserverExecutor<OT, S, SP>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
S: State + HasExecutions,
S::Input: HasTargetBytes,
@ -1476,21 +1476,14 @@ where
type State = S;
}
impl<OT, S, SP> UsesObservers for ForkserverExecutor<OT, S, SP>
impl<OT, S, SP> HasObservers for ForkserverExecutor<OT, S, SP>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
SP: ShMemProvider,
{
type Observers = OT;
}
impl<OT, S, SP> HasObservers for ForkserverExecutor<OT, S, SP>
where
OT: ObserversTuple<S>,
S: State,
SP: ShMemProvider,
{
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
RefIndexable::from(&self.observers)

View File

@ -33,9 +33,11 @@ use crate::{
executors::{hooks::ExecutorHook, inprocess::HasInProcessHooks, Executor, HasObservers},
feedbacks::Feedback,
inputs::UsesInput,
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, UsesState},
Error, HasObjective,
};
/// The inmem executor's handlers.
#[allow(missing_debug_implementations)]
pub struct InProcessHooks<S>
@ -235,6 +237,7 @@ where
pub fn new<E, EM, OF, Z>(exec_tmout: Duration) -> Result<Self, Error>
where
E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,
@ -277,6 +280,7 @@ where
pub fn new<E, EM, OF, Z>(exec_tmout: Duration) -> Result<Self, Error>
where
E: Executor<EM, Z> + HasObservers + HasInProcessHooks<E::State>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: State + HasExecutions + HasSolutions + HasCorpus,

View File

@ -21,6 +21,8 @@ use crate::{
HasObservers,
},
inputs::UsesInput,
observers::ObserversTuple,
state::UsesState,
Error,
};
@ -58,7 +60,8 @@ impl<S> InChildProcessHooks<S> {
/// Create new [`InChildProcessHooks`].
pub fn new<E>() -> Result<Self, Error>
where
E: HasObservers,
E: HasObservers + UsesState,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
{
#[cfg_attr(miri, allow(unused_variables, unused_unsafe))]
unsafe {

View File

@ -20,6 +20,7 @@ pub mod unix_signal_handler {
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::{Input, UsesInput},
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, UsesState},
};
@ -76,7 +77,8 @@ pub mod unix_signal_handler {
/// invokes the `post_exec` hook on all observer in case of panic
pub fn setup_panic_hook<E, EM, OF, Z>()
where
E: HasObservers,
E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,
@ -125,7 +127,8 @@ pub mod unix_signal_handler {
_context: Option<&mut ucontext_t>,
data: &mut InProcessExecutorHandlerData,
) where
E: HasObservers + HasInProcessHooks<E::State>,
E: Executor<EM, Z> + HasInProcessHooks<E::State> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,
@ -183,6 +186,7 @@ pub mod unix_signal_handler {
data: &mut InProcessExecutorHandlerData,
) where
E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,

View File

@ -21,6 +21,7 @@ pub mod windows_asan_handler {
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, UsesState},
};
@ -32,6 +33,7 @@ pub mod windows_asan_handler {
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
<<<E as UsesState>::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me
@ -138,6 +140,7 @@ pub mod windows_exception_handler {
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::{Input, UsesInput},
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
};
@ -179,10 +182,11 @@ pub mod windows_exception_handler {
#[cfg(feature = "std")]
pub fn setup_panic_hook<E, EM, OF, Z>()
where
E: HasObservers,
E: HasObservers + Executor<EM, Z>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
<<<E as UsesState>::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me
@ -241,7 +245,8 @@ pub mod windows_exception_handler {
global_state: *mut c_void,
_p1: *mut u8,
) where
E: HasObservers + HasInProcessHooks<E::State>,
E: HasObservers + HasInProcessHooks<E::State> + Executor<EM, Z>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: State + HasExecutions + HasSolutions + HasCorpus,
@ -314,6 +319,7 @@ pub mod windows_exception_handler {
data: &mut InProcessExecutorHandlerData,
) where
E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,

View File

@ -29,7 +29,7 @@ use crate::{
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
Error,
};
@ -38,7 +38,7 @@ use crate::{
pub struct GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
/// The observers, observing each run
@ -51,7 +51,7 @@ where
impl<HT, OT, S> Debug for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: State,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@ -64,27 +64,20 @@ where
impl<HT, OT, S> UsesState for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type State = S;
}
impl<HT, OT, S> UsesObservers for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
type Observers = OT;
}
impl<HT, OT, S> HasObservers for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
RefIndexable::from(&self.observers)
@ -99,7 +92,7 @@ where
impl<HT, OT, S> GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
/// This function marks the boundary between the fuzzer and the target
@ -162,7 +155,7 @@ where
impl<HT, OT, S> GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: HasExecutions + HasSolutions + HasCorpus + State,
{
/// Create a new in mem executor with the default timeout (5 sec)
@ -175,6 +168,7 @@ where
) -> Result<Self, Error>
where
E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>,
S: State,
@ -204,6 +198,7 @@ where
) -> Result<Self, Error>
where
E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>,
S: State,
@ -236,6 +231,7 @@ where
) -> Result<Self, Error>
where
E: Executor<EM, Z, State = S> + HasObservers + HasInProcessHooks<S>,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = S> + EventRestarter,
OF: Feedback<S>,
S: State,
@ -293,7 +289,7 @@ where
impl<HT, OT, S> HasInProcessHooks<S> for GenericInProcessExecutorInner<HT, OT, S>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions + HasSolutions + HasCorpus,
{
/// the timeout handler

View File

@ -31,7 +31,7 @@ use crate::{
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions, State, UsesState},
Error, HasMetadata,
};
@ -65,7 +65,7 @@ where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
harness_fn: HB,
@ -78,7 +78,7 @@ where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: State,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@ -94,30 +94,19 @@ where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type State = S;
}
impl<H, HB, HT, OT, S> UsesObservers for GenericInProcessExecutor<H, HB, HT, OT, S>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
type Observers = OT;
}
impl<EM, H, HB, HT, OT, S, Z> Executor<EM, Z> for GenericInProcessExecutor<H, HB, HT, OT, S>
where
EM: UsesState<State = S>,
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions,
Z: UsesState<State = S>,
{
@ -149,9 +138,11 @@ where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.inner.observers()
@ -166,7 +157,7 @@ where
impl<'a, H, OT, S> InProcessExecutor<'a, H, OT, S>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: HasExecutions + HasSolutions + HasCorpus + State,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
<<S as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me
@ -279,7 +270,7 @@ where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions + HasSolutions + HasCorpus,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
<<S as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me
@ -421,7 +412,7 @@ where
H: FnMut(&<S as UsesInput>::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions + HasSolutions + HasCorpus,
{
/// the timeout handler
@ -448,7 +439,8 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
event_mgr: &mut EM,
exitkind: ExitKind,
) where
E: HasObservers,
E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,
@ -511,6 +503,7 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
pub unsafe fn generic_inproc_crash_handler<E, EM, OF, Z>()
where
E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus + HasCurrentTestcase,

View File

@ -21,7 +21,7 @@ use crate::{
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
Error,
};
@ -50,7 +50,7 @@ where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
/// The harness function, being executed for each fuzzing loop execution
@ -67,7 +67,7 @@ where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: State,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@ -83,23 +83,12 @@ where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type State = S;
}
impl<H, HB, HT, OT, S, ES> UsesObservers for StatefulGenericInProcessExecutor<H, HB, HT, OT, S, ES>
where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
{
type Observers = OT;
}
impl<EM, H, HB, HT, OT, S, Z, ES> Executor<EM, Z>
for StatefulGenericInProcessExecutor<H, HB, HT, OT, S, ES>
where
@ -107,7 +96,7 @@ where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions,
Z: UsesState<State = S>,
{
@ -139,9 +128,10 @@ where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.inner.observers()
@ -156,7 +146,7 @@ where
impl<'a, H, OT, S, ES> StatefulInProcessExecutor<'a, H, OT, S, ES>
where
H: FnMut(&mut ES, &mut S, &<S as UsesInput>::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: HasExecutions + HasSolutions + HasCorpus + State,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
<<S as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me
@ -275,7 +265,7 @@ where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
/// The executor state given to the harness
@ -294,7 +284,7 @@ where
H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions + HasSolutions + HasCorpus,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
<<S as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me
@ -430,7 +420,7 @@ where
H: FnMut(&mut ES, &mut S, &<S as UsesInput>::Input) -> ExitKind + ?Sized,
HB: BorrowMut<H>,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions + HasSolutions + HasCorpus,
{
/// the timeout handler

View File

@ -29,7 +29,7 @@ use crate::{
ExitKind, HasObservers,
},
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{State, UsesState},
Error,
};
@ -37,7 +37,7 @@ use crate::{
/// Inner state of GenericInProcessExecutor-like structures.
pub struct GenericInProcessForkExecutorInner<HT, OT, S, SP, EM, Z>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -56,7 +56,7 @@ where
impl<HT, OT, S, SP, EM, Z> Debug for GenericInProcessForkExecutorInner<HT, OT, S, SP, EM, Z>
where
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: UsesInput,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S> + Debug,
@ -86,7 +86,7 @@ where
impl<HT, OT, S, SP, EM, Z> UsesState for GenericInProcessForkExecutorInner<HT, OT, S, SP, EM, Z>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -98,7 +98,7 @@ where
impl<EM, HT, OT, S, SP, Z> GenericInProcessForkExecutorInner<HT, OT, S, SP, EM, Z>
where
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: State + UsesInput,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -194,7 +194,7 @@ impl<HT, OT, S, SP, EM, Z> GenericInProcessForkExecutorInner<HT, OT, S, SP, EM,
where
HT: ExecutorHooksTuple<S>,
S: State,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
EM: EventFirer<State = S> + EventRestarter<State = S>,
Z: UsesState<State = S>,
@ -317,27 +317,17 @@ where
}
}
impl<HT, OT, S, SP, EM, Z> UsesObservers for GenericInProcessForkExecutorInner<HT, OT, S, SP, EM, Z>
impl<HT, OT, S, SP, EM, Z> HasObservers for GenericInProcessForkExecutorInner<HT, OT, S, SP, EM, Z>
where
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
EM: UsesState<State = S>,
Z: UsesState<State = S>,
{
type Observers = OT;
}
impl<HT, OT, S, SP, EM, Z> HasObservers for GenericInProcessForkExecutorInner<HT, OT, S, SP, EM, Z>
where
HT: ExecutorHooksTuple<S>,
S: State,
OT: ObserversTuple<S>,
SP: ShMemProvider,
EM: UsesState<State = S>,
Z: UsesState<State = S>,
{
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
RefIndexable::from(&self.observers)

View File

@ -22,7 +22,7 @@ use crate::{
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{HasExecutions, HasSolutions, State, UsesState},
Error,
};
@ -50,7 +50,7 @@ impl<'a, H, OT, S, SP, EM, Z, OF> InProcessForkExecutor<'a, H, OT, S, SP, EM, Z>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
S: State,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>,
@ -88,7 +88,7 @@ where
pub struct GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -103,7 +103,7 @@ impl<'a, H, HT, OT, S, SP, EM, Z> Debug
for GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: UsesInput,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S> + Debug,
@ -131,7 +131,7 @@ impl<'a, H, HT, OT, S, SP, EM, Z> UsesState
for GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -145,7 +145,7 @@ impl<'a, EM, H, HT, OT, S, SP, Z> Executor<EM, Z>
for GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: State + HasExecutions,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -187,7 +187,7 @@ impl<'a, H, HT, OT, S, SP, EM, Z, OF> GenericInProcessForkExecutor<'a, H, HT, OT
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>,
@ -234,31 +234,18 @@ where {
}
}
impl<'a, H, HT, OT, S, SP, EM, Z> UsesObservers
for GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
SP: ShMemProvider,
EM: UsesState<State = S>,
Z: UsesState<State = S>,
{
type Observers = OT;
}
impl<'a, H, HT, OT, S, SP, EM, Z> HasObservers
for GenericInProcessForkExecutor<'a, H, HT, OT, S, SP, EM, Z>
where
H: FnMut(&S::Input) -> ExitKind + ?Sized,
HT: ExecutorHooksTuple<S>,
S: State,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
EM: UsesState<State = S>,
Z: UsesState<State = S>,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.inner.observers()
@ -286,12 +273,14 @@ pub mod child_signal_handlers {
},
inputs::UsesInput,
observers::ObserversTuple,
state::UsesState,
};
/// invokes the `post_exec_child` hook on all observer in case the child process panics
pub fn setup_child_panic_hook<E>()
where
E: HasObservers,
E: HasObservers + UsesState,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
{
let old_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| unsafe {
@ -326,7 +315,8 @@ pub mod child_signal_handlers {
_context: Option<&mut ucontext_t>,
data: &mut InProcessForkExecutorGlobalData,
) where
E: HasObservers,
E: HasObservers + UsesState,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
{
if data.is_valid() {
let executor = data.executor_mut::<E>();
@ -349,7 +339,8 @@ pub mod child_signal_handlers {
_context: Option<&mut ucontext_t>,
data: &mut InProcessForkExecutorGlobalData,
) where
E: HasObservers,
E: HasObservers + UsesState,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
{
if data.is_valid() {
let executor = data.executor_mut::<E>();

View File

@ -23,7 +23,7 @@ use crate::{
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::UsesInput,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{HasExecutions, HasSolutions, State, UsesState},
Error,
};
@ -35,7 +35,7 @@ pub type StatefulInProcessForkExecutor<'a, H, OT, S, SP, ES, EM, Z> =
impl<'a, H, OT, S, SP, ES, EM, Z, OF> StatefulInProcessForkExecutor<'a, H, OT, S, SP, ES, EM, Z>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
EM: EventFirer<State = S> + EventRestarter<State = S>,
OF: Feedback<S>,
@ -72,7 +72,7 @@ where
pub struct StatefulGenericInProcessForkExecutor<'a, H, HT, OT, S, SP, ES, EM, Z>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -89,7 +89,7 @@ impl<'a, H, HT, OT, S, SP, ES, EM, Z> Debug
for StatefulGenericInProcessForkExecutor<'a, H, HT, OT, S, SP, ES, EM, Z>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: UsesInput,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S> + Debug,
@ -117,7 +117,7 @@ impl<'a, H, HT, OT, S, SP, ES, EM, Z> UsesState
for StatefulGenericInProcessForkExecutor<'a, H, HT, OT, S, SP, ES, EM, Z>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -131,7 +131,7 @@ impl<'a, EM, H, HT, OT, S, SP, Z, ES, OF> Executor<EM, Z>
for StatefulGenericInProcessForkExecutor<'a, H, HT, OT, S, SP, ES, EM, Z>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: State + HasExecutions,
SP: ShMemProvider,
HT: ExecutorHooksTuple<S>,
@ -175,7 +175,7 @@ impl<'a, H, HT, OT, S, SP, ES, EM, Z, OF>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
Z: UsesState<State = S>,
EM: EventFirer<State = S> + EventRestarter<State = S>,
@ -225,31 +225,18 @@ where
}
}
impl<'a, H, HT, OT, S, SP, ES, EM, Z> UsesObservers
for StatefulGenericInProcessForkExecutor<'a, H, HT, OT, S, SP, ES, EM, Z>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
HT: ExecutorHooksTuple<S>,
OT: ObserversTuple<S>,
S: State,
SP: ShMemProvider,
EM: UsesState<State = S>,
Z: UsesState<State = S>,
{
type Observers = OT;
}
impl<'a, H, HT, OT, S, SP, ES, EM, Z> HasObservers
for StatefulGenericInProcessForkExecutor<'a, H, HT, OT, S, SP, ES, EM, Z>
where
H: FnMut(&S::Input, &mut ES) -> ExitKind + ?Sized,
HT: ExecutorHooksTuple<S>,
S: State,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
SP: ShMemProvider,
EM: UsesState<State = S>,
Z: UsesState<State = S>,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.inner.observers()

View File

@ -20,11 +20,7 @@ use serde::{Deserialize, Serialize};
pub use shadow::ShadowExecutor;
pub use with_observers::WithObservers;
use crate::{
observers::{ObserversTuple, UsesObservers},
state::UsesState,
Error,
};
use crate::{observers::ObserversTuple, state::UsesState, Error};
pub mod combined;
#[cfg(all(feature = "std", any(unix, doc)))]
@ -109,7 +105,10 @@ impl From<ExitKind> for DiffExitKind {
libafl_bolts::impl_serdeany!(DiffExitKind);
/// Holds a tuple of Observers
pub trait HasObservers: UsesObservers {
pub trait HasObservers {
/// The observer
type Observers;
/// Get the linked observers
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers>;
@ -139,7 +138,7 @@ where
fn with_observers<OT>(self, observers: OT) -> WithObservers<Self, OT>
where
Self: Sized,
OT: ObserversTuple<Self::State>,
OT: ObserversTuple<Self::Input, Self::State>,
{
WithObservers::new(self, observers)
}

View File

@ -6,7 +6,8 @@ use libafl_bolts::tuples::RefIndexable;
use crate::{
executors::{Executor, ExitKind, HasObservers},
observers::{ObserversTuple, UsesObservers},
inputs::UsesInput,
observers::ObserversTuple,
state::UsesState,
Error,
};
@ -34,8 +35,8 @@ where
impl<E, SOT> ShadowExecutor<E, SOT>
where
E: HasObservers,
SOT: ObserversTuple<<Self as UsesState>::State>,
E: HasObservers + UsesState,
SOT: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
{
/// Create a new `ShadowExecutor`, wrapping the given `executor`.
pub fn new(executor: E, shadow_observers: SOT) -> Self {
@ -61,7 +62,7 @@ where
impl<E, EM, SOT, Z> Executor<EM, Z> for ShadowExecutor<E, SOT>
where
E: Executor<EM, Z> + HasObservers,
SOT: ObserversTuple<Self::State>,
SOT: ObserversTuple<Self::Input, Self::State>,
EM: UsesState<State = Self::State>,
Z: UsesState<State = Self::State>,
{
@ -83,18 +84,12 @@ where
type State = E::State;
}
impl<E, SOT> UsesObservers for ShadowExecutor<E, SOT>
where
E: UsesObservers,
{
type Observers = E::Observers;
}
impl<E, SOT> HasObservers for ShadowExecutor<E, SOT>
where
E: HasObservers,
SOT: ObserversTuple<Self::State>,
E: HasObservers + UsesState,
SOT: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
{
type Observers = E::Observers;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.executor.observers()

View File

@ -6,7 +6,8 @@ use libafl_bolts::tuples::RefIndexable;
use crate::{
executors::{Executor, ExitKind, HasObservers},
observers::{ObserversTuple, UsesObservers},
inputs::UsesInput,
observers::ObserversTuple,
state::UsesState,
Error,
};
@ -42,19 +43,12 @@ where
type State = E::State;
}
impl<E, OT> UsesObservers for WithObservers<E, OT>
where
E: UsesState,
OT: ObserversTuple<Self::State>,
{
type Observers = OT;
}
impl<E, OT> HasObservers for WithObservers<E, OT>
where
E: UsesState,
OT: ObserversTuple<Self::State>,
OT: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
{
type Observers = OT;
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
RefIndexable::from(&self.observers)
}

View File

@ -67,7 +67,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(false)
}
@ -80,7 +80,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
if let Some(metadata) = observers

View File

@ -120,7 +120,7 @@ where
testcase: &mut Testcase<<S>::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
*testcase.filename_mut() = Some((self.func)(state, testcase)?);

View File

@ -105,8 +105,8 @@ impl<F, I, O1, O2, S, T> FeedbackFactory<DiffFeedback<F, I, O1, O2, S>, T>
where
F: FnMut(&O1, &O2) -> DiffResult + Clone,
I: Input,
O1: Observer<S> + Named,
O2: Observer<S> + Named,
O1: Observer<S::Input, S> + Named,
O2: Observer<S::Input, S> + Named,
S: HasMetadata + State<Input = I>,
{
fn create_feedback(&self, _ctx: &T) -> DiffFeedback<F, I, O1, O2, S> {
@ -153,8 +153,8 @@ where
F: FnMut(&O1, &O2) -> DiffResult,
I: Input,
S: HasMetadata + State<Input = I>,
O1: Observer<S>,
O2: Observer<S>,
O1: Observer<S::Input, S>,
O2: Observer<S::Input, S>,
{
#[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>(
@ -167,7 +167,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S> + MatchName,
OT: ObserversTuple<S::Input, S> + MatchName,
{
fn err(name: &str) -> Error {
Error::illegal_argument(format!("DiffFeedback: observer {name} not found"))
@ -203,7 +203,7 @@ mod tests {
events::EventFirer,
executors::ExitKind,
feedbacks::{differential::DiffResult, DiffFeedback, Feedback},
inputs::{BytesInput, UsesInput},
inputs::BytesInput,
observers::Observer,
state::{NopState, State, UsesState},
};
@ -221,7 +221,7 @@ mod tests {
}
}
}
impl<S> Observer<S> for NopObserver where S: UsesInput {}
impl<I, S> Observer<I, S> for NopObserver {}
impl PartialEq for NopObserver {
fn eq(&self, other: &Self) -> bool {
self.value == other.value

View File

@ -103,7 +103,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// TODO Replace with match_name_type when stable
let observer = observers.get(&self.observer_handle).unwrap();
@ -130,7 +130,7 @@ where
_testcase: &mut crate::corpus::Testcase<<S>::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
let history_set = state

View File

@ -407,7 +407,7 @@ where
R: Reducer<T>,
S: State + HasNamedMetadata,
T: Default + Copy + Serialize + for<'de> Deserialize<'de> + PartialEq + Debug + 'static,
C: CanTrack + AsRef<O> + Observer<S>,
C: CanTrack + AsRef<O> + Named,
{
fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
// Initialize `MapFeedbackMetadata` with an empty vector and add it to the state.
@ -427,7 +427,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let res = self.is_interesting_default(state, manager, input, observers, exit_kind);
#[cfg(feature = "track_hit_feedbacks")]
@ -448,7 +448,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<<S as UsesInput>::Input, S>,
{
let res = self.is_interesting_default(state, manager, input, observers, exit_kind);
@ -467,7 +467,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
if let Some(novelties) = self.novelties.as_mut().map(core::mem::take) {
@ -564,7 +564,7 @@ impl<C, O, S> Feedback<S> for MapFeedback<C, DifferentIsNovel, O, MaxReducer, u8
where
O: MapObserver<Entry = u8> + for<'a> AsSlice<'a, Entry = u8> + for<'a> AsIter<'a, Item = u8>,
S: State + HasNamedMetadata,
C: CanTrack + AsRef<O> + Observer<S>,
C: CanTrack + AsRef<O> + Observer<S::Input, S>,
{
#[allow(clippy::wrong_self_convention)]
#[allow(clippy::needless_range_loop)]
@ -578,7 +578,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// 128 bits vectors
type VectorType = core::simd::u8x16;
@ -761,7 +761,7 @@ where
) -> bool
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput + HasNamedMetadata,
{
let mut interesting = false;

View File

@ -79,7 +79,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>;
OT: ObserversTuple<S::Input, S>;
/// Returns if the result of a run is interesting and the value input should be stored in a corpus.
/// It also keeps track of introspection stats.
@ -96,7 +96,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// Start a timer for this feedback
let start_time = libafl_bolts::cpu::read_time_counter();
@ -141,7 +141,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
Ok(())
@ -247,7 +247,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
FL::is_pair_interesting(
&mut self.first,
@ -272,7 +272,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
FL::is_pair_interesting_introspection(
&mut self.first,
@ -294,7 +294,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
self.first
@ -348,7 +348,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>;
OT: ObserversTuple<S::Input, S>;
/// Get the result of the last `Self::is_interesting` run
#[cfg(feature = "track_hit_feedbacks")]
@ -378,7 +378,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>;
OT: ObserversTuple<S::Input, S>;
}
/// Factory for feedbacks which should be sensitive to an existing context, e.g. observer(s) from a
@ -433,7 +433,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let a = first.is_interesting(state, manager, input, observers, exit_kind)?;
let b = second.is_interesting(state, manager, input, observers, exit_kind)?;
@ -473,7 +473,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// Execute this feedback
let a = first.is_interesting_introspection(state, manager, input, observers, exit_kind)?;
@ -504,7 +504,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let a = first.is_interesting(state, manager, input, observers, exit_kind)?;
if a {
@ -548,7 +548,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// Execute this feedback
let a = first.is_interesting_introspection(state, manager, input, observers, exit_kind)?;
@ -582,7 +582,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let a = first.is_interesting(state, manager, input, observers, exit_kind)?;
let b = second.is_interesting(state, manager, input, observers, exit_kind)?;
@ -618,7 +618,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// Execute this feedback
let a = first.is_interesting_introspection(state, manager, input, observers, exit_kind)?;
@ -649,7 +649,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let a = first.is_interesting(state, manager, input, observers, exit_kind)?;
if !a {
@ -695,7 +695,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// Execute this feedback
let a = first.is_interesting_introspection(state, manager, input, observers, exit_kind)?;
@ -774,7 +774,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(!self
.first
@ -790,7 +790,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
self.first
@ -921,7 +921,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(false)
}
@ -954,7 +954,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let res = matches!(exit_kind, ExitKind::Crash);
#[cfg(feature = "track_hit_feedbacks")]
@ -1024,7 +1024,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let res = matches!(exit_kind, ExitKind::Timeout);
#[cfg(feature = "track_hit_feedbacks")]
@ -1095,7 +1095,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let res = matches!(exit_kind, ExitKind::Diff { .. });
#[cfg(feature = "track_hit_feedbacks")]
@ -1167,7 +1167,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
// TODO Replace with match_name_type when stable
Ok(false)
@ -1183,7 +1183,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
let observer = observers.get(&self.observer_handle).unwrap();
@ -1246,7 +1246,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
Ok((*self).into())
}

View File

@ -96,7 +96,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<NautilusInput, S>,
{
Ok(false)
}
@ -109,7 +109,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<NautilusInput, S>,
{
state.corpus().load_input_into(testcase)?;
let input = testcase.input().as_ref().unwrap().clone();

View File

@ -117,7 +117,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let observer = observers
.get(&self.o_ref)

View File

@ -51,7 +51,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(false)
}
@ -66,7 +66,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
let observer = observers
@ -146,7 +146,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(false)
}
@ -161,7 +161,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
EM: EventFirer<State = S>,
{
let observer = observers

View File

@ -71,7 +71,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let res = state.metadata::<TransferringMetadata>()?.transferring;
#[cfg(feature = "track_hit_feedbacks")]

View File

@ -81,7 +81,7 @@ pub trait ExecutionProcessor: UsesState {
) -> Result<ExecuteInputResult, Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State>;
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State>;
/// Process `ExecuteInputResult`. Add to corpus, solution or ignore
#[allow(clippy::too_many_arguments)]
@ -95,7 +95,7 @@ pub trait ExecutionProcessor: UsesState {
) -> Result<Option<CorpusId>, Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State>;
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State>;
/// serialize and send event via manager
fn serialize_and_dispatch<EM, OT>(
@ -109,7 +109,7 @@ pub trait ExecutionProcessor: UsesState {
) -> Result<(), Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State> + Serialize;
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize;
/// send event via manager
fn dispatch_event<EM>(
@ -136,7 +136,7 @@ pub trait ExecutionProcessor: UsesState {
) -> Result<(ExecuteInputResult, Option<CorpusId>), Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State> + Serialize;
OT: ObserversTuple<<Self as UsesInput>::Input, Self::State> + Serialize;
}
/// Evaluates an input modifying the state of the fuzzer
@ -153,7 +153,7 @@ pub trait EvaluatorObservers<OT>: UsesState + Sized {
send_events: bool,
) -> Result<(ExecuteInputResult, Option<CorpusId>), Error>
where
E: Executor<EM, Self> + HasObservers<Observers = OT, State = Self::State>,
E: Executor<EM, Self, State = Self::State> + HasObservers<Observers = OT>,
EM: EventFirer<State = Self::State>;
}
@ -386,7 +386,7 @@ where
) -> Result<ExecuteInputResult, Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State>,
OT: ObserversTuple<Self::Input, Self::State>,
{
let mut res = ExecuteInputResult::None;
@ -431,7 +431,7 @@ where
) -> Result<(ExecuteInputResult, Option<CorpusId>), Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State> + Serialize,
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
{
let exec_res = self.check_results(state, manager, &input, observers, exit_kind)?;
let corpus_id = self.process_execution(state, manager, &input, &exec_res, observers)?;
@ -452,7 +452,7 @@ where
) -> Result<(), Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State> + Serialize,
OT: ObserversTuple<Self::Input, Self::State> + Serialize,
{
// Now send off the event
let observers_buf = match exec_res {
@ -537,7 +537,7 @@ where
) -> Result<Option<CorpusId>, Error>
where
EM: EventFirer<State = Self::State>,
OT: ObserversTuple<Self::State>,
OT: ObserversTuple<Self::Input, Self::State>,
{
match exec_res {
ExecuteInputResult::None => {
@ -588,7 +588,7 @@ where
impl<CS, F, OF, OT, S> EvaluatorObservers<OT> for StdFuzzer<CS, F, OF, S>
where
CS: Scheduler<S::Input, S>,
OT: ObserversTuple<S> + Serialize + DeserializeOwned,
OT: ObserversTuple<S::Input, S> + Serialize + DeserializeOwned,
F: Feedback<S>,
OF: Feedback<S>,
S: HasCorpus + HasSolutions + HasExecutions + State,
@ -606,7 +606,7 @@ where
send_events: bool,
) -> Result<(ExecuteInputResult, Option<CorpusId>), Error>
where
E: Executor<EM, Self> + HasObservers<Observers = OT, State = S>,
E: Executor<EM, Self, State = S> + HasObservers<Observers = OT>,
EM: EventFirer<State = S>,
{
let exit_kind = self.execute_input(state, executor, manager, &input)?;
@ -618,14 +618,14 @@ where
}
}
impl<CS, E, EM, F, OF, OT, S> Evaluator<E, EM> for StdFuzzer<CS, F, OF, S>
impl<CS, E, EM, F, OF, S> Evaluator<E, EM> for StdFuzzer<CS, F, OF, S>
where
CS: Scheduler<S::Input, S>,
E: HasObservers<State = S, Observers = OT> + Executor<EM, Self>,
E: HasObservers + Executor<EM, Self, State = S>,
E::Observers: ObserversTuple<S::Input, S> + Serialize + DeserializeOwned,
EM: EventFirer<State = S>,
F: Feedback<S>,
OF: Feedback<S>,
OT: ObserversTuple<S> + Serialize + DeserializeOwned,
S: HasCorpus + HasSolutions + HasExecutions + HasLastFoundTime + State,
S::Corpus: Corpus<Input = S::Input>, //delete me
S::Solutions: Corpus<Input = S::Input>, //delete me
@ -734,7 +734,7 @@ where
let observers_buf = if manager.configuration() == EventConfig::AlwaysUnique {
None
} else {
manager.serialize_observers::<OT>(&*observers)?
manager.serialize_observers::<E::Observers>(&*observers)?
};
manager.fire(
state,
@ -860,7 +860,8 @@ where
input: &<<Self as UsesState>::State as UsesInput>::Input,
) -> Result<ExitKind, Error>
where
E: Executor<EM, Self> + HasObservers<State = <Self as UsesState>::State>,
E: Executor<EM, Self, State = <Self as UsesState>::State> + HasObservers,
E::Observers: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
EM: UsesState<State = <Self as UsesState>::State>,
{
start_timer!(state);
@ -902,7 +903,8 @@ where
CS: Scheduler<S::Input, S>,
F: Feedback<<Self as UsesState>::State>,
OF: Feedback<<Self as UsesState>::State>,
E: Executor<EM, Self> + HasObservers<State = Self::State>,
E: Executor<EM, Self, State = S> + HasObservers,
E::Observers: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
EM: UsesState<State = Self::State>,
S: UsesInput + HasExecutions + HasCorpus + State,
{

View File

@ -1,39 +1,16 @@
//! The `CmpObserver` provides access to the logged values of CMP instructions
use alloc::{borrow::Cow, vec::Vec};
use core::{
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut},
};
use c2rust_bitfields::BitfieldStruct;
use hashbrown::HashMap;
use libafl_bolts::{ownedref::OwnedRefMut, serdeany::SerdeAny, AsSlice, HasLen, Named};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use libafl_bolts::{ownedref::OwnedRefMut, AsSlice, HasLen, Named};
use serde::{Deserialize, Serialize};
use crate::{executors::ExitKind, inputs::UsesInput, observers::Observer, Error, HasMetadata};
/// Generic metadata trait for use in a `CmpObserver`, which adds comparisons from a `CmpObserver`
/// primarily intended for use with `AFLppCmpValuesMetadata` or `CmpValuesMetadata`
pub trait CmpObserverMetadata<'a, CM>: SerdeAny + Debug
where
CM: CmpMap + Debug,
{
/// Extra data used by the metadata when adding information from a `CmpObserver`, for example
/// the `original` field in `AFLppCmpLogObserver`
type Data: 'a + Debug + Default + Serialize + DeserializeOwned;
/// Instantiate a new metadata instance. This is used by `CmpObserver` to create a new
/// metadata if one is missing and `add_meta` is specified. This will typically juse call
/// `new()`
fn new_metadata() -> Self;
/// Add comparisons to a metadata from a `CmpObserver`. `cmp_map` is mutable in case
/// it is needed for a custom map, but this is not utilized for `CmpObserver` or
/// `AFLppCmpLogObserver`.
fn add_from(&mut self, usable_count: usize, cmp_map: &mut CM, cmp_observer_data: Self::Data);
}
use crate::{executors::ExitKind, observers::Observer, Error, HasMetadata};
/// A bytes string for cmplog with up to 32 elements.
#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq)]
@ -139,20 +116,14 @@ impl CmpValuesMetadata {
pub fn new() -> Self {
Self { list: vec![] }
}
}
impl<'a, CM> CmpObserverMetadata<'a, CM> for CmpValuesMetadata
where
CM: CmpMap,
{
type Data = bool;
#[must_use]
fn new_metadata() -> Self {
Self::new()
}
fn add_from(&mut self, usable_count: usize, cmp_map: &mut CM, _: Self::Data) {
/// Add comparisons to a metadata from a `CmpObserver`. `cmp_map` is mutable in case
/// it is needed for a custom map, but this is not utilized for `CmpObserver` or
/// `AFLppCmpLogObserver`.
pub fn add_from<CM>(&mut self, usable_count: usize, cmp_map: &mut CM)
where
CM: CmpMap,
{
self.list.clear();
let count = usable_count;
for i in 0..count {
@ -232,65 +203,35 @@ pub trait CmpMap: Debug {
}
/// A [`CmpObserver`] observes the traced comparisons during the current execution using a [`CmpMap`]
pub trait CmpObserver<'a, CM, S, M>: Observer<S>
where
CM: CmpMap,
S: UsesInput,
M: CmpObserverMetadata<'a, CM>,
{
pub trait CmpObserver {
/// The underlying map
type Map;
/// Get the number of usable cmps (all by default)
fn usable_count(&self) -> usize;
/// Get the `CmpMap`
fn cmp_map(&self) -> &CM;
fn cmp_map(&self) -> &Self::Map;
/// Get the `CmpMap` (mutable)
fn cmp_map_mut(&mut self) -> &mut CM;
/// Get the observer data. By default, this is the default metadata aux data, which is `()`.
fn cmp_observer_data(&self) -> M::Data {
M::Data::default()
}
/// Add [`struct@CmpValuesMetadata`] to the State including the logged values.
/// This routine does a basic loop filtering because loop index cmps are not interesting.
fn add_cmpvalues_meta(&mut self, state: &mut S)
where
S: HasMetadata,
{
#[allow(clippy::option_if_let_else)] // we can't mutate state in a closure
let meta = state.metadata_or_insert_with(|| M::new_metadata());
let usable_count = self.usable_count();
let cmp_observer_data = self.cmp_observer_data();
meta.add_from(usable_count, self.cmp_map_mut(), cmp_observer_data);
}
/// Get the mut `CmpMap`
fn cmp_map_mut(&mut self) -> &mut Self::Map;
}
/// A standard [`CmpObserver`] observer
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "CM: serde::de::DeserializeOwned")]
pub struct StdCmpObserver<'a, CM, S, M>
where
CM: CmpMap + Serialize,
S: UsesInput + HasMetadata,
M: CmpObserverMetadata<'a, CM>,
{
#[serde(bound = "CM: serde::de::DeserializeOwned + Serialize")]
pub struct StdCmpObserver<'a, CM> {
cmp_map: OwnedRefMut<'a, CM>,
size: Option<OwnedRefMut<'a, usize>>,
name: Cow<'static, str>,
add_meta: bool,
data: M::Data,
phantom: PhantomData<S>,
}
impl<'a, CM, S, M> CmpObserver<'a, CM, S, M> for StdCmpObserver<'a, CM, S, M>
impl<'a, CM> CmpObserver for StdCmpObserver<'a, CM>
where
CM: CmpMap + Serialize + DeserializeOwned,
S: UsesInput + Debug + HasMetadata,
M: CmpObserverMetadata<'a, CM>,
CM: HasLen,
{
type Map = CM;
/// Get the number of usable cmps (all by default)
fn usable_count(&self) -> usize {
match &self.size {
@ -299,59 +240,45 @@ where
}
}
fn cmp_map(&self) -> &CM {
fn cmp_map(&self) -> &Self::Map {
self.cmp_map.as_ref()
}
fn cmp_map_mut(&mut self) -> &mut CM {
fn cmp_map_mut(&mut self) -> &mut Self::Map {
self.cmp_map.as_mut()
}
fn cmp_observer_data(&self) -> <M as CmpObserverMetadata<'a, CM>>::Data {
<M as CmpObserverMetadata<CM>>::Data::default()
}
}
impl<'a, CM, S, M> Observer<S> for StdCmpObserver<'a, CM, S, M>
impl<'a, CM, I, S> Observer<I, S> for StdCmpObserver<'a, CM>
where
CM: CmpMap + Serialize + DeserializeOwned,
S: UsesInput + Debug + HasMetadata,
M: CmpObserverMetadata<'a, CM>,
CM: Serialize + CmpMap + HasLen,
S: HasMetadata,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.cmp_map.as_mut().reset()?;
Ok(())
}
fn post_exec(
&mut self,
state: &mut S,
_input: &S::Input,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
fn post_exec(&mut self, state: &mut S, _input: &I, _exit_kind: &ExitKind) -> Result<(), Error> {
if self.add_meta {
self.add_cmpvalues_meta(state);
#[allow(clippy::option_if_let_else)] // we can't mutate state in a closure
let meta = state.metadata_or_insert_with(CmpValuesMetadata::new);
meta.add_from(self.usable_count(), self.cmp_map_mut());
}
Ok(())
}
}
impl<'a, CM, S, M> Named for StdCmpObserver<'a, CM, S, M>
where
CM: CmpMap + Serialize + DeserializeOwned,
S: UsesInput + HasMetadata,
M: CmpObserverMetadata<'a, CM>,
{
impl<'a, CM> Named for StdCmpObserver<'a, CM> {
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a, CM, S, M> StdCmpObserver<'a, CM, S, M>
impl<'a, CM> StdCmpObserver<'a, CM>
where
CM: CmpMap + Serialize + DeserializeOwned,
S: UsesInput + HasMetadata,
M: CmpObserverMetadata<'a, CM>,
CM: CmpMap,
{
/// Creates a new [`StdCmpObserver`] with the given name and map.
#[must_use]
@ -361,27 +288,6 @@ where
size: None,
cmp_map: map,
add_meta,
data: M::Data::default(),
phantom: PhantomData,
}
}
/// Creates a new [`StdCmpObserver`] with the given name, map, and auxiliary data used to
/// populate metadata
#[must_use]
pub fn with_data(
name: &'static str,
cmp_map: OwnedRefMut<'a, CM>,
add_meta: bool,
data: M::Data,
) -> Self {
Self {
name: Cow::from(name),
size: None,
cmp_map,
add_meta,
data,
phantom: PhantomData,
}
}
@ -398,45 +304,10 @@ where
size: Some(size),
cmp_map,
add_meta,
data: M::Data::default(),
phantom: PhantomData,
}
}
/// Creates a new [`StdCmpObserver`] with the given name, map, auxiliary data, and
/// reference to variable size.
#[must_use]
pub fn with_size_data(
name: &'static str,
cmp_map: OwnedRefMut<'a, CM>,
add_meta: bool,
data: M::Data,
size: OwnedRefMut<'a, usize>,
) -> Self {
Self {
name: Cow::from(name),
size: Some(size),
cmp_map,
add_meta,
data,
phantom: PhantomData,
}
}
/// Handle the stored auxiliary data associated with the [`CmpObserverMetadata`]
pub fn data(&self) -> &M::Data {
&self.data
}
/// Mutably reference the stored auxiliary data associated with the [`CmpObserverMetadata`]
pub fn data_mut(&mut self) -> &mut M::Data {
&mut self.data
}
}
/// A [`StdCmpObserver`] that optionally adds comparisons into a [`CmpValuesMetadata`]
pub type StdCmpValuesObserver<'a, CM, S> = StdCmpObserver<'a, CM, S, CmpValuesMetadata>;
/* From AFL++ cmplog.h
#define CMP_MAP_W 65536

View File

@ -3,12 +3,9 @@ use alloc::borrow::Cow;
use libafl_bolts::Named;
use serde::{Deserialize, Serialize};
use crate::{
inputs::UsesInput,
observers::{
concolic::{serialization_format::MessageFileReader, ConcolicMetadata},
Observer,
},
use crate::observers::{
concolic::{serialization_format::MessageFileReader, ConcolicMetadata},
Observer,
};
/// A standard [`ConcolicObserver`] observer, observing constraints written into a memory buffer.
@ -19,7 +16,7 @@ pub struct ConcolicObserver<'map> {
name: Cow<'static, str>,
}
impl<'map, S> Observer<S> for ConcolicObserver<'map> where S: UsesInput {}
impl<'map, I, S> Observer<I, S> for ConcolicObserver<'map> {}
impl<'map> ConcolicObserver<'map> {
/// Create the concolic observer metadata for this run

View File

@ -4,11 +4,11 @@ use core::fmt::Debug;
use libafl_bolts::{ownedref::OwnedMutPtr, Error, Named};
use serde::{Deserialize, Serialize};
use crate::{inputs::UsesInput, observers::Observer};
use crate::observers::Observer;
/// A simple observer with a list of things.
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned + serde::Serialize")]
#[serde(bound = "T: Serialize + for<'a> Deserialize<'a>")]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct ListObserver<T> {
name: Cow<'static, str>,
@ -16,10 +16,7 @@ pub struct ListObserver<T> {
list: OwnedMutPtr<Vec<T>>,
}
impl<T> ListObserver<T>
where
T: Debug + Serialize + serde::de::DeserializeOwned,
{
impl<T> ListObserver<T> {
/// Creates a new [`ListObserver`] with the given name.
///
/// # Safety
@ -46,21 +43,14 @@ where
}
}
impl<S, T> Observer<S> for ListObserver<T>
where
S: UsesInput,
T: Debug + Serialize + serde::de::DeserializeOwned,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
impl<I, S, T> Observer<I, S> for ListObserver<T> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.list.as_mut().clear();
Ok(())
}
}
impl<T> Named for ListObserver<T>
where
T: Debug + Serialize + serde::de::DeserializeOwned,
{
impl<T> Named for ListObserver<T> {
fn name(&self) -> &Cow<'static, str> {
&self.name
}

View File

@ -5,16 +5,13 @@ use core::{
fmt::Debug,
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
slice::{Iter, IterMut},
};
use ahash::RandomState;
use libafl_bolts::{ownedref::OwnedMutSlice, AsSlice, AsSliceMut, HasLen, Named};
use num_traits::Bounded;
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{
inputs::UsesInput,
observers::{map::MapObserver, Observer},
Error,
};
@ -22,144 +19,53 @@ use crate::{
/// Use a const size to speedup `Feedback::is_interesting` when the user can
/// know the size of the map at compile time.
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct ConstMapObserver<'a, T, const N: usize>
where
T: Default + Copy + 'static + Serialize,
{
pub struct ConstMapObserver<'a, T, const N: usize> {
map: OwnedMutSlice<'a, T>,
initial: T,
name: Cow<'static, str>,
}
impl<'a, S, T, const N: usize> Observer<S> for ConstMapObserver<'a, T, N>
impl<'a, I, S, T, const N: usize> Observer<I, S> for ConstMapObserver<'a, T, N>
where
S: UsesInput,
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
Self: MapObserver,
{
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.reset_map()
}
}
impl<'a, T, const N: usize> Named for ConstMapObserver<'a, T, N>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{
impl<'a, T, const N: usize> Named for ConstMapObserver<'a, T, N> {
#[inline]
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a, T, const N: usize> HasLen for ConstMapObserver<'a, T, N>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{
impl<'a, T, const N: usize> HasLen for ConstMapObserver<'a, T, N> {
#[inline]
fn len(&self) -> usize {
N
}
}
impl<'a, 'it, T, const N: usize> IntoIterator for &'it ConstMapObserver<'a, T, N>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
type Item = <Iter<'it, T> as Iterator>::Item;
type IntoIter = Iter<'it, T>;
fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count();
self.as_slice()[..cnt].iter()
}
}
impl<'a, 'it, T, const N: usize> IntoIterator for &'it mut ConstMapObserver<'a, T, N>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
type Item = <IterMut<'it, T> as Iterator>::Item;
type IntoIter = IterMut<'it, T>;
fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count();
self.as_slice_mut()[..cnt].iter_mut()
}
}
impl<'a, T, const N: usize> ConstMapObserver<'a, T, N>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
/// Returns an iterator over the map.
pub fn iter(&self) -> Iter<'_, T> {
<&Self as IntoIterator>::into_iter(self)
}
/// Returns a mutable iterator over the map.
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
<&mut Self as IntoIterator>::into_iter(self)
}
}
impl<'a, T, const N: usize> Hash for ConstMapObserver<'a, T, N>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
T: Hash,
{
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.as_slice().hash(hasher);
self.map.as_slice().hash(hasher);
}
}
impl<'a, T, const N: usize> AsRef<Self> for ConstMapObserver<'a, T, N>
where
T: Default + Copy + 'static + Serialize,
{
impl<'a, T, const N: usize> AsRef<Self> for ConstMapObserver<'a, T, N> {
fn as_ref(&self) -> &Self {
self
}
}
impl<'a, T, const N: usize> AsMut<Self> for ConstMapObserver<'a, T, N>
where
T: Default + Copy + 'static + Serialize,
{
impl<'a, T, const N: usize> AsMut<Self> for ConstMapObserver<'a, T, N> {
fn as_mut(&mut self) -> &mut Self {
self
}
@ -167,15 +73,7 @@ where
impl<'a, T, const N: usize> MapObserver for ConstMapObserver<'a, T, N>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
T: PartialEq + Copy + Hash + Serialize + DeserializeOwned + Debug + 'static,
{
type Entry = T;
@ -249,20 +147,14 @@ where
}
}
impl<'a, T, const N: usize> Deref for ConstMapObserver<'a, T, N>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<'a, T, const N: usize> Deref for ConstMapObserver<'a, T, N> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.map
}
}
impl<'a, T, const N: usize> DerefMut for ConstMapObserver<'a, T, N>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<'a, T, const N: usize> DerefMut for ConstMapObserver<'a, T, N> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.map
}
@ -270,7 +162,7 @@ where
impl<'a, T, const N: usize> ConstMapObserver<'a, T, N>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
T: Default,
{
/// Creates a new [`MapObserver`]
///
@ -287,18 +179,6 @@ where
}
}
/// Creates a new [`MapObserver`] with an owned map
#[must_use]
pub fn owned(name: &'static str, map: Vec<T>) -> Self {
assert!(map.len() >= N);
let initial = if map.is_empty() { T::default() } else { map[0] };
Self {
map: OwnedMutSlice::from(map),
name: Cow::from(name),
initial,
}
}
/// Creates a new [`MapObserver`] from a raw pointer
///
/// # Safety
@ -311,3 +191,24 @@ where
}
}
}
impl<'a, T, const N: usize> ConstMapObserver<'a, T, N>
where
T: Default + Clone,
{
/// Creates a new [`MapObserver`] with an owned map
#[must_use]
pub fn owned(name: &'static str, map: Vec<T>) -> Self {
assert!(map.len() >= N);
let initial = if map.is_empty() {
T::default()
} else {
map[0].clone()
};
Self {
map: OwnedMutSlice::from(map),
name: Cow::from(name),
initial,
}
}
}

View File

@ -4,6 +4,7 @@ use core::{
fmt::Debug,
hash::Hash,
mem::size_of,
ops::{Deref, DerefMut},
ptr::{addr_of, addr_of_mut},
slice,
};
@ -13,8 +14,7 @@ use serde::{Deserialize, Serialize};
use crate::{
executors::ExitKind,
inputs::UsesInput,
observers::{map::MapObserver, DifferentialObserver, Observer, ObserversTuple},
observers::{map::MapObserver, DifferentialObserver, Observer},
Error,
};
@ -65,32 +65,36 @@ fn init_count_class_16() {
/// [`MapObserver`]s that are not slice-backed, such as `MultiMapObserver`, can use
/// [`HitcountsIterableMapObserver`] instead.
#[derive(Serialize, Deserialize, Clone, Debug, Hash)]
#[serde(bound = "M: serde::de::DeserializeOwned")]
pub struct HitcountsMapObserver<M>
where
M: Serialize,
{
pub struct HitcountsMapObserver<M> {
base: M,
}
impl<S, M> Observer<S> for HitcountsMapObserver<M>
impl<M> Deref for HitcountsMapObserver<M> {
type Target = M;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl<M> DerefMut for HitcountsMapObserver<M> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl<I, S, M> Observer<I, S> for HitcountsMapObserver<M>
where
M: MapObserver<Entry = u8> + Observer<S> + for<'a> AsSliceMut<'a, Entry = u8>,
S: UsesInput,
M: MapObserver<Entry = u8> + Observer<I, S> + for<'a> AsSliceMut<'a, Entry = u8>,
{
#[inline]
fn pre_exec(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.base.pre_exec(state, input)
}
#[inline]
#[allow(clippy::cast_ptr_alignment)]
fn post_exec(
&mut self,
state: &mut S,
input: &S::Input,
exit_kind: &ExitKind,
) -> Result<(), Error> {
fn post_exec(&mut self, state: &mut S, input: &I, exit_kind: &ExitKind) -> Result<(), Error> {
let mut map = self.as_slice_mut();
let mut len = map.len();
let align_offset = map.as_ptr().align_offset(size_of::<u16>());
@ -137,7 +141,7 @@ where
impl<M> Named for HitcountsMapObserver<M>
where
M: Named + Serialize + serde::de::DeserializeOwned,
M: Named,
{
#[inline]
fn name(&self) -> &Cow<'static, str> {
@ -145,9 +149,17 @@ where
}
}
impl<M> HitcountsMapObserver<M> {
/// Creates a new [`MapObserver`]
pub fn new(base: M) -> Self {
init_count_class_16();
Self { base }
}
}
impl<M> HasLen for HitcountsMapObserver<M>
where
M: MapObserver,
M: HasLen,
{
#[inline]
fn len(&self) -> usize {
@ -155,19 +167,13 @@ where
}
}
impl<M> AsRef<Self> for HitcountsMapObserver<M>
where
M: MapObserver<Entry = u8>,
{
impl<M> AsRef<Self> for HitcountsMapObserver<M> {
fn as_ref(&self) -> &Self {
self
}
}
impl<M> AsMut<Self> for HitcountsMapObserver<M>
where
M: MapObserver<Entry = u8>,
{
impl<M> AsMut<Self> for HitcountsMapObserver<M> {
fn as_mut(&mut self) -> &mut Self {
self
}
@ -234,7 +240,7 @@ where
impl<'a, M> AsSlice<'a> for HitcountsMapObserver<M>
where
M: MapObserver + AsSlice<'a>,
M: AsSlice<'a>,
{
type Entry = <M as AsSlice<'a>>::Entry;
type SliceRef = <M as AsSlice<'a>>::SliceRef;
@ -247,7 +253,7 @@ where
impl<'a, M> AsSliceMut<'a> for HitcountsMapObserver<M>
where
M: MapObserver + AsSliceMut<'a>,
M: AsSliceMut<'a>,
{
type SliceRefMut = <M as AsSliceMut<'a>>::SliceRefMut;
#[inline]
@ -256,74 +262,11 @@ where
}
}
impl<M> HitcountsMapObserver<M>
impl<M, OTA, OTB, I, S> DifferentialObserver<OTA, OTB, I, S> for HitcountsMapObserver<M>
where
M: MapObserver,
{
/// Creates a new [`MapObserver`]
pub fn new(base: M) -> Self {
init_count_class_16();
Self { base }
}
}
impl<'it, M> IntoIterator for &'it HitcountsMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
&'it M: IntoIterator<Item = &'it u8>,
{
type Item = &'it u8;
type IntoIter = <&'it M as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.base.into_iter()
}
}
impl<'it, M> IntoIterator for &'it mut HitcountsMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
&'it mut M: IntoIterator<Item = &'it mut u8>,
{
type Item = &'it mut u8;
type IntoIter = <&'it mut M as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.base.into_iter()
}
}
impl<M> HitcountsMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
for<'it> &'it M: IntoIterator<Item = &'it u8>,
{
/// Returns an iterator over the map.
pub fn iter(&self) -> <&M as IntoIterator>::IntoIter {
<&Self as IntoIterator>::into_iter(self)
}
}
impl<M> HitcountsMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
for<'it> &'it mut M: IntoIterator<Item = &'it mut u8>,
{
/// Returns a mutable iterator over the map.
pub fn iter_mut(&mut self) -> <&mut M as IntoIterator>::IntoIter {
<&mut Self as IntoIterator>::into_iter(self)
}
}
impl<M, OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for HitcountsMapObserver<M>
where
M: DifferentialObserver<OTA, OTB, S>
M: DifferentialObserver<OTA, OTB, I, S>
+ MapObserver<Entry = u8>
+ Serialize
+ for<'a> AsSliceMut<'a, Entry = u8>,
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
fn pre_observe_first(&mut self, observers: &mut OTA) -> Result<(), Error> {
self.base.pre_observe_first(observers)
@ -346,33 +289,36 @@ where
/// Less optimized version for non-slice iterators.
/// Slice-backed observers should use a [`HitcountsMapObserver`].
#[derive(Serialize, Deserialize, Clone, Debug, Hash)]
#[serde(bound = "M: serde::de::DeserializeOwned")]
pub struct HitcountsIterableMapObserver<M>
where
M: Serialize,
{
pub struct HitcountsIterableMapObserver<M> {
base: M,
}
impl<S, M> Observer<S> for HitcountsIterableMapObserver<M>
impl<M> Deref for HitcountsIterableMapObserver<M> {
type Target = M;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl<M> DerefMut for HitcountsIterableMapObserver<M> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl<I, S, M> Observer<I, S> for HitcountsIterableMapObserver<M>
where
M: MapObserver<Entry = u8> + Observer<S>,
for<'it> M: AsIterMut<'it, Item = u8>,
S: UsesInput,
M: MapObserver<Entry = u8> + Observer<I, S> + for<'it> AsIterMut<'it, Item = u8>,
{
#[inline]
fn pre_exec(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.base.pre_exec(state, input)
}
#[inline]
#[allow(clippy::cast_ptr_alignment)]
fn post_exec(
&mut self,
state: &mut S,
input: &S::Input,
exit_kind: &ExitKind,
) -> Result<(), Error> {
fn post_exec(&mut self, state: &mut S, input: &I, exit_kind: &ExitKind) -> Result<(), Error> {
for mut item in self.as_iter_mut() {
*item = unsafe { *COUNT_CLASS_LOOKUP.get_unchecked((*item) as usize) };
}
@ -383,7 +329,7 @@ where
impl<M> Named for HitcountsIterableMapObserver<M>
where
M: Named + Serialize + serde::de::DeserializeOwned,
M: Named,
{
#[inline]
fn name(&self) -> &Cow<'static, str> {
@ -391,9 +337,17 @@ where
}
}
impl<M> HitcountsIterableMapObserver<M> {
/// Creates a new [`MapObserver`]
pub fn new(base: M) -> Self {
init_count_class_16();
Self { base }
}
}
impl<M> HasLen for HitcountsIterableMapObserver<M>
where
M: MapObserver,
M: HasLen,
{
#[inline]
fn len(&self) -> usize {
@ -401,21 +355,13 @@ where
}
}
impl<M> AsRef<Self> for HitcountsIterableMapObserver<M>
where
M: MapObserver<Entry = u8>,
for<'it> M: AsIterMut<'it, Item = u8>,
{
impl<M> AsRef<Self> for HitcountsIterableMapObserver<M> {
fn as_ref(&self) -> &Self {
self
}
}
impl<M> AsMut<Self> for HitcountsIterableMapObserver<M>
where
M: MapObserver<Entry = u8>,
for<'it> M: AsIterMut<'it, Item = u8>,
{
impl<M> AsMut<Self> for HitcountsIterableMapObserver<M> {
fn as_mut(&mut self) -> &mut Self {
self
}
@ -424,7 +370,6 @@ where
impl<M> MapObserver for HitcountsIterableMapObserver<M>
where
M: MapObserver<Entry = u8>,
for<'it> M: AsIterMut<'it, Item = u8>,
{
type Entry = u8;
@ -481,97 +426,11 @@ where
}
}
impl<M> HitcountsIterableMapObserver<M>
impl<M, OTA, OTB, I, S> DifferentialObserver<OTA, OTB, I, S> for HitcountsIterableMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
{
/// Creates a new [`MapObserver`]
pub fn new(base: M) -> Self {
init_count_class_16();
Self { base }
}
}
impl<'it, M> AsIter<'it> for HitcountsIterableMapObserver<M>
where
M: Named + Serialize + serde::de::DeserializeOwned + AsIter<'it, Item = u8>,
{
type Item = u8;
type Ref = <M as AsIter<'it>>::Ref;
type IntoIter = <M as AsIter<'it>>::IntoIter;
fn as_iter(&'it self) -> Self::IntoIter {
self.base.as_iter()
}
}
impl<'it, M> AsIterMut<'it> for HitcountsIterableMapObserver<M>
where
M: Named + Serialize + serde::de::DeserializeOwned + AsIterMut<'it, Item = u8>,
{
type RefMut = <M as AsIterMut<'it>>::RefMut;
type IntoIterMut = <M as AsIterMut<'it>>::IntoIterMut;
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
self.base.as_iter_mut()
}
}
impl<'it, M> IntoIterator for &'it HitcountsIterableMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
&'it M: IntoIterator<Item = &'it u8>,
{
type Item = &'it u8;
type IntoIter = <&'it M as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.base.into_iter()
}
}
impl<'it, M> IntoIterator for &'it mut HitcountsIterableMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
&'it mut M: IntoIterator<Item = &'it mut u8>,
{
type Item = &'it mut u8;
type IntoIter = <&'it mut M as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.base.into_iter()
}
}
impl<M> HitcountsIterableMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
for<'it> &'it M: IntoIterator<Item = &'it u8>,
{
/// Returns an iterator over the map.
pub fn iter(&self) -> <&M as IntoIterator>::IntoIter {
<&Self as IntoIterator>::into_iter(self)
}
}
impl<M> HitcountsIterableMapObserver<M>
where
M: Serialize + serde::de::DeserializeOwned,
for<'it> &'it mut M: IntoIterator<Item = &'it mut u8>,
{
/// Returns a mutable iterator over the map.
pub fn iter_mut(&mut self) -> <&mut M as IntoIterator>::IntoIter {
<&mut Self as IntoIterator>::into_iter(self)
}
}
impl<M, OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for HitcountsIterableMapObserver<M>
where
M: MapObserver<Entry = u8> + Observer<S> + DifferentialObserver<OTA, OTB, S>,
for<'it> M: AsIterMut<'it, Item = u8>,
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
M: DifferentialObserver<OTA, OTB, I, S>
+ MapObserver<Entry = u8>
+ for<'it> AsIterMut<'it, Item = u8>,
{
fn pre_observe_first(&mut self, observers: &mut OTA) -> Result<(), Error> {
self.base.pre_observe_first(observers)
@ -589,3 +448,28 @@ where
self.base.post_observe_second(observers)
}
}
impl<'it, M> AsIter<'it> for HitcountsIterableMapObserver<M>
where
M: AsIter<'it>,
{
type Item = M::Item;
type Ref = M::Ref;
type IntoIter = M::IntoIter;
fn as_iter(&'it self) -> Self::IntoIter {
self.base.as_iter()
}
}
impl<'it, M> AsIterMut<'it> for HitcountsIterableMapObserver<M>
where
M: AsIterMut<'it>,
{
type RefMut = M::RefMut;
type IntoIterMut = M::IntoIterMut;
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
self.base.as_iter_mut()
}
}

View File

@ -5,18 +5,15 @@ use core::{
fmt::Debug,
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
slice::{Iter, IterMut},
};
use ahash::RandomState;
use libafl_bolts::{ownedref::OwnedMutSlice, AsSlice, AsSliceMut, HasLen, Named, Truncate};
use num_traits::Bounded;
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{
executors::ExitKind,
inputs::UsesInput,
observers::{DifferentialObserver, Observer, ObserversTuple},
observers::{DifferentialObserver, Observer},
Error,
};
@ -134,18 +131,6 @@ impl<T, const ITH: bool, const NTH: bool> CanTrack for ExplicitTracking<T, ITH,
}
}
impl<T, const ITH: bool, const NTH: bool> AsRef<T> for ExplicitTracking<T, ITH, NTH> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl<T, const ITH: bool, const NTH: bool> AsMut<T> for ExplicitTracking<T, ITH, NTH> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T, const ITH: bool, const NTH: bool> Named for ExplicitTracking<T, ITH, NTH>
where
T: Named,
@ -155,49 +140,40 @@ where
}
}
impl<S, T, const ITH: bool, const NTH: bool> Observer<S> for ExplicitTracking<T, ITH, NTH>
impl<S, I, T, const ITH: bool, const NTH: bool> Observer<I, S> for ExplicitTracking<T, ITH, NTH>
where
S: UsesInput,
T: Observer<S>,
T: Observer<I, S>,
{
fn flush(&mut self) -> Result<(), Error> {
self.0.flush()
}
fn pre_exec(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.0.pre_exec(state, input)
}
fn post_exec(
&mut self,
state: &mut S,
input: &S::Input,
exit_kind: &ExitKind,
) -> Result<(), Error> {
fn post_exec(&mut self, state: &mut S, input: &I, exit_kind: &ExitKind) -> Result<(), Error> {
self.0.post_exec(state, input, exit_kind)
}
fn pre_exec_child(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec_child(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.0.pre_exec_child(state, input)
}
fn post_exec_child(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error> {
self.0.post_exec_child(state, input, exit_kind)
}
}
impl<S, T, OTA, OTB, const ITH: bool, const NTH: bool> DifferentialObserver<OTA, OTB, S>
impl<T, OTA, OTB, I, S, const ITH: bool, const NTH: bool> DifferentialObserver<OTA, OTB, I, S>
for ExplicitTracking<T, ITH, NTH>
where
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
T: DifferentialObserver<OTA, OTB, S>,
T: DifferentialObserver<OTA, OTB, I, S>,
{
fn pre_observe_first(&mut self, observers: &mut OTA) -> Result<(), Error> {
self.as_mut().pre_observe_first(observers)
@ -216,6 +192,18 @@ where
}
}
impl<T, const ITH: bool, const NTH: bool> AsRef<T> for ExplicitTracking<T, ITH, NTH> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl<T, const ITH: bool, const NTH: bool> AsMut<T> for ExplicitTracking<T, ITH, NTH> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
/// Module which holds the necessary functions and types for map-relevant macros, namely
/// [`crate::require_index_tracking`] and [`crate::require_novelties_tracking`].
pub mod macros {
@ -362,12 +350,12 @@ pub mod macros {
///
/// TODO: enforce `iter() -> AssociatedTypeIter` when generic associated types stabilize
pub trait MapObserver:
HasLen + Named + Serialize + serde::de::DeserializeOwned + AsRef<Self> + AsMut<Self> + Hash
HasLen + Named + Serialize + DeserializeOwned + AsRef<Self> + AsMut<Self> + Hash
// where
// for<'it> &'it Self: IntoIterator<Item = &'it Self::Entry>
{
/// Type of each entry in this map
type Entry: Bounded + PartialEq + Default + Copy + Debug + Hash + 'static;
type Entry: PartialEq + Copy;
/// Get the value at `idx`
fn get(&self, idx: usize) -> Self::Entry;
@ -419,147 +407,42 @@ where
/// that will get updated by the target.
/// A well-known example is the AFL-Style coverage map.
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct StdMapObserver<'a, T, const DIFFERENTIAL: bool>
where
T: Default + Copy + 'static + Serialize,
{
pub struct StdMapObserver<'a, T, const DIFFERENTIAL: bool> {
map: OwnedMutSlice<'a, T>,
initial: T,
name: Cow<'static, str>,
}
impl<'a, S, T> Observer<S> for StdMapObserver<'a, T, false>
impl<'a, I, S, T> Observer<I, S> for StdMapObserver<'a, T, false>
where
S: UsesInput,
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
Self: MapObserver,
{
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.reset_map()
}
}
impl<'a, S, T> Observer<S> for StdMapObserver<'a, T, true>
where
S: UsesInput,
T: Bounded
+ PartialEq
+ Default
+ Copy
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
}
impl<'a, I, S, T> Observer<I, S> for StdMapObserver<'a, T, true> {}
impl<'a, T, const DIFFERENTIAL: bool> Named for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{
impl<'a, T, const DIFFERENTIAL: bool> Named for StdMapObserver<'a, T, DIFFERENTIAL> {
#[inline]
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a, T, const DIFFERENTIAL: bool> HasLen for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{
impl<'a, T, const DIFFERENTIAL: bool> HasLen for StdMapObserver<'a, T, DIFFERENTIAL> {
#[inline]
fn len(&self) -> usize {
self.map.as_slice().len()
}
}
impl<'a, 'it, T, const DIFFERENTIAL: bool> IntoIterator for &'it StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
type Item = <Iter<'it, T> as Iterator>::Item;
type IntoIter = Iter<'it, T>;
fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count();
self.as_slice()[..cnt].iter()
}
}
impl<'a, 'it, T, const DIFFERENTIAL: bool> IntoIterator
for &'it mut StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
type Item = <IterMut<'it, T> as Iterator>::Item;
type IntoIter = IterMut<'it, T>;
fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count();
self.as_slice_mut()[..cnt].iter_mut()
}
}
impl<'a, T, const DIFFERENTIAL: bool> StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
/// Returns an iterator over the map.
pub fn iter(&self) -> Iter<'_, T> {
<&Self as IntoIterator>::into_iter(self)
}
/// Returns a mutable iterator over the map.
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
<&mut Self as IntoIterator>::into_iter(self)
}
}
impl<'a, T, const DIFFERENTIAL: bool> Hash for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
T: Hash,
{
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
@ -567,19 +450,13 @@ where
}
}
impl<'a, T, const DIFFERENTIAL: bool> AsRef<Self> for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Default + Copy + 'static + Serialize,
{
impl<'a, T, const DIFFERENTIAL: bool> AsRef<Self> for StdMapObserver<'a, T, DIFFERENTIAL> {
fn as_ref(&self) -> &Self {
self
}
}
impl<'a, T, const DIFFERENTIAL: bool> AsMut<Self> for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Default + Copy + 'static + Serialize,
{
impl<'a, T, const DIFFERENTIAL: bool> AsMut<Self> for StdMapObserver<'a, T, DIFFERENTIAL> {
fn as_mut(&mut self) -> &mut Self {
self
}
@ -587,15 +464,7 @@ where
impl<'a, T, const DIFFERENTIAL: bool> MapObserver for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
T: PartialEq + Copy + Hash + Serialize + DeserializeOwned + Debug,
{
type Entry = T;
@ -668,36 +537,20 @@ where
}
}
impl<'a, T, const DIFFERENTIAL: bool> Truncate for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
impl<'a, T, const DIFFERENTIAL: bool> Truncate for StdMapObserver<'a, T, DIFFERENTIAL> {
fn truncate(&mut self, new_len: usize) {
self.map.truncate(new_len);
}
}
impl<'a, T, const DIFFERENTIAL: bool> Deref for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<'a, T, const DIFFERENTIAL: bool> Deref for StdMapObserver<'a, T, DIFFERENTIAL> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.map
}
}
impl<'a, T, const DIFFERENTIAL: bool> DerefMut for StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<'a, T, const DIFFERENTIAL: bool> DerefMut for StdMapObserver<'a, T, DIFFERENTIAL> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.map
}
@ -705,7 +558,7 @@ where
impl<'a, T, const DIFFERENTIAL: bool> StdMapObserver<'a, T, DIFFERENTIAL>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
T: Default,
{
/// Creates a new [`MapObserver`]
///
@ -796,7 +649,7 @@ where
impl<'a, T> StdMapObserver<'a, T, false>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
T: Default,
{
/// Creates a new [`MapObserver`]
///
@ -854,7 +707,7 @@ where
impl<'a, T> StdMapObserver<'a, T, true>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
T: Default,
{
/// Creates a new [`MapObserver`] in differential mode
///
@ -902,18 +755,4 @@ where
}
}
impl<'a, OTA, OTB, S, T> DifferentialObserver<OTA, OTB, S> for StdMapObserver<'a, T, true>
where
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
T: Bounded
+ PartialEq
+ Default
+ Copy
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
{
}
impl<'a, OTA, OTB, I, S, T> DifferentialObserver<OTA, OTB, I, S> for StdMapObserver<'a, T, true> {}

View File

@ -5,8 +5,7 @@ use core::{
fmt::Debug,
hash::{Hash, Hasher},
iter::Flatten,
mem::size_of,
slice::{self, Iter, IterMut},
slice::{Iter, IterMut},
};
use ahash::RandomState;
@ -14,23 +13,17 @@ use libafl_bolts::{
ownedref::OwnedMutSlice, AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named,
};
use meminterval::IntervalTree;
use num_traits::Bounded;
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{
inputs::UsesInput,
observers::{map::MapObserver, DifferentialObserver, Observer, ObserversTuple},
observers::{map::MapObserver, DifferentialObserver, Observer},
Error,
};
/// The Multi Map Observer merge different maps into one observer
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct MultiMapObserver<'a, T, const DIFFERENTIAL: bool>
where
T: 'static + Default + Copy + Serialize + Debug,
{
pub struct MultiMapObserver<'a, T, const DIFFERENTIAL: bool> {
maps: Vec<OwnedMutSlice<'a, T>>,
intervals: IntervalTree<usize, usize>,
len: usize,
@ -39,41 +32,28 @@ where
iter_idx: usize,
}
impl<'a, S, T> Observer<S> for MultiMapObserver<'a, T, false>
impl<'a, I, S, T> Observer<I, S> for MultiMapObserver<'a, T, false>
where
S: UsesInput,
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
Self: MapObserver,
{
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.reset_map()
}
}
impl<'a, S, T> Observer<S> for MultiMapObserver<'a, T, true>
where
S: UsesInput,
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
Self: MapObserver,
{
impl<'a, I, S, T> Observer<I, S> for MultiMapObserver<'a, T, true> {
// in differential mode, we are *not* responsible for resetting the map!
}
impl<'a, T, const DIFFERENTIAL: bool> Named for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<'a, T, const DIFFERENTIAL: bool> Named for MultiMapObserver<'a, T, DIFFERENTIAL> {
#[inline]
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a, T, const DIFFERENTIAL: bool> HasLen for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<'a, T, const DIFFERENTIAL: bool> HasLen for MultiMapObserver<'a, T, DIFFERENTIAL> {
#[inline]
fn len(&self) -> usize {
self.len
@ -82,33 +62,24 @@ where
impl<'a, T, const DIFFERENTIAL: bool> Hash for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
T: Hash,
{
fn hash<H: Hasher>(&self, hasher: &mut H) {
for map in &self.maps {
let slice = map.as_slice();
let ptr = slice.as_ptr() as *const u8;
let map_size = slice.len() / size_of::<T>();
unsafe {
hasher.write(slice::from_raw_parts(ptr, map_size));
}
slice.hash(hasher);
}
}
}
impl<'a, T, const DIFFERENTIAL: bool> AsRef<Self> for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + Debug,
{
impl<'a, T, const DIFFERENTIAL: bool> AsRef<Self> for MultiMapObserver<'a, T, DIFFERENTIAL> {
fn as_ref(&self) -> &Self {
self
}
}
impl<'a, T, const DIFFERENTIAL: bool> AsMut<Self> for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + Debug,
{
impl<'a, T, const DIFFERENTIAL: bool> AsMut<Self> for MultiMapObserver<'a, T, DIFFERENTIAL> {
fn as_mut(&mut self) -> &mut Self {
self
}
@ -116,15 +87,7 @@ where
impl<'a, T, const DIFFERENTIAL: bool> MapObserver for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static
+ Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
T: PartialEq + Copy + Hash + Serialize + DeserializeOwned + Debug,
{
type Entry = T;
@ -206,7 +169,7 @@ where
impl<'a, T, const DIFFERENTIAL: bool> MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
T: Default,
{
/// Creates a new [`MultiMapObserver`], maybe in differential mode
#[must_use]
@ -231,7 +194,7 @@ where
impl<'a, T> MultiMapObserver<'a, T, true>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
T: Default,
{
/// Creates a new [`MultiMapObserver`] in differential mode
#[must_use]
@ -242,7 +205,7 @@ where
impl<'a, T> MultiMapObserver<'a, T, false>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
T: Default,
{
/// Creates a new [`MultiMapObserver`]
#[must_use]
@ -279,7 +242,7 @@ where
impl<'a, 'it, T, const DIFFERENTIAL: bool> AsIter<'it> for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
T: 'a,
'a: 'it,
{
type Item = T;
@ -293,7 +256,7 @@ where
impl<'a, 'it, T, const DIFFERENTIAL: bool> AsIterMut<'it> for MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
T: 'a,
'a: 'it,
{
type RefMut = &'it mut T;
@ -304,53 +267,4 @@ where
}
}
impl<'a, 'it, T, const DIFFERENTIAL: bool> IntoIterator
for &'it MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
type Item = <Iter<'it, T> as Iterator>::Item;
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'a, T>>>;
fn into_iter(self) -> Self::IntoIter {
self.maps.iter().flatten()
}
}
impl<'a, 'it, T, const DIFFERENTIAL: bool> IntoIterator
for &'it mut MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
type Item = <IterMut<'it, T> as Iterator>::Item;
type IntoIter = Flatten<IterMut<'it, OwnedMutSlice<'a, T>>>;
fn into_iter(self) -> Self::IntoIter {
self.maps.iter_mut().flatten()
}
}
impl<'a, T, const DIFFERENTIAL: bool> MultiMapObserver<'a, T, DIFFERENTIAL>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
/// Returns an iterator over the map.
pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
<&Self as IntoIterator>::into_iter(self)
}
/// Returns a mutable iterator over the map.
pub fn iter_mut(&mut self) -> <&mut Self as IntoIterator>::IntoIter {
<&mut Self as IntoIterator>::into_iter(self)
}
}
impl<'a, T, OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for MultiMapObserver<'a, T, true>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
Self: MapObserver,
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
}
impl<'a, OTA, OTB, I, S, T> DifferentialObserver<OTA, OTB, I, S> for MultiMapObserver<'a, T, true> {}

View File

@ -5,107 +5,53 @@ use core::{
fmt::Debug,
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
slice::{Iter, IterMut},
};
use ahash::RandomState;
use libafl_bolts::{AsSlice, AsSliceMut, HasLen, Named};
use num_traits::Bounded;
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{
inputs::UsesInput,
observers::{map::MapObserver, Observer},
Error,
};
/// Exact copy of `StdMapObserver` that owns its map
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize,
{
pub struct OwnedMapObserver<T> {
map: Vec<T>,
initial: T,
name: Cow<'static, str>,
}
impl<S, T> Observer<S> for OwnedMapObserver<T>
impl<I, S, T> Observer<I, S> for OwnedMapObserver<T>
where
S: UsesInput,
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
Self: MapObserver,
{
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.reset_map()
}
}
impl<T> Named for OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned,
{
impl<T> Named for OwnedMapObserver<T> {
#[inline]
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<T> HasLen for OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned,
{
impl<T> HasLen for OwnedMapObserver<T> {
#[inline]
fn len(&self) -> usize {
self.map.as_slice().len()
}
}
impl<'it, T> IntoIterator for &'it OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
type Item = <Iter<'it, T> as Iterator>::Item;
type IntoIter = Iter<'it, T>;
fn into_iter(self) -> Self::IntoIter {
self.as_slice().iter()
}
}
impl<'it, T> IntoIterator for &'it mut OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
type Item = <IterMut<'it, T> as Iterator>::Item;
type IntoIter = IterMut<'it, T>;
fn into_iter(self) -> Self::IntoIter {
self.as_slice_mut().iter_mut()
}
}
impl<T> OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
/// Returns an iterator over the map.
pub fn iter(&self) -> Iter<'_, T> {
<&Self as IntoIterator>::into_iter(self)
}
/// Returns a mutable iterator over the map.
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
<&mut Self as IntoIterator>::into_iter(self)
}
}
impl<T> Hash for OwnedMapObserver<T>
where
T: 'static + Hash + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
T: Hash,
{
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
@ -113,19 +59,13 @@ where
}
}
impl<T> AsRef<Self> for OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize,
{
impl<T> AsRef<Self> for OwnedMapObserver<T> {
fn as_ref(&self) -> &Self {
self
}
}
impl<T> AsMut<Self> for OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize,
{
impl<T> AsMut<Self> for OwnedMapObserver<T> {
fn as_mut(&mut self) -> &mut Self {
self
}
@ -133,15 +73,7 @@ where
impl<T> MapObserver for OwnedMapObserver<T>
where
T: 'static
+ Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ Serialize
+ serde::de::DeserializeOwned
+ Debug,
T: PartialEq + Copy + Hash + Serialize + DeserializeOwned + Debug,
{
type Entry = T;
@ -214,10 +146,7 @@ where
}
}
impl<T> Deref for OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<T> Deref for OwnedMapObserver<T> {
type Target = [T];
fn deref(&self) -> &[T] {
@ -225,10 +154,7 @@ where
}
}
impl<T> DerefMut for OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{
impl<T> DerefMut for OwnedMapObserver<T> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.map
}
@ -236,7 +162,7 @@ where
impl<T> OwnedMapObserver<T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned,
T: Copy + Default,
{
/// Creates a new [`MapObserver`] with an owned map
#[must_use]

View File

@ -5,7 +5,6 @@ use core::{
fmt::Debug,
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
slice::{Iter, IterMut},
};
use ahash::RandomState;
@ -13,152 +12,50 @@ use libafl_bolts::{
ownedref::{OwnedMutPtr, OwnedMutSlice},
AsSlice, AsSliceMut, HasLen, Named,
};
use num_traits::Bounded;
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{
inputs::UsesInput,
observers::{map::MapObserver, Observer},
Error,
};
/// Overlooking a variable bitmap
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct VariableMapObserver<'a, T>
where
T: Default + Copy + 'static + Serialize + PartialEq + Bounded,
{
pub struct VariableMapObserver<'a, T> {
map: OwnedMutSlice<'a, T>,
size: OwnedMutPtr<usize>,
initial: T,
name: Cow<'static, str>,
}
impl<'a, S, T> Observer<S> for VariableMapObserver<'a, T>
impl<'a, I, S, T> Observer<I, S> for VariableMapObserver<'a, T>
where
S: UsesInput,
T: Default
+ Copy
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ Bounded
+ PartialEq,
Self: MapObserver,
{
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.reset_map()
}
}
impl<'a, T> Named for VariableMapObserver<'a, T>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Bounded + PartialEq,
{
impl<'a, T> Named for VariableMapObserver<'a, T> {
#[inline]
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a, T> HasLen for VariableMapObserver<'a, T>
where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + PartialEq + Bounded,
{
impl<'a, T> HasLen for VariableMapObserver<'a, T> {
#[inline]
fn len(&self) -> usize {
*self.size.as_ref()
}
}
impl<'a, 'it, T> IntoIterator for &'it VariableMapObserver<'a, T>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ PartialEq
+ Bounded,
{
type Item = <Iter<'it, T> as Iterator>::Item;
type IntoIter = Iter<'it, T>;
fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count();
self.as_slice()[..cnt].iter()
}
}
impl<'a, 'it, T> IntoIterator for &'it mut VariableMapObserver<'a, T>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ PartialEq
+ Bounded,
{
type Item = <IterMut<'it, T> as Iterator>::Item;
type IntoIter = IterMut<'it, T>;
fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count();
self.as_slice_mut()[..cnt].iter_mut()
}
}
impl<'a, T> VariableMapObserver<'a, T>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ PartialEq
+ Bounded,
{
/// Returns an iterator over the map.
pub fn iter(&self) -> Iter<'_, T> {
<&Self as IntoIterator>::into_iter(self)
}
/// Returns a mutable iterator over the map.
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
<&mut Self as IntoIterator>::into_iter(self)
}
}
impl<'a, T> Hash for VariableMapObserver<'a, T>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ PartialEq
+ Bounded,
T: Hash,
{
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
@ -166,19 +63,13 @@ where
}
}
impl<'a, T> AsRef<Self> for VariableMapObserver<'a, T>
where
T: Default + Copy + 'static + Serialize + PartialEq + Bounded,
{
impl<'a, T> AsRef<Self> for VariableMapObserver<'a, T> {
fn as_ref(&self) -> &Self {
self
}
}
impl<'a, T> AsMut<Self> for VariableMapObserver<'a, T>
where
T: Default + Copy + 'static + Serialize + PartialEq + Bounded,
{
impl<'a, T> AsMut<Self> for VariableMapObserver<'a, T> {
fn as_mut(&mut self) -> &mut Self {
self
}
@ -186,17 +77,7 @@ where
impl<'a, T> MapObserver for VariableMapObserver<'a, T>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ PartialEq
+ Bounded,
T: PartialEq + Copy + Hash + Serialize + DeserializeOwned + Debug,
{
type Entry = T;
@ -268,48 +149,24 @@ where
}
}
impl<'a, T> Deref for VariableMapObserver<'a, T>
where
T: Bounded
+ PartialEq
+ Default
+ Copy
+ Hash
+ 'static
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ PartialEq
+ Bounded,
{
impl<'a, T> Deref for VariableMapObserver<'a, T> {
type Target = [T];
fn deref(&self) -> &[T] {
let cnt = self.usable_count();
let cnt = *self.size.as_ref();
&self.map[..cnt]
}
}
impl<'a, T> DerefMut for VariableMapObserver<'a, T>
where
T: 'static
+ Default
+ Copy
+ Hash
+ Serialize
+ serde::de::DeserializeOwned
+ Debug
+ PartialEq
+ Bounded,
{
impl<'a, T> DerefMut for VariableMapObserver<'a, T> {
fn deref_mut(&mut self) -> &mut [T] {
let cnt = self.usable_count();
let cnt = *self.size.as_ref();
&mut self.map[..cnt]
}
}
impl<'a, T> VariableMapObserver<'a, T>
where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + PartialEq + Bounded,
T: Default,
{
/// Creates a new [`MapObserver`] from an [`OwnedMutSlice`]
///

View File

@ -39,14 +39,11 @@ pub use list::*;
use serde::{Deserialize, Serialize};
pub use value::*;
use crate::{executors::ExitKind, inputs::UsesInput, state::UsesState, Error};
use crate::{executors::ExitKind, Error};
/// Observers observe different information about the target.
/// They can then be used by various sorts of feedback.
pub trait Observer<S>: Named
where
S: UsesInput,
{
pub trait Observer<I, S>: Named {
/// The testcase finished execution, calculate any changes.
/// Reserved for future use.
#[inline]
@ -56,7 +53,7 @@ where
/// Called right before execution starts.
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
Ok(())
}
@ -65,7 +62,7 @@ where
fn post_exec(
&mut self,
_state: &mut S,
_input: &S::Input,
_input: &I,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
Ok(())
@ -73,7 +70,7 @@ where
/// Called right before execution starts in the child process, if any.
#[inline]
fn pre_exec_child(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec_child(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
Ok(())
}
@ -82,86 +79,72 @@ where
fn post_exec_child(
&mut self,
_state: &mut S,
_input: &S::Input,
_input: &I,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
Ok(())
}
}
/// Defines the observer type shared across traits of the type.
/// Needed for consistency across HasCorpus/HasSolutions and friends.
pub trait UsesObservers: UsesState {
/// The observers type
type Observers: ObserversTuple<Self::State>;
}
/// A haskell-style tuple of observers
pub trait ObserversTuple<S>: MatchName
where
S: UsesInput,
{
pub trait ObserversTuple<I, S>: MatchName {
/// This is called right before the next execution.
fn pre_exec_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error>;
fn pre_exec_all(&mut self, state: &mut S, input: &I) -> Result<(), Error>;
/// This is called right after the last execution
fn post_exec_all(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error>;
/// This is called right before the next execution in the child process, if any.
fn pre_exec_child_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error>;
fn pre_exec_child_all(&mut self, state: &mut S, input: &I) -> Result<(), Error>;
/// This is called right after the last execution in the child process, if any.
fn post_exec_child_all(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error>;
}
impl<S> ObserversTuple<S> for ()
where
S: UsesInput,
{
fn pre_exec_all(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
impl<I, S> ObserversTuple<I, S> for () {
fn pre_exec_all(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
Ok(())
}
fn post_exec_all(
&mut self,
_state: &mut S,
_input: &S::Input,
_input: &I,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
Ok(())
}
fn pre_exec_child_all(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec_child_all(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
Ok(())
}
fn post_exec_child_all(
&mut self,
_state: &mut S,
_input: &S::Input,
_input: &I,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
Ok(())
}
}
impl<Head, Tail, S> ObserversTuple<S> for (Head, Tail)
impl<Head, Tail, I, S> ObserversTuple<I, S> for (Head, Tail)
where
Head: Observer<S>,
Tail: ObserversTuple<S>,
S: UsesInput,
Head: Observer<I, S>,
Tail: ObserversTuple<I, S>,
{
fn pre_exec_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec_all(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.0.pre_exec(state, input)?;
self.1.pre_exec_all(state, input)
}
@ -169,14 +152,14 @@ where
fn post_exec_all(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error> {
self.0.post_exec(state, input, exit_kind)?;
self.1.post_exec_all(state, input, exit_kind)
}
fn pre_exec_child_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec_child_all(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.0.pre_exec_child(state, input)?;
self.1.pre_exec_child_all(state, input)
}
@ -184,7 +167,7 @@ where
fn post_exec_child_all(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error> {
self.0.post_exec_child(state, input, exit_kind)?;
@ -219,12 +202,7 @@ pub trait ObserverWithHashField {
/// `DifferentialObserver::{pre,post}_observe_{first,second}` as necessary for first and second,
/// respectively.
#[allow(unused_variables)]
pub trait DifferentialObserver<OTA, OTB, S>: Observer<S>
where
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
pub trait DifferentialObserver<OTA, OTB, I, S>: Observer<I, S> {
/// Perform an operation with the first set of observers before they are `pre_exec`'d.
fn pre_observe_first(&mut self, observers: &mut OTA) -> Result<(), Error> {
Ok(())
@ -247,12 +225,7 @@ where
}
/// Differential observers tuple, for when you're using multiple differential observers.
pub trait DifferentialObserversTuple<OTA, OTB, S>: ObserversTuple<S>
where
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
pub trait DifferentialObserversTuple<OTA, OTB, I, S>: ObserversTuple<I, S> {
/// Perform an operation with the first set of observers before they are `pre_exec`'d on all the
/// differential observers in this tuple.
fn pre_observe_first_all(&mut self, observers: &mut OTA) -> Result<(), Error>;
@ -270,12 +243,7 @@ where
fn post_observe_second_all(&mut self, observers: &mut OTB) -> Result<(), Error>;
}
impl<OTA, OTB, S> DifferentialObserversTuple<OTA, OTB, S> for ()
where
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
impl<OTA, OTB, I, S> DifferentialObserversTuple<OTA, OTB, I, S> for () {
fn pre_observe_first_all(&mut self, _: &mut OTA) -> Result<(), Error> {
Ok(())
}
@ -293,13 +261,10 @@ where
}
}
impl<Head, Tail, OTA, OTB, S> DifferentialObserversTuple<OTA, OTB, S> for (Head, Tail)
impl<Head, Tail, OTA, OTB, I, S> DifferentialObserversTuple<OTA, OTB, I, S> for (Head, Tail)
where
Head: DifferentialObserver<OTA, OTB, S>,
Tail: DifferentialObserversTuple<OTA, OTB, S>,
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
Head: DifferentialObserver<OTA, OTB, I, S>,
Tail: DifferentialObserversTuple<OTA, OTB, I, S>,
{
fn pre_observe_first_all(&mut self, observers: &mut OTA) -> Result<(), Error> {
self.0.pre_observe_first(observers)?;
@ -387,19 +352,16 @@ impl TimeObserver {
}
}
impl<S> Observer<S> for TimeObserver
where
S: UsesInput,
{
impl<I, S> Observer<I, S> for TimeObserver {
#[cfg(feature = "std")]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.last_runtime = None;
self.start_time = Instant::now();
Ok(())
}
#[cfg(not(feature = "std"))]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.last_runtime = None;
self.start_time = current_time();
Ok(())
@ -409,7 +371,7 @@ where
fn post_exec(
&mut self,
_state: &mut S,
_input: &S::Input,
_input: &I,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
self.last_runtime = Some(self.start_time.elapsed());
@ -420,7 +382,7 @@ where
fn post_exec(
&mut self,
_state: &mut S,
_input: &S::Input,
_input: &I,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
self.last_runtime = current_time().checked_sub(self.start_time);
@ -434,13 +396,7 @@ impl Named for TimeObserver {
}
}
impl<OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for TimeObserver
where
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
}
impl<OTA, OTB, I, S> DifferentialObserver<OTA, OTB, I, S> for TimeObserver {}
#[cfg(feature = "std")]
#[cfg(test)]

View File

@ -5,7 +5,7 @@ use hashbrown::HashMap;
use libafl_bolts::{ownedref::OwnedMutPtr, Named};
use serde::{Deserialize, Serialize};
use crate::{inputs::UsesInput, observers::Observer, state::State, Error};
use crate::{observers::Observer, Error};
#[derive(Debug, Serialize, Deserialize)]
/// The json data
pub struct FunctionData {
@ -124,14 +124,11 @@ impl Named for ProfilingObserver {
}
}
impl<S> Observer<S> for ProfilingObserver
where
S: State,
{
impl<I, S> Observer<I, S> for ProfilingObserver {
fn post_exec(
&mut self,
_state: &mut S,
_input: &<S as UsesInput>::Input,
_input: &I,
_exit_kind: &crate::executors::ExitKind,
) -> Result<(), Error> {
// in reality, this should be done in a stage

View File

@ -39,7 +39,7 @@ use regex::Regex;
use serde::{Deserialize, Serialize};
use super::ObserverWithHashField;
use crate::{executors::ExitKind, inputs::UsesInput, observers::Observer, Error};
use crate::{executors::ExitKind, observers::Observer, Error};
#[cfg(not(feature = "casr"))]
/// Collects the backtrace via [`Backtrace`] and [`Debug`]
@ -196,16 +196,8 @@ impl<'a> ObserverWithHashField for BacktraceObserver<'a> {
}
}
impl<'a, S> Observer<S> for BacktraceObserver<'a>
where
S: UsesInput,
{
fn post_exec(
&mut self,
_state: &mut S,
_input: &S::Input,
exit_kind: &ExitKind,
) -> Result<(), Error> {
impl<'a, I, S> Observer<I, S> for BacktraceObserver<'a> {
fn post_exec(&mut self, _state: &mut S, _input: &I, exit_kind: &ExitKind) -> Result<(), Error> {
if self.harness_type == HarnessType::InProcess {
if *exit_kind == ExitKind::Crash {
self.update_hash(collect_backtrace());
@ -218,18 +210,11 @@ where
fn post_exec_child(
&mut self,
_state: &mut S,
_input: &S::Input,
state: &mut S,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error> {
if self.harness_type == HarnessType::Child {
if *exit_kind == ExitKind::Crash {
self.update_hash(collect_backtrace());
} else {
self.clear_hash();
}
}
Ok(())
self.post_exec(state, input, exit_kind)
}
}
@ -373,23 +358,7 @@ impl Default for AsanBacktraceObserver {
}
}
impl<S> Observer<S> for AsanBacktraceObserver
where
S: UsesInput,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
Ok(())
}
fn post_exec(
&mut self,
_state: &mut S,
_input: &S::Input,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
Ok(())
}
}
impl<I, S> Observer<I, S> for AsanBacktraceObserver {}
impl Named for AsanBacktraceObserver {
fn name(&self) -> &Cow<'static, str> {

View File

@ -10,7 +10,7 @@ use std::vec::Vec;
use libafl_bolts::Named;
use serde::{Deserialize, Serialize};
use crate::{inputs::UsesInput, observers::Observer, state::State, Error};
use crate::{observers::Observer, Error};
/// An observer that captures stdout of a target.
/// Only works for supported executors.
@ -67,7 +67,7 @@ use crate::{inputs::UsesInput, observers::Observer, state::State, Error};
/// ) -> Result<bool, Error>
/// where
/// EM: EventFirer<State = S>,
/// OT: ObserversTuple<S>,
/// OT: ObserversTuple<S::Input, S>,
/// {
/// unsafe {
/// STDOUT = observers.get(&self.stdout_observer).unwrap().stdout.clone();
@ -198,20 +198,13 @@ impl Named for StdOutObserver {
}
}
impl<S> Observer<S> for StdOutObserver
where
S: State,
{
fn pre_exec_child(
&mut self,
_state: &mut S,
_input: &<S as UsesInput>::Input,
) -> Result<(), Error> {
impl<I, S> Observer<I, S> for StdOutObserver {
fn pre_exec_child(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.stdout = None;
Ok(())
}
fn pre_exec(&mut self, _state: &mut S, _input: &<S as UsesInput>::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.stdout = None;
Ok(())
}
@ -252,20 +245,13 @@ impl Named for StdErrObserver {
}
}
impl<S> Observer<S> for StdErrObserver
where
S: State,
{
fn pre_exec_child(
&mut self,
_state: &mut S,
_input: &<S as UsesInput>::Input,
) -> Result<(), Error> {
impl<I, S> Observer<I, S> for StdErrObserver {
fn pre_exec_child(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.stderr = None;
Ok(())
}
fn pre_exec(&mut self, _state: &mut S, _input: &<S as UsesInput>::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.stderr = None;
Ok(())
}

View File

@ -9,32 +9,28 @@ use core::{
};
use ahash::RandomState;
use libafl_bolts::{ownedref::OwnedRef, AsIter, AsIterMut, AsSlice, AsSliceMut, Named};
use serde::{Deserialize, Serialize};
use libafl_bolts::{ownedref::OwnedRef, AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use super::Observer;
use crate::{inputs::UsesInput, observers::ObserverWithHashField, Error};
use crate::{
observers::{MapObserver, ObserverWithHashField},
Error,
};
/// A simple observer with a single value.
///
/// The intent is that the value is something with interior mutability which the target could write to even though this
/// observer has a reference to it. Use [`RefCellValueObserver`] if using a [`RefCell`] around the value.
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct ValueObserver<'a, T>
where
T: Debug + Serialize,
{
pub struct ValueObserver<'a, T> {
/// The name of this observer.
name: Cow<'static, str>,
/// The value.
pub value: OwnedRef<'a, T>,
}
impl<'a, T> ValueObserver<'a, T>
where
T: Debug + Serialize + serde::de::DeserializeOwned,
{
impl<'a, T> ValueObserver<'a, T> {
/// Creates a new [`ValueObserver`] with the given name.
#[must_use]
pub fn new(name: &'static str, value: OwnedRef<'a, T>) -> Self {
@ -70,29 +66,15 @@ where
}
/// This *does not* reset the value inside the observer.
impl<'a, S, T> Observer<S> for ValueObserver<'a, T>
where
S: UsesInput,
T: Debug + Serialize + serde::de::DeserializeOwned,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
Ok(())
}
}
impl<'a, I, S, T> Observer<I, S> for ValueObserver<'a, T> {}
impl<'a, T> Named for ValueObserver<'a, T>
where
T: Debug + Serialize + serde::de::DeserializeOwned,
{
impl<'a, T> Named for ValueObserver<'a, T> {
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a, T: Hash> ObserverWithHashField for ValueObserver<'a, T>
where
T: Debug + Serialize + serde::de::DeserializeOwned,
{
impl<'a, T: Hash> ObserverWithHashField for ValueObserver<'a, T> {
fn hash(&self) -> Option<u64> {
Some(RandomState::with_seeds(1, 2, 3, 4).hash_one(self.value.as_ref()))
}
@ -100,7 +82,6 @@ where
/// A simple observer with a single [`RefCell`]'d value.
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned + serde::Serialize")]
pub struct RefCellValueObserver<'a, T> {
/// The name of this observer.
name: Cow<'static, str>,
@ -160,14 +141,7 @@ impl<'a, T> RefCellValueObserver<'a, T> {
}
/// This *does not* reset the value inside the observer.
impl<'a, S, T> Observer<S> for RefCellValueObserver<'a, T>
where
S: UsesInput,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
Ok(())
}
}
impl<'a, I, S, T> Observer<I, S> for RefCellValueObserver<'a, T> {}
impl<'a, T> Named for RefCellValueObserver<'a, T> {
fn name(&self) -> &Cow<'static, str> {
@ -239,7 +213,7 @@ pub struct RefCellValueObserverIterMut<'it, T> {
v: Option<RefMut<'it, [T]>>,
}
impl<'it, T: 'it, A: Debug + DerefMut<Target = [T]> + Serialize> AsIterMut<'it>
impl<'it, T: 'it, A: DerefMut<Target = [T]> + Serialize> AsIterMut<'it>
for RefCellValueObserver<'_, A>
{
type RefMut = RefMut<'it, T>;
@ -274,25 +248,20 @@ impl<'it, T: 'it> Iterator for RefCellValueObserverIterMut<'it, T> {
}
}
impl<'a, T: Hash, A> Hash for RefCellValueObserver<'a, A>
where
T: Debug,
A: Debug + Deref<Target = [T]> + Serialize + serde::de::DeserializeOwned,
{
impl<'a, A: Hash> Hash for RefCellValueObserver<'a, A> {
/// Panics if the contained value is already mutably borrowed (calls
/// [`RefCell::borrow`]).
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
(*self.get_ref()).hash(hasher);
self.get_ref().hash(hasher);
}
}
/// Panics if the contained value is already mutably borrowed (calls
/// [`RefCell::borrow`]).
impl<T, A> libafl_bolts::HasLen for RefCellValueObserver<'_, A>
impl<A> HasLen for RefCellValueObserver<'_, A>
where
T: Debug,
A: Debug + Deref<Target = [T]> + Serialize + serde::de::DeserializeOwned,
A: HasLen,
{
/// Panics if the contained value is already mutably borrowed (calls
/// [`RefCell::borrow`]).
@ -307,32 +276,21 @@ where
}
}
impl<T: Debug + Serialize + serde::de::DeserializeOwned> AsMut<Self>
for RefCellValueObserver<'_, T>
{
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<T: Debug + Serialize + serde::de::DeserializeOwned> AsRef<Self>
for RefCellValueObserver<'_, T>
{
impl<T> AsRef<Self> for RefCellValueObserver<'_, T> {
fn as_ref(&self) -> &Self {
self
}
}
impl<T, A> crate::observers::MapObserver for RefCellValueObserver<'_, A>
impl<T> AsMut<Self> for RefCellValueObserver<'_, T> {
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<T, A> MapObserver for RefCellValueObserver<'_, A>
where
T: Copy + Debug + Default + Eq + Hash + num_traits::bounds::Bounded + 'static,
A: Debug
+ Default
+ Deref<Target = [T]>
+ DerefMut<Target = [T]>
+ serde::de::DeserializeOwned
+ Serialize
+ 'static,
T: PartialEq + Copy + Hash + Default + DeserializeOwned + Serialize + Debug,
A: DerefMut<Target = [T]> + Hash + Serialize + DeserializeOwned + HasLen + Default,
{
type Entry = T;
@ -385,7 +343,7 @@ where
/// Panics if the contained value is already mutably borrowed (calls
/// [`RefCell::borrow`]).
fn to_vec(&self) -> Vec<Self::Entry> {
(*self.get_ref()).to_vec()
self.get_ref().to_vec()
}
/// Panics if the contained value is already mutably borrowed (calls

View File

@ -18,6 +18,7 @@ use crate::{
executors::{Executor, ExitKind, HasObservers},
feedbacks::{map::MapFeedbackMetadata, HasObserverHandle},
fuzzer::Evaluator,
inputs::UsesInput,
monitors::{AggregatorOps, UserStats, UserStatsValue},
observers::{MapObserver, ObserversTuple},
schedulers::powersched::SchedulerMetadata,
@ -98,8 +99,9 @@ where
EM: EventFirer<State = Self::State>,
O: MapObserver,
C: AsRef<O>,
for<'de> <O as MapObserver>::Entry: Serialize + Deserialize<'de> + 'static,
OT: ObserversTuple<Self::State>,
for<'de> <O as MapObserver>::Entry:
Serialize + Deserialize<'de> + 'static + Default + Debug + Bounded,
OT: ObserversTuple<Self::Input, Self::State>,
E::State: HasCorpus + HasMetadata + HasNamedMetadata + HasExecutions + HasCurrentTestcase,
Z: Evaluator<E, EM, State = Self::State>,
<<E as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, //delete me
@ -382,7 +384,7 @@ where
O: MapObserver,
for<'it> O: AsIter<'it, Item = O::Entry>,
C: AsRef<O>,
OT: ObserversTuple<<Self as UsesState>::State>,
OT: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
E: UsesState,
{
/// Create a new [`CalibrationStage`].

View File

@ -17,7 +17,7 @@ use crate::{
corpus::Corpus,
events::EventFirer,
executors::{Executor, HasObservers},
inputs::HasMutatorBytes,
inputs::{HasMutatorBytes, UsesInput},
mutators::mutations::buffer_copy,
observers::{MapObserver, ObserversTuple},
stages::{RetryCountRestartHelper, Stage},
@ -89,6 +89,7 @@ where
EM: UsesState<State = Self::State> + EventFirer,
E: HasObservers + Executor<EM, Z>,
E::State: HasCorpus + HasMetadata + HasRand + HasNamedMetadata,
E::Observers: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
E::Input: HasMutatorBytes,
O: MapObserver,
C: AsRef<O> + Named,
@ -167,6 +168,7 @@ where
O: MapObserver,
C: AsRef<O> + Named,
E: HasObservers + Executor<EM, Z>,
E::Observers: ObserversTuple<<Self as UsesInput>::Input, <Self as UsesState>::State>,
<E as UsesState>::State: HasCorpus + HasMetadata + HasRand,
E::Input: HasMutatorBytes,
Z: UsesState<State = <Self as UsesState>::State>,

View File

@ -19,7 +19,7 @@ use crate::state::HasClientPerfMonitor;
use crate::{
corpus::Corpus,
executors::{Executor, HasObservers},
observers::concolic::ConcolicObserver,
observers::{concolic::ConcolicObserver, ObserversTuple},
stages::{RetryCountRestartHelper, Stage, TracingStage},
state::{HasCorpus, HasCurrentTestcase, HasExecutions, UsesState},
Error, HasMetadata, HasNamedMetadata,
@ -63,6 +63,7 @@ where
E: UsesState<State = Self::State>,
EM: UsesState<State = Self::State>,
TE: Executor<EM, Z> + HasObservers,
TE::Observers: ObserversTuple<TE::Input, <Self as UsesState>::State>,
TE::State: HasExecutions + HasCorpus + HasNamedMetadata + HasCurrentTestcase,
Z: UsesState<State = Self::State>,
<<Self as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Self::Input>, //delete me

View File

@ -73,6 +73,7 @@ where
O: MapObserver,
C: CanTrack + AsRef<O> + Named,
E: Executor<EM, Z, State = Self::State> + HasObservers,
E::Observers: ObserversTuple<BytesInput, <Self as UsesState>::State>,
EM::State:
UsesInput<Input = BytesInput> + HasExecutions + HasMetadata + HasCorpus + HasNamedMetadata,
EM: UsesState,
@ -344,9 +345,9 @@ where
EM: UsesState,
O: MapObserver,
C: CanTrack + AsRef<O> + Named,
OT: ObserversTuple<<Self as UsesState>::State>,
<Self as UsesState>::State:
UsesInput<Input = BytesInput> + HasExecutions + HasMetadata + HasCorpus,
OT: ObserversTuple<BytesInput, <EM as UsesState>::State>,
{
/// Create a new [`GeneralizationStage`].
#[must_use]
@ -372,8 +373,9 @@ where
input: &BytesInput,
) -> Result<bool, Error>
where
E: Executor<EM, Z> + HasObservers<Observers = OT, State = <Self as UsesState>::State>,
Z: UsesState<State = <Self as UsesState>::State>,
E: Executor<EM, Z, State = <Self as UsesState>::State> + HasObservers,
E::Observers: ObserversTuple<BytesInput, <Self as UsesState>::State>,
Z: UsesState<State = EM::State>,
{
start_timer!(state);
executor.observers_mut().pre_exec_all(state, input)?;
@ -414,8 +416,8 @@ where
split_char: u8,
) -> Result<(), Error>
where
E: Executor<EM, Z> + HasObservers<Observers = OT, State = <Self as UsesState>::State>,
Z: UsesState<State = <Self as UsesState>::State>,
E: Executor<EM, Z, State = <Self as UsesState>::State> + HasObservers<Observers = OT>,
Z: UsesState<State = EM::State>,
{
let mut start = 0;
while start < payload.len() {
@ -453,8 +455,8 @@ where
closing_char: u8,
) -> Result<(), Error>
where
E: Executor<EM, Z> + HasObservers<Observers = OT, State = <Self as UsesState>::State>,
Z: UsesState<State = <Self as UsesState>::State>,
E: Executor<EM, Z, State = <Self as UsesState>::State> + HasObservers<Observers = OT>,
Z: UsesState<State = EM::State>,
{
let mut index = 0;
while index < payload.len() {

View File

@ -439,12 +439,12 @@ where
+ HasCurrentCorpusId
+ HasNamedMetadata
+ HasMetadata,
E: Executor<EM, Z> + HasObservers<Observers = OT, State = Self::State>,
E: Executor<EM, Z, State = <Self as UsesState>::State> + HasObservers<Observers = OT>,
EM: EventFirer<State = Self::State>
+ EventRestarter
+ HasEventManagerId
+ ProgressReporter<State = Self::State>,
OT: ObserversTuple<Self::State>,
OT: ObserversTuple<Self::Input, Self::State>,
PS: PushStage<CS, EM, OT, Z>,
Z: ExecutesInput<E, EM>
+ ExecutionProcessor

View File

@ -38,7 +38,7 @@ pub struct PushStageSharedState<CS, EM, OT, Z>
where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::State>,
OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{
@ -57,7 +57,7 @@ impl<CS, EM, OT, Z> PushStageSharedState<CS, EM, OT, Z>
where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::State>,
OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{
@ -80,7 +80,7 @@ pub struct PushStageHelper<CS, EM, OT, Z>
where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::State>,
OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{
@ -108,7 +108,7 @@ impl<CS, EM, OT, Z> PushStageHelper<CS, EM, OT, Z>
where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
OT: ObserversTuple<Z::State>,
OT: ObserversTuple<Z::Input, Z::State>,
Z::State: HasRand + HasCorpus,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{
@ -176,7 +176,7 @@ where
CS: Scheduler<Z::Input, Z::State>,
Z::State: HasRand + HasExecutions + HasMetadata + HasCorpus + HasLastReportTime,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId + ProgressReporter,
OT: ObserversTuple<Z::State>,
OT: ObserversTuple<Z::Input, Z::State>,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{
/// Gets the [`PushStageHelper`]

View File

@ -46,7 +46,7 @@ where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::State> + Serialize,
OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasRand + HasCorpus + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{
@ -64,7 +64,7 @@ where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::State> + Serialize,
OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{
@ -85,7 +85,7 @@ where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId + ProgressReporter,
M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::State> + Serialize,
OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + HasExecutions + HasLastReportTime + HasMetadata + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
<<Z as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Z::Input>, //delete me
@ -194,7 +194,7 @@ where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer + EventRestarter + HasEventManagerId + ProgressReporter<State = Z::State>,
M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::State> + Serialize,
OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + HasExecutions + HasMetadata + HasLastReportTime + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
<<Z as UsesState>::State as HasCorpus>::Corpus: Corpus<Input = Z::Input>, //delete me
@ -211,7 +211,7 @@ where
CS: Scheduler<Z::Input, Z::State>,
EM: EventFirer<State = Z::State> + EventRestarter + HasEventManagerId,
M: Mutator<Z::Input, Z::State>,
OT: ObserversTuple<Z::State> + Serialize,
OT: ObserversTuple<Z::Input, Z::State> + Serialize,
Z::State: HasCorpus + HasRand + Clone + Debug,
Z: ExecutionProcessor + EvaluatorObservers<OT> + HasScheduler<Scheduler = CS>,
{

View File

@ -251,7 +251,7 @@ where
EM: UsesState<State = S> + EventFirer,
S: State + HasExecutions + HasCorpus + HasRand + HasMetadata,
SP: ShMemProvider,
E: HasObservers<State = S> + Executor<EM, Z>,
E: HasObservers + Executor<EM, Z, State = S>,
for<'a> E::Observers: Deserialize<'a>,
Z: EvaluatorObservers<E::Observers, State = S> + ExecutionProcessor<State = S>,
IC: InputConverter<From = S::Input, To = DI>,

View File

@ -23,7 +23,7 @@ use crate::{
inputs::UsesInput,
mark_feature_time,
mutators::{MutationResult, Mutator},
observers::{MapObserver, ObserversTuple, UsesObservers},
observers::{MapObserver, ObserversTuple},
schedulers::RemovableScheduler,
stages::{
mutational::{MutatedTransform, MutatedTransformPost},
@ -45,7 +45,7 @@ pub trait TMinMutationalStage<E, EM, F, IP, M, Z>:
Stage<E, EM, Z> + FeedbackFactory<F, E::Observers>
where
E: UsesState<State = Self::State> + HasObservers,
<E as UsesObservers>::Observers: Serialize,
E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize,
EM: UsesState<State = Self::State> + EventFirer,
F: Feedback<Self::State>,
Self::State: HasMaxSize + HasCorpus + HasSolutions + HasExecutions + HasCurrentTestcase,
@ -241,8 +241,8 @@ impl<E, EM, F, FF, IP, M, Z> Stage<E, EM, Z> for StdTMinMutationalStage<E, EM, F
where
Z: HasScheduler + ExecutionProcessor + ExecutesInput<E, EM> + HasFeedback,
Z::Scheduler: RemovableScheduler<Self::Input, Self::State>,
E: HasObservers<State = Self::State>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + UsesState<State = Z::State>,
E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize,
EM: EventFirer<State = Self::State>,
FF: FeedbackFactory<F, E::Observers>,
F: Feedback<Self::State>,
@ -304,8 +304,8 @@ impl<E, EM, F, FF, IP, M, Z> TMinMutationalStage<E, EM, F, IP, M, Z>
where
Z: HasScheduler + ExecutionProcessor + ExecutesInput<E, EM> + HasFeedback,
Z::Scheduler: RemovableScheduler<Self::Input, Self::State>,
E: HasObservers<State = Self::State>,
<E as UsesObservers>::Observers: Serialize,
E: HasObservers + UsesState<State = Z::State>,
E::Observers: ObserversTuple<Self::Input, Self::State> + Serialize,
EM: EventFirer<State = Self::State>,
FF: FeedbackFactory<F, E::Observers>,
F: Feedback<Self::State>,
@ -407,7 +407,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let obs = observers
.get(self.observer_handle())
@ -458,7 +458,7 @@ impl<C, M, OT, S> FeedbackFactory<MapEqualityFeedback<C, M, S>, OT> for MapEqual
where
M: MapObserver,
C: AsRef<M> + Handled,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput,
{
fn create_feedback(&self, observers: &OT) -> MapEqualityFeedback<C, M, S> {

View File

@ -40,6 +40,7 @@ where
impl<EM, TE, Z> TracingStage<EM, TE, Z>
where
TE: Executor<EM, Z> + HasObservers,
TE::Observers: ObserversTuple<TE::Input, <Self as UsesState>::State>,
<TE as UsesState>::State: HasExecutions + HasCorpus + HasNamedMetadata + HasCurrentTestcase,
EM: UsesState<State = <Self as UsesState>::State>,
Z: UsesState<State = <Self as UsesState>::State>,
@ -86,6 +87,7 @@ impl<E, EM, TE, Z> Stage<E, EM, Z> for TracingStage<EM, TE, Z>
where
E: UsesState<State = <Self as UsesState>::State>,
TE: Executor<EM, Z> + HasObservers,
TE::Observers: ObserversTuple<TE::Input, <Self as UsesState>::State>,
<TE as UsesState>::State: HasExecutions + HasCorpus + HasNamedMetadata,
EM: UsesState<State = <Self as UsesState>::State>,
Z: UsesState<State = <Self as UsesState>::State>,
@ -181,8 +183,9 @@ where
impl<E, EM, SOT, Z> Stage<ShadowExecutor<E, SOT>, EM, Z> for ShadowTracingStage<E, EM, SOT, Z>
where
E: Executor<EM, Z> + HasObservers,
E::Observers: ObserversTuple<E::Input, E::State>,
EM: UsesState<State = <Self as UsesState>::State>,
SOT: ObserversTuple<E::State>,
SOT: ObserversTuple<E::Input, E::State>,
Z: UsesState<State = <Self as UsesState>::State>,
<E as UsesState>::State:
State + HasExecutions + HasCorpus + HasNamedMetadata + Debug + HasCurrentTestcase,
@ -238,7 +241,7 @@ where
E: Executor<EM, Z> + HasObservers,
<Self as UsesState>::State: State + HasExecutions + HasCorpus,
EM: UsesState<State = <Self as UsesState>::State>,
SOT: ObserversTuple<E::State>,
SOT: ObserversTuple<E::Input, E::State>,
Z: UsesState<State = <Self as UsesState>::State>,
{
/// Creates a new default stage

View File

@ -17,7 +17,7 @@ use libafl::{
events::EventFirer,
executors::ExitKind,
feedbacks::Feedback,
inputs::{HasTargetBytes, UsesInput},
inputs::HasTargetBytes,
observers::{Observer, ObserversTuple},
state::State,
Error, HasMetadata,
@ -579,11 +579,8 @@ pub enum AsanErrorsObserver {
Static,
}
impl<S> Observer<S> for AsanErrorsObserver
where
S: UsesInput,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
impl<I, S> Observer<I, S> for AsanErrorsObserver {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
AsanErrors::get_mut_blocking().clear();
Ok(())
@ -666,7 +663,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
let observer = observers
.get(&self.observer_handle)
@ -688,7 +685,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
if let Some(errors) = &self.errors {
testcase.add_metadata(errors.clone());

View File

@ -16,7 +16,7 @@ use libafl::{
use libafl::{
executors::{Executor, ExitKind, HasObservers, InProcessExecutor},
inputs::HasTargetBytes,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{HasExecutions, State, UsesState},
Error,
};
@ -34,7 +34,7 @@ where
H: FnMut(&S::Input) -> ExitKind,
S::Input: HasTargetBytes,
S: State,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
'b: 'a,
{
base: InProcessExecutor<'a, H, OT, S>,
@ -53,7 +53,7 @@ where
H: FnMut(&S::Input) -> ExitKind,
S: State,
S::Input: HasTargetBytes,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("FridaInProcessExecutor")
@ -71,7 +71,7 @@ where
H: FnMut(&S::Input) -> ExitKind,
S: State + HasExecutions,
S::Input: HasTargetBytes,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
RT: FridaRuntimeTuple,
Z: UsesState<State = S>,
{
@ -121,20 +121,10 @@ where
}
}
impl<'a, 'b, 'c, H, OT, RT, S> UsesObservers for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
where
H: FnMut(&S::Input) -> ExitKind,
OT: ObserversTuple<S>,
S: State,
S::Input: HasTargetBytes,
{
type Observers = OT;
}
impl<'a, 'b, 'c, H, OT, RT, S> UsesState for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
where
H: FnMut(&S::Input) -> ExitKind,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
S::Input: HasTargetBytes,
{
@ -146,8 +136,9 @@ where
H: FnMut(&S::Input) -> ExitKind,
S::Input: HasTargetBytes,
S: State,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.base.observers()
@ -164,7 +155,7 @@ where
H: FnMut(&S::Input) -> ExitKind,
S: State,
S::Input: HasTargetBytes,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
RT: FridaRuntimeTuple,
{
/// Creates a new [`FridaInProcessExecutor`].
@ -241,7 +232,7 @@ where
H: FnMut(&S::Input) -> ExitKind,
S: State + HasSolutions + HasCorpus + HasExecutions,
S::Input: HasTargetBytes,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
RT: FridaRuntimeTuple,
<S as HasSolutions>::Solutions: Corpus<Input = S::Input>, //delete me
<<S as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me

View File

@ -57,7 +57,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
Ok(*self.keep.borrow())
}
@ -133,7 +133,7 @@ where
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
self.exit_kind = *exit_kind;
Ok(false)
@ -151,7 +151,7 @@ where
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
match self.exit_kind {
ExitKind::Crash | ExitKind::Oom if OomFeedback::oomed() => {

View File

@ -165,10 +165,10 @@ where
type State = M::State;
}
impl<M, O, S> Observer<S> for MappedEdgeMapObserver<M, O>
impl<M, O, S> Observer<S::Input, S> for MappedEdgeMapObserver<M, O>
where
M: Observer<S> + Debug,
O: Observer<S> + Debug,
M: Observer<S::Input, S> + Debug,
O: Observer<S::Input, S> + Debug,
S: UsesInput,
{
fn pre_exec(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
@ -224,6 +224,7 @@ where
impl<'it, M, O> AsIter<'it> for MappedEdgeMapObserver<M, O>
where
M: MapObserver + for<'a> AsIter<'a, Item = M::Entry>,
M::Entry: 'it,
O: ValueObserver + 'it,
{
type Item = O::ValueType;
@ -261,7 +262,7 @@ impl Named for SizeValueObserver {
}
}
impl<S> Observer<S> for SizeValueObserver
impl<S> Observer<S::Input, S> for SizeValueObserver
where
S: UsesInput,
S::Input: HasLen,
@ -305,7 +306,7 @@ impl Named for TimeValueObserver {
}
}
impl<S> Observer<S> for TimeValueObserver
impl<S> Observer<S::Input, S> for TimeValueObserver
where
S: UsesInput,
{
@ -367,7 +368,7 @@ impl Named for SizeTimeValueObserver {
}
}
impl<S> Observer<S> for SizeTimeValueObserver
impl<S> Observer<S::Input, S> for SizeTimeValueObserver
where
S: UsesInput,
S::Input: HasLen,

View File

@ -7,7 +7,7 @@ use libafl::{
inputs::UsesInput,
monitors::SimpleMonitor,
stages::{HasCurrentStageId, StagesTuple},
state::{HasExecutions, HasLastReportTime, Stoppable},
state::{HasExecutions, HasLastReportTime, Stoppable, UsesState},
Error, Fuzzer, HasMetadata, HasNamedMetadata,
};
@ -31,7 +31,7 @@ where
+ HasLastReportTime
+ HasCurrentStageId
+ Stoppable,
E: HasObservers<State = S>,
E: HasObservers + UsesState<State = S>,
EM: ProgressReporter<State = S> + EventProcessor<E, F>,
ST: StagesTuple<E, EM, S, F>,
{

View File

@ -7,7 +7,7 @@ use std::{
use libafl::{
executors::{Executor, ExitKind, HasObservers},
inputs::HasTargetBytes,
observers::{ObserversTuple, StdOutObserver, UsesObservers},
observers::{ObserversTuple, StdOutObserver},
state::{HasExecutions, State, UsesState},
Error,
};
@ -45,21 +45,13 @@ where
type State = S;
}
impl<S, OT> UsesObservers for NyxExecutor<S, OT>
where
OT: ObserversTuple<S>,
S: State,
{
type Observers = OT;
}
impl<EM, S, Z, OT> Executor<EM, Z> for NyxExecutor<S, OT>
where
EM: UsesState<State = S>,
S: State + HasExecutions,
S::Input: HasTargetBytes,
Z: UsesState<State = S>,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
fn run_target(
&mut self,
@ -195,8 +187,10 @@ impl NyxExecutorBuilder {
impl<S, OT> HasObservers for NyxExecutor<S, OT>
where
S: State,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
type Observers = OT;
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
RefIndexable::from(&self.observers)
}

View File

@ -74,7 +74,7 @@ where
state: &mut S,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
emulator
.modules
@ -201,7 +201,7 @@ where
state: &mut S,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
if !emulator.driver.hooks_locked {
emulator

View File

@ -1161,7 +1161,7 @@ where
observers: &mut OT,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
unsafe {
self.modules_mut().post_exec_all(

View File

@ -441,7 +441,7 @@ where
state: &mut S,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
ED::post_harness_exec(self, input, observers, state, exit_kind);
}

View File

@ -19,14 +19,14 @@ use libafl::{
},
feedbacks::Feedback,
fuzzer::HasObjective,
observers::{ObserversTuple, UsesObservers},
inputs::UsesInput,
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, State, UsesState},
Error, ExecutionProcessor, HasScheduler,
};
#[cfg(feature = "fork")]
use libafl::{
events::EventManager, executors::InProcessForkExecutor, inputs::UsesInput,
state::HasLastReportTime, HasMetadata,
events::EventManager, executors::InProcessForkExecutor, state::HasLastReportTime, HasMetadata,
};
#[cfg(feature = "fork")]
use libafl_bolts::shmem::ShMemProvider;
@ -52,7 +52,7 @@ where
CM: CommandManager<ED, ET, S, SM>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&mut Emulator<CM, ED, ET, S, SM>, &mut S, &S::Input) -> ExitKind,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
inner: StatefulInProcessExecutor<'a, H, OT, S, Emulator<CM, ED, ET, S, SM>>,
@ -86,7 +86,8 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, OF, Z>(
context: Option<&mut ucontext_t>,
data: &mut InProcessExecutorHandlerData,
) where
E: HasObservers + HasInProcessHooks<E::State>,
E: HasObservers + HasInProcessHooks<E::State> + Executor<EM, Z>,
E::Observers: ObserversTuple<E::Input, E::State>,
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasExecutions + HasSolutions + HasCorpus,
@ -108,7 +109,7 @@ where
CM: CommandManager<ED, ET, S, SM>,
ET: EmulatorModuleTuple<S> + Debug,
H: FnMut(&mut Emulator<CM, ED, ET, S, SM>, &mut S, &S::Input) -> ExitKind,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: State,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@ -123,7 +124,7 @@ where
CM: CommandManager<ED, ET, S, SM>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&mut Emulator<CM, ED, ET, S, SM>, &mut S, &S::Input) -> ExitKind,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
pub fn new<EM, OF, Z>(
@ -212,7 +213,7 @@ where
EM: UsesState<State = S>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&mut Emulator<CM, ED, ET, S, SM>, &mut S, &S::Input) -> ExitKind,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasExecutions + Unpin,
Z: UsesState<State = S>,
{
@ -250,31 +251,21 @@ where
CM: CommandManager<ED, ET, S, SM>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&mut Emulator<CM, ED, ET, S, SM>, &mut S, &S::Input) -> ExitKind,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type State = S;
}
impl<'a, CM, ED, ET, H, OT, S, SM> UsesObservers for QemuExecutor<'a, CM, ED, ET, H, OT, S, SM>
where
CM: CommandManager<ED, ET, S, SM>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&mut Emulator<CM, ED, ET, S, SM>, &mut S, &S::Input) -> ExitKind,
OT: ObserversTuple<S>,
S: State,
{
type Observers = OT;
}
impl<'a, CM, ED, ET, H, OT, S, SM> HasObservers for QemuExecutor<'a, CM, ED, ET, H, OT, S, SM>
where
CM: CommandManager<ED, ET, S, SM>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&mut Emulator<CM, ED, ET, S, SM>, &mut S, &S::Input) -> ExitKind,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.inner.observers()
@ -293,7 +284,7 @@ where
EM: UsesState<State = S>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: UsesInput,
SP: ShMemProvider,
Z: UsesState<State = S>,
@ -311,7 +302,7 @@ where
ED: Debug,
ET: EmulatorModuleTuple<S> + Debug,
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
S: UsesInput + Debug,
SM: Debug,
SP: ShMemProvider,
@ -333,7 +324,7 @@ where
EM: EventFirer<State = S> + EventRestarter<State = S>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State + HasSolutions,
SP: ShMemProvider,
Z: HasObjective<State = S>,
@ -389,7 +380,7 @@ where
EM: EventManager<InProcessForkExecutor<'a, H, OT, S, SP, EM, Z>, Z, State = S>,
H: FnMut(&S::Input) -> ExitKind,
S: Unpin + State + HasMetadata + HasExecutions + HasLastReportTime + HasCorpus + HasSolutions,
OT: ObserversTuple<S> + Debug,
OT: ObserversTuple<S::Input, S> + Debug,
ET: EmulatorModuleTuple<S>,
SP: ShMemProvider,
OF: Feedback<S>,
@ -406,22 +397,6 @@ where
}
}
#[cfg(feature = "fork")]
impl<'a, CM, ED, EM, ET, H, OT, S, SM, SP, Z> UsesObservers
for QemuForkExecutor<'a, CM, ED, EM, ET, H, OT, S, SM, SP, Z>
where
CM: CommandManager<ED, ET, S, SM>,
EM: UsesState<State = S>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
S: State,
SP: ShMemProvider,
Z: UsesState<State = S>,
{
type Observers = OT;
}
#[cfg(feature = "fork")]
impl<'a, CM, ED, EM, ET, H, OT, S, SM, SP, Z> UsesState
for QemuForkExecutor<'a, CM, ED, EM, ET, H, OT, S, SM, SP, Z>
@ -430,7 +405,7 @@ where
EM: UsesState<State = S>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
SP: ShMemProvider,
Z: UsesState<State = S>,
@ -446,11 +421,12 @@ where
EM: UsesState<State = S>,
ET: EmulatorModuleTuple<S>,
H: FnMut(&S::Input) -> ExitKind + ?Sized,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: State,
SP: ShMemProvider,
Z: UsesState<State = S>,
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
self.inner.observers()

View File

@ -56,7 +56,7 @@ pub trait CallTraceCollector: 'static {
_observers: &mut OT,
_exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: Unpin + UsesInput,
{
}
@ -94,7 +94,7 @@ pub trait CallTraceCollectorTuple: 'static + MatchFirstType {
_observers: &mut OT,
_exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: Unpin + UsesInput;
}
@ -136,7 +136,7 @@ impl CallTraceCollectorTuple for () {
_observers: &mut OT,
_exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: Unpin + UsesInput,
{
}
@ -206,7 +206,7 @@ where
observers: &mut OT,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: Unpin + UsesInput,
{
self.0.post_exec(qemu, input, observers, exit_kind);
@ -426,7 +426,7 @@ where
observers: &mut OT,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
ET: EmulatorModuleTuple<S>,
{
self.collectors.as_mut().unwrap().post_exec_all(
@ -528,7 +528,7 @@ where
observers: &mut OT,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
S: Unpin + UsesInput,
{
let observer = observers

View File

@ -85,7 +85,7 @@ where
_observers: &mut OT,
_exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
ET: EmulatorModuleTuple<S>,
{
}
@ -130,7 +130,7 @@ where
observers: &mut OT,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
ET: EmulatorModuleTuple<S>;
fn allow_address_range_all(&mut self, address_range: Range<GuestAddr>);
@ -175,7 +175,7 @@ where
_observers: &mut OT,
_exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
ET: EmulatorModuleTuple<S>,
{
}
@ -230,7 +230,7 @@ where
observers: &mut OT,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
ET: EmulatorModuleTuple<S>,
{
self.0

View File

@ -997,7 +997,7 @@ where
_observers: &mut OT,
exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
ET: EmulatorModuleTuple<S>,
{
if self.reset(emulator_modules.qemu()) == AsanRollback::HasLeaks {

View File

@ -116,7 +116,7 @@ where
_observers: &mut OT,
_exit_kind: &mut ExitKind,
) where
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
ET: EmulatorModuleTuple<S>,
{
let lengths_opt = DRCOV_LENGTHS.lock().unwrap();

View File

@ -16,6 +16,7 @@ use libafl::{
observers::{cmp::AFLppCmpLogHeader, CmpMap, CmpValues, CmplogBytes},
Error,
};
use libafl_bolts::HasLen;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub use stages::*;
@ -62,6 +63,7 @@ pub use libafl_cmplog_map_ptr as CMPLOG_MAP_PTR;
/// Value indicating if cmplog is enabled.
#[no_mangle]
#[allow(non_upper_case_globals)]
pub static mut libafl_cmplog_enabled: u8 = 0;
pub use libafl_cmplog_enabled as CMPLOG_ENABLED;
@ -423,6 +425,7 @@ impl CmpMap for CmpLogMap {
/// The global `CmpLog` map for the current `LibAFL` run.
#[no_mangle]
#[allow(clippy::large_stack_arrays)]
#[allow(non_upper_case_globals)]
pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap {
headers: [CmpLogHeader {
hits: 0,
@ -467,6 +470,12 @@ pub struct AFLppCmpLogMap {
vals: AFLppCmpLogVals,
}
impl HasLen for AFLppCmpLogMap {
fn len(&self) -> usize {
CMPLOG_MAP_W
}
}
impl AFLppCmpLogMap {
#[must_use]
/// Instantiate a new boxed zeroed `AFLppCmpLogMap`. This should be used to create a new

View File

@ -1,11 +1,10 @@
use alloc::{borrow::Cow, vec::Vec};
use core::{fmt::Debug, marker::PhantomData};
use core::fmt::Debug;
use libafl::{
executors::ExitKind,
inputs::UsesInput,
observers::{
cmp::{AFLppCmpValuesMetadata, CmpMap, CmpObserver, CmpObserverMetadata, CmpValues},
cmp::{AFLppCmpValuesMetadata, CmpMap, CmpObserver, CmpValues},
Observer,
},
Error, HasMetadata,
@ -65,20 +64,17 @@ struct cmp_map {
/// A [`CmpObserver`] observer for AFL++ redqueen
#[derive(Serialize, Deserialize, Debug)]
pub struct AFLppCmpLogObserver<'a, S> {
pub struct AFLppCmpLogObserver<'a> {
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
size: Option<OwnedRefMut<'a, usize>>,
name: Cow<'static, str>,
add_meta: bool,
original: <AFLppCmpValuesMetadata as CmpObserverMetadata<'a, AFLppCmpLogMap>>::Data,
phantom: PhantomData<S>,
original: bool,
}
impl<'a, S> CmpObserver<'a, AFLppCmpLogMap, S, AFLppCmpValuesMetadata>
for AFLppCmpLogObserver<'a, S>
where
S: UsesInput + HasMetadata,
{
impl<'a> CmpObserver for AFLppCmpLogObserver<'a> {
type Map = AFLppCmpLogMap;
/// Get the number of usable cmps (all by default)
fn usable_count(&self) -> usize {
match &self.size {
@ -94,16 +90,87 @@ where
fn cmp_map_mut(&mut self) -> &mut AFLppCmpLogMap {
self.cmp_map.as_mut()
}
}
fn cmp_observer_data(
&self,
) -> <AFLppCmpValuesMetadata as CmpObserverMetadata<'a, AFLppCmpLogMap>>::Data {
self.original
impl<'a, I, S> Observer<I, S> for AFLppCmpLogObserver<'a>
where
S: HasMetadata,
{
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
#[cfg(feature = "cmplog_extended_instrumentation")]
unsafe {
// if the target is compiled with aflpp and you are running forkserver then this is not needed
// because with forkserver, you have two executors (processes), one is dedicated for edge-cov
// the other dedicated for cmplog.
// however if it is in-process, then cmplog instrumentation is in the same binary as the edge-cov binary
// (so we only have one executable)
// therefore we need to turn this thing on and off to change this according to what executors we are using
CMPLOG_ENABLED = 1;
}
self.cmp_map.as_mut().reset()?;
Ok(())
}
fn post_exec(&mut self, state: &mut S, _input: &I, _exit_kind: &ExitKind) -> Result<(), Error> {
#[cfg(feature = "cmplog_extended_instrumentation")]
unsafe {
CMPLOG_ENABLED = 0;
}
if self.add_meta {
self.add_cmpvalues_meta(state);
}
Ok(())
}
}
impl<'a> Named for AFLppCmpLogObserver<'a> {
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a> AFLppCmpLogObserver<'a> {
/// Creates a new [`AFLppCmpLogObserver`] with the given name and map.
#[must_use]
pub fn new(
name: &'static str,
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
add_meta: bool,
) -> Self {
Self {
name: Cow::from(name),
size: None,
cmp_map,
add_meta,
original: false,
}
}
/// Setter for the flag if the executed input is a mutated one or the original one
pub fn set_original(&mut self, v: bool) {
self.original = v;
}
/// Creates a new [`AFLppCmpLogObserver`] with the given name, map and reference to variable size.
#[must_use]
pub fn with_size(
name: &'static str,
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
add_meta: bool,
original: bool,
size: OwnedRefMut<'a, usize>,
) -> Self {
Self {
name: Cow::from(name),
size: Some(size),
cmp_map,
add_meta,
original,
}
}
/// Add `AFLppCmpValuesMetadata` to the State including the logged values.
/// This routine does a basic loop filtering because loop index cmps are not interesting.
fn add_cmpvalues_meta(&mut self, state: &mut S)
fn add_cmpvalues_meta<S>(&mut self, state: &mut S)
where
S: HasMetadata,
{
@ -131,193 +198,101 @@ where
}
let usable_count = self.usable_count();
let cmp_observer_data = self.cmp_observer_data();
meta.add_from(usable_count, self.cmp_map_mut(), cmp_observer_data);
let original = self.original;
add_to_aflpp_cmp_metadata(meta, usable_count, self.cmp_map_mut(), original);
}
}
impl<'a, S> Observer<S> for AFLppCmpLogObserver<'a, S>
where
S: UsesInput + HasMetadata,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
#[cfg(feature = "cmplog_extended_instrumentation")]
unsafe {
// if the target is compiled with aflpp and you are running forkserver then this is not needed
// because with forkserver, you have two executors (processes), one is dedicated for edge-cov
// the other dedicated for cmplog.
// however if it is in-process, then cmplog instrumentation is in the same binary as the edge-cov binary
// (so we only have one executable)
// therefore we need to turn this thing on and off to change this according to what executors we are using
CMPLOG_ENABLED = 1;
}
self.cmp_map.as_mut().reset()?;
Ok(())
}
/// Add the metadata
pub fn add_to_aflpp_cmp_metadata(
meta: &mut AFLppCmpValuesMetadata,
usable_count: usize,
cmp_map: &mut AFLppCmpLogMap,
original: bool,
) {
let count = usable_count;
for i in 0..count {
let execs = cmp_map.usable_executions_for(i);
if execs > 0 {
if original {
// Update header
meta.headers.push((i, cmp_map.headers[i]));
}
fn post_exec(
&mut self,
state: &mut S,
_input: &S::Input,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
#[cfg(feature = "cmplog_extended_instrumentation")]
unsafe {
CMPLOG_ENABLED = 0;
}
if self.add_meta {
self.add_cmpvalues_meta(state);
}
Ok(())
}
}
// Recongize loops and discard if needed
if execs > 4 {
let mut increasing_v0 = 0;
let mut increasing_v1 = 0;
let mut decreasing_v0 = 0;
let mut decreasing_v1 = 0;
impl<'a, S> Named for AFLppCmpLogObserver<'a, S> {
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<'a, S> AFLppCmpLogObserver<'a, S> {
/// Creates a new [`AFLppCmpLogObserver`] with the given name and map.
#[must_use]
pub fn new(
name: &'static str,
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
add_meta: bool,
) -> Self {
Self {
name: Cow::from(name),
size: None,
cmp_map,
add_meta,
original: false,
phantom: PhantomData,
}
}
/// Setter for the flag if the executed input is a mutated one or the original one
pub fn set_original(&mut self, v: bool) {
self.original = v;
}
/// Creates a new [`AFLppCmpLogObserver`] with the given name, map and reference to variable size.
#[must_use]
pub fn with_size(
name: &'static str,
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
add_meta: bool,
original: bool,
size: OwnedRefMut<'a, usize>,
) -> Self {
Self {
name: Cow::from(name),
size: Some(size),
cmp_map,
add_meta,
original,
phantom: PhantomData,
}
}
}
impl<'a> CmpObserverMetadata<'a, AFLppCmpLogMap> for AFLppCmpValuesMetadata {
type Data = bool;
fn new_metadata() -> Self {
Self::new()
}
fn add_from(
&mut self,
usable_count: usize,
cmp_map: &mut AFLppCmpLogMap,
cmp_observer_data: Self::Data,
) {
let count = usable_count;
for i in 0..count {
let execs = cmp_map.usable_executions_for(i);
if execs > 0 {
if cmp_observer_data {
// Update header
self.headers.push((i, cmp_map.headers[i]));
}
// Recongize loops and discard if needed
if execs > 4 {
let mut increasing_v0 = 0;
let mut increasing_v1 = 0;
let mut decreasing_v0 = 0;
let mut decreasing_v1 = 0;
let mut last: Option<CmpValues> = None;
for j in 0..execs {
if let Some(val) = cmp_map.values_of(i, j) {
if let Some(l) = last.and_then(|x| x.to_u64_tuple()) {
if let Some(v) = val.to_u64_tuple() {
if l.0.wrapping_add(1) == v.0 {
increasing_v0 += 1;
}
if l.1.wrapping_add(1) == v.1 {
increasing_v1 += 1;
}
if l.0.wrapping_sub(1) == v.0 {
decreasing_v0 += 1;
}
if l.1.wrapping_sub(1) == v.1 {
decreasing_v1 += 1;
}
let mut last: Option<CmpValues> = None;
for j in 0..execs {
if let Some(val) = cmp_map.values_of(i, j) {
if let Some(l) = last.and_then(|x| x.to_u64_tuple()) {
if let Some(v) = val.to_u64_tuple() {
if l.0.wrapping_add(1) == v.0 {
increasing_v0 += 1;
}
if l.1.wrapping_add(1) == v.1 {
increasing_v1 += 1;
}
if l.0.wrapping_sub(1) == v.0 {
decreasing_v0 += 1;
}
if l.1.wrapping_sub(1) == v.1 {
decreasing_v1 += 1;
}
}
last = Some(val);
}
}
// We check for execs-2 because the logged execs may wrap and have something like
// 8 9 10 3 4 5 6 7
if increasing_v0 >= execs - 2
|| increasing_v1 >= execs - 2
|| decreasing_v0 >= execs - 2
|| decreasing_v1 >= execs - 2
{
continue;
last = Some(val);
}
}
// We check for execs-2 because the logged execs may wrap and have something like
// 8 9 10 3 4 5 6 7
if increasing_v0 >= execs - 2
|| increasing_v1 >= execs - 2
|| decreasing_v0 >= execs - 2
|| decreasing_v1 >= execs - 2
{
continue;
}
}
let cmpmap_idx = i;
let mut cmp_values = Vec::new();
if cmp_observer_data {
// push into orig_cmpvals
// println!("Adding to orig_cmpvals");
for j in 0..execs {
if let Some(val) = cmp_map.values_of(i, j) {
cmp_values.push(val);
}
let cmpmap_idx = i;
let mut cmp_values = Vec::new();
if original {
// push into orig_cmpvals
// println!("Adding to orig_cmpvals");
for j in 0..execs {
if let Some(val) = cmp_map.values_of(i, j) {
cmp_values.push(val);
}
// println!("idx: {cmpmap_idx} cmp_values: {:#?}", cmp_values);
self.orig_cmpvals.insert(cmpmap_idx, cmp_values);
} else {
// push into new_cmpvals
// println!("Adding to new_cmpvals");
/*
unsafe {
println!(
"idx {:#?} type {:#?} sz {:#?} ptr1 {:p} val1 {:x}",
i,
cmp_map.headers()[i]._type(),
cmp_map.headers()[i].shape(),
&cmp_map.vals.operands[i][0],
cmp_map.vals.operands[i][0].v0(),
);
}
*/
for j in 0..execs {
if let Some(val) = cmp_map.values_of(i, j) {
cmp_values.push(val);
}
}
// println!("idx: {cmpmap_idx} cmp_values: {:#?}", cmp_values);
self.new_cmpvals.insert(cmpmap_idx, cmp_values);
}
// println!("idx: {cmpmap_idx} cmp_values: {:#?}", cmp_values);
meta.orig_cmpvals.insert(cmpmap_idx, cmp_values);
} else {
// push into new_cmpvals
// println!("Adding to new_cmpvals");
/*
unsafe {
println!(
"idx {:#?} type {:#?} sz {:#?} ptr1 {:p} val1 {:x}",
i,
cmp_map.headers()[i]._type(),
cmp_map.headers()[i].shape(),
&cmp_map.vals.operands[i][0],
cmp_map.vals.operands[i][0].v0(),
);
}
*/
for j in 0..execs {
if let Some(val) = cmp_map.values_of(i, j) {
cmp_values.push(val);
}
}
// println!("idx: {cmpmap_idx} cmp_values: {:#?}", cmp_values);
meta.new_cmpvals.insert(cmpmap_idx, cmp_values);
}
}
}

View File

@ -7,7 +7,6 @@ use core::fmt::Debug;
use libafl::{
executors::ExitKind,
inputs::UsesInput,
observers::{cmp::CmpValuesMetadata, CmpMap, CmpObserver, Observer},
Error, HasMetadata,
};
@ -25,10 +24,9 @@ pub struct CmpLogObserver {
name: Cow<'static, str>,
}
impl<'a, S> CmpObserver<'a, CmpLogMap, S, CmpValuesMetadata> for CmpLogObserver
where
S: UsesInput + HasMetadata,
{
// Is the only difference here between this and StdCmpObserver that CMPLOG_ENABLED = 1??
impl CmpObserver for CmpLogObserver {
type Map = CmpLogMap;
/// Get the number of usable cmps (all by default)
fn usable_count(&self) -> usize {
match &self.size {
@ -46,12 +44,11 @@ where
}
}
impl<'a, S> Observer<S> for CmpLogObserver
impl<I, S> Observer<I, S> for CmpLogObserver
where
S: UsesInput + HasMetadata,
Self: CmpObserver<'a, CmpLogMap, S, CmpValuesMetadata>,
S: HasMetadata,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.map.as_mut().reset()?;
unsafe {
CMPLOG_ENABLED = 1;
@ -59,18 +56,17 @@ where
Ok(())
}
fn post_exec(
&mut self,
state: &mut S,
_input: &S::Input,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
fn post_exec(&mut self, state: &mut S, _input: &I, _exit_kind: &ExitKind) -> Result<(), Error> {
unsafe {
CMPLOG_ENABLED = 0;
}
if self.add_meta {
self.add_cmpvalues_meta(state);
let meta = state.metadata_or_insert_with(CmpValuesMetadata::new);
let usable_count = self.usable_count();
meta.add_from(usable_count, self.cmp_map_mut());
}
Ok(())

View File

@ -25,7 +25,7 @@ where
{
name: Cow<'static, str>,
tracer_executor: TE,
cmplog_observer_handle: Handle<AFLppCmpLogObserver<'a, <Self as UsesState>::State>>,
cmplog_observer_handle: Handle<AFLppCmpLogObserver<'a>>,
#[allow(clippy::type_complexity)]
phantom: PhantomData<(EM, TE, Z)>,
}
@ -58,6 +58,7 @@ where
+ UsesInput<Input = BytesInput>
+ HasNamedMetadata
+ HasCurrentTestcase,
TE::Observers: MatchNameRef + ObserversTuple<BytesInput, TE::State>,
EM: UsesState<State = Self::State>,
Z: UsesState<State = Self::State>,
<Self::State as HasCorpus>::Corpus: Corpus<Input = BytesInput>, //delete me
@ -147,10 +148,7 @@ where
TE: UsesState,
{
/// With cmplog observer
pub fn new(
tracer_executor: TE,
observer_handle: Handle<AFLppCmpLogObserver<'a, TE::State>>,
) -> Self {
pub fn new(tracer_executor: TE, observer_handle: Handle<AFLppCmpLogObserver<'a>>) -> Self {
let observer_name = observer_handle.name().clone();
Self {
name: Cow::Owned(

View File

@ -211,8 +211,7 @@ mod swap {
use core::fmt::Debug;
use libafl::{
inputs::UsesInput,
observers::{DifferentialObserver, Observer, ObserversTuple, StdMapObserver},
observers::{DifferentialObserver, Observer, StdMapObserver},
Error,
};
use libafl_bolts::{ownedref::OwnedMutSlice, AsSliceMut, Named};
@ -285,15 +284,9 @@ mod swap {
}
}
impl<'a, 'b, S> Observer<S> for DifferentialAFLMapSwapObserver<'a, 'b> where S: UsesInput {}
impl<'a, 'b, I, S> Observer<I, S> for DifferentialAFLMapSwapObserver<'a, 'b> {}
impl<'a, 'b, OTA, OTB, S> DifferentialObserver<OTA, OTB, S>
for DifferentialAFLMapSwapObserver<'a, 'b>
where
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
impl<'a, 'b, OTA, OTB, I, S> DifferentialObserver<OTA, OTB, I, S> for DifferentialAFLMapSwapObserver<'a, 'b> {
fn pre_observe_first(&mut self, _: &mut OTA) -> Result<(), Error> {
let slice = self.first_map.as_slice_mut();
unsafe {

View File

@ -2,15 +2,7 @@ use alloc::borrow::Cow;
use core::{ffi::c_void, fmt::Debug};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use libafl::{
events::EventFirer,
executors::ExitKind,
feedbacks::Feedback,
inputs::UsesInput,
observers::{Observer, ObserversTuple},
state::State,
Error,
};
use libafl::{executors::ExitKind, feedbacks::Feedback, observers::Observer, state::State, Error};
use libafl_bolts::Named;
use libc::SIGABRT;
use serde::{Deserialize, Serialize};
@ -94,11 +86,8 @@ impl Named for OomObserver {
}
}
impl<S> Observer<S> for OomObserver
where
S: UsesInput,
{
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
impl<I, S> Observer<I, S> for OomObserver {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
OOMED.store(false, Ordering::Relaxed);
// must reset for platforms which do not offer malloc tracking
MALLOC_SIZE.store(0, Ordering::Relaxed);
@ -109,7 +98,7 @@ where
fn post_exec(
&mut self,
_state: &mut S,
_input: &S::Input,
_input: &I,
_exit_kind: &ExitKind,
) -> Result<(), Error> {
RUNNING.store(false, Ordering::Relaxed);
@ -117,14 +106,14 @@ where
Ok(())
}
fn pre_exec_child(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> {
fn pre_exec_child(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
self.pre_exec(state, input)
}
fn post_exec_child(
&mut self,
state: &mut S,
input: &S::Input,
input: &I,
exit_kind: &ExitKind,
) -> Result<(), Error> {
self.post_exec(state, input, exit_kind)
@ -160,11 +149,7 @@ where
_input: &S::Input,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
{
) -> Result<bool, Error> {
Ok(Self::oomed())
}

View File

@ -78,8 +78,7 @@ mod observers {
use ahash::RandomState;
use libafl::{
inputs::UsesInput,
observers::{DifferentialObserver, MapObserver, Observer, ObserversTuple},
observers::{DifferentialObserver, MapObserver, Observer},
Error,
};
use libafl_bolts::{
@ -131,20 +130,18 @@ mod observers {
iter_idx: usize,
}
impl<S> Observer<S> for CountersMultiMapObserver<false>
impl<I, S> Observer<I, S> for CountersMultiMapObserver<false>
where
S: UsesInput,
Self: MapObserver,
{
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
self.reset_map()
}
}
impl<S> Observer<S> for CountersMultiMapObserver<true>
impl<I, S> Observer<I, S> for CountersMultiMapObserver<true>
where
S: UsesInput,
Self: MapObserver,
{
// in differential mode, we are *not* responsible for resetting the map!
@ -389,12 +386,5 @@ mod observers {
}
}
impl<OTA, OTB, S> DifferentialObserver<OTA, OTB, S> for CountersMultiMapObserver<true>
where
Self: MapObserver,
OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>,
S: UsesInput,
{
}
impl<OTA, OTB, I, S> DifferentialObserver<OTA, OTB, I, S> for CountersMultiMapObserver<true> {}
}

View File

@ -5,6 +5,8 @@ use libafl::{
events::{EventFirer, EventRestarter},
executors::{hooks::windows::windows_asan_handler::asan_death_handler, Executor, HasObservers},
feedbacks::Feedback,
inputs::UsesInput,
observers::ObserversTuple,
state::{HasCorpus, HasExecutions, HasSolutions, UsesState},
HasObjective,
};
@ -34,6 +36,7 @@ where
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
OF: Feedback<E::State>,
E::State: HasSolutions + HasCorpus + HasExecutions,
E::Observers: ObserversTuple<<E::State as UsesInput>::Input, E::State>,
Z: HasObjective<Objective = OF, State = E::State>,
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
<<<E as UsesState>::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me

View File

@ -3,7 +3,7 @@ use core::{marker::PhantomData, ptr, time::Duration};
use libafl::{
executors::{Executor, ExitKind, HasObservers},
inputs::HasTargetBytes,
observers::{ObserversTuple, UsesObservers},
observers::ObserversTuple,
state::{HasExecutions, State, UsesState},
Error,
};
@ -320,8 +320,10 @@ impl<S, SP, OT> HasObservers for TinyInstExecutor<S, SP, OT>
where
S: State,
SP: ShMemProvider,
OT: ObserversTuple<S>,
OT: ObserversTuple<S::Input, S>,
{
type Observers = OT;
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
RefIndexable::from(&self.observers)
}
@ -337,11 +339,3 @@ where
{
type State = S;
}
impl<S, SP, OT> UsesObservers for TinyInstExecutor<S, SP, OT>
where
OT: ObserversTuple<S>,
S: State,
SP: ShMemProvider,
{
type Observers = OT;
}

View File

@ -70,6 +70,7 @@ RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests
# Loop through each project and run Clippy
for project in "${PROJECTS[@]}"; do
echo "aa"
# Trim leading and trailing whitespace
project=$(echo "$project" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [ -d "$project" ]; then