remove unused code

This commit is contained in:
Alwin Berger 2024-06-20 13:25:21 +02:00
parent 6cb2be4408
commit acf9b04e70
9 changed files with 87 additions and 764 deletions

View File

@ -1,41 +1,22 @@
use hashbrown::{hash_map::Entry, HashMap}; use libafl_bolts::Named;
use libafl_bolts::{
current_nanos,
rands::StdRand,
tuples::{tuple_list,MatchName},
impl_serdeany,
Named,
};
use libafl::{ use libafl::{
executors::{ExitKind}, executors::ExitKind,
fuzzer::{StdFuzzer}, observers::Observer,
inputs::{BytesInput, HasTargetBytes},
observers::{Observer,VariableMapObserver},
state::{StdState},
Error, Error,
common::HasNamedMetadata, common::HasNamedMetadata,
observers::ObserversTuple, prelude::UsesInput, observers::ObserversTuple, prelude::UsesInput,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{cell::UnsafeCell, cmp::max, env, fs::OpenOptions, io::Write, time::Instant}; use std::{fs::OpenOptions, io::Write};
use libafl_qemu::{
emu,
emu::Emulator,
executor::QemuExecutor,
helpers::{QemuHelper, QemuHelperTuple, HasInstrumentationFilter},
};
use libafl::events::EventFirer; use libafl::events::EventFirer;
use libafl::state::MaybeHasClientPerfMonitor; use libafl::state::MaybeHasClientPerfMonitor;
use libafl::prelude::State; use libafl::prelude::State;
use libafl::inputs::Input;
use libafl::feedbacks::Feedback; use libafl::feedbacks::Feedback;
use libafl::SerdeAny; use libafl::SerdeAny;
use libafl::common::HasMetadata; use libafl::common::HasMetadata;
use libafl::corpus::testcase::Testcase; use libafl::corpus::testcase::Testcase;
use core::{fmt::Debug, time::Duration}; use core::{fmt::Debug, time::Duration};
// use libafl::feedbacks::FeedbackState;
// use libafl::state::HasFeedbackStates;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use std::path::PathBuf; use std::path::PathBuf;
use std::borrow::Cow; use std::borrow::Cow;
@ -45,12 +26,12 @@ pub static mut FUZZ_START_TIMESTAMP : SystemTime = UNIX_EPOCH;
pub const QEMU_ICOUNT_SHIFT : u32 = 5; pub const QEMU_ICOUNT_SHIFT : u32 = 5;
pub const QEMU_ISNS_PER_SEC : u32 = u32::pow(10, 9) / u32::pow(2, QEMU_ICOUNT_SHIFT); pub const QEMU_ISNS_PER_SEC : u32 = u32::pow(10, 9) / u32::pow(2, QEMU_ICOUNT_SHIFT);
pub const QEMU_ISNS_PER_USEC : u32 = QEMU_ISNS_PER_SEC / 1000000; pub const QEMU_ISNS_PER_USEC : u32 = QEMU_ISNS_PER_SEC / 1000000;
pub const QEMU_NS_PER_ISN : u32 = 1 << QEMU_ICOUNT_SHIFT; pub const _QEMU_NS_PER_ISN : u32 = 1 << QEMU_ICOUNT_SHIFT;
pub const TARGET_SYSCLK_FREQ : u32 = 25 * 1000 * 1000; pub const _TARGET_SYSCLK_FREQ : u32 = 25 * 1000 * 1000;
pub const TARGET_MHZ_PER_MIPS : f32 = TARGET_SYSCLK_FREQ as f32 / QEMU_ISNS_PER_SEC as f32; pub const _TARGET_MHZ_PER_MIPS : f32 = _TARGET_SYSCLK_FREQ as f32 / QEMU_ISNS_PER_SEC as f32;
pub const TARGET_MIPS_PER_MHZ : f32 = QEMU_ISNS_PER_SEC as f32 / TARGET_SYSCLK_FREQ as f32; pub const _TARGET_MIPS_PER_MHZ : f32 = QEMU_ISNS_PER_SEC as f32 / _TARGET_SYSCLK_FREQ as f32;
pub const TARGET_SYSCLK_PER_QEMU_SEC : u32 = (TARGET_SYSCLK_FREQ as f32 * TARGET_MIPS_PER_MHZ) as u32; pub const _TARGET_SYSCLK_PER_QEMU_SEC : u32 = (_TARGET_SYSCLK_FREQ as f32 * _TARGET_MIPS_PER_MHZ) as u32;
pub const QEMU_SYSCLK_PER_TARGET_SEC : u32 = (TARGET_SYSCLK_FREQ as f32 * TARGET_MHZ_PER_MIPS) as u32; pub const _QEMU_SYSCLK_PER_TARGET_SEC : u32 = (_TARGET_SYSCLK_FREQ as f32 * _TARGET_MHZ_PER_MIPS) as u32;
//========== Metadata //========== Metadata
#[derive(Debug, SerdeAny, Serialize, Deserialize)] #[derive(Debug, SerdeAny, Serialize, Deserialize)]
@ -244,7 +225,7 @@ where
&mut self, &mut self,
_state: &mut S, _state: &mut S,
_manager: &mut EM, _manager: &mut EM,
observers: &OT, _observers: &OT,
testcase: &mut Testcase<S::Input>, testcase: &mut Testcase<S::Input>,
) -> Result<(), Error> { ) -> Result<(), Error> {
*testcase.exec_time_mut() = self.exec_time; *testcase.exec_time_mut() = self.exec_time;
@ -325,7 +306,7 @@ where
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> { fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime}); // testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
Ok(()) Ok(())
} }

View File

