implemented MapMaxPow2Feedback (#371)

* implemented MapMaxPow2Feedback

* using num-traits for qemu as well

* moved back to Num for float fun

* OneOrFilled Feedback
This commit is contained in:
Dominik Maier 2021-11-11 01:49:46 +01:00 committed by GitHub
parent 3e85cf22de
commit fff7cbd90f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 191 additions and 62 deletions

View File

@ -46,7 +46,7 @@ serial_test = "0.5"
[dependencies] [dependencies]
tuple_list = { version = "0.1.3" } tuple_list = { version = "0.1.3" }
hashbrown = { version = "0.11", features = ["serde", "ahash-compile-time-rng"], default-features=false } # A faster hashmap, nostd compatible hashbrown = { version = "0.11", features = ["serde", "ahash-compile-time-rng"], default-features=false } # A faster hashmap, nostd compatible
num = { version = "0.4.0", default-features = false } num-traits = { version = "0.2", default-features = false }
xxhash-rust = { version = "0.8.2", features = ["xxh3"] } # xxh3 hashing for rust xxhash-rust = { version = "0.8.2", features = ["xxh3"] } # xxh3 hashing for rust
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
erased-serde = { version = "0.3.12", default-features = false, features = ["alloc"] } # erased serde erased-serde = { version = "0.3.12", default-features = false, features = ["alloc"] } # erased serde

View File

@ -5,7 +5,7 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use core::marker::PhantomData; use core::marker::PhantomData;
use num::Integer; use num_traits::PrimInt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -22,26 +22,41 @@ use crate::{
}; };
/// A [`MapFeedback`] that strives to maximize the map contents. /// A [`MapFeedback`] that strives to maximize the map contents.
pub type MaxMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, O, MaxReducer, S, T>; pub type MaxMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, MapNopFilter, O, MaxReducer, S, T>;
/// A [`MapFeedback`] that strives to minimize the map contents. /// A [`MapFeedback`] that strives to minimize the map contents.
pub type MinMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, O, MinReducer, S, T>; pub type MinMapFeedback<FT, I, O, S, T> = MapFeedback<FT, I, MapNopFilter, O, MinReducer, S, T>;
/// A Reducer function is used to aggregate values for the novelty search /// A [`MapFeedback`] that strives to maximize the map contents,
/// but only, if a value is larger than `pow2` of the previous.
pub type MaxMapPow2Feedback<FT, I, O, S, T> =
MapFeedback<FT, I, MaxMapPow2Filter, O, MaxReducer, S, T>;
/// A [`MapFeedback`] that strives to maximize the map contents,
/// but only, if a value is larger than `pow2` of the previous.
pub type MaxMapOneOrFilledFeedback<FT, I, O, S, T> =
MapFeedback<FT, I, MaxMapOneOrFilledFilter, O, MaxReducer, S, T>;
/// A `Reducer` function is used to aggregate values for the novelty search
pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static pub trait Reducer<T>: Serialize + serde::de::DeserializeOwned + 'static
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
/// Reduce two values to one value, with the current [`Reducer`]. /// Reduce two values to one value, with the current [`Reducer`].
fn reduce(first: T, second: T) -> T; fn reduce(first: T, second: T) -> T;
} }
/// A [`MaxReducer`] reduces [`Integer`] values and returns their maximum. /// A [`MaxReducer`] reduces int values and returns their maximum.
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MaxReducer {} pub struct MaxReducer {}
impl<T> Reducer<T> for MaxReducer impl<T> Reducer<T> for MaxReducer
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt
+ Default
+ Copy
+ 'static
+ serde::Serialize
+ serde::de::DeserializeOwned
+ PartialOrd,
{ {
#[inline] #[inline]
fn reduce(first: T, second: T) -> T { fn reduce(first: T, second: T) -> T {
@ -53,13 +68,19 @@ where
} }
} }
/// A [`MinReducer`] reduces [`Integer`] values and returns their minimum. /// A [`MinReducer`] reduces int values and returns their minimum.
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MinReducer {} pub struct MinReducer {}
impl<T> Reducer<T> for MinReducer impl<T> Reducer<T> for MinReducer
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt
+ Default
+ Copy
+ 'static
+ serde::Serialize
+ serde::de::DeserializeOwned
+ PartialOrd,
{ {
#[inline] #[inline]
fn reduce(first: T, second: T) -> T { fn reduce(first: T, second: T) -> T {
@ -71,6 +92,79 @@ where
} }
} }
/// A `MapFindFilter` function gets called after the `MapFeedback` found a new entry.
pub trait MapFindFilter<T>: Serialize + serde::de::DeserializeOwned + 'static
where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
/// If a new value in the [`MapFeedback`] was found,
/// this filter can decide if the result is intersting or not.
/// This way, you can restrict the finds further.
fn is_interesting(old: T, new: T) -> bool;
}
/// A filter that never filters out any finds.
/// The default
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MapNopFilter {}
impl<T> MapFindFilter<T> for MapNopFilter
where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn is_interesting(_old: T, _new: T) -> bool {
true
}
}
/// Calculate the next power of two
/// See <https://stackoverflow.com/a/66253960/1345238>
/// Will saturate at the max value.
/// In case of negative values, returns 1.
#[inline]
fn saturating_next_power_of_two<T: PrimInt>(n: T) -> T {
if n <= T::one() {
T::one()
} else {
(T::max_value() >> (n - T::one()).leading_zeros().try_into().unwrap())
.saturating_add(T::one())
}
}
/// A filter that only saves values which are at least the next pow2 class
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MaxMapPow2Filter {}
impl<T> MapFindFilter<T> for MaxMapPow2Filter
where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn is_interesting(old: T, new: T) -> bool {
// We use a trait so we build our numbers from scratch here.
// This way it works with Nums of any size.
if new <= old {
false
} else {
let pow2 = saturating_next_power_of_two(old.saturating_add(T::one()));
new >= pow2
}
}
}
/// A filter that only saves values which are at least the next pow2 class
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MaxMapOneOrFilledFilter {}
impl<T> MapFindFilter<T> for MaxMapOneOrFilledFilter
where
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{
#[inline]
fn is_interesting(old: T, new: T) -> bool {
(new == T::one() || new == T::one() || new == T::max_value()) && new > old
}
}
/// A testcase metadata holding a list of indexes of a map /// A testcase metadata holding a list of indexes of a map
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct MapIndexesMetadata { pub struct MapIndexesMetadata {
@ -136,7 +230,7 @@ impl MapNoveltiesMetadata {
#[serde(bound = "T: serde::de::DeserializeOwned")] #[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct MapFeedbackState<T> pub struct MapFeedbackState<T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
/// Contains information about untouched entries /// Contains information about untouched entries
pub history_map: Vec<T>, pub history_map: Vec<T>,
@ -146,7 +240,7 @@ where
impl<T> FeedbackState for MapFeedbackState<T> impl<T> FeedbackState for MapFeedbackState<T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
fn reset(&mut self) -> Result<(), Error> { fn reset(&mut self) -> Result<(), Error> {
self.history_map.iter_mut().for_each(|x| *x = T::default()); self.history_map.iter_mut().for_each(|x| *x = T::default());
@ -156,7 +250,7 @@ where
impl<T> Named for MapFeedbackState<T> impl<T> Named for MapFeedbackState<T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &str {
@ -166,7 +260,7 @@ where
impl<T> MapFeedbackState<T> impl<T> MapFeedbackState<T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
/// Create new `MapFeedbackState` /// Create new `MapFeedbackState`
#[must_use] #[must_use]
@ -202,11 +296,12 @@ where
/// The most common AFL-like feedback type /// The most common AFL-like feedback type
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(bound = "T: serde::de::DeserializeOwned")] #[serde(bound = "T: serde::de::DeserializeOwned")]
pub struct MapFeedback<FT, I, O, R, S, T> pub struct MapFeedback<FT, I, MF, O, R, S, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T>, O: MapObserver<T>,
MF: MapFindFilter<T>,
S: HasFeedbackStates<FT>, S: HasFeedbackStates<FT>,
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
{ {
@ -219,14 +314,15 @@ where
/// Name identifier of the observer /// Name identifier of the observer
observer_name: String, observer_name: String,
/// Phantom Data of Reducer /// Phantom Data of Reducer
phantom: PhantomData<(FT, I, S, R, O, T)>, phantom: PhantomData<(FT, I, MF, S, R, O, T)>,
} }
impl<I, FT, O, R, S, T> Feedback<I, S> for MapFeedback<FT, I, O, R, S, T> impl<FT, I, MF, O, R, S, T> Feedback<I, S> for MapFeedback<FT, I, MF, O, R, S, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
O: MapObserver<T>, O: MapObserver<T>,
MF: MapFindFilter<T>,
I: Input, I: Input,
S: HasFeedbackStates<FT> + HasClientPerfStats, S: HasFeedbackStates<FT> + HasClientPerfStats,
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
@ -264,7 +360,7 @@ where
let item = *observer.get(i); let item = *observer.get(i);
let reduced = R::reduce(history, item); let reduced = R::reduce(history, item);
if history != reduced { if history != reduced && MF::is_interesting(history, reduced) {
map_state.history_map[i] = reduced; map_state.history_map[i] = reduced;
interesting = true; interesting = true;
self.novelties.as_mut().unwrap().push(i); self.novelties.as_mut().unwrap().push(i);
@ -276,7 +372,7 @@ where
let item = *observer.get(i); let item = *observer.get(i);
let reduced = R::reduce(history, item); let reduced = R::reduce(history, item);
if history != reduced { if history != reduced && MF::is_interesting(history, reduced) {
map_state.history_map[i] = reduced; map_state.history_map[i] = reduced;
interesting = true; interesting = true;
} }
@ -330,10 +426,11 @@ where
} }
} }
impl<FT, I, O, R, S, T> Named for MapFeedback<FT, I, O, R, S, T> impl<FT, I, MF, O, R, S, T> Named for MapFeedback<FT, I, MF, O, R, S, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
R: Reducer<T>, R: Reducer<T>,
MF: MapFindFilter<T>,
O: MapObserver<T>, O: MapObserver<T>,
S: HasFeedbackStates<FT>, S: HasFeedbackStates<FT>,
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
@ -344,10 +441,17 @@ where
} }
} }
impl<FT, I, O, R, S, T> MapFeedback<FT, I, O, R, S, T> impl<FT, I, MF, O, R, S, T> MapFeedback<FT, I, MF, O, R, S, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt
+ Default
+ Copy
+ 'static
+ serde::Serialize
+ serde::de::DeserializeOwned
+ PartialOrd,
R: Reducer<T>, R: Reducer<T>,
MF: MapFindFilter<T>,
O: MapObserver<T>, O: MapObserver<T>,
S: HasFeedbackStates<FT>, S: HasFeedbackStates<FT>,
FT: FeedbackStatesTuple, FT: FeedbackStatesTuple,
@ -503,3 +607,28 @@ where
self.name.as_str() self.name.as_str()
} }
} }
#[cfg(test)]
mod tests {
use crate::feedbacks::{MapFindFilter, MapNopFilter, MaxMapPow2Filter};
#[test]
fn test_map_max_pow2_filter() {
// sanity check
assert!(MapNopFilter::is_interesting(0_u8, 0));
assert!(!MaxMapPow2Filter::is_interesting(0_u8, 0));
assert!(MaxMapPow2Filter::is_interesting(0_u8, 1));
assert!(!MaxMapPow2Filter::is_interesting(1_u8, 1));
assert!(MaxMapPow2Filter::is_interesting(1_u8, 2));
assert!(!MaxMapPow2Filter::is_interesting(2_u8, 2));
assert!(!MaxMapPow2Filter::is_interesting(2_u8, 3));
assert!(MaxMapPow2Filter::is_interesting(2_u8, 4));
assert!(!MaxMapPow2Filter::is_interesting(128_u8, 128));
assert!(!MaxMapPow2Filter::is_interesting(129_u8, 128));
assert!(MaxMapPow2Filter::is_interesting(128_u8, 255));
assert!(!MaxMapPow2Filter::is_interesting(255_u8, 128));
assert!(MaxMapPow2Filter::is_interesting(254_u8, 255));
assert!(!MaxMapPow2Filter::is_interesting(255_u8, 255));
}
}

