From e450ab7dc2001f4231880230286a6377c70353d2 Mon Sep 17 00:00:00 2001 From: Edwin Fernando Date: Mon, 1 Apr 2024 15:23:22 +0100 Subject: [PATCH 1/6] MapObserver implements Hash * Rename the hash utility function (in MapObserver) to hash_easy * Use hash_slice as a helper function to impl Hash trait --- libafl/src/observers/map.rs | 135 +++++++++++++++++++++++------- libafl/src/schedulers/mod.rs | 2 +- libafl/src/stages/colorization.rs | 2 +- libafl/src/stages/tmin.rs | 4 +- 4 files changed, 109 insertions(+), 34 deletions(-) diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index 652c2b5aac..9f906e236c 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -6,7 +6,7 @@ use alloc::{ }; use core::{ fmt::Debug, - hash::{BuildHasher, Hasher}, + hash::{BuildHasher, Hash, Hasher}, iter::Flatten, marker::PhantomData, mem::size_of, @@ -70,8 +70,7 @@ fn init_count_class_16() { } /// Compute the hash of a slice -fn hash_slice(slice: &[T]) -> u64 { - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); +fn hash_slice(slice: &[T], hasher: &mut H) -> u64 { let ptr = slice.as_ptr() as *const u8; let map_size = slice.len() / size_of::(); unsafe { @@ -83,7 +82,7 @@ fn hash_slice(slice: &[T]) -> u64 { /// A [`MapObserver`] observes the static map, as oftentimes used for AFL-like coverage information /// /// TODO: enforce `iter() -> AssociatedTypeIter` when generic associated types stabilize -pub trait MapObserver: HasLen + Named + Serialize + serde::de::DeserializeOwned +pub trait MapObserver: HasLen + Named + Serialize + serde::de::DeserializeOwned + Hash // where // for<'it> &'it Self: IntoIterator { @@ -102,8 +101,8 @@ pub trait MapObserver: HasLen + Named + Serialize + serde::de::DeserializeOwned /// Count the set bytes in the map fn count_bytes(&self) -> u64; - /// Compute the hash of the map - fn hash(&self) -> u64; + /// Compute the hash of the map without needing to provide a hasher + fn hash_easy(&self) -> u64; /// Get the initial value for `reset()` fn initial(&self) -> Self::Entry; @@ -346,6 +345,22 @@ where } } +impl<'a, T, const DIFFERENTIAL: bool> Hash for StdMapObserver<'a, T, DIFFERENTIAL> +where + T: Bounded + + PartialEq + + Default + + Copy + + 'static + + Serialize + + serde::de::DeserializeOwned + + Debug, +{ + fn hash(&self, hasher: &mut H) { + hash_slice(self.as_slice(), hasher); + } +} + impl<'a, T, const DIFFERENTIAL: bool> MapObserver for StdMapObserver<'a, T, DIFFERENTIAL> where T: Bounded @@ -388,8 +403,10 @@ where self.as_slice().len() } - fn hash(&self) -> u64 { - hash_slice(self.as_slice()) + fn hash_easy(&self) -> u64 { + let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); + Hash::hash(self, &mut hasher); + hasher.finish() } #[inline] @@ -830,6 +847,22 @@ where } } +impl<'a, T, const N: usize> Hash for ConstMapObserver<'a, T, N> +where + T: Bounded + + PartialEq + + Default + + Copy + + 'static + + Serialize + + serde::de::DeserializeOwned + + Debug, +{ + fn hash(&self, hasher: &mut H) { + hash_slice(self.as_slice(), hasher); + } +} + impl<'a, T, const N: usize> MapObserver for ConstMapObserver<'a, T, N> where T: Bounded @@ -876,8 +909,10 @@ where self.as_slice().len() } - fn hash(&self) -> u64 { - hash_slice(self.as_slice()) + fn hash_easy(&self) -> u64 { + let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); + Hash::hash(self, &mut hasher); + hasher.finish() } /// Reset the map @@ -1142,6 +1177,24 @@ where } } +impl<'a, T> Hash for VariableMapObserver<'a, T> +where + T: Bounded + + PartialEq + + Default + + Copy + + 'static + + Serialize + + serde::de::DeserializeOwned + + Debug + + PartialEq + + Bounded, +{ + fn hash(&self, hasher: &mut H) { + hash_slice(self.as_slice(), hasher); + } +} + impl<'a, T> MapObserver for VariableMapObserver<'a, T> where T: Bounded @@ -1188,8 +1241,10 @@ where } res } - fn hash(&self) -> u64 { - hash_slice(self.as_slice()) + fn hash_easy(&self) -> u64 { + let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); + Hash::hash(self, &mut hasher); + hasher.finish() } /// Reset the map @@ -1307,7 +1362,7 @@ where /// /// [`MapObserver`]s that are not slice-backed, /// such as [`MultiMapObserver`], can use [`HitcountsIterableMapObserver`] instead. -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Hash)] #[serde(bound = "M: serde::de::DeserializeOwned")] pub struct HitcountsMapObserver where @@ -1433,8 +1488,8 @@ where self.base.reset_map() } - fn hash(&self) -> u64 { - self.base.hash() + fn hash_easy(&self) -> u64 { + self.base.hash_easy() } fn to_vec(&self) -> Vec { self.base.to_vec() @@ -1589,7 +1644,7 @@ where /// Map observer with hitcounts postprocessing /// Less optimized version for non-slice iterators. /// Slice-backed observers should use a [`HitcountsMapObserver`]. -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Hash)] #[serde(bound = "M: serde::de::DeserializeOwned")] pub struct HitcountsIterableMapObserver where @@ -1683,8 +1738,8 @@ where self.base.reset_map() } - fn hash(&self) -> u64 { - self.base.hash() + fn hash_easy(&self) -> u64 { + self.base.hash_easy() } fn to_vec(&self) -> Vec { self.base.to_vec() @@ -1890,6 +1945,22 @@ where } } +impl<'a, T, const DIFFERENTIAL: bool> Hash for MultiMapObserver<'a, T, DIFFERENTIAL> +where + T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, +{ + fn hash(&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::(); + unsafe { + hasher.write(slice::from_raw_parts(ptr, map_size)); + } + } + } +} + impl<'a, T, const DIFFERENTIAL: bool> MapObserver for MultiMapObserver<'a, T, DIFFERENTIAL> where T: 'static @@ -1937,16 +2008,9 @@ where res } - fn hash(&self) -> u64 { + fn hash_easy(&self) -> u64 { let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - 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::(); - unsafe { - hasher.write(slice::from_raw_parts(ptr, map_size)); - } - } + Hash::hash(self, &mut hasher); hasher.finish() } @@ -2246,6 +2310,15 @@ where } } +impl Hash for OwnedMapObserver +where + T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, +{ + fn hash(&self, hasher: &mut H) { + hash_slice(self.as_slice(), hasher); + } +} + impl MapObserver for OwnedMapObserver where T: 'static @@ -2288,8 +2361,10 @@ where self.as_slice().len() } - fn hash(&self) -> u64 { - hash_slice(self.as_slice()) + fn hash_easy(&self) -> u64 { + let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); + Hash::hash(self, &mut hasher); + hasher.finish() } #[inline] @@ -2666,7 +2741,7 @@ pub mod pybind { mapob_unwrap_me!($wrapper_name, self.wrapper, m, { m.usable_count() }) } - fn hash(&self) -> u64 { + fn hash_easy(&self) -> u64 { mapob_unwrap_me!($wrapper_name, self.wrapper, m, { m.hash() }) } diff --git a/libafl/src/schedulers/mod.rs b/libafl/src/schedulers/mod.rs index e3664e8b35..23ee289686 100644 --- a/libafl/src/schedulers/mod.rs +++ b/libafl/src/schedulers/mod.rs @@ -194,7 +194,7 @@ where .match_name::(self.map_observer_name()) .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))?; - let mut hash = observer.hash() as usize; + let mut hash = observer.hash_easy() as usize; let psmeta = state.metadata_mut::()?; diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index f1015893c6..c4a71088f5 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -322,7 +322,7 @@ where .match_name::(name) .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))?; - let hash = observer.hash() as usize; + let hash = observer.hash_easy() as usize; executor .observers_mut() diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index a4235cdc78..0a7eee895c 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -401,7 +401,7 @@ where let obs = observers .match_name::(self.observer_name()) .expect("Should have been provided valid observer name."); - Ok(obs.hash() == self.orig_hash) + Ok(obs.hash_easy() == self.orig_hash) } } @@ -444,7 +444,7 @@ where MapEqualityFeedback { name: "MapEq".to_string(), obs_name: self.obs_name.clone(), - orig_hash: obs.hash(), + orig_hash: obs.hash_easy(), phantom: PhantomData, } } From 5a53b75cc5952b5bdff1f1e6f4c7bcda5894b067 Mon Sep 17 00:00:00 2001 From: Edwin Fernando Date: Sun, 7 Apr 2024 14:58:12 +0100 Subject: [PATCH 2/6] define_python_map_observer macro implements Hash trait * Also rename hash_easy to hash_simple --- libafl/src/observers/map.rs | 38 +++++++++++++++++++++---------- libafl/src/schedulers/mod.rs | 2 +- libafl/src/stages/colorization.rs | 2 +- libafl/src/stages/tmin.rs | 4 ++-- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index 9f906e236c..44b3e65fe7 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -102,7 +102,7 @@ pub trait MapObserver: HasLen + Named + Serialize + serde::de::DeserializeOwned fn count_bytes(&self) -> u64; /// Compute the hash of the map without needing to provide a hasher - fn hash_easy(&self) -> u64; + fn hash_simple(&self) -> u64; /// Get the initial value for `reset()` fn initial(&self) -> Self::Entry; @@ -403,7 +403,8 @@ where self.as_slice().len() } - fn hash_easy(&self) -> u64 { + #[inline] + fn hash_simple(&self) -> u64 { let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); Hash::hash(self, &mut hasher); hasher.finish() @@ -909,7 +910,8 @@ where self.as_slice().len() } - fn hash_easy(&self) -> u64 { + #[inline] + fn hash_simple(&self) -> u64 { let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); Hash::hash(self, &mut hasher); hasher.finish() @@ -1241,7 +1243,9 @@ where } res } - fn hash_easy(&self) -> u64 { + + #[inline] + fn hash_simple(&self) -> u64 { let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); Hash::hash(self, &mut hasher); hasher.finish() @@ -1488,8 +1492,9 @@ where self.base.reset_map() } - fn hash_easy(&self) -> u64 { - self.base.hash_easy() + #[inline] + fn hash_simple(&self) -> u64 { + self.base.hash_simple() } fn to_vec(&self) -> Vec { self.base.to_vec() @@ -1738,8 +1743,9 @@ where self.base.reset_map() } - fn hash_easy(&self) -> u64 { - self.base.hash_easy() + #[inline] + fn hash_simple(&self) -> u64 { + self.base.hash_simple() } fn to_vec(&self) -> Vec { self.base.to_vec() @@ -2008,7 +2014,8 @@ where res } - fn hash_easy(&self) -> u64 { + #[inline] + fn hash_simple(&self) -> u64 { let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); Hash::hash(self, &mut hasher); hasher.finish() @@ -2361,7 +2368,8 @@ where self.as_slice().len() } - fn hash_easy(&self) -> u64 { + #[inline] + fn hash_simple(&self) -> u64 { let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); Hash::hash(self, &mut hasher); hasher.finish() @@ -2717,6 +2725,12 @@ pub mod pybind { } } + impl Hash for $struct_name_trait { + fn hash(&self, hasher: &mut H) { + hash_slice(self.as_slice(), hasher); + } + } + impl MapObserver for $struct_name_trait { type Entry = $datatype; @@ -2741,8 +2755,8 @@ pub mod pybind { mapob_unwrap_me!($wrapper_name, self.wrapper, m, { m.usable_count() }) } - fn hash_easy(&self) -> u64 { - mapob_unwrap_me!($wrapper_name, self.wrapper, m, { m.hash() }) + fn hash_simple(&self) -> u64 { + mapob_unwrap_me!($wrapper_name, self.wrapper, m, { m.hash_simple() }) } #[inline] diff --git a/libafl/src/schedulers/mod.rs b/libafl/src/schedulers/mod.rs index 23ee289686..494a354c30 100644 --- a/libafl/src/schedulers/mod.rs +++ b/libafl/src/schedulers/mod.rs @@ -194,7 +194,7 @@ where .match_name::(self.map_observer_name()) .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))?; - let mut hash = observer.hash_easy() as usize; + let mut hash = observer.hash_simple() as usize; let psmeta = state.metadata_mut::()?; diff --git a/libafl/src/stages/colorization.rs b/libafl/src/stages/colorization.rs index c4a71088f5..8919077c03 100644 --- a/libafl/src/stages/colorization.rs +++ b/libafl/src/stages/colorization.rs @@ -322,7 +322,7 @@ where .match_name::(name) .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))?; - let hash = observer.hash_easy() as usize; + let hash = observer.hash_simple() as usize; executor .observers_mut() diff --git a/libafl/src/stages/tmin.rs b/libafl/src/stages/tmin.rs index 0a7eee895c..3331fb12e2 100644 --- a/libafl/src/stages/tmin.rs +++ b/libafl/src/stages/tmin.rs @@ -401,7 +401,7 @@ where let obs = observers .match_name::(self.observer_name()) .expect("Should have been provided valid observer name."); - Ok(obs.hash_easy() == self.orig_hash) + Ok(obs.hash_simple() == self.orig_hash) } } @@ -444,7 +444,7 @@ where MapEqualityFeedback { name: "MapEq".to_string(), obs_name: self.obs_name.clone(), - orig_hash: obs.hash_easy(), + orig_hash: obs.hash_simple(), phantom: PhantomData, } } From d17012c314a01c34133c06ab00ad1d21c8f1cb98 Mon Sep 17 00:00:00 2001 From: Edwin Fernando Date: Sun, 7 Apr 2024 15:37:39 +0100 Subject: [PATCH 3/6] Rename hash_slice to hash_helper * hash_helper is used to define the implementation of hash function/trait --- libafl/src/observers/map.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index 44b3e65fe7..b68c650c19 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -70,7 +70,7 @@ fn init_count_class_16() { } /// Compute the hash of a slice -fn hash_slice(slice: &[T], hasher: &mut H) -> u64 { +fn hash_helper(slice: &[T], hasher: &mut H) -> u64 { let ptr = slice.as_ptr() as *const u8; let map_size = slice.len() / size_of::(); unsafe { @@ -357,7 +357,7 @@ where + Debug, { fn hash(&self, hasher: &mut H) { - hash_slice(self.as_slice(), hasher); + hash_helper(self.as_slice(), hasher); } } @@ -860,7 +860,7 @@ where + Debug, { fn hash(&self, hasher: &mut H) { - hash_slice(self.as_slice(), hasher); + hash_helper(self.as_slice(), hasher); } } @@ -1193,7 +1193,7 @@ where + Bounded, { fn hash(&self, hasher: &mut H) { - hash_slice(self.as_slice(), hasher); + hash_helper(self.as_slice(), hasher); } } @@ -2322,7 +2322,7 @@ where T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, { fn hash(&self, hasher: &mut H) { - hash_slice(self.as_slice(), hasher); + hash_helper(self.as_slice(), hasher); } } @@ -2727,7 +2727,7 @@ pub mod pybind { impl Hash for $struct_name_trait { fn hash(&self, hasher: &mut H) { - hash_slice(self.as_slice(), hasher); + hash_helper(self.as_slice(), hasher); } } From 8128b7b529980e699d1ad1f37d3eabf0b2c4762d Mon Sep 17 00:00:00 2001 From: Edwin Fernando Date: Mon, 15 Apr 2024 11:37:40 +0100 Subject: [PATCH 4/6] Factor out the Hash trait and function for runtime library structs (#1977) --- .../libafl_libfuzzer_runtime/src/observers.rs | 28 ++++++++++++------ libafl_targets/src/sancov_8bit.rs | 29 +++++++++++-------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs index 22ada45c5a..16f802737d 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/observers.rs @@ -70,6 +70,23 @@ impl Named for MappedEdgeMapObserver { } } +impl Hash for MappedEdgeMapObserver +where + M: MapObserver + for<'it> AsIter<'it, Item = M::Entry>, + O: ValueObserver, +{ + fn hash(&self, hasher: &mut H) { + let initial = self.inner.initial(); + for e in self.inner.as_iter() { + if *e == initial { + self.value_observer.default_value().hash(hasher); + } else { + self.value_observer.value().hash(hasher); + } + } + } +} + impl MapObserver for MappedEdgeMapObserver where M: MapObserver + for<'it> AsIter<'it, Item = M::Entry>, @@ -98,16 +115,9 @@ where self.inner.count_bytes() } - fn hash(&self) -> u64 { + fn hash_simple(&self) -> u64 { let mut hasher = AHasher::default(); - let initial = self.inner.initial(); - for e in self.inner.as_iter() { - if *e == initial { - self.value_observer.default_value().hash(&mut hasher); - } else { - self.value_observer.value().hash(&mut hasher); - } - } + self.hash(&mut hasher); hasher.finish() } diff --git a/libafl_targets/src/sancov_8bit.rs b/libafl_targets/src/sancov_8bit.rs index 96751eda57..0055fb603c 100644 --- a/libafl_targets/src/sancov_8bit.rs +++ b/libafl_targets/src/sancov_8bit.rs @@ -65,7 +65,7 @@ mod observers { }; use core::{ fmt::Debug, - hash::{BuildHasher, Hasher}, + hash::{Hash, Hasher}, iter::Flatten, ptr::{addr_of, addr_of_mut}, slice::{from_raw_parts, Iter, IterMut}, @@ -159,6 +159,19 @@ mod observers { } } + impl Hash for CountersMultiMapObserver { + fn hash(&self, hasher: &mut H) { + for map in unsafe { &*addr_of!(COUNTERS_MAPS) } { + let slice = map.as_slice(); + let ptr = slice.as_ptr(); + let map_size = slice.len() / core::mem::size_of::(); + unsafe { + hasher.write(from_raw_parts(ptr, map_size)); + } + } + } + } + impl MapObserver for CountersMultiMapObserver { type Entry = u8; @@ -196,17 +209,9 @@ mod observers { res } - fn hash(&self) -> u64 { - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - for map in unsafe { &*addr_of!(COUNTERS_MAPS) } { - let slice = map.as_slice(); - let ptr = slice.as_ptr(); - let map_size = slice.len() / core::mem::size_of::(); - unsafe { - hasher.write(from_raw_parts(ptr, map_size)); - } - } - hasher.finish() + #[inline] + fn hash_simple(&self) -> u64 { + RandomState::with_seeds(0, 0, 0, 0).hash_one(self) } fn reset_map(&mut self) -> Result<(), Error> { From 054bb4002afe6dab8b418e620e93408253abbfd8 Mon Sep 17 00:00:00 2001 From: Edwin Fernando Date: Wed, 17 Apr 2024 09:42:45 +0100 Subject: [PATCH 5/6] Simplify hash_simple (of trait MapObserver) (#1977) * Use hash_one function to make hash_simple a one-liner --- libafl/src/observers/map.rs | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index cb2c836698..a17801adea 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -6,7 +6,7 @@ use alloc::{ }; use core::{ fmt::Debug, - hash::{BuildHasher, Hash, Hasher}, + hash::{Hash, Hasher}, iter::Flatten, marker::PhantomData, mem::size_of, @@ -711,6 +711,7 @@ where + serde::de::DeserializeOwned + Debug, { + #[inline] fn hash(&self, hasher: &mut H) { hash_helper(self.as_slice(), hasher); } @@ -778,9 +779,7 @@ where #[inline] fn hash_simple(&self) -> u64 { - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - Hash::hash(self, &mut hasher); - hasher.finish() + RandomState::with_seeds(0, 0, 0, 0).hash_one(self) } #[inline] @@ -1233,6 +1232,7 @@ where + serde::de::DeserializeOwned + Debug, { + #[inline] fn hash(&self, hasher: &mut H) { hash_helper(self.as_slice(), hasher); } @@ -1303,9 +1303,7 @@ where #[inline] fn hash_simple(&self) -> u64 { - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - Hash::hash(self, &mut hasher); - hasher.finish() + RandomState::with_seeds(0, 0, 0, 0).hash_one(self) } /// Reset the map @@ -1584,6 +1582,7 @@ where + PartialEq + Bounded, { + #[inline] fn hash(&self, hasher: &mut H) { hash_helper(self.as_slice(), hasher); } @@ -1655,9 +1654,7 @@ where #[inline] fn hash_simple(&self) -> u64 { - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - Hash::hash(self, &mut hasher); - hasher.finish() + RandomState::with_seeds(0, 0, 0, 0).hash_one(self) } /// Reset the map @@ -2483,9 +2480,7 @@ where #[inline] fn hash_simple(&self) -> u64 { - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - Hash::hash(self, &mut hasher); - hasher.finish() + RandomState::with_seeds(0, 0, 0, 0).hash_one(self) } fn reset_map(&mut self) -> Result<(), Error> { @@ -2787,6 +2782,7 @@ impl Hash for OwnedMapObserver where T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, { + #[inline] fn hash(&self, hasher: &mut H) { hash_helper(self.as_slice(), hasher); } @@ -2854,9 +2850,7 @@ where #[inline] fn hash_simple(&self) -> u64 { - let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher(); - Hash::hash(self, &mut hasher); - hasher.finish() + RandomState::with_seeds(0, 0, 0, 0).hash_one(self) } #[inline] From 3f677869a679c2bfb7e88656cfb9d21f2bde03cf Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Wed, 17 Apr 2024 16:11:29 +0200 Subject: [PATCH 6/6] remove hash_helper --- libafl/src/observers/map.rs | 48 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index a17801adea..45cd46be53 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -69,16 +69,6 @@ fn init_count_class_16() { } } -/// Compute the hash of a slice -fn hash_helper(slice: &[T], hasher: &mut H) -> u64 { - let ptr = slice.as_ptr() as *const u8; - let map_size = slice.len() / size_of::(); - unsafe { - hasher.write(slice::from_raw_parts(ptr, map_size)); - } - hasher.finish() -} - /// Trait marker which indicates that this [`MapObserver`] is tracked for indices or novelties. /// Implementors of feedbacks similar to [`crate::feedbacks::MapFeedback`] may wish to use this to /// ensure that edge metadata is recorded as is appropriate for the provided observer. @@ -424,7 +414,7 @@ pub trait MapObserver: // for<'it> &'it Self: IntoIterator { /// Type of each entry in this map - type Entry: Bounded + PartialEq + Default + Copy + Debug + 'static; + type Entry: Bounded + PartialEq + Default + Copy + Debug + Hash + 'static; /// Get the value at `idx` fn get(&self, idx: usize) -> &Self::Entry; @@ -552,6 +542,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -603,6 +594,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -623,6 +615,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -643,6 +636,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -664,6 +658,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -684,6 +679,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -706,6 +702,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -713,7 +710,7 @@ where { #[inline] fn hash(&self, hasher: &mut H) { - hash_helper(self.as_slice(), hasher); + self.as_slice().hash(hasher); } } @@ -741,6 +738,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1125,6 +1123,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1145,6 +1144,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1165,6 +1165,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1185,6 +1186,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1205,6 +1207,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1227,6 +1230,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1234,7 +1238,7 @@ where { #[inline] fn hash(&self, hasher: &mut H) { - hash_helper(self.as_slice(), hasher); + self.as_slice().hash(hasher); } } impl<'a, T, const N: usize> AsRef for ConstMapObserver<'a, T, N> @@ -1261,6 +1265,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1463,6 +1468,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1485,6 +1491,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1507,6 +1514,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1529,6 +1537,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1551,6 +1560,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1575,6 +1585,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1584,7 +1595,7 @@ where { #[inline] fn hash(&self, hasher: &mut H) { - hash_helper(self.as_slice(), hasher); + self.as_slice().hash(hasher); } } impl<'a, T> AsRef for VariableMapObserver<'a, T> @@ -1611,6 +1622,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1694,6 +1706,7 @@ where + PartialEq + Default + Copy + + Hash + 'static + Serialize + serde::de::DeserializeOwned @@ -1714,6 +1727,7 @@ where T: 'static + Default + Copy + + Hash + Serialize + serde::de::DeserializeOwned + Debug @@ -2438,6 +2452,7 @@ where + PartialEq + Default + Copy + + Hash + Serialize + serde::de::DeserializeOwned + Debug, @@ -2780,11 +2795,11 @@ where impl Hash for OwnedMapObserver where - T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, + T: 'static + Hash + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, { #[inline] fn hash(&self, hasher: &mut H) { - hash_helper(self.as_slice(), hasher); + self.as_slice().hash(hasher); } } @@ -2813,6 +2828,7 @@ where + PartialEq + Default + Copy + + Hash + Serialize + serde::de::DeserializeOwned + Debug,