map observer
This commit is contained in:
parent
63a83a70ff
commit
34d51ee5e0
@ -215,10 +215,6 @@ mod tests {
|
||||
fn post_exec(&mut self) -> Result<(), AflError> {
|
||||
Err(AflError::Unknown("Nop exec, testing only".to_string()))
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn test_harness_fn_nop(_executor: &dyn Executor<NopInput>, buf: &[u8]) -> ExitKind {
|
||||
|
@ -65,26 +65,28 @@ where
|
||||
}
|
||||
|
||||
/// The most common AFL-like feedback type
|
||||
pub struct MapFeedback<'a, T, R>
|
||||
pub struct MapFeedback<'a, T, R, O>
|
||||
where
|
||||
T: Integer + Copy + 'static,
|
||||
R: Reducer<T>,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
/// Contains information about untouched entries
|
||||
history_map: &'a RefCell<Vec<T>>,
|
||||
/// The observer this feedback struct observes
|
||||
map_observer: &'a RefCell<MapObserver</*'a,*/ T>>,
|
||||
map_observer: &'a RefCell<O>,
|
||||
/// Phantom Data of Reducer
|
||||
phantom: PhantomData<R>,
|
||||
}
|
||||
|
||||
impl<'a, T, R, I> Feedback<I> for MapFeedback<'a, T, R>
|
||||
impl<'a, T, R, O, I> Feedback<I> for MapFeedback<'a, T, R, O>
|
||||
where
|
||||
T: Integer + Copy + 'static,
|
||||
R: Reducer<T>,
|
||||
O: MapObserver<T>,
|
||||
I: Input,
|
||||
{
|
||||
fn is_interesting(&mut self, _executor: &dyn Executor<I>, entry: &Testcase<I>) -> u8 {
|
||||
fn is_interesting(&mut self, _executor: &dyn Executor<I>, _entry: &Testcase<I>) -> u8 {
|
||||
let mut interesting = 0;
|
||||
|
||||
// TODO: impl. correctly, optimize
|
||||
@ -92,7 +94,7 @@ where
|
||||
.history_map
|
||||
.borrow_mut()
|
||||
.iter_mut()
|
||||
.zip(self.map_observer.borrow().get_map().iter())
|
||||
.zip(self.map_observer.borrow().map().iter())
|
||||
{
|
||||
let reduced = R::reduce(*history, *map);
|
||||
if *history != reduced {
|
||||
@ -107,17 +109,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, R> MapFeedback<'a, T, R>
|
||||
impl<'a, T, R, O> MapFeedback<'a, T, R, O>
|
||||
where
|
||||
T: Integer + Copy + 'static,
|
||||
R: Reducer<T>,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
/// Create new MapFeedback using a map observer, and a map.
|
||||
/// The map can be shared.
|
||||
pub fn new(
|
||||
map_observer: &'a RefCell<MapObserver</*'a, */ T>>,
|
||||
history_map: &'a RefCell<Vec<T>>,
|
||||
) -> Self {
|
||||
pub fn new(map_observer: &'a RefCell<O>, history_map: &'a RefCell<Vec<T>>) -> Self {
|
||||
MapFeedback {
|
||||
map_observer: map_observer,
|
||||
history_map: history_map,
|
||||
@ -136,7 +136,5 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
type MaxMapFeedback<'a, T> = MapFeedback<'a, T, MaxReducer<T>>;
|
||||
#[allow(dead_code)]
|
||||
type MinMapFeedback<'a, T> = MapFeedback<'a, T, MinReducer<T>>;
|
||||
pub type MaxMapFeedback<'a, T, O> = MapFeedback<'a, T, MaxReducer<T>, O>;
|
||||
pub type MinMapFeedback<'a, T, O> = MapFeedback<'a, T, MinReducer<T>, O>;
|
||||
|
@ -1,14 +1,13 @@
|
||||
extern crate num;
|
||||
|
||||
use num::Integer;
|
||||
use std::any::Any;
|
||||
use std::slice::from_raw_parts_mut;
|
||||
|
||||
use crate::AflError;
|
||||
|
||||
/// Observers observe different information about the target.
|
||||
/// They can then be used by various sorts of feedback.
|
||||
pub trait Observer: Any {
|
||||
pub trait Observer {
|
||||
fn flush(&mut self) -> Result<(), AflError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -18,45 +17,91 @@ pub trait Observer: Any {
|
||||
fn post_exec(&mut self) -> Result<(), AflError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
/// A staticMapObserver observes the static map, as oftentimes used for afl-like coverage information
|
||||
pub struct MapObserver<MapT: Integer + Copy + 'static + 'static> {
|
||||
map: &'static mut [MapT],
|
||||
}
|
||||
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
|
||||
pub trait MapObserver<T>
|
||||
where
|
||||
T: Integer + Copy,
|
||||
{
|
||||
/// Get the map
|
||||
fn map(&self) -> &[T];
|
||||
|
||||
impl<MapT: Integer + Copy + 'static> Observer for MapObserver<MapT> {
|
||||
fn reset(&mut self) -> Result<(), AflError> {
|
||||
/// Get the map (mutable)
|
||||
fn map_mut(&mut self) -> &mut [T];
|
||||
|
||||
/// Get the initial value for reset()
|
||||
fn initial(&self) -> &T;
|
||||
|
||||
/// Get the initial value for reset()
|
||||
fn initial_mut(&mut self) -> &mut T;
|
||||
|
||||
/// Set the initial value for reset()
|
||||
fn set_initial(&mut self, initial: T);
|
||||
|
||||
/// Reset the map
|
||||
fn reset_map(&mut self) -> Result<(), AflError> {
|
||||
// Normal memset, see https://rust.godbolt.org/z/Trs5hv
|
||||
for i in self.map.iter_mut() {
|
||||
*i = MapT::zero();
|
||||
for i in self.map_mut().iter_mut() {
|
||||
*i = T::zero();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
pub struct DefaultMapObserver<'a, T>
|
||||
where
|
||||
T: Integer + Copy,
|
||||
{
|
||||
map: &'a mut [T],
|
||||
initial: T,
|
||||
}
|
||||
|
||||
impl<'a, T: Integer + Copy> Observer for DefaultMapObserver<'a, T> {
|
||||
fn reset(&mut self) -> Result<(), AflError> {
|
||||
self.reset_map()
|
||||
}
|
||||
}
|
||||
|
||||
impl<MapT: Integer + Copy + 'static> MapObserver<MapT> {
|
||||
pub fn get_map(&self) -> &[MapT] {
|
||||
self.map
|
||||
impl<'a, T: Integer + Copy> MapObserver<T> for DefaultMapObserver<'a, T> {
|
||||
fn map(&self) -> &[T] {
|
||||
&self.map
|
||||
}
|
||||
|
||||
pub fn get_map_mut(&mut self) -> &mut [MapT] {
|
||||
self.map
|
||||
fn map_mut(&mut self) -> &mut [T] {
|
||||
&mut self.map
|
||||
}
|
||||
|
||||
fn initial(&self) -> &T {
|
||||
&self.initial
|
||||
}
|
||||
|
||||
fn initial_mut(&mut self) -> &mut T {
|
||||
&mut self.initial
|
||||
}
|
||||
|
||||
fn set_initial(&mut self, initial: T) {
|
||||
self.initial = initial
|
||||
}
|
||||
}
|
||||
|
||||
impl<MapT: Integer + Copy + 'static> MapObserver<MapT> {
|
||||
/// Creates a new MapObserver from a raw pointer.
|
||||
pub fn new(map_ptr: *mut MapT, len: usize) -> Self {
|
||||
impl<'a, T: Integer + Copy> DefaultMapObserver<'a, T> {
|
||||
/// Creates a new MapObserver
|
||||
pub fn new(map: &'a mut [T]) -> Self {
|
||||
let initial = if map.len() > 0 { map[0] } else { T::zero() };
|
||||
DefaultMapObserver {
|
||||
map: map,
|
||||
initial: initial,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new MapObserver from a raw pointer
|
||||
pub fn new_from_ptr(map_ptr: *mut T, len: usize) -> Self {
|
||||
unsafe {
|
||||
MapObserver {
|
||||
let initial = if len > 0 { *map_ptr } else { T::zero() };
|
||||
DefaultMapObserver {
|
||||
map: from_raw_parts_mut(map_ptr, len),
|
||||
initial: initial,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user