diff --git a/libafl/Cargo.toml b/libafl/Cargo.toml index f0b02df3b7..ed37ce0fe4 100644 --- a/libafl/Cargo.toml +++ b/libafl/Cargo.toml @@ -46,7 +46,7 @@ serial_test = "0.5" [dependencies] tuple_list = { version = "0.1.3" } 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 serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib erased-serde = { version = "0.3.12", default-features = false, features = ["alloc"] } # erased serde diff --git a/libafl/src/feedbacks/map.rs b/libafl/src/feedbacks/map.rs index 467dc3c943..338a2f8858 100644 --- a/libafl/src/feedbacks/map.rs +++ b/libafl/src/feedbacks/map.rs @@ -5,7 +5,7 @@ use alloc::{ vec::Vec, }; use core::marker::PhantomData; -use num::Integer; +use num_traits::PrimInt; use serde::{Deserialize, Serialize}; use crate::{ @@ -22,26 +22,41 @@ use crate::{ }; /// A [`MapFeedback`] that strives to maximize the map contents. -pub type MaxMapFeedback = MapFeedback; +pub type MaxMapFeedback = MapFeedback; /// A [`MapFeedback`] that strives to minimize the map contents. -pub type MinMapFeedback = MapFeedback; +pub type MinMapFeedback = MapFeedback; -/// 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 = + MapFeedback; +/// A [`MapFeedback`] that strives to maximize the map contents, +/// but only, if a value is larger than `pow2` of the previous. +pub type MaxMapOneOrFilledFeedback = + MapFeedback; + +/// A `Reducer` function is used to aggregate values for the novelty search pub trait Reducer: Serialize + serde::de::DeserializeOwned + 'static 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`]. 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)] pub struct MaxReducer {} impl Reducer for MaxReducer where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + + Default + + Copy + + 'static + + serde::Serialize + + serde::de::DeserializeOwned + + PartialOrd, { #[inline] 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)] pub struct MinReducer {} impl Reducer for MinReducer where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + + Default + + Copy + + 'static + + serde::Serialize + + serde::de::DeserializeOwned + + PartialOrd, { #[inline] 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: 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 MapFindFilter 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 +/// Will saturate at the max value. +/// In case of negative values, returns 1. +#[inline] +fn saturating_next_power_of_two(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 MapFindFilter 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 MapFindFilter 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 #[derive(Serialize, Deserialize)] pub struct MapIndexesMetadata { @@ -136,7 +230,7 @@ impl MapNoveltiesMetadata { #[serde(bound = "T: serde::de::DeserializeOwned")] pub struct MapFeedbackState 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 pub history_map: Vec, @@ -146,7 +240,7 @@ where impl FeedbackState for MapFeedbackState 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> { self.history_map.iter_mut().for_each(|x| *x = T::default()); @@ -156,7 +250,7 @@ where impl Named for MapFeedbackState where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn name(&self) -> &str { @@ -166,7 +260,7 @@ where impl MapFeedbackState where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { /// Create new `MapFeedbackState` #[must_use] @@ -202,11 +296,12 @@ where /// The most common AFL-like feedback type #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(bound = "T: serde::de::DeserializeOwned")] -pub struct MapFeedback +pub struct MapFeedback where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, R: Reducer, O: MapObserver, + MF: MapFindFilter, S: HasFeedbackStates, FT: FeedbackStatesTuple, { @@ -219,14 +314,15 @@ where /// Name identifier of the observer observer_name: String, /// Phantom Data of Reducer - phantom: PhantomData<(FT, I, S, R, O, T)>, + phantom: PhantomData<(FT, I, MF, S, R, O, T)>, } -impl Feedback for MapFeedback +impl Feedback for MapFeedback where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, R: Reducer, O: MapObserver, + MF: MapFindFilter, I: Input, S: HasFeedbackStates + HasClientPerfStats, FT: FeedbackStatesTuple, @@ -264,7 +360,7 @@ where let item = *observer.get(i); let reduced = R::reduce(history, item); - if history != reduced { + if history != reduced && MF::is_interesting(history, reduced) { map_state.history_map[i] = reduced; interesting = true; self.novelties.as_mut().unwrap().push(i); @@ -276,7 +372,7 @@ where let item = *observer.get(i); let reduced = R::reduce(history, item); - if history != reduced { + if history != reduced && MF::is_interesting(history, reduced) { map_state.history_map[i] = reduced; interesting = true; } @@ -330,10 +426,11 @@ where } } -impl Named for MapFeedback +impl Named for MapFeedback where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, R: Reducer, + MF: MapFindFilter, O: MapObserver, S: HasFeedbackStates, FT: FeedbackStatesTuple, @@ -344,10 +441,17 @@ where } } -impl MapFeedback +impl MapFeedback where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + + Default + + Copy + + 'static + + serde::Serialize + + serde::de::DeserializeOwned + + PartialOrd, R: Reducer, + MF: MapFindFilter, O: MapObserver, S: HasFeedbackStates, FT: FeedbackStatesTuple, @@ -503,3 +607,28 @@ where 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)); + } +} diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index 221a43926d..b1f82ce00d 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -10,7 +10,7 @@ use core::{ slice::{from_raw_parts, from_raw_parts_mut}, }; use intervaltree::IntervalTree; -use num::Integer; +use num_traits::PrimInt; use serde::{Deserialize, Serialize}; use crate::{ @@ -26,7 +26,7 @@ use crate::{ /// A [`MapObserver`] observes the static map, as oftentimes used for afl-like coverage information pub trait MapObserver: HasLen + Named + serde::Serialize + serde::de::DeserializeOwned where - T: Integer + Default + Copy, + T: PrimInt + Default + Copy, { /// Get the map if the observer can be represented with a slice fn map(&self) -> Option<&[T]>; @@ -108,7 +108,7 @@ where #[allow(clippy::unsafe_derive_deserialize)] pub struct StdMapObserver<'a, T> 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>, initial: T, @@ -117,7 +117,7 @@ where impl<'a, I, S, T> Observer for StdMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, Self: MapObserver, { #[inline] @@ -128,7 +128,7 @@ where impl<'a, T> Named for StdMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn name(&self) -> &str { @@ -138,7 +138,7 @@ where impl<'a, T> HasLen for StdMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn len(&self) -> usize { @@ -148,7 +148,7 @@ where impl<'a, T> MapObserver for StdMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn map(&self) -> Option<&[T]> { @@ -178,7 +178,7 @@ where impl<'a, T> StdMapObserver<'a, T> 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`] #[must_use] @@ -223,7 +223,7 @@ where #[allow(clippy::unsafe_derive_deserialize)] pub struct ConstMapObserver<'a, T, const N: usize> 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>, initial: T, @@ -232,7 +232,7 @@ where impl<'a, I, S, T, const N: usize> Observer for ConstMapObserver<'a, T, N> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, Self: MapObserver, { #[inline] @@ -243,7 +243,7 @@ where impl<'a, T, const N: usize> Named for ConstMapObserver<'a, T, N> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn name(&self) -> &str { @@ -253,7 +253,7 @@ where impl<'a, T, const N: usize> HasLen for ConstMapObserver<'a, T, N> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn len(&self) -> usize { @@ -263,7 +263,7 @@ where impl<'a, T, const N: usize> MapObserver for ConstMapObserver<'a, T, N> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn usable_count(&self) -> usize { @@ -298,7 +298,7 @@ where impl<'a, T, const N: usize> ConstMapObserver<'a, T, N> 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`] #[must_use] @@ -344,7 +344,7 @@ where #[allow(clippy::unsafe_derive_deserialize)] pub struct VariableMapObserver<'a, T> 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>, size: OwnedRefMut<'a, usize>, @@ -354,7 +354,7 @@ where impl<'a, I, S, T> Observer for VariableMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, Self: MapObserver, { #[inline] @@ -365,7 +365,7 @@ where impl<'a, T> Named for VariableMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn name(&self) -> &str { @@ -375,7 +375,7 @@ where impl<'a, T> HasLen for VariableMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn len(&self) -> usize { @@ -385,7 +385,7 @@ where impl<'a, T> MapObserver for VariableMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn map(&self) -> Option<&[T]> { @@ -420,7 +420,7 @@ where impl<'a, T> VariableMapObserver<'a, T> 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`] 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)] pub struct MultiMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { maps: Vec>, intervals: IntervalTree, @@ -579,7 +579,7 @@ where impl<'a, I, S, T> Observer for MultiMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, Self: MapObserver, { #[inline] @@ -590,7 +590,7 @@ where impl<'a, T> Named for MultiMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn name(&self) -> &str { @@ -600,7 +600,7 @@ where impl<'a, T> HasLen for MultiMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn len(&self) -> usize { @@ -610,7 +610,7 @@ where impl<'a, T> MapObserver for MultiMapObserver<'a, T> where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, { #[inline] fn map(&self) -> Option<&[T]> { @@ -692,7 +692,7 @@ where impl<'a, T> MultiMapObserver<'a, T> 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`] #[must_use] diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 7b116b3863..7978256dfc 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -16,13 +16,13 @@ use alloc::{ vec::Vec, }; use core::{marker::PhantomData, time::Duration}; -use num::Integer; +use num_traits::PrimInt; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug)] pub struct CalibrationStage where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, C: Corpus, E: Executor + HasObservers, I: Input, @@ -42,7 +42,7 @@ const CAL_STAGE_MAX: usize = 8; impl Stage for CalibrationStage where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, C: Corpus, E: Executor + HasObservers, I: Input, @@ -210,7 +210,7 @@ crate::impl_serdeany!(PowerScheduleMetadata); impl CalibrationStage where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, C: Corpus, E: Executor + HasObservers, I: Input, diff --git a/libafl/src/stages/power.rs b/libafl/src/stages/power.rs index 2b5a19a1da..ac4e6854d1 100644 --- a/libafl/src/stages/power.rs +++ b/libafl/src/stages/power.rs @@ -2,7 +2,7 @@ use alloc::string::{String, ToString}; use core::marker::PhantomData; -use num::Integer; +use num_traits::PrimInt; use crate::{ corpus::{Corpus, IsFavoredMetadata, PowerScheduleTestcaseMetaData, Testcase}, @@ -34,7 +34,7 @@ const HAVOC_MAX_MULT: f64 = 64.0; #[derive(Clone, Debug)] pub struct PowerMutationalStage where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, C: Corpus, E: Executor + HasObservers, I: Input, @@ -55,7 +55,7 @@ where impl MutationalStage for PowerMutationalStage where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, C: Corpus, E: Executor + HasObservers, I: Input, @@ -156,7 +156,7 @@ where impl Stage for PowerMutationalStage where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, C: Corpus, E: Executor + HasObservers, I: Input, @@ -183,7 +183,7 @@ where impl PowerMutationalStage where - T: Integer + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned, C: Corpus, E: Executor + HasObservers, I: Input, diff --git a/libafl_qemu/Cargo.toml b/libafl_qemu/Cargo.toml index 226465d8ea..df5e8078fa 100644 --- a/libafl_qemu/Cargo.toml +++ b/libafl_qemu/Cargo.toml @@ -19,7 +19,7 @@ libafl = { path = "../libafl", version = "0.6.1" } libafl_targets = { path = "../libafl_targets", version = "0.6.1" } 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 -num = "0.4" +num-traits = "0.2" num_enum = "0.5.1" goblin = "0.4.2" libc = "0.2" diff --git a/libafl_qemu/src/emu.rs b/libafl_qemu/src/emu.rs index 90358b7960..40d1660567 100644 --- a/libafl_qemu/src/emu.rs +++ b/libafl_qemu/src/emu.rs @@ -6,8 +6,8 @@ use core::{ mem::{size_of, transmute, MaybeUninit}, ptr::{copy_nonoverlapping, null}, }; -use num::Num; use num_enum::{IntoPrimitive, TryFromPrimitive}; +use num_traits::Num; use std::{slice::from_raw_parts, str::from_utf8_unchecked}; use strum_macros::EnumIter;