make generic edge-map post-processor
This commit is contained in:
parent
c252d6cad0
commit
bec4743978
@ -21,3 +21,4 @@ hashbrown = { version = "0.11", features = ["serde", "ahash-compile-time-rng"],
|
||||
nix = "0.23.0"
|
||||
goblin = "0.4.2"
|
||||
either = "1.6.1"
|
||||
num-traits = "0.2"
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||
|
||||
use wcet_qemu_sys::worst::QemuHashMapObserver;
|
||||
use hashbrown::HashMap;
|
||||
use clap::{App, Arg};
|
||||
use core::{cell::RefCell, time::Duration};
|
||||
@ -64,7 +65,7 @@ use libafl_qemu::{
|
||||
clock::ClockFeedback,
|
||||
clock::QemuClockIncreaseFeedback
|
||||
};
|
||||
use wcet_qemu_sys::worst::{SortedFeedback,HitFeedback,HitcountsMapObserver,HitImprovingFeedback,LenTimeMaximizerCorpusScheduler};
|
||||
use wcet_qemu_sys::worst::{SortedFeedback,HitFeedback,HitImprovingFeedback,LenTimeMaximizerCorpusScheduler};
|
||||
|
||||
|
||||
/// The fuzzer main
|
||||
@ -276,7 +277,7 @@ fn fuzz(
|
||||
let edges = unsafe { &mut edges::EDGES_MAP };
|
||||
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM };
|
||||
let edges_observer =
|
||||
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
||||
QemuHashMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
||||
|
||||
// Create an observation channel to keep track of the execution time
|
||||
// let time_observer = TimeObserver::new("time");
|
||||
@ -301,14 +302,14 @@ fn fuzz(
|
||||
let feedback = feedback_or!(
|
||||
// New maximization map feedback linked to the edges observer and the feedback state
|
||||
MaxMapFeedback::new_tracking(&feedback_state, &edges_observer, true, false),
|
||||
// HitImprovingFeedback::new(target_map.clone()),
|
||||
HitImprovingFeedback::new(target_map.clone(), &edges_observer),
|
||||
QemuClockIncreaseFeedback::default(),
|
||||
ClockFeedback::new_with_observer(&clock_observer)
|
||||
);
|
||||
|
||||
// A feedback to choose if an input is a solution or not
|
||||
// let objective = HitFeedback::new(target_map,0.0);
|
||||
let objective = SortedFeedback::new();
|
||||
let objective = HitFeedback::new(target_map,0.0,&edges_observer);
|
||||
// let objective = SortedFeedback::new();
|
||||
|
||||
// create a State from scratch
|
||||
let mut state = state.unwrap_or_else(||{
|
||||
|
@ -1,7 +1,8 @@
|
||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||
|
||||
use wcet_qemu_sys::worst::QemuHashMapObserver;
|
||||
use wcet_qemu_sys::{
|
||||
worst::{DumpMapFeedback,DummyFeedback,HitcountsMapObserver},
|
||||
worst::{DumpMapFeedback,DummyFeedback},
|
||||
system_trace::QemuSystemStateHelper,
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
@ -262,13 +263,13 @@ fn fuzz(
|
||||
let edges = unsafe { &mut edges::EDGES_MAP };
|
||||
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM };
|
||||
let edges_observer =
|
||||
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
||||
QemuHashMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
||||
|
||||
//========== Observe Execution Cycles
|
||||
let clock_observer = QemuClockObserver::default();
|
||||
|
||||
//========= Feedback-Function evaluate the Maps. Need to dump it for debugging and check if it reaches targets.
|
||||
let feedback = DumpMapFeedback::with_dump(dump_edges);
|
||||
let feedback = DumpMapFeedback::with_dump(dump_edges, &edges_observer);
|
||||
|
||||
// A feedback to choose if an input is a solution or not
|
||||
let objective = DummyFeedback::new(false);
|
||||
|
@ -1,3 +1,5 @@
|
||||
use num_traits::PrimInt;
|
||||
use core::fmt::Debug;
|
||||
use core::cmp::Ordering::{Greater,Less,Equal};
|
||||
use libafl::inputs::BytesInput;
|
||||
use libafl::inputs::HasTargetBytes;
|
||||
@ -8,7 +10,6 @@ use core::marker::PhantomData;
|
||||
use libafl::corpus::MinimizerCorpusScheduler;
|
||||
use std::path::PathBuf;
|
||||
use std::fs;
|
||||
use libafl::observers::VariableMapObserver;
|
||||
use hashbrown::{HashMap};
|
||||
use libafl::observers::ObserversTuple;
|
||||
use libafl::executors::ExitKind;
|
||||
@ -30,36 +31,23 @@ use libafl::{
|
||||
observers::Observer,
|
||||
Error,
|
||||
};
|
||||
|
||||
/// Map observer with hitcounts postprocessing
|
||||
//===================================================================
|
||||
/// A wrapper around some other [`MapObserver`], using [`QemuEdgesMapMetadata`] to offer a convinient Hashmap.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(bound = "M: serde::de::DeserializeOwned")]
|
||||
pub struct HitcountsMapObserver<M>
|
||||
pub struct QemuHashMapObserver<M,T>
|
||||
where
|
||||
M: serde::Serialize + serde::de::DeserializeOwned,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
{
|
||||
base: M,
|
||||
pub edgemap: HashMap<(u64,u64),u8>,
|
||||
pub edgemap: HashMap<(u64,u64),T>,
|
||||
}
|
||||
|
||||
static COUNT_CLASS_LOOKUP: [u8; 256] = [
|
||||
0, 1, 2, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
];
|
||||
|
||||
impl<I, S, M> Observer<I, S> for HitcountsMapObserver<M>
|
||||
impl<I, S, M, T> Observer<I, S> for QemuHashMapObserver<M, T>
|
||||
where
|
||||
M: MapObserver<u8> + Observer<I, S>,
|
||||
M: MapObserver<T> + Observer<I, S>,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
S: HasMetadata, // Need to grab the HashMap from a Helper
|
||||
{
|
||||
#[inline]
|
||||
@ -70,25 +58,18 @@ where
|
||||
|
||||
#[inline]
|
||||
fn post_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
|
||||
//new stuff
|
||||
let original_hashmap=&state.metadata().get::<QemuEdgesMapMetadata>().unwrap().map;
|
||||
let original_hashmap=&state.metadata().get::<QemuEdgesMapMetadata>().expect("QemuEdgesMapMetadata not found").map;
|
||||
for (key, val) in original_hashmap.iter() {
|
||||
self.edgemap.insert(*key,*self.base.get(*val as usize));
|
||||
}
|
||||
// println!("Post-Exec Len: {} Cap: {}",self.edgemap.len(),self.edgemap.capacity());
|
||||
// println!("{:#?}",self.edgemap);
|
||||
//end new stuff
|
||||
let cnt = self.usable_count();
|
||||
for i in 0..cnt {
|
||||
*self.get_mut(i) = COUNT_CLASS_LOOKUP[*self.get(i) as usize];
|
||||
}
|
||||
self.base.post_exec(state, input)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Named for HitcountsMapObserver<M>
|
||||
impl<M, T> Named for QemuHashMapObserver<M, T>
|
||||
where
|
||||
M: Named + serde::Serialize + serde::de::DeserializeOwned,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
{
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
@ -96,9 +77,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> HasLen for HitcountsMapObserver<M>
|
||||
impl<M, T> HasLen for QemuHashMapObserver<M, T>
|
||||
where
|
||||
M: MapObserver<u8>,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
{
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
@ -106,9 +88,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> MapObserver<u8> for HitcountsMapObserver<M>
|
||||
impl<M, T> MapObserver<u8> for QemuHashMapObserver<M, T>
|
||||
where
|
||||
M: MapObserver<u8>,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
{
|
||||
#[inline]
|
||||
fn map(&self) -> Option<&[u8]> {
|
||||
@ -141,9 +124,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> HitcountsMapObserver<M>
|
||||
impl<M, T> QemuHashMapObserver<M, T>
|
||||
where
|
||||
M: serde::Serialize + serde::de::DeserializeOwned,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
{
|
||||
/// Creates a new [`MapObserver`]
|
||||
pub fn new(base: M) -> Self {
|
||||
@ -156,15 +140,23 @@ where
|
||||
|
||||
/// A [`HitFeedback`] reports as interesting when all predicted worst case edges have been matched.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct HitFeedback {
|
||||
target_map: HashMap<(u64,u64),u8>,
|
||||
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
||||
pub struct HitFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
target_map: HashMap<(u64,u64),T>,
|
||||
target_msd: f64,
|
||||
phantom: PhantomData<(O, T)>,
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for HitFeedback
|
||||
impl<I, S, T, O> Feedback<I, S> for HitFeedback<O, T>
|
||||
where
|
||||
I: Input,
|
||||
S: HasClientPerfMonitor,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
@ -178,15 +170,17 @@ where
|
||||
EM: EventFirer<I>,
|
||||
OT: ObserversTuple<I, S>,
|
||||
{
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
let observer = _observers.match_name::<QemuHashMapObserver<O, T>>("edges")
|
||||
.expect("QemuHashMapObserver not found");
|
||||
if self.target_map.len() == 0 { return Ok(false) };
|
||||
|
||||
let mut sum_of_square_difference : u64 = 0; // does not include found edges not in target
|
||||
for (edg, val) in &self.target_map {
|
||||
match observer.edgemap.get(&edg) {
|
||||
Some(x) => sum_of_square_difference+=((cmp::max(*x,*val)-cmp::min(*x,*val)) as u64).pow(2),
|
||||
None => sum_of_square_difference+=(*val as u64).pow(2),
|
||||
Some(x) => {
|
||||
sum_of_square_difference+=((cmp::max(*x,*val)-cmp::min(*x,*val)).to_u64().unwrap()).pow(2);
|
||||
},
|
||||
None => sum_of_square_difference+=((*val).to_u64().unwrap()).pow(2),
|
||||
}
|
||||
}
|
||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||
@ -200,99 +194,111 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for HitFeedback {
|
||||
impl<O, T> Named for HitFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"HitFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl HitFeedback {
|
||||
impl<O, T> HitFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new(target_map: HashMap<(u64,u64),u8>, target_msd: f64) -> Self {
|
||||
Self {target_map: target_map, target_msd: target_msd}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HitFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new(HashMap::new(),0.0)
|
||||
pub fn new(target_map: HashMap<(u64,u64),T>, target_msd: f64, _map_observer: &O) -> Self {
|
||||
Self {target_map: target_map, target_msd: target_msd, phantom: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
|
||||
/// A [`MapHitIncreaseFeedback`] reports as interesting when the total number of used edges increases.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct MapHitIncreaseFeedback {
|
||||
record_high : u64,
|
||||
}
|
||||
// /// A [`MapHitIncreaseFeedback`] reports as interesting when the total number of used edges increases.
|
||||
// #[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
// pub struct MapHitIncreaseFeedback {
|
||||
// record_high : u64,
|
||||
// }
|
||||
|
||||
impl<I, S> Feedback<I, S> for MapHitIncreaseFeedback
|
||||
where
|
||||
I: Input,
|
||||
S: HasClientPerfMonitor,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
_manager: &mut EM,
|
||||
_input: &I,
|
||||
_observers: &OT,
|
||||
_exit_kind: &ExitKind,
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
EM: EventFirer<I>,
|
||||
OT: ObserversTuple<I, S>,
|
||||
{
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
let cur = observer.edgemap.values().fold(0,|a,b| a+(*b as u64));
|
||||
if cur > self.record_high {
|
||||
self.record_high = cur;
|
||||
return Ok(true);
|
||||
}
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
// impl<I, S, O, T> Feedback<I, S> for MapHitIncreaseFeedback
|
||||
// where
|
||||
// I: Input,
|
||||
// S: HasClientPerfMonitor,
|
||||
// T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
// O: MapObserver<T>,
|
||||
// {
|
||||
// fn is_interesting<EM, OT>(
|
||||
// &mut self,
|
||||
// _state: &mut S,
|
||||
// _manager: &mut EM,
|
||||
// _input: &I,
|
||||
// _observers: &OT,
|
||||
// _exit_kind: &ExitKind,
|
||||
// ) -> Result<bool, Error>
|
||||
// where
|
||||
// EM: EventFirer<I>,
|
||||
// OT: ObserversTuple<I, S>,
|
||||
// {
|
||||
// let observer = _observers.match_name::<QemuHashMapObserver<O, T>>("edges")
|
||||
// .expect("QemuHashMapObserver not found");
|
||||
// let cur = observer.edgemap.values().fold(0,|a,b| a+(*b as u64));
|
||||
// if cur > self.record_high {
|
||||
// self.record_high = cur;
|
||||
// return Ok(true);
|
||||
// }
|
||||
// return Ok(false);
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Named for MapHitIncreaseFeedback {
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"HitFeedback"
|
||||
}
|
||||
}
|
||||
// impl Named for MapHitIncreaseFeedback {
|
||||
// #[inline]
|
||||
// fn name(&self) -> &str {
|
||||
// "HitFeedback"
|
||||
// }
|
||||
// }
|
||||
|
||||
impl MapHitIncreaseFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {record_high: 0}
|
||||
}
|
||||
}
|
||||
// impl MapHitIncreaseFeedback {
|
||||
// /// Creates a new [`HitFeedback`]
|
||||
// #[must_use]
|
||||
// pub fn new() -> Self {
|
||||
// Self {record_high: 0}
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Default for MapHitIncreaseFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
// impl Default for MapHitIncreaseFeedback {
|
||||
// fn default() -> Self {
|
||||
// Self::new()
|
||||
// }
|
||||
// }
|
||||
|
||||
//===================================================================
|
||||
|
||||
|
||||
/// A [`HitFeedback`] reports as interesting when all predicted worst case edges have been matched.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct HitImprovingFeedback {
|
||||
target_map: HashMap<(u64,u64),u8>,
|
||||
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
||||
pub struct HitImprovingFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
target_map: HashMap<(u64,u64),T>,
|
||||
best_msd: f64,
|
||||
phantom: PhantomData<(O, T)>,
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for HitImprovingFeedback
|
||||
impl<O, T, I, S> Feedback<I, S> for HitImprovingFeedback<O, T>
|
||||
where
|
||||
I: Input,
|
||||
S: HasClientPerfMonitor,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
@ -306,15 +312,17 @@ where
|
||||
EM: EventFirer<I>,
|
||||
OT: ObserversTuple<I, S>,
|
||||
{
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
let observer = _observers.match_name::<QemuHashMapObserver<O, T>>("edges")
|
||||
.expect("QemuHashMapObserver not found");
|
||||
if self.target_map.len() == 0 { return Ok(false) };
|
||||
|
||||
let mut sum_of_square_difference : u64 = 0; // does not include found edges not in target
|
||||
for (edg, val) in &self.target_map {
|
||||
match observer.edgemap.get(&edg) {
|
||||
Some(x) => sum_of_square_difference+=((cmp::max(*x,*val)-cmp::min(*x,*val)) as u64).pow(2),
|
||||
None => sum_of_square_difference+=(*val as u64).pow(2),
|
||||
Some(x) => {
|
||||
sum_of_square_difference+=((cmp::max(*x,*val)-cmp::min(*x,*val)).to_u64().unwrap()).pow(2);
|
||||
},
|
||||
None => sum_of_square_difference+=((*val).to_u64().unwrap()).pow(2),
|
||||
}
|
||||
}
|
||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||
@ -329,38 +337,47 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for HitImprovingFeedback {
|
||||
impl<O, T> Named for HitImprovingFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"HitFeedback"
|
||||
"HitImprovingFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl HitImprovingFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
impl<O, T> HitImprovingFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
/// Creates a new [`HitImprovingFeedback`]
|
||||
#[must_use]
|
||||
pub fn new(target_map: HashMap<(u64,u64),u8>) -> Self {
|
||||
Self {target_map: target_map, best_msd: f64::MAX}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HitImprovingFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new(HashMap::new())
|
||||
pub fn new(target_map: HashMap<(u64,u64),T>, _map_observer: &O) -> Self {
|
||||
Self {target_map: target_map, best_msd: f64::MAX, phantom: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================== Debugging Feedback
|
||||
/// A [`Feedback`] meant to dump the edgemap for debugging.
|
||||
#[derive(Debug)]
|
||||
pub struct DumpMapFeedback {
|
||||
dumpfile: Option<PathBuf>
|
||||
pub struct DumpMapFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
dumpfile: Option<PathBuf>,
|
||||
phantom: PhantomData<(O, T)>,
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for DumpMapFeedback
|
||||
impl<I, S, O, T> Feedback<I, S> for DumpMapFeedback<O, T>
|
||||
where
|
||||
I: Input,
|
||||
S: HasClientPerfMonitor,
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
@ -374,8 +391,8 @@ where
|
||||
EM: EventFirer<I>,
|
||||
OT: ObserversTuple<I, S>,
|
||||
{
|
||||
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||
.expect("HitcountsMapObserver not found");
|
||||
let observer = _observers.match_name::<QemuHashMapObserver<O, T>>("edges")
|
||||
.expect("QemuHashMapObserver not found");
|
||||
match &self.dumpfile {
|
||||
Some(s) => {
|
||||
fs::write(s,ron::to_string(&observer.edgemap).expect("Error serializing hashmap")).expect("Can not dump to file");
|
||||
@ -387,27 +404,29 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for DumpMapFeedback {
|
||||
impl<O, T> Named for DumpMapFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"HitFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl DumpMapFeedback {
|
||||
impl<O, T> DumpMapFeedback<O, T>
|
||||
where
|
||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||
O: MapObserver<T>,
|
||||
{
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {dumpfile: None}
|
||||
pub fn new(_map_observer: &O) -> Self {
|
||||
Self {dumpfile: None, phantom: PhantomData}
|
||||
}
|
||||
pub fn with_dump(dumpfile: Option<PathBuf>) -> Self {
|
||||
Self {dumpfile: dumpfile}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DumpMapFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
pub fn with_dump(dumpfile: Option<PathBuf>,_map_observer: &O) -> Self {
|
||||
Self {dumpfile: dumpfile, phantom: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
@ -511,6 +530,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
/// A Feedback reporting if the Input consists of strictly decreasing bytes.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SortedFeedback {
|
||||
|
Loading…
x
Reference in New Issue
Block a user