From df901d37cf6b61a666760bf68b93e10e9cef8c65 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 7 Dec 2020 11:55:34 +0100 Subject: [PATCH] meta map --- afl/src/lib.rs | 1 + afl/src/metamap.rs | 167 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 afl/src/metamap.rs diff --git a/afl/src/lib.rs b/afl/src/lib.rs index 1e8c7727af..8b21f5220c 100644 --- a/afl/src/lib.rs +++ b/afl/src/lib.rs @@ -15,6 +15,7 @@ pub mod observers; pub mod stages; pub mod utils; pub mod serde_anymap; +pub mod metamap; use alloc::string::String; use core::fmt; diff --git a/afl/src/metamap.rs b/afl/src/metamap.rs new file mode 100644 index 0000000000..4d0953d797 --- /dev/null +++ b/afl/src/metamap.rs @@ -0,0 +1,167 @@ +use hashbrown::HashMap; +use hashbrown::hash_map::{ValuesMut, Values}; +use core::slice::{Iter, IterMut}; +use core::any::{TypeId, Any}; + +pub struct MetaMap { + map: HashMap> +} + +impl MetaMap { + pub fn get(&self) -> Option<&T> where T: Any { + self.map.get(&TypeId::of::()).map(|x| x.as_ref().downcast_ref::().unwrap()) + } + + pub fn get_mut(&mut self) -> Option<&mut T> where T: Any { + self.map.get_mut(&TypeId::of::()).map(|x| x.as_mut().downcast_mut::().unwrap()) + } + + pub fn insert(&mut self, t: T) where T: Any { + self.map.insert(TypeId::of::(), Box::new(t)); + } + + pub fn len(&self) -> usize { + self.map.len() + } + + pub fn contains(&self) -> bool where T: Any { + self.map.contains_key(&TypeId::of::()) + } + + pub fn new() -> Self { + Self { map: HashMap::default() } + } +} + +pub struct MultiMetaMap { + map: HashMap>> +} + +impl MultiMetaMap { + pub fn get(&self) -> Option>, fn(&Box) -> &T>> where T: Any { + match self.map.get(&TypeId::of::()) { + None => None, + Some(v) => { + Some(v.iter().map(|x| x.as_ref().downcast_ref::().unwrap())) + } + } + } + + pub fn get_mut(&mut self) -> Option>, fn(&mut Box) -> &mut T>> where T: Any { + match self.map.get_mut(&TypeId::of::()) { + None => None, + Some(v) => { + Some(v.iter_mut().map(|x| x.as_mut().downcast_mut::().unwrap())) + } + } + } + + pub fn insert(&mut self, t: T) where T: Any { + let typeid = TypeId::of::(); + if !self.map.contains_key(&typeid) { + self.map.insert(typeid, vec![Box::new(t)]); + } else { + self.map.get_mut(&typeid).unwrap().push(Box::new(t)); + } + } + + pub fn len(&self) -> usize { + self.map.len() + } + + pub fn contains(&self) -> bool where T: Any { + self.map.contains_key(&TypeId::of::()) + } + + pub fn new() -> Self { + Self { map: HashMap::default() } + } +} + + +pub struct MetaInstanceMap { + map: HashMap>> +} + +impl MetaInstanceMap { + pub fn get(&self, instance: &U) -> Option<&T> where T: Any { + self.get_ptr::(instance as *const _ as *const ()) + } + + pub fn get_ptr(&self, instance: *const ()) -> Option<&T> where T: Any { + match self.map.get(&TypeId::of::()) { + None => None, + Some(h) => { + h.get(&instance).map(|x| x.as_ref().downcast_ref::().unwrap()) + } + } + } + + pub fn get_mut(&mut self, instance: &U) -> Option<&mut T> where T: Any { + self.get_mut_ptr::(instance as *const _ as *const ()) + } + + pub fn get_mut_ptr(&mut self, instance: *const ()) -> Option<&mut T> where T: Any { + match self.map.get_mut(&TypeId::of::()) { + None => None, + Some(h) => { + h.get_mut(&instance).map(|x| x.as_mut().downcast_mut::().unwrap()) + } + } + } + + pub fn get_all(&self) -> Option>, fn(&Box) -> &T>> where T: Any { + match self.map.get(&TypeId::of::()) { + None => None, + Some(h) => { + Some(h.values().map(|x| x.as_ref().downcast_ref::().unwrap())) + } + } + } + + pub fn get_all_mut(&mut self) -> Option>, fn(&mut Box) -> &mut T>> where T: Any { + match self.map.get_mut(&TypeId::of::()) { + None => None, + Some(h) => { + Some(h.values_mut().map(|x| x.as_mut().downcast_mut::().unwrap())) + } + } + } + + pub fn insert(&mut self, t: T, instance: &U) where T: Any { + self.insert_ptr(t, instance as *const _ as *const ()) + } + + pub fn insert_ptr(&mut self, t: T, instance: *const ()) where T: Any { + let typeid = TypeId::of::(); + if !self.map.contains_key(&typeid) { + self.map.insert(typeid, HashMap::default()); + } + self.map.get_mut(&typeid).unwrap().insert(instance, Box::new(t)); + } + + pub fn len(&self) -> usize { + self.map.len() + } + + pub fn contains_type(&self) -> bool where T: Any { + self.map.contains_key(&TypeId::of::()) + } + + pub fn contains(&self, instance: &U) -> bool where T: Any { + self.contains_ptr::(instance as *const _ as *const ()) + } + + pub fn contains_ptr(&self, instance: *const ()) -> bool where T: Any { + match self.map.get(&TypeId::of::()) { + None => false, + Some(h) => { + h.contains_key(&instance) + } + } + } + + pub fn new() -> Self { + Self { map: HashMap::default() } + } +} \ No newline at end of file