@ -7,7 +7,7 @@ use libafl_bolts::{
core_affinity::Cores, current_nanos, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, AsSlice core_affinity::Cores, current_nanos, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, AsSlice
}; };
use libafl::{ use libafl::{
common::{HasMetadata, HasNamedMetadata}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::ExitKind, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes}, monitors::MultiMonitor, observers::{CanTrack, VariableMapObserver}, prelude::{havoc_mutations, minimizer::TopRatedsMetadata, CorpusId, Generator, HitcountsMapObserver, RandBytesGenerator, SimpleEventManager, SimpleMonitor, SimpleRestartingEventManager, StdScheduledMutator}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::StdMutationalStage, state::{HasCorpus, StdState}, Error, Evaluator common::{HasMetadata, HasNamedMetadata}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::ExitKind, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes}, monitors::MultiMonitor, observers::{CanTrack, VariableMapObserver}, prelude::{havoc_mutations, minimizer::TopRatedsMetadata, CorpusId, Generator, HitcountsMapObserver, RandBytesGenerator, SimpleEventManager, SimpleMonitor, SimpleRestartingEventManager, StdScheduledMutator}, schedulers::QueueScheduler, stages::StdMutationalStage, state::{HasCorpus, StdState}, Error, Evaluator
}; };
use libafl_qemu::{ use libafl_qemu::{
edges::{self, edges_map_mut_ptr, QemuEdgeCoverageHelper, MAX_EDGES_FOUND}, elf::EasyElf, emu::Emulator, GuestAddr, GuestPhysAddr, QemuExecutor, QemuFilterList, QemuHooks, Regs, StdInstrumentationFilter edges::{self, edges_map_mut_ptr, QemuEdgeCoverageHelper, MAX_EDGES_FOUND}, elf::EasyElf, emu::Emulator, GuestAddr, GuestPhysAddr, QemuExecutor, QemuFilterList, QemuHooks, Regs, StdInstrumentationFilter
@ -780,7 +780,7 @@ let mut run_client = |state: Option<_>, mut mgr, _core_id| {
#[cfg(feature = "restarting")] #[cfg(feature = "restarting")]
{ {
let mut shmem_provider = StdShMemProvider::new().unwrap(); let mut shmem_provider = StdShMemProvider::new().unwrap();
let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider) let (state, mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider)
{ {
// The restarting state will spawn the same process again as child, then restarted it each time it crashes. // The restarting state will spawn the same process again as child, then restarted it each time it crashes.
Ok(res) => res, Ok(res) => res,

View File

@ -1,12 +1,9 @@
use libafl::SerdeAny; use libafl::SerdeAny;
use libafl_bolts::ownedref::OwnedSlice;
use libafl::inputs::BytesInput;
use libafl::prelude::UsesInput; use libafl::prelude::UsesInput;
use libafl::common::HasNamedMetadata; use libafl::common::HasNamedMetadata;
use std::path::PathBuf; use std::path::PathBuf;
use crate::clock::QemuClockObserver; use crate::clock::QemuClockObserver;
use libafl::corpus::Testcase; use libafl::corpus::Testcase;
use libafl_bolts::tuples::MatchName;
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher; use std::hash::Hasher;
use std::hash::Hash; use std::hash::Hash;
@ -17,17 +14,13 @@ use libafl::feedbacks::Feedback;
use libafl_bolts::Named; use libafl_bolts::Named;
use libafl::Error; use libafl::Error;
use hashbrown::HashMap; use hashbrown::HashMap;
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, common::HasMetadata}; use libafl::{executors::ExitKind, observers::ObserversTuple, common::HasMetadata};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::ExecInterval; use super::ExecInterval;
use super::ReducedFreeRTOSSystemState; use super::ReducedFreeRTOSSystemState;
use super::FreeRTOSSystemStateMetadata; use super::FreeRTOSSystemStateMetadata;
use super::observers::QemuSystemStateObserver; use super::observers::QemuSystemStateObserver;
use petgraph::prelude::DiGraph;
use petgraph::graph::NodeIndex;
use petgraph::Direction;
use std::cmp::Ordering;
use std::borrow::Cow; use std::borrow::Cow;
//============================= Feedback //============================= Feedback
@ -71,10 +64,10 @@ where
fn is_interesting<EM, OT>( fn is_interesting<EM, OT>(
&mut self, &mut self,
state: &mut S, state: &mut S,
manager: &mut EM, _manager: &mut EM,
input: &S::Input, _input: &S::Input,
observers: &OT, observers: &OT,
exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error>
where where
EM: EventFirer<State = S>, EM: EventFirer<State = S>,
@ -127,7 +120,7 @@ where
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> { fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
let a = self.last_trace.take(); let a = self.last_trace.take();
match a { match a {
Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)), Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
@ -177,11 +170,11 @@ where
{ {
fn is_interesting<EM, OT>( fn is_interesting<EM, OT>(
&mut self, &mut self,
state: &mut S, _state: &mut S,
manager: &mut EM, _manager: &mut EM,
input: &S::Input, _input: &S::Input,
observers: &OT, observers: &OT,
exit_kind: &ExitKind, _exit_kind: &ExitKind,
) -> Result<bool, Error> ) -> Result<bool, Error>
where where
EM: EventFirer<State = S>, EM: EventFirer<State = S>,
@ -203,7 +196,7 @@ where
} }
/// Append to the testcase the generated metadata in case of a new corpus item /// Append to the testcase the generated metadata in case of a new corpus item
#[inline] #[inline]
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> { fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
if !self.dump_metadata {return Ok(());} if !self.dump_metadata {return Ok(());}
// let a = self.last_trace.take(); // let a = self.last_trace.take();
// match a { // match a {
@ -232,13 +225,15 @@ impl Named for DumpSystraceFeedback
impl DumpSystraceFeedback impl DumpSystraceFeedback
{ {
/// Creates a new [`DumpSystraceFeedback`] /// Creates a new [`DumpSystraceFeedback`]
#[must_use] #[allow(unused)]
pub fn new() -> Self { pub fn new() -> Self {
Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: None, dump_metadata: false, last_trace: None, last_states: None } Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: None, dump_metadata: false, last_trace: None, last_states: None }
} }
#[allow(unused)]
pub fn with_dump(dumpfile: Option<PathBuf>) -> Self { pub fn with_dump(dumpfile: Option<PathBuf>) -> Self {
Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: dumpfile, dump_metadata: false, last_trace: None, last_states: None} Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: dumpfile, dump_metadata: false, last_trace: None, last_states: None}
} }
#[allow(unused)]
pub fn metadata_only() -> Self { pub fn metadata_only() -> Self {
Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: None, dump_metadata: true, last_trace: None, last_states: None} Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: None, dump_metadata: true, last_trace: None, last_states: None}
} }

View File

@ -1,7 +1,7 @@
#![allow(non_camel_case_types,non_snake_case,non_upper_case_globals,deref_nullptr)] #![allow(non_camel_case_types,non_snake_case,non_upper_case_globals,deref_nullptr,unused)]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// Manual Types // Manual Types
use libafl_qemu::{Emulator, Qemu}; use libafl_qemu::Qemu;
/*========== Start of generated Code =============*/ /*========== Start of generated Code =============*/
pub type char_ptr = ::std::os::raw::c_uint; pub type char_ptr = ::std::os::raw::c_uint;

View File

@ -1,632 +0,0 @@
use libafl::SerdeAny;
/// Feedbacks organizing SystemStates as a graph
// use libafl::inputs::HasBytesVec;
use libafl_bolts::rands::random_seed;
use libafl_bolts::rands::StdRand;
use libafl::mutators::Mutator;
use libafl::mutators::MutationResult;
use libafl::prelude::HasTargetBytes;
use libafl::prelude::UsesInput;
use libafl::common::HasNamedMetadata;
use libafl::state::UsesState;
use libafl::prelude::State;
use core::marker::PhantomData;
use libafl::state::HasCorpus;
use libafl::state::HasSolutions;
use libafl::state::HasRand;
use crate::worst::MaxExecsLenFavFactor;
use crate::worst::MaxTimeFavFactor;
use libafl::schedulers::MinimizerScheduler;
use libafl_bolts::HasRefCnt;
use libafl_bolts::AsSlice;
use libafl_bolts::ownedref::OwnedSlice;
use libafl::inputs::BytesInput;
use std::path::PathBuf;
use crate::clock::QemuClockObserver;
use libafl::corpus::Testcase;
use libafl_bolts::tuples::MatchName;
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
use std::hash::Hash;
use libafl::events::EventFirer;
use libafl::state::MaybeHasClientPerfMonitor;
use libafl::feedbacks::Feedback;
use libafl_bolts::Named;
use libafl::Error;
use hashbrown::HashMap;
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, common::HasMetadata};
use serde::{Deserialize, Serialize};
use super::ExecInterval;
use super::ReducedFreeRTOSSystemState;
use super::FreeRTOSSystemStateMetadata;
use super::observers::QemuSystemStateObserver;
use petgraph::prelude::DiGraph;
use petgraph::graph::NodeIndex;
use petgraph::Direction;
use std::cmp::Ordering;
use std::borrow::Cow;
use libafl_bolts::rands::Rand;
//============================= Data Structures
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub struct VariantTuple
{
pub start_tick: u64,
pub end_tick: u64,
input_counter: u32,
pub input: Vec<u8>, // in the end any kind of input are bytes, regardless of type and lifetime
}
impl VariantTuple {
fn from(other: &ReducedFreeRTOSSystemState,input: Vec<u8>) -> Self {
// VariantTuple{
// start_tick: other.tick,
// end_tick: other.end_tick,
// input_counter: other.input_counter,
// input: input,
// }
todo!()
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SysGraphNode
{
base: ReducedFreeRTOSSystemState,
pub variants: Vec<VariantTuple>,
}
impl SysGraphNode {
fn from(base: ReducedFreeRTOSSystemState, input: Vec<u8>) -> Self {
SysGraphNode{variants: vec![VariantTuple::from(&base, input)], base:base }
}
/// unites the variants of this value with another, draining the other if the bases are equal
fn unite(&mut self, other: &mut SysGraphNode) -> bool {
if self!=other {return false;}
self.variants.append(&mut other.variants);
self.variants.dedup();
return true;
}
/// add a Varint from a [`RefinedFreeRTOSSystemState`]
fn unite_raw(&mut self, other: &ReducedFreeRTOSSystemState, input: &Vec<u8>) -> bool {
if &self.base!=other {return false;}
self.variants.push(VariantTuple::from(other, input.clone()));
self.variants.dedup();
return true;
}
/// add a Varint from a [`RefinedFreeRTOSSystemState`], if it's interesting
fn unite_interesting(&mut self, other: &ReducedFreeRTOSSystemState, input: &Vec<u8>) -> bool {
// if &self.base!=other {return false;}
// let interesting =
// self.variants.iter().all(|x| x.end_tick-x.start_tick<other.end_tick-other.tick) || // longest variant
// self.variants.iter().all(|x| x.end_tick-x.start_tick>other.end_tick-other.tick) || // shortest variant
// self.variants.iter().all(|x| x.input_counter>other.input_counter) || // longest input
// self.variants.iter().all(|x| x.input_counter<other.input_counter); // shortest input
// if interesting {
// let var = VariantTuple::from(other, input.clone());
// self.variants.push(var);
// }
// return interesting;
todo!()
}
pub fn get_taskname(&self) -> &str {
&self.base.current_task.task_name
}
pub fn get_input_counts(&self) -> Vec<u32> {
self.variants.iter().map(|x| x.input_counter).collect()
}
pub fn pretty_print(&self) -> String {
let mut ret = String::new();
ret.push_str(&format!("{}",&self.base.current_task.task_name));
ret.push_str(";Rl:");
for i in &self.base.ready_list_after {
ret.push_str(&format!(";{}",i.task_name));
}
ret.push_str(";Dl:");
for i in &self.base.delay_list_after {
ret.push_str(&format!(";{}",i.task_name));
}
// println!("{}",ret);
ret
}
}
impl PartialEq for SysGraphNode {
fn eq(&self, other: &SysGraphNode) -> bool {
self.base==other.base
}
}
// Wrapper around Vec<RefinedFreeRTOSSystemState> to attach as Metadata
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct SysGraphMetadata {
pub inner: Vec<NodeIndex>,
indices: Vec<usize>,
tcref: isize,
}
impl SysGraphMetadata {
pub fn new(inner: Vec<NodeIndex>) -> Self{
Self {indices: inner.iter().map(|x| x.index()).collect(), inner: inner, tcref: 0}
}
}
// impl AsSlice for SysGraphMetadata {
// /// Convert the slice of system-states to a slice of hashes over enumerated states
// fn as_slice(&self) -> &[usize] {
// self.indices.as_slice()
// }
// type Entry = usize;
// }
impl HasRefCnt for SysGraphMetadata {
fn refcnt(&self) -> isize {
self.tcref
}
fn refcnt_mut(&mut self) -> &mut isize {
&mut self.tcref
}
}
libafl_bolts::impl_serdeany!(SysGraphMetadata);
pub type GraphMaximizerCorpusScheduler<CS, O> =
MinimizerScheduler<CS, MaxTimeFavFactor<<CS as UsesState>::State>,SysGraphMetadata,O>;
//============================= Graph Feedback
/// Improved System State Graph
#[derive(Serialize, Deserialize, Clone, Debug, SerdeAny)]
pub struct SysGraphFeedbackState
{
pub graph: DiGraph<SysGraphNode, ()>,
entrypoint: NodeIndex,
exit: NodeIndex,
name: Cow<'static, str>
}
impl SysGraphFeedbackState
{
pub fn new() -> Self {
let mut graph = DiGraph::<SysGraphNode, ()>::new();
let mut entry = SysGraphNode::default();
entry.base.current_task.task_name="Start".to_string();
let mut exit = SysGraphNode::default();
exit.base.current_task.task_name="End".to_string();
let entry = graph.add_node(entry);
let exit = graph.add_node(exit);
Self {graph: graph, entrypoint: entry, exit: exit, name: Cow::from(String::from("SysMap"))}
}
fn insert(&mut self, list: Vec<ReducedFreeRTOSSystemState>, input: &Vec<u8>) {
let mut current_index = self.entrypoint;
for n in list {
let mut done = false;
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
if n == self.graph[i].base {
done = true;
current_index = i;
break;
}
}
if !done {
let j = self.graph.add_node(SysGraphNode::from(n,input.clone()));
self.graph.add_edge(current_index, j, ());
current_index = j;
}
}
}
/// Try adding a system state path from a [Vec<RefinedFreeRTOSSystemState>], return true if the path was interesting
fn update(&mut self, list: &Vec<ReducedFreeRTOSSystemState>, input: &Vec<u8>) -> (bool, Vec<NodeIndex>) {
let mut current_index = self.entrypoint;
let mut novel = false;
let mut trace : Vec<NodeIndex> = vec![current_index];
for n in list {
let mut matching : Option<NodeIndex> = None;
for i in self.graph.node_indices() {
let tmp = &self.graph[i];
if n == &tmp.base {
matching = Some(i);
break;
}
}
match matching {
None => {
novel = true;
let j = self.graph.add_node(SysGraphNode::from(n.clone(),input.clone()));
self.graph.update_edge(current_index, j, ());
current_index = j;
},
Some(i) => {
novel |= self.graph[i].unite_interesting(&n, input);
self.graph.update_edge(current_index, i, ());
current_index = i;
}
}
trace.push(current_index);
}
if current_index != self.entrypoint {
self.graph.update_edge(current_index, self.exit, ()); // every path ends in the exit noded
}
return (novel, trace);
}
}
impl Named for SysGraphFeedbackState
{
#[inline]
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl Default for SysGraphFeedbackState {
fn default() -> Self {
Self::new()
}
}
impl SysGraphFeedbackState
{
fn reset(&mut self) -> Result<(), Error> {
self.graph.clear();
let mut entry = SysGraphNode::default();
entry.base.current_task.task_name="Start".to_string();
let mut exit = SysGraphNode::default();
exit.base.current_task.task_name="End".to_string();
self.entrypoint = self.graph.add_node(entry);
self.exit = self.graph.add_node(exit);
Ok(())
}
}
/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSystemStateObserver`]
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SysMapFeedback
{
name: Cow<'static, str>,
last_trace: Option<Vec<NodeIndex>>,
}
impl SysMapFeedback {
pub fn new() -> Self {
Self {name: Cow::from(String::from("SysMapFeedback")), last_trace: None }
}
}
impl<S> Feedback<S> for SysMapFeedback
where
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
S::Input: HasTargetBytes,
{
#[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>(
&mut self,
state: &mut S,
_manager: &mut EM,
_input: &S::Input,
observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
{
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemuSystemStateObserver not found");
let feedbackstate = match state
.named_metadata_map_mut()
.get_mut::<SysGraphFeedbackState>("SysMap") {
Some(s) => s,
None => {
let n=SysGraphFeedbackState::default();
state.named_metadata_map_mut().insert("SysMap",n);
state.named_metadata_map_mut().get_mut::<SysGraphFeedbackState>("SysMap").unwrap()
}
};
let ret = feedbackstate.update(&observer.last_run, &observer.last_input);
self.last_trace = Some(ret.1);
Ok(ret.0)
}
/// Append to the testcase the generated metadata in case of a new corpus item
#[inline]
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
let a = self.last_trace.take();
match a {
Some(s) => testcase.metadata_map_mut().insert(SysGraphMetadata::new(s)),
None => (),
}
Ok(())
}
/// Discard the stored metadata in case that the testcase is not added to the corpus
#[inline]
fn discard_metadata(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
self.last_trace = None;
Ok(())
}
}
impl Named for SysMapFeedback
{
#[inline]
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
//============================= Mutators
//=============================== Snippets
// pub struct RandGraphSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// phantom: PhantomData<(I, S)>,
// }
// impl<I, S> RandGraphSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// pub fn new() -> Self {
// RandGraphSnippetMutator{phantom: PhantomData}
// }
// }
// impl<I, S> Mutator<I, S> for RandGraphSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// fn mutate(
// &mut self,
// state: &mut S,
// input: &mut I,
// _stage_idx: i32
// ) -> Result<MutationResult, Error>
// {
// // need our own random generator, because borrowing rules
// let mut myrand = StdRand::new();
// let tmp = &mut state.rand_mut();
// myrand.set_seed(tmp.next());
// drop(tmp);
// let feedbackstate = state
// .feedback_states()
// .match_name::<SysGraphFeedbackState>("SysMap")
// .unwrap();
// let g = &feedbackstate.graph;
// let tmp = state.metadata().get::<SysGraphMetadata>();
// if tmp.is_none() { // if there are no metadata it was probably not interesting anyways
// return Ok(MutationResult::Skipped);
// }
// let trace =tmp.expect("SysGraphMetadata not found");
// // follow the path, extract snippets from last reads, find common snippets.
// // those are likley keys parts. choose random parts from other sibling traces
// let sibling_inputs : Vec<&Vec<u8>>= g[*trace.inner.last().unwrap()].variants.iter().map(|x| &x.input).collect();
// let mut snippet_collector = vec![];
// let mut per_input_counters = HashMap::<&Vec<u8>,usize>::new(); // ugly workaround to track multiple inputs
// for t in &trace.inner {
// let node = &g[*t];
// let mut per_node_snippets = HashMap::<&Vec<u8>,&[u8]>::new();
// for v in &node.variants {
// match per_input_counters.get_mut(&v.input) {
// None => {
// if sibling_inputs.iter().any(|x| *x==&v.input) { // only collect info about siblin inputs from target
// per_input_counters.insert(&v.input, v.input_counter.try_into().unwrap());
// }
// },
// Some(x) => {
// let x_u = *x;
// if x_u<v.input_counter as usize {
// *x=v.input_counter as usize;
// per_node_snippets.insert(&v.input,&v.input[x_u..v.input_counter as usize]);
// }
// }
// }
// }
// snippet_collector.push(per_node_snippets);
// }
// let mut new_input : Vec<u8> = vec![];
// for c in snippet_collector {
// new_input.extend_from_slice(myrand.choose(c).1);
// }
// for i in new_input.iter().enumerate() {
// input.bytes_mut()[i.0]=*i.1;
// }
// Ok(MutationResult::Mutated)
// }
// fn post_exec(
// &mut self,
// _state: &mut S,
// _stage_idx: i32,
// _corpus_idx: Option<usize>
// ) -> Result<(), Error> {
// Ok(())
// }
// }
// impl<I, S> Named for RandGraphSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// fn name(&self) -> &str {
// "RandGraphSnippetMutator"
// }
// }
// //=============================== Snippets
// pub struct RandInputSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// phantom: PhantomData<(I, S)>,
// }
// impl<I, S> RandInputSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// pub fn new() -> Self {
// RandInputSnippetMutator{phantom: PhantomData}
// }
// }
// impl<I, S> Mutator<I, S> for RandInputSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// fn mutate(
// &mut self,
// state: &mut S,
// input: &mut I,
// _stage_idx: i32
// ) -> Result<MutationResult, Error>
// {
// // need our own random generator, because borrowing rules
// let mut myrand = StdRand::new();
// let tmp = &mut state.rand_mut();
// myrand.set_seed(tmp.next());
// drop(tmp);
// let feedbackstate = state
// .feedback_states()
// .match_name::<SysGraphFeedbackState>("SysMap")
// .unwrap();
// let g = &feedbackstate.graph;
// let tmp = state.metadata().get::<SysGraphMetadata>();
// if tmp.is_none() { // if there are no metadata it was probably not interesting anyways
// return Ok(MutationResult::Skipped);
// }
// let trace = tmp.expect("SysGraphMetadata not found");
// let mut collection : Vec<Vec<u8>> = Vec::new();
// let mut current_pointer : usize = 0;
// for t in &trace.inner {
// let node = &g[*t];
// for v in &node.variants {
// if v.input == input.bytes() {
// if v.input_counter > current_pointer.try_into().unwrap() {
// collection.push(v.input[current_pointer..v.input_counter as usize].to_owned());
// current_pointer = v.input_counter as usize;
// }
// break;
// }
// }
// }
// let index_to_mutate = myrand.below(collection.len() as u64) as usize;
// for i in 0..collection[index_to_mutate].len() {
// collection[index_to_mutate][i] = myrand.below(0xFF) as u8;
// }
// for i in collection.concat().iter().enumerate() {
// input.bytes_mut()[i.0]=*i.1;
// }
// Ok(MutationResult::Mutated)
// }
// fn post_exec(
// &mut self,
// _state: &mut S,
// _stage_idx: i32,
// _corpus_idx: Option<usize>
// ) -> Result<(), Error> {
// Ok(())
// }
// }
// impl<I, S> Named for RandInputSnippetMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// fn name(&self) -> &str {
// "RandInputSnippetMutator"
// }
// }
// //=============================== Suffix
// pub struct RandGraphSuffixMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// phantom: PhantomData<(I, S)>,
// }
// impl<I, S> RandGraphSuffixMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// pub fn new() -> Self {
// RandGraphSuffixMutator{phantom: PhantomData}
// }
// }
// impl<I, S> Mutator<I, S> for RandGraphSuffixMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// fn mutate(
// &mut self,
// state: &mut S,
// input: &mut I,
// _stage_idx: i32
// ) -> Result<MutationResult, Error>
// {
// // need our own random generator, because borrowing rules
// let mut myrand = StdRand::new();
// let tmp = &mut state.rand_mut();
// myrand.set_seed(tmp.next());
// drop(tmp);
// let feedbackstate = state
// .feedback_states()
// .match_name::<SysGraphFeedbackState>("SysMap")
// .unwrap();
// let g = &feedbackstate.graph;
// let tmp = state.metadata().get::<SysGraphMetadata>();
// if tmp.is_none() { // if there are no metadata it was probably not interesting anyways
// return Ok(MutationResult::Skipped);
// }
// let trace =tmp.expect("SysGraphMetadata not found");
// // follow the path, extract snippets from last reads, find common snippets.
// // those are likley keys parts. choose random parts from other sibling traces
// let inp_c_end = g[*trace.inner.last().unwrap()].base.input_counter;
// let mut num_to_reverse = myrand.below(trace.inner.len().try_into().unwrap());
// for t in trace.inner.iter().rev() {
// let int_c_prefix = g[*t].base.input_counter;
// if int_c_prefix < inp_c_end {
// num_to_reverse-=1;
// if num_to_reverse<=0 {
// let mut new_input=input.bytes()[..(int_c_prefix as usize)].to_vec();
// let mut ext : Vec<u8> = (int_c_prefix..inp_c_end).map(|_| myrand.next().to_le_bytes()).flatten().collect();
// new_input.append(&mut ext);
// for i in new_input.iter().enumerate() {
// if input.bytes_mut().len()>i.0 {
// input.bytes_mut()[i.0]=*i.1;
// }
// else { break };
// }
// break;
// }
// }
// }
// Ok(MutationResult::Mutated)
// }
// fn post_exec(
// &mut self,
// _state: &mut S,
// _stage_idx: i32,
// _corpus_idx: Option<usize>
// ) -> Result<(), Error> {
// Ok(())
// }
// }
// impl<I, S> Named for RandGraphSuffixMutator<I, S>
// where
// I: Input + HasBytesVec,
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
// {
// fn name(&self) -> &str {
// "RandGraphSuffixMutator"
// }
// }

View File

@ -1,21 +1,13 @@
use std::cell::UnsafeCell;
use std::io::Write;
use std::ops::Range; use std::ops::Range;
use hashbrown::HashMap; use hashbrown::HashMap;
use libafl::prelude::ExitKind; use libafl::prelude::ExitKind;
use libafl::prelude::UsesInput; use libafl::prelude::UsesInput;
use libafl_qemu::read_user_reg_unchecked; use libafl_qemu::read_user_reg_unchecked;
use libafl_qemu::Emulator;
use libafl_qemu::GuestAddr; use libafl_qemu::GuestAddr;
use libafl_qemu::GuestPhysAddr;
use libafl_qemu::GuestReg;
use libafl_qemu::Qemu;
use libafl_qemu::QemuHooks; use libafl_qemu::QemuHooks;
use libafl_qemu::edges::QemuEdgesMapMetadata;
use libafl_qemu::emu;
use libafl_qemu::hooks;
use libafl_qemu::Hook; use libafl_qemu::Hook;
// use crate::systemstate::extract_abbs_from_trace; use libafl_qemu::helpers::{QemuHelper, QemuHelperTuple};
use crate::systemstate::RawFreeRTOSSystemState; use crate::systemstate::RawFreeRTOSSystemState;
use crate::systemstate::CURRENT_SYSTEMSTATE_VEC; use crate::systemstate::CURRENT_SYSTEMSTATE_VEC;
use crate::systemstate::NUM_PRIOS; use crate::systemstate::NUM_PRIOS;
@ -26,18 +18,7 @@ use super::freertos::rtos_struct::*;
use super::freertos; use super::freertos;
use super::CaptureEvent; use super::CaptureEvent;
use libafl_qemu::{
helpers::{QemuHelper, QemuHelperTuple},
// edges::SAVED_JUMP,
};
//============================= Struct definitions
pub static mut INTR_OFFSET : Option<u64> = None;
pub static mut INTR_DONE : bool = true;
// only used when inputs are injected
pub static mut NEXT_INPUT : Vec<u8> = Vec::new();
//============================= API symbols //============================= API symbols
@ -235,7 +216,7 @@ fn trigger_collection(emulator: &libafl_qemu::Qemu, edge: (GuestAddr, GuestAddr)
// println!("{:?}",std::str::from_utf8(&current_tcb.pcTaskName)); // println!("{:?}",std::str::from_utf8(&current_tcb.pcTaskName));
let critical : void_ptr = freertos::emu_lookup::lookup(emulator, h.critical_addr); let critical : void_ptr = freertos::emu_lookup::lookup(emulator, h.critical_addr);
let suspended : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_lock_addr); let suspended : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_lock_addr);
let running : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_running_addr); let _running : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_running_addr);
systemstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr); systemstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
// During ISRs it is only safe to extract structs if they are not currently being modified // During ISRs it is only safe to extract structs if they are not currently being modified

View File

@ -3,13 +3,11 @@ use std::collections::hash_map::DefaultHasher;
use std::fmt; use std::fmt;
use hashbrown::HashSet; use hashbrown::HashSet;
use libafl_bolts::HasRefCnt; use libafl_bolts::HasRefCnt;
use libafl_bolts::AsSlice;
use libafl_qemu::GuestAddr; use libafl_qemu::GuestAddr;
use std::hash::Hasher; use std::hash::Hasher;
use std::hash::Hash; use std::hash::Hash;
use hashbrown::HashMap; use hashbrown::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::rc::Rc;
use freertos::TCB_t; use freertos::TCB_t;
@ -17,7 +15,6 @@ pub mod freertos;
pub mod helpers; pub mod helpers;
pub mod observers; pub mod observers;
pub mod feedbacks; pub mod feedbacks;
pub mod graph;
pub mod schedulers; pub mod schedulers;
pub mod stg; pub mod stg;

View File

@ -1,4 +1,3 @@
// use crate::systemstate::IRQ_INPUT_BYTES_NUMBER;
use libafl::prelude::ExitKind; use libafl::prelude::ExitKind;
use libafl::{inputs::HasTargetBytes, prelude::UsesInput}; use libafl::{inputs::HasTargetBytes, prelude::UsesInput};
use libafl_bolts::HasLen; use libafl_bolts::HasLen;
@ -54,11 +53,11 @@ where
fn post_exec(&mut self, _state: &mut S, _input: &S::Input, _exit_kind: &ExitKind) -> Result<(), Error> { fn post_exec(&mut self, _state: &mut S, _input: &S::Input, _exit_kind: &ExitKind) -> Result<(), Error> {
// unsafe {self.last_run = invalidate_ineffective_isr(refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC));} // unsafe {self.last_run = invalidate_ineffective_isr(refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC));}
unsafe { unsafe {
let mut temp = refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC); let temp = refine_system_states(CURRENT_SYSTEMSTATE_VEC.drain(..).collect());
// fix_broken_trace(&mut temp.1); // fix_broken_trace(&mut temp.1);
self.last_run = temp.0.clone(); self.last_run = temp.0.clone();
// println!("{:?}",temp); // println!("{:?}",temp);
let mut temp = states2intervals(temp.0, temp.1); let temp = states2intervals(temp.0, temp.1);
self.last_trace = temp.0; self.last_trace = temp.0;
self.last_states = temp.1; self.last_states = temp.1;
self.success = temp.2; self.success = temp.2;
@ -138,7 +137,7 @@ fn tcb_list_to_vec_cached(list: List_t, dump: &mut HashMap<u32,rtos_struct>) ->
ret ret
} }
/// Drains a List of raw SystemStates to produce a refined trace /// Drains a List of raw SystemStates to produce a refined trace
fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> (Vec<ReducedFreeRTOSSystemState>, Vec<(u64, CaptureEvent, String, (u32, u32))>) { fn refine_system_states(mut input: Vec<RawFreeRTOSSystemState>) -> (Vec<ReducedFreeRTOSSystemState>, Vec<(u64, CaptureEvent, String, (u32, u32))>) {
let mut ret = (Vec::<_>::new(), Vec::<_>::new()); let mut ret = (Vec::<_>::new(), Vec::<_>::new());
for mut i in input.drain(..) { for mut i in input.drain(..) {
let cur = RefinedTCB::from_tcb_owned(i.current_tcb); let cur = RefinedTCB::from_tcb_owned(i.current_tcb);
@ -354,39 +353,39 @@ fn add_abb_info(trace: &mut Vec<ExecInterval>, table: &HashMap<u64, ReducedFreeR
} }
/// restore the isr/api begin/end invariant // /// restore the isr/api begin/end invariant
fn fix_broken_trace(meta: &mut Vec<(u64, CaptureEvent, String, (Option<u32>, Option<u32>))>) { // fn fix_broken_trace(meta: &mut Vec<(u64, CaptureEvent, String, (Option<u32>, Option<u32>))>) {
for i in meta.iter_mut() { // for i in meta.iter_mut() {
if i.1 == CaptureEvent::APIStart && i.2.ends_with("FromISR") { // if i.1 == CaptureEvent::APIStart && i.2.ends_with("FromISR") {
i.1 = CaptureEvent::ISREnd; // i.1 = CaptureEvent::ISREnd;
i.2 = "isr_starter".to_string(); // i.2 = "isr_starter".to_string();
} // }
} // }
} // }
/// invalidate subsequent intervals of equal states where an ISREnd follows an ISRStart. If the interrupt had no effect on the system we, are not interested. // /// invalidate subsequent intervals of equal states where an ISREnd follows an ISRStart. If the interrupt had no effect on the system we, are not interested.
fn invalidate_ineffective_isr(trace: &mut Vec<ExecInterval>) { // fn invalidate_ineffective_isr(trace: &mut Vec<ExecInterval>) {
let mut i = 0; // let mut i = 0;
while i < trace.len() - 1 { // while i < trace.len() - 1 {
if trace[i].is_valid() && // if trace[i].is_valid() &&
matches!(trace[i].start_capture.0, CaptureEvent::ISRStart) && matches!(trace[i].end_capture.0, CaptureEvent::ISREnd) && // matches!(trace[i].start_capture.0, CaptureEvent::ISRStart) && matches!(trace[i].end_capture.0, CaptureEvent::ISREnd) &&
trace[i].start_capture.1 == trace[i].end_capture.1 && trace[i].start_state == trace[i].end_state // trace[i].start_capture.1 == trace[i].end_capture.1 && trace[i].start_state == trace[i].end_state
{ // {
trace[i].invaildate(); // trace[i].invaildate();
} // }
} // }
} // }
/// merge a sequence of intervals of the same state+abb. jump over all invalid blocks. // /// merge a sequence of intervals of the same state+abb. jump over all invalid blocks.
fn merge_subsequent_abbs(trace: &mut Vec<ExecInterval>) { // fn merge_subsequent_abbs(trace: &mut Vec<ExecInterval>) {
let mut i = 1; // let mut i = 1;
let mut lst_valid=0; // let mut lst_valid=0;
while i < trace.len() - 1 { // while i < trace.len() - 1 {
if trace[i].is_valid() { // if trace[i].is_valid() {
let mut temp = trace[i].clone(); // let mut temp = trace[i].clone();
trace[lst_valid].try_unite_with_later_interval(&mut temp); // trace[lst_valid].try_unite_with_later_interval(&mut temp);
trace[i] = temp; // trace[i] = temp;
lst_valid = i; // lst_valid = i;
} // }
} // }
} // }

View File

@ -1,14 +1,14 @@
//! The Minimizer schedulers are a family of corpus schedulers that feed the fuzzer //! The Minimizer schedulers are a family of corpus schedulers that feed the fuzzer
//! with testcases only from a subset of the total corpus. //! with testcases only from a subset of the total corpus.
use core::{marker::PhantomData}; use core::marker::PhantomData;
use std::{cmp::{max, min}, mem::swap, borrow::BorrowMut}; use std::{cmp::{max, min}, mem::swap};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use libafl_bolts::{rands::Rand, serdeany::SerdeAny, AsSlice, HasRefCnt, HasLen}; use libafl_bolts::{rands::Rand, HasLen};
use libafl::{ use libafl::{
corpus::{Corpus, Testcase}, corpus::Corpus,
inputs::UsesInput, inputs::UsesInput,
schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB }, schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB },
state::{HasCorpus, HasRand, UsesState, State}, state::{HasCorpus, HasRand, UsesState, State},
@ -40,7 +40,7 @@ impl LongestTracesMetadata {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct LongestTraceScheduler<CS> { pub struct LongestTraceScheduler<CS> {
base: CS, base: CS,
skip_non_favored_prob: usize, skip_non_favored_prob: f64,
} }
impl<CS> UsesState for LongestTraceScheduler<CS> impl<CS> UsesState for LongestTraceScheduler<CS>
@ -104,7 +104,7 @@ where
.get::<STGNodeMetadata>().map_or(0, |x| x.nodes.len()); .get::<STGNodeMetadata>().map_or(0, |x| x.nodes.len());
let m = self.get_update_trace_length(state,l); let m = self.get_update_trace_length(state,l);
state.rand_mut().below(m as usize) > l state.rand_mut().below(m as usize) > l
} && state.rand_mut().below(100) < self.skip_non_favored_prob } && state.rand_mut().coinflip(self.skip_non_favored_prob)
{ {
idx = self.base.next(state)?; idx = self.base.next(state)?;
} }
@ -128,10 +128,11 @@ where
par as u64 par as u64
} }
} }
#[allow(unused)]
pub fn new(base: CS) -> Self { pub fn new(base: CS) -> Self {
Self { Self {
base, base,
skip_non_favored_prob: (DEFAULT_SKIP_NON_FAVORED_PROB * 100.0) as usize, skip_non_favored_prob: DEFAULT_SKIP_NON_FAVORED_PROB,
} }
} }
} }
@ -175,15 +176,15 @@ where
/// if current_gen is empty, swap lists, sort by FavFactor, take top k and return first /// if current_gen is empty, swap lists, sort by FavFactor, take top k and return first
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> { fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
let mut to_remove : Vec<(usize, f64)> = vec![]; let mut to_remove : Vec<(usize, f64)> = vec![];
let mut to_return : usize = 0; let mut _to_return : usize = 0;
let corpus_len = state.corpus().count(); let corpus_len = state.corpus().count();
let mut current_len = 0; let mut _current_len = 0;
let gm = state.metadata_map_mut().get_mut::<GeneticMetadata>().expect("Corpus Scheduler empty"); let gm = state.metadata_map_mut().get_mut::<GeneticMetadata>().expect("Corpus Scheduler empty");
// println!("index: {} curr: {:?} next: {:?} gen: {} corp: {}", gm.current_cursor, gm.current_gen.len(), gm.next_gen.len(), gm.gen, // println!("index: {} curr: {:?} next: {:?} gen: {} corp: {}", gm.current_cursor, gm.current_gen.len(), gm.next_gen.len(), gm.gen,
// c); // c);
match gm.current_gen.get(gm.current_cursor) { match gm.current_gen.get(gm.current_cursor) {
Some(c) => { Some(c) => {
current_len = gm.current_gen.len(); _current_len = gm.current_gen.len();
gm.current_cursor+=1; gm.current_cursor+=1;
// println!("normal next: {}", (*c).0); // println!("normal next: {}", (*c).0);
return Ok((*c).0.into()) return Ok((*c).0.into())
@ -201,25 +202,25 @@ where
// for i in 0..gm.current_gen.len() { // for i in 0..gm.current_gen.len() {
// gm.current_gen[i] = (i, gm.current_gen[i].1); // gm.current_gen[i] = (i, gm.current_gen[i].1);
// } // }
to_return = gm.current_gen.get(0).unwrap().0; _to_return = gm.current_gen.get(0).unwrap().0;
// assert_eq!(to_return, 0); // assert_eq!(to_return, 0);
gm.current_cursor=1; gm.current_cursor=1;
gm.gen+=1; gm.gen+=1;
current_len = gm.current_gen.len(); _current_len = gm.current_gen.len();
} }
}; };
// removing these elements will move all indices left by to_remove.len() // removing these elements will move all indices left by to_remove.len()
// to_remove.sort_by(|x,y| x.0.cmp(&(*y).0)); // to_remove.sort_by(|x,y| x.0.cmp(&(*y).0));
// to_remove.reverse(); // to_remove.reverse();
let cm = state.corpus_mut(); let cm = state.corpus_mut();
assert_eq!(corpus_len-to_remove.len(), current_len); assert_eq!(corpus_len-to_remove.len(), _current_len);
assert_ne!(current_len,0); assert_ne!(_current_len,0);
for i in to_remove { for i in to_remove {
cm.remove(i.0.into()).unwrap(); cm.remove(i.0.into()).unwrap();
} }
assert_eq!(cm.get(to_return.into()).is_ok(),true); assert_eq!(cm.get(_to_return.into()).is_ok(),true);
// println!("switch next: {to_return}"); // println!("switch next: {to_return}");
return Ok(to_return.into()); return Ok(_to_return.into());
} }
/// Add the new input to the next generation /// Add the new input to the next generation
@ -267,6 +268,7 @@ where
impl<S> GenerationScheduler<S> impl<S> GenerationScheduler<S>
{ {
#[allow(unused)]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
phantom: PhantomData, phantom: PhantomData,