anymap as macro

This commit is contained in:
Andrea Fioraldi 2020-12-09 10:28:54 +01:00
parent 6f6567e215
commit 9d402882e7
10 changed files with 435 additions and 373 deletions

View File

@ -202,7 +202,7 @@ where
engine.events_manager_mut().fire(Event::LoadInitial {
sender_id: 0,
phantom: PhantomData,
})?;
}, self, corpus)?;
}
engine.events_manager_mut().process(self, corpus)?;
Ok(())
@ -328,7 +328,7 @@ where
sender_id: 0,
new_execs: 1,
phantom: PhantomData,
})?; // TODO self.new_execs});
}, state, corpus)?; // TODO self.new_execs});
}
}
}

View File

@ -1,18 +1,18 @@
#[cfg(feature = "std")]
pub mod llmp;
//#[cfg(feature = "std")]
//pub mod llmp;
use alloc::string::String;
use core::marker::PhantomData;
use serde::{Deserialize, Serialize};
#[cfg(feature = "std")]
pub mod llmp_translated; // TODO: Abstract away.
#[cfg(feature = "std")]
pub mod shmem_translated;
//#[cfg(feature = "std")]
//pub mod llmp_translated; // TODO: Abstract away.
//#[cfg(feature = "std")]
//pub mod shmem_translated;
#[cfg(feature = "std")]
pub use crate::events::llmp::LLMPEventManager;
//#[cfg(feature = "std")]
//pub use crate::events::llmp::LLMPEventManager;
#[cfg(feature = "std")]
use std::io::Write;
@ -22,6 +22,7 @@ use crate::engines::State;
use crate::executors::Executor;
use crate::inputs::Input;
use crate::utils::Rand;
use crate::serde_anymap::{Ptr, PtrMut};
use crate::AflError;
/// Indicate if an event worked or not
enum BrokerEventResult {
@ -67,7 +68,7 @@ where
/// Events sent around in the library
#[derive(Serialize, Deserialize)]
pub enum Event<C, E, I, R>
pub enum Event<'a, C, E, I, R>
where
C: Corpus<I, R>,
E: Executor<I>,
@ -84,6 +85,11 @@ where
testcase: Testcase<I>,
phantom: PhantomData<(C, E, I, R)>,
},
NewTestcase2 {
sender_id: u64,
input: Ptr<'a, I>,
observers: PtrMut<'a, crate::observers::observer_serde::NamedSerdeAnyMap>
},
UpdateStats {
sender_id: u64,
new_execs: usize,
@ -111,7 +117,7 @@ where
//Custom {sender_id: u64, custom_event: CE},
}
impl<C, E, I, R> Event<C, E, I, R>
impl<'a, C, E, I, R> Event<'a, C, E, I, R>
where
C: Corpus<I, R>,
E: Executor<I>,
@ -130,6 +136,11 @@ where
testcase: _,
phantom: _,
} => "New Testcase",
Event::NewTestcase2 {
sender_id: _,
input: _,
observers: _,
} => "New Testcase 2",
Event::UpdateStats {
sender_id: _,
new_execs: _,
@ -171,6 +182,11 @@ where
testcase: _,
phantom: _,
} => Ok(BrokerEventResult::Forward),
Event::NewTestcase2 {
sender_id: _,
input: _,
observers: _,
} => Ok(BrokerEventResult::Forward),
Event::UpdateStats {
sender_id: _,
new_execs: _,
@ -246,7 +262,7 @@ where
fn enabled(&self) -> bool;
/// Fire an Event
fn fire(&mut self, event: Event<C, E, I, R>) -> Result<(), AflError>;
fn fire<'a>(&mut self, event: Event<'a, C, E, I, R>, state: &mut State<I, R>, corpus: &mut C) -> Result<(), AflError>;
/// Lookup for incoming events and process them.
/// Return the number of processes events or an error
@ -274,15 +290,12 @@ where
#[cfg(feature = "std")]
pub struct LoggerEventManager<C, E, I, R, W>
where
C: Corpus<I, R>,
I: Input,
E: Executor<I>,
R: Rand,
W: Write,
//CE: CustomEvent<C, E, I, R>,
{
events: Vec<Event<C, E, I, R>>,
writer: W,
count: usize,
phantom: PhantomData<(C, E, I, R)>
}
#[cfg(feature = "std")]
@ -299,28 +312,19 @@ where
true
}
fn fire(&mut self, event: Event<C, E, I, R>) -> Result<(), AflError> {
self.events.push(event);
Ok(())
}
fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError> {
// TODO: iterators
let mut handled = vec![];
for x in self.events.iter() {
handled.push(x.handle_in_broker(state, corpus)?);
}
let count = self.events.len();
while self.events.len() > 0 {
let event = self.events.pop().unwrap();
match handled.pop().unwrap() {
fn fire<'a>(&mut self, event: Event<'a, C, E, I, R>, state: &mut State<I, R>, corpus: &mut C) -> Result<(), AflError> {
match event.handle_in_broker(state, corpus)? {
BrokerEventResult::Forward => event.handle_in_client(state, corpus)?,
// Ignore broker-only events
BrokerEventResult::Handled => (),
}
Ok(())
}
dbg!("Handled {} events", count);
Ok(count)
fn process(&mut self, state: &mut State<I, R>, corpus: &mut C) -> Result<usize, AflError> {
let c = self.count;
self.count = 0;
Ok(c)
}
}
@ -336,8 +340,9 @@ where
{
pub fn new(writer: W) -> Self {
Self {
events: vec![],
writer: writer,
count: 0,
phantom: PhantomData
}
}
}

View File

@ -4,7 +4,7 @@ use core::ptr;
use crate::executors::{Executor, ExitKind};
use crate::inputs::Input;
use crate::observers::Observer;
use crate::serde_anymap::NamedSerdeAnyMap;
use crate::observers::observer_serde::NamedSerdeAnyMap;
use crate::AflError;
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
@ -14,7 +14,7 @@ where
I: Input,
{
harness: HarnessFunction<I>,
observers: NamedSerdeAnyMap<dyn Observer>,
observers: NamedSerdeAnyMap,
}
static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null();
@ -35,11 +35,11 @@ where
Ok(ret)
}
fn observers(&self) -> &NamedSerdeAnyMap<dyn Observer> {
fn observers(&self) -> &NamedSerdeAnyMap {
&self.observers
}
fn observers_mut(&mut self) -> &mut NamedSerdeAnyMap<dyn Observer> {
fn observers_mut(&mut self) -> &mut NamedSerdeAnyMap {
&mut self.observers
}
}

View File

@ -2,7 +2,7 @@ pub mod inmemory;
use crate::inputs::Input;
use crate::observers::Observer;
use crate::serde_anymap::NamedSerdeAnyMap;
use crate::observers::observer_serde::NamedSerdeAnyMap;
use crate::AflError;
pub enum ExitKind {
@ -20,10 +20,10 @@ where
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError>;
/// Get the linked observers
fn observers(&self) -> &NamedSerdeAnyMap<dyn Observer>;
fn observers(&self) -> &NamedSerdeAnyMap;
/// Get the linked observers
fn observers_mut(&mut self) -> &mut NamedSerdeAnyMap<dyn Observer>;
fn observers_mut(&mut self) -> &mut NamedSerdeAnyMap;
/// Add a linked observer
fn add_observer(&mut self, observer: Box<dyn Observer>) {

View File

@ -5,7 +5,7 @@ use num::Integer;
use crate::corpus::{Testcase, TestcaseMetadata};
use crate::inputs::Input;
use crate::observers::{MapObserver, Observer};
use crate::serde_anymap::NamedSerdeAnyMap;
use crate::observers::observer_serde::NamedSerdeAnyMap;
use crate::AflError;
pub trait Feedback<I>
@ -16,7 +16,7 @@ where
fn is_interesting(
&mut self,
input: &I,
observers: &NamedSerdeAnyMap<dyn Observer>,
observers: &NamedSerdeAnyMap,
) -> Result<u32, AflError>;
/// Append to the testcase the generated metadata in case of a new corpus item
@ -105,7 +105,7 @@ where
fn is_interesting(
&mut self,
_input: &I,
observers: &NamedSerdeAnyMap<dyn Observer>,
observers: &NamedSerdeAnyMap,
) -> Result<u32, AflError> {
let mut interesting = 0;
// TODO optimize

View File

@ -5,6 +5,7 @@ use core::slice::{Iter, IterMut};
use hashbrown::hash_map::{Keys, Values, ValuesMut};
use hashbrown::HashMap;
#[derive(Default)]
pub struct MetaMap {
map: HashMap<TypeId, Box<dyn Any>>,
}

View File

@ -24,6 +24,34 @@ pub trait Observer: SerdeAny + 'static {
fn name(&self) -> &'static str;
}
crate::create_serde_registry_for_trait!(observer_serde, crate::observers::Observer);
#[derive(Serialize, Deserialize)]
pub struct NopObserver {
}
impl Observer for NopObserver {
fn name(&self) -> &'static str {
"aa"
}
fn reset(&mut self) -> Result<(), AflError> { Ok(()) }
}
impl SerdeAny for NopObserver
{
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
impl NopObserver {
pub fn new() -> Self {
Self {}
}
}
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
pub trait MapObserver<T>
where

View File

@ -4,8 +4,6 @@ use serde::{Deserialize, Serialize};
use alloc::boxed::Box;
use core::any::{Any, TypeId};
use core::default::Default;
use core::fmt;
use core::slice::{Iter, IterMut};
use hashbrown::hash_map::{Keys, Values, ValuesMut};
use crate::AflError;
@ -23,11 +21,8 @@ pub trait SerdeAny: Any + erased_serde::Serialize {
fn as_any_mut(&mut self) -> &mut dyn Any;
}
type DeserializeCallback =
fn(&mut dyn erased_serde::Deserializer) -> Result<Box<dyn SerdeAny>, erased_serde::Error>;
struct Wrap<'a, T: ?Sized>(pub &'a T);
impl<'a, T> Serialize for Wrap<'a, T>
pub struct Wrap<'a, T: ?Sized>(pub &'a T);
impl<'a, T> serde::Serialize for Wrap<'a, T>
where
T: ?Sized + erased_serde::Serialize + 'a,
{
@ -39,27 +34,15 @@ where
}
}
impl<'a> serde::Serialize for dyn SerdeAny + 'a {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeSeq;
pub type DeserializeCallback<B> =
fn(&mut dyn erased_serde::Deserializer) -> Result<Box<B>, erased_serde::Error>;
let id = unpack_type_id(self.type_id());
let mut seq = se.serialize_seq(Some(2))?;
seq.serialize_element(&id)?;
seq.serialize_element(&Wrap(self))?;
seq.end()
}
pub struct DeserializeCallbackSeed<B> where B: ?Sized {
pub cb: DeserializeCallback<B>,
}
struct DeserializeCallbackSeed {
pub cb: DeserializeCallback,
}
impl<'de> serde::de::DeserializeSeed<'de> for DeserializeCallbackSeed {
type Value = Box<dyn SerdeAny>;
impl<'de, B> serde::de::DeserializeSeed<'de> for DeserializeCallbackSeed<B> where B: ?Sized {
type Value = Box<B>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
@ -70,54 +53,63 @@ impl<'de> serde::de::DeserializeSeed<'de> for DeserializeCallbackSeed {
}
}
struct BoxAnyVisitor {}
impl<'de> serde::de::Visitor<'de> for BoxAnyVisitor {
type Value = Box<dyn SerdeAny>;
#[macro_export]
macro_rules! create_serde_registry_for_trait {
($mod_name:ident, $trait_name:path) => {
pub mod $mod_name {
use alloc::boxed::Box;
use core::fmt;
use core::any::{Any, TypeId};
use serde::{Deserialize, Serialize};
use hashbrown::HashMap;
use hashbrown::hash_map::{Keys, Values, ValuesMut};
use $crate::AflError;
use $crate::serde_anymap::{DeserializeCallback, DeserializeCallbackSeed, pack_type_id, unpack_type_id};
pub struct BoxDynVisitor {}
impl<'de> serde::de::Visitor<'de> for BoxDynVisitor {
type Value = Box<dyn $trait_name>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Expecting a serialized SerdeAny trait object (Box<dyn SerdeAny>)")
formatter.write_str("Expecting a serialized trait object")
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Box<dyn SerdeAny>, V::Error>
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: serde::de::SeqAccess<'de>,
{
let id: u64 = visitor.next_element()?.unwrap();
/*let id: u64 = visitor.next_element()?.unwrap();
let cb = unsafe {
*REGISTRY
.deserializers
.as_ref()
.unwrap()
.get(&id)
.expect("Cannot deserialize an unregistered SerdeAny")
};
let seed = DeserializeCallbackSeed { cb: cb };
let obj: Box<dyn SerdeAny> = visitor.next_element_seed(seed)?.unwrap();
.expect("Cannot deserialize an unregistered type")
};*/
//let seed = DeserializeCallbackSeed::<dyn $trait_name> { cb: cb };
//let obj: Self::Value = visitor.next_element_seed(seed)?.unwrap();
let obj = Box::new(crate::observers::NopObserver::new());
Ok(obj)
}
}
impl<'de> Deserialize<'de> for Box<dyn SerdeAny> {
fn deserialize<D>(deserializer: D) -> Result<Box<dyn SerdeAny>, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq(BoxAnyVisitor {})
}
}
pub struct Registry {
deserializers: Option<HashMap<u64, DeserializeCallback>>,
struct Registry {
deserializers: Option<HashMap<u64, DeserializeCallback<dyn $trait_name>>>,
finalized: bool,
}
impl Registry {
pub fn register<T>(&mut self)
where
T: SerdeAny + Serialize + serde::de::DeserializeOwned,
T: $trait_name + serde::Serialize + serde::de::DeserializeOwned,
{
if self.finalized {
panic!("Global Registry of SerdeAny types is already finalized!");
panic!("Registry is already finalized!");
}
let deserializers = self.deserializers.get_or_insert_with(|| HashMap::default());
@ -140,7 +132,7 @@ pub struct RegistryBuilder {}
impl RegistryBuilder {
pub fn register<T>()
where
T: SerdeAny + Serialize + serde::de::DeserializeOwned,
T: $trait_name + serde::Serialize + serde::de::DeserializeOwned,
{
unsafe {
REGISTRY.register::<T>();
@ -154,15 +146,17 @@ impl RegistryBuilder {
}
}
#[derive(Default, Serialize, Deserialize)]
pub struct SerdeAnyMap {
map: HashMap<u64, Box<dyn SerdeAny>>,
#[derive(Serialize, Deserialize)]
pub struct SerdeAnyMap
{
map: HashMap<u64, Box<dyn $trait_name>>,
}
impl SerdeAnyMap {
impl SerdeAnyMap
{
pub fn get<T>(&self) -> Option<&T>
where
T: SerdeAny,
T: $trait_name,
{
self.map
.get(&unpack_type_id(TypeId::of::<T>()))
@ -171,7 +165,7 @@ impl SerdeAnyMap {
pub fn get_mut<T>(&mut self) -> Option<&mut T>
where
T: SerdeAny,
T: $trait_name,
{
self.map
.get_mut(&unpack_type_id(TypeId::of::<T>()))
@ -180,7 +174,7 @@ impl SerdeAnyMap {
pub fn insert<T>(&mut self, t: T)
where
T: SerdeAny,
T: $trait_name,
{
self.map
.insert(unpack_type_id(TypeId::of::<T>()), Box::new(t));
@ -192,7 +186,7 @@ impl SerdeAnyMap {
pub fn contains<T>(&self) -> bool
where
T: SerdeAny,
T: $trait_name,
{
self.map.contains_key(&unpack_type_id(TypeId::of::<T>()))
}
@ -204,17 +198,21 @@ impl SerdeAnyMap {
}
}
#[derive(Serialize, Deserialize)]
pub struct NamedSerdeAnyMap<B>
where
B: ?Sized + SerdeAny,
impl Default for SerdeAnyMap
{
map: HashMap<u64, HashMap<u64, Box<B>>>,
fn default() -> Self {
Self::new()
}
}
impl<B> NamedSerdeAnyMap<B>
where
B: ?Sized + SerdeAny,
#[derive(Serialize, Deserialize)]
pub struct NamedSerdeAnyMap
{
map: HashMap<u64, HashMap<u64, Box<dyn $trait_name>>>,
}
impl NamedSerdeAnyMap
{
pub fn get<T>(&self, name: &'static str) -> Option<&T>
where
@ -228,7 +226,7 @@ where
}
}
pub fn by_typeid(&self, name: &'static str, typeid: &TypeId) -> Option<&B> {
pub fn by_typeid(&self, name: &'static str, typeid: &TypeId) -> Option<&dyn $trait_name> {
match self.map.get(&unpack_type_id(*typeid)) {
None => None,
Some(h) => h
@ -249,7 +247,7 @@ where
}
}
pub fn by_typeid_mut(&mut self, name: &'static str, typeid: &TypeId) -> Option<&mut B> {
pub fn by_typeid_mut(&mut self, name: &'static str, typeid: &TypeId) -> Option<&mut dyn $trait_name> {
match self.map.get_mut(&unpack_type_id(*typeid)) {
None => None,
Some(h) => h
@ -258,7 +256,7 @@ where
}
}
pub fn get_all<T>(&self) -> Option<core::iter::Map<Values<'_, u64, Box<B>>, fn(&Box<B>) -> &T>>
pub fn get_all<T>(&self) -> Option<core::iter::Map<Values<'_, u64, Box<dyn $trait_name>>, fn(&Box<dyn $trait_name>) -> &T>>
where
T: Any,
{
@ -271,7 +269,7 @@ where
pub fn all_by_typeid(
&self,
typeid: &TypeId,
) -> Option<core::iter::Map<Values<'_, u64, Box<B>>, fn(&Box<B>) -> &B>> {
) -> Option<core::iter::Map<Values<'_, u64, Box<dyn $trait_name>>, fn(&Box<dyn $trait_name>) -> &dyn $trait_name>> {
match self.map.get(&unpack_type_id(*typeid)) {
None => None,
Some(h) => Some(h.values().map(|x| x.as_ref())),
@ -280,7 +278,7 @@ where
pub fn get_all_mut<T>(
&mut self,
) -> Option<core::iter::Map<ValuesMut<'_, u64, Box<B>>, fn(&mut Box<B>) -> &mut T>>
) -> Option<core::iter::Map<ValuesMut<'_, u64, Box<dyn $trait_name>>, fn(&mut Box<dyn $trait_name>) -> &mut T>>
where
T: Any,
{
@ -296,7 +294,7 @@ where
pub fn all_by_typeid_mut(
&mut self,
typeid: &TypeId,
) -> Option<core::iter::Map<ValuesMut<'_, u64, Box<B>>, fn(&mut Box<B>) -> &mut B>> {
) -> Option<core::iter::Map<ValuesMut<'_, u64, Box<dyn $trait_name>>, fn(&mut Box<dyn $trait_name>) -> &mut dyn $trait_name>> {
match self.map.get_mut(&unpack_type_id(*typeid)) {
None => None,
Some(h) => Some(h.values_mut().map(|x| x.as_mut())),
@ -305,13 +303,13 @@ where
pub fn all_typeids(
&self,
) -> core::iter::Map<Keys<'_, u64, HashMap<u64, Box<B>>>, fn(&u64) -> TypeId> {
) -> core::iter::Map<Keys<'_, u64, HashMap<u64, Box<dyn $trait_name>>>, fn(&u64) -> TypeId> {
self.map.keys().map(|x| pack_type_id(*x))
}
pub fn for_each(
&self,
func: fn(&TypeId, &Box<B>) -> Result<(), AflError>,
func: fn(&TypeId, &Box<dyn $trait_name>) -> Result<(), AflError>,
) -> Result<(), AflError> {
for (id, h) in self.map.iter() {
for x in h.values() {
@ -323,7 +321,7 @@ where
pub fn for_each_mut(
&mut self,
func: fn(&TypeId, &mut Box<B>) -> Result<(), AflError>,
func: fn(&TypeId, &mut Box<dyn $trait_name>) -> Result<(), AflError>,
) -> Result<(), AflError> {
for (id, h) in self.map.iter_mut() {
for x in h.values_mut() {
@ -333,7 +331,7 @@ where
Ok(())
}
pub fn insert(&mut self, val: Box<B>, name: &'static str) {
pub fn insert(&mut self, val: Box<dyn $trait_name>, name: &'static str) {
let id = unpack_type_id(val.type_id());
if !self.map.contains_key(&id) {
self.map.insert(id, HashMap::default());
@ -372,15 +370,45 @@ where
}
}
impl<B> Default for NamedSerdeAnyMap<B>
where
B: ?Sized + SerdeAny,
impl Default for NamedSerdeAnyMap
{
fn default() -> Self {
Self::new()
}
}
}
impl<'a> serde::Serialize for dyn $trait_name {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeSeq;
let id = $crate::serde_anymap::unpack_type_id(self.type_id());
let mut seq = se.serialize_seq(Some(2))?;
seq.serialize_element(&id)?;
seq.serialize_element(&$crate::serde_anymap::Wrap(self))?;
seq.end()
}
}
impl<'de> serde::Deserialize<'de> for Box<dyn $trait_name> {
fn deserialize<D>(deserializer: D) -> Result<Box<dyn $trait_name>, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq($mod_name::BoxDynVisitor {})
}
}
};
}
create_serde_registry_for_trait!(serdeany_serde, crate::serde_anymap::SerdeAny);
pub use serdeany_serde::*;
#[derive(Serialize)]
pub enum Ptr<'a, T: 'a + ?Sized> {
Ref(&'a T),

View File

@ -22,7 +22,7 @@ where
&mut self,
rand: &mut R,
state: &mut State<I, R>,
corpus: &C,
corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>,
input: &I,
) -> Result<(), AflError>;

View File

@ -38,7 +38,7 @@ where
&mut self,
rand: &mut R,
state: &mut State<I, R>,
corpus: &C,
corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>,
input: &I,
) -> Result<(), AflError> {
@ -60,7 +60,7 @@ where
sender_id: 0,
testcase: testcase,
phantom: PhantomData,
})?;
}, state, corpus)?;
}
}
Ok(())
@ -114,7 +114,7 @@ where
&mut self,
rand: &mut R,
state: &mut State<I, R>,
corpus: &C,
corpus: &mut C,
engine: &mut Engine<EM, E, C, I, R>,
input: &I,
) -> Result<(), AflError> {