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