View File

@ -10,7 +10,7 @@ use core::{
slice::{from_raw_parts, from_raw_parts_mut}, slice::{from_raw_parts, from_raw_parts_mut},
}; };
use intervaltree::IntervalTree; use intervaltree::IntervalTree;
use num::Integer; use num_traits::PrimInt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -26,7 +26,7 @@ use crate::{
/// A [`MapObserver`] observes the static map, as oftentimes used for afl-like coverage information /// A [`MapObserver`] observes the static map, as oftentimes used for afl-like coverage information
pub trait MapObserver<T>: HasLen + Named + serde::Serialize + serde::de::DeserializeOwned pub trait MapObserver<T>: HasLen + Named + serde::Serialize + serde::de::DeserializeOwned
where where
T: Integer + Default + Copy, T: PrimInt + Default + Copy,
{ {
/// Get the map if the observer can be represented with a slice /// Get the map if the observer can be represented with a slice
fn map(&self) -> Option<&[T]>; fn map(&self) -> Option<&[T]>;
@ -108,7 +108,7 @@ where
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
pub struct StdMapObserver<'a, T> pub struct StdMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
map: OwnedSliceMut<'a, T>, map: OwnedSliceMut<'a, T>,
initial: T, initial: T,
@ -117,7 +117,7 @@ where
impl<'a, I, S, T> Observer<I, S> for StdMapObserver<'a, T> impl<'a, I, S, T> Observer<I, S> for StdMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
Self: MapObserver<T>, Self: MapObserver<T>,
{ {
#[inline] #[inline]
@ -128,7 +128,7 @@ where
impl<'a, T> Named for StdMapObserver<'a, T> impl<'a, T> Named for StdMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &str {
@ -138,7 +138,7 @@ where
impl<'a, T> HasLen for StdMapObserver<'a, T> impl<'a, T> HasLen for StdMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -148,7 +148,7 @@ where
impl<'a, T> MapObserver<T> for StdMapObserver<'a, T> impl<'a, T> MapObserver<T> for StdMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn map(&self) -> Option<&[T]> { fn map(&self) -> Option<&[T]> {
@ -178,7 +178,7 @@ where
impl<'a, T> StdMapObserver<'a, T> impl<'a, T> StdMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] /// Creates a new [`MapObserver`]
#[must_use] #[must_use]
@ -223,7 +223,7 @@ where
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
pub struct ConstMapObserver<'a, T, const N: usize> pub struct ConstMapObserver<'a, T, const N: usize>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
map: OwnedSliceMut<'a, T>, map: OwnedSliceMut<'a, T>,
initial: T, initial: T,
@ -232,7 +232,7 @@ where
impl<'a, I, S, T, const N: usize> Observer<I, S> for ConstMapObserver<'a, T, N> impl<'a, I, S, T, const N: usize> Observer<I, S> for ConstMapObserver<'a, T, N>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
Self: MapObserver<T>, Self: MapObserver<T>,
{ {
#[inline] #[inline]
@ -243,7 +243,7 @@ where
impl<'a, T, const N: usize> Named for ConstMapObserver<'a, T, N> impl<'a, T, const N: usize> Named for ConstMapObserver<'a, T, N>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &str {
@ -253,7 +253,7 @@ where
impl<'a, T, const N: usize> HasLen for ConstMapObserver<'a, T, N> impl<'a, T, const N: usize> HasLen for ConstMapObserver<'a, T, N>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -263,7 +263,7 @@ where
impl<'a, T, const N: usize> MapObserver<T> for ConstMapObserver<'a, T, N> impl<'a, T, const N: usize> MapObserver<T> for ConstMapObserver<'a, T, N>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn usable_count(&self) -> usize { fn usable_count(&self) -> usize {
@ -298,7 +298,7 @@ where
impl<'a, T, const N: usize> ConstMapObserver<'a, T, N> impl<'a, T, const N: usize> ConstMapObserver<'a, T, N>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] /// Creates a new [`MapObserver`]
#[must_use] #[must_use]
@ -344,7 +344,7 @@ where
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
pub struct VariableMapObserver<'a, T> pub struct VariableMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
map: OwnedSliceMut<'a, T>, map: OwnedSliceMut<'a, T>,
size: OwnedRefMut<'a, usize>, size: OwnedRefMut<'a, usize>,
@ -354,7 +354,7 @@ where
impl<'a, I, S, T> Observer<I, S> for VariableMapObserver<'a, T> impl<'a, I, S, T> Observer<I, S> for VariableMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
Self: MapObserver<T>, Self: MapObserver<T>,
{ {
#[inline] #[inline]
@ -365,7 +365,7 @@ where
impl<'a, T> Named for VariableMapObserver<'a, T> impl<'a, T> Named for VariableMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &str {
@ -375,7 +375,7 @@ where
impl<'a, T> HasLen for VariableMapObserver<'a, T> impl<'a, T> HasLen for VariableMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -385,7 +385,7 @@ where
impl<'a, T> MapObserver<T> for VariableMapObserver<'a, T> impl<'a, T> MapObserver<T> for VariableMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn map(&self) -> Option<&[T]> { fn map(&self) -> Option<&[T]> {
@ -420,7 +420,7 @@ where
impl<'a, T> VariableMapObserver<'a, T> impl<'a, T> VariableMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MapObserver`] /// Creates a new [`MapObserver`]
pub fn new(name: &'static str, map: &'a mut [T], size: &'a mut usize) -> Self { pub fn new(name: &'static str, map: &'a mut [T], size: &'a mut usize) -> Self {
@ -568,7 +568,7 @@ where
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
pub struct MultiMapObserver<'a, T> pub struct MultiMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
maps: Vec<OwnedSliceMut<'a, T>>, maps: Vec<OwnedSliceMut<'a, T>>,
intervals: IntervalTree<usize, usize>, intervals: IntervalTree<usize, usize>,
@ -579,7 +579,7 @@ where
impl<'a, I, S, T> Observer<I, S> for MultiMapObserver<'a, T> impl<'a, I, S, T> Observer<I, S> for MultiMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
Self: MapObserver<T>, Self: MapObserver<T>,
{ {
#[inline] #[inline]
@ -590,7 +590,7 @@ where
impl<'a, T> Named for MultiMapObserver<'a, T> impl<'a, T> Named for MultiMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &str {
@ -600,7 +600,7 @@ where
impl<'a, T> HasLen for MultiMapObserver<'a, T> impl<'a, T> HasLen for MultiMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -610,7 +610,7 @@ where
impl<'a, T> MapObserver<T> for MultiMapObserver<'a, T> impl<'a, T> MapObserver<T> for MultiMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn map(&self) -> Option<&[T]> { fn map(&self) -> Option<&[T]> {
@ -692,7 +692,7 @@ where
impl<'a, T> MultiMapObserver<'a, T> impl<'a, T> MultiMapObserver<'a, T>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
{ {
/// Creates a new [`MultiMapObserver`] /// Creates a new [`MultiMapObserver`]
#[must_use] #[must_use]

View File

@ -16,13 +16,13 @@ use alloc::{
vec::Vec, vec::Vec,
}; };
use core::{marker::PhantomData, time::Duration}; use core::{marker::PhantomData, time::Duration};
use num::Integer; use num_traits::PrimInt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CalibrationStage<C, E, EM, I, O, OT, S, T, Z> pub struct CalibrationStage<C, E, EM, I, O, OT, S, T, Z>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
C: Corpus<I>, C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
@ -42,7 +42,7 @@ const CAL_STAGE_MAX: usize = 8;
impl<C, E, EM, I, O, OT, S, T, Z> Stage<E, EM, S, Z> impl<C, E, EM, I, O, OT, S, T, Z> Stage<E, EM, S, Z>
for CalibrationStage<C, E, EM, I, O, OT, S, T, Z> for CalibrationStage<C, E, EM, I, O, OT, S, T, Z>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
C: Corpus<I>, C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
@ -210,7 +210,7 @@ crate::impl_serdeany!(PowerScheduleMetadata);
impl<C, E, I, EM, O, OT, S, T, Z> CalibrationStage<C, E, EM, I, O, OT, S, T, Z> impl<C, E, I, EM, O, OT, S, T, Z> CalibrationStage<C, E, EM, I, O, OT, S, T, Z>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
C: Corpus<I>, C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,

View File

@ -2,7 +2,7 @@
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use core::marker::PhantomData; use core::marker::PhantomData;
use num::Integer; use num_traits::PrimInt;
use crate::{ use crate::{
corpus::{Corpus, IsFavoredMetadata, PowerScheduleTestcaseMetaData, Testcase}, corpus::{Corpus, IsFavoredMetadata, PowerScheduleTestcaseMetaData, Testcase},
@ -34,7 +34,7 @@ const HAVOC_MAX_MULT: f64 = 64.0;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> pub struct PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
C: Corpus<I>, C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
@ -55,7 +55,7 @@ where
impl<C, E, EM, I, M, O, OT, S, T, Z> MutationalStage<C, E, EM, I, M, S, Z> impl<C, E, EM, I, M, O, OT, S, T, Z> MutationalStage<C, E, EM, I, M, S, Z>
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
C: Corpus<I>, C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
@ -156,7 +156,7 @@ where
impl<C, E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z> impl<C, E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z>
for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> for PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
C: Corpus<I>, C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,
@ -183,7 +183,7 @@ where
impl<C, E, EM, I, M, O, OT, S, T, Z> PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z> impl<C, E, EM, I, M, O, OT, S, T, Z> PowerMutationalStage<C, E, EM, I, M, O, OT, S, T, Z>
where where
T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned,
C: Corpus<I>, C: Corpus<I>,
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>, E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
I: Input, I: Input,

View File

@ -19,7 +19,7 @@ libafl = { path = "../libafl", version = "0.6.1" }
libafl_targets = { path = "../libafl_targets", version = "0.6.1" } libafl_targets = { path = "../libafl_targets", version = "0.6.1" }
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
hashbrown = { version = "0.9", features = ["serde", "ahash-compile-time-rng"] } # A faster hashmap, nostd compatible hashbrown = { version = "0.9", features = ["serde", "ahash-compile-time-rng"] } # A faster hashmap, nostd compatible
num = "0.4" num-traits = "0.2"
num_enum = "0.5.1" num_enum = "0.5.1"
goblin = "0.4.2" goblin = "0.4.2"
libc = "0.2" libc = "0.2"

View File

@ -6,8 +6,8 @@ use core::{
mem::{size_of, transmute, MaybeUninit}, mem::{size_of, transmute, MaybeUninit},
ptr::{copy_nonoverlapping, null}, ptr::{copy_nonoverlapping, null},
}; };
use num::Num;
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
use num_traits::Num;
use std::{slice::from_raw_parts, str::from_utf8_unchecked}; use std::{slice::from_raw_parts, str::from_utf8_unchecked};
use strum_macros::EnumIter; use strum_macros::EnumIter;