introduce JobInstance, TaskJob
This commit is contained in:
parent
d8a15adb1d
commit
d89d5e3e5e
@ -36,6 +36,16 @@ pub enum CaptureEvent {
|
|||||||
Undefined,
|
Undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Hierarchy of tracing data:
|
||||||
|
- RawFreeRTOSSystemState: Raw data from Qemu, represents a particular instant
|
||||||
|
- ReducedFreeRTOSSystemState: Generalized state of the system, without execution context
|
||||||
|
- ExecInterval: Some interval of execution between instants
|
||||||
|
- AtomicBasicBlock: A single-entry multiple-exit region between api calls. May be used referenced in multiple intervals.
|
||||||
|
- JobInstance: A single execution of a task, records the place and input read
|
||||||
|
- TaskJob: Generalized Job instance, records the worst inputs seen so far
|
||||||
|
*/
|
||||||
|
|
||||||
// ============================= State info
|
// ============================= State info
|
||||||
|
|
||||||
/// Raw info Dump from Qemu
|
/// Raw info Dump from Qemu
|
||||||
@ -356,6 +366,107 @@ fn get_task_names(trace: &Vec<ReducedFreeRTOSSystemState>) -> HashSet<String> {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(AtomicBasicBlock);
|
libafl_bolts::impl_serdeany!(AtomicBasicBlock);
|
||||||
|
|
||||||
|
// ============================= Job instances
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct JobInstance {
|
||||||
|
pub name: String,
|
||||||
|
pub mem_reads: Vec<(u32, u8)>,
|
||||||
|
pub release: u64,
|
||||||
|
pub response: u64,
|
||||||
|
pub exec_ticks: u64,
|
||||||
|
pub ticks_per_abb: Vec<u64>,
|
||||||
|
pub abbs: Vec<AtomicBasicBlock>,
|
||||||
|
hash_cache: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for JobInstance {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.abbs == other.abbs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Eq for JobInstance {}
|
||||||
|
impl Hash for JobInstance {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.abbs.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl JobInstance {
|
||||||
|
pub fn get_hash(&mut self) -> u64 {
|
||||||
|
if self.hash_cache == 0 {
|
||||||
|
let mut s = DefaultHasher::new();
|
||||||
|
self.hash(&mut s);
|
||||||
|
self.hash_cache = s.finish();
|
||||||
|
}
|
||||||
|
self.hash_cache
|
||||||
|
}
|
||||||
|
pub fn get_hash_cached(&self) -> u64 {
|
||||||
|
if self.hash_cache == 0 {
|
||||||
|
let mut s = DefaultHasher::new();
|
||||||
|
self.hash(&mut s);
|
||||||
|
s.finish()
|
||||||
|
} else {
|
||||||
|
self.hash_cache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================= Generalized job instances
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct TaskJob {
|
||||||
|
pub name: String,
|
||||||
|
pub worst_bytes: Vec<u8>,
|
||||||
|
pub woet_ticks: u64,
|
||||||
|
pub woet_per_abb: Vec<u64>,
|
||||||
|
pub abbs: Vec<AtomicBasicBlock>,
|
||||||
|
hash_cache: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for TaskJob {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.abbs == other.abbs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Eq for TaskJob {}
|
||||||
|
impl Hash for TaskJob {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.abbs.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl TaskJob {
|
||||||
|
pub fn get_hash(&mut self) -> u64 {
|
||||||
|
if self.hash_cache == 0 {
|
||||||
|
let mut s = DefaultHasher::new();
|
||||||
|
self.hash(&mut s);
|
||||||
|
self.hash_cache = s.finish();
|
||||||
|
}
|
||||||
|
self.hash_cache
|
||||||
|
}
|
||||||
|
pub fn get_hash_cached(&self) -> u64 {
|
||||||
|
if self.hash_cache == 0 {
|
||||||
|
let mut s = DefaultHasher::new();
|
||||||
|
self.hash(&mut s);
|
||||||
|
s.finish()
|
||||||
|
} else {
|
||||||
|
self.hash_cache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn try_update(&mut self, other: &mut JobInstance) -> bool {
|
||||||
|
assert_eq!(self.get_hash(), other.get_hash());
|
||||||
|
let mut ret = false;
|
||||||
|
if other.exec_ticks > self.woet_ticks {
|
||||||
|
self.woet_ticks = other.exec_ticks;
|
||||||
|
self.woet_per_abb = other.ticks_per_abb.clone();
|
||||||
|
other.mem_reads.sort_by(|a,b| a.0.cmp(&b.0));
|
||||||
|
self.worst_bytes = other.mem_reads.iter().map(|x| x.1).collect();
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================= Per testcase metadata
|
// ============================= Per testcase metadata
|
||||||
|
|
||||||
// Wrapper around Vec<RefinedFreeRTOSSystemState> to attach as Metadata
|
// Wrapper around Vec<RefinedFreeRTOSSystemState> to attach as Metadata
|
||||||
|
@ -17,6 +17,7 @@ use std::collections::VecDeque;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use super::helpers::USR_ISR_SYMBOLS;
|
use super::helpers::USR_ISR_SYMBOLS;
|
||||||
|
use super::JobInstance;
|
||||||
use super::{ AtomicBasicBlock, ExecInterval};
|
use super::{ AtomicBasicBlock, ExecInterval};
|
||||||
use super::{
|
use super::{
|
||||||
CURRENT_SYSTEMSTATE_VEC,
|
CURRENT_SYSTEMSTATE_VEC,
|
||||||
@ -63,7 +64,7 @@ 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 temp = refine_system_states(CURRENT_SYSTEMSTATE_VEC.drain(..).collect());
|
let temp = refine_system_states(CURRENT_SYSTEMSTATE_VEC.split_off(0));
|
||||||
// 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);
|
||||||
@ -78,8 +79,24 @@ where
|
|||||||
let releases = get_releases(&self.last_trace, &self.last_states);
|
let releases = get_releases(&self.last_trace, &self.last_states);
|
||||||
// println!("Releases: {:?}",&releases);
|
// println!("Releases: {:?}",&releases);
|
||||||
let jobs_done = JOBS_DONE.split_off(0);
|
let jobs_done = JOBS_DONE.split_off(0);
|
||||||
(self.job_instances, self.do_report) = get_release_response_pairs(&releases, &jobs_done);
|
let (job_instances, do_report) = get_release_response_pairs(&releases, &jobs_done);
|
||||||
// println!("Instances: {:?}",&self.job_instances);
|
self.do_report = do_report;
|
||||||
|
let job_instances = job_instances.into_iter().map(|x| {
|
||||||
|
let intervals = self.last_trace.iter().enumerate().filter(|y| y.1.start_tick <= x.1 && y.1.end_tick >= x.0 && x.2 == y.1.get_task_name_unchecked()).map(|(idx,x)| (x, &self.last_reads[idx])).collect::<Vec<_>>();
|
||||||
|
let (abbs, rest) : (Vec<_>, Vec<_>) = intervals.chunk_by(|a,b| a.0.abb.as_ref().unwrap().instance_eq(b.0.abb.as_ref().unwrap())).into_iter().map(|intervals| (intervals[0].0.abb.as_ref().unwrap().clone(), (intervals.iter().fold(0, |sum, x| sum+x.0.get_exec_time()), intervals.iter().fold(HashSet::new(), |mut sum, x| {sum.extend(x.1.iter()); sum})))).unzip();
|
||||||
|
let (ticks_per_abb, mem_reads) : (Vec<_>, Vec<_>) = rest.into_iter().unzip();
|
||||||
|
JobInstance {
|
||||||
|
name: x.2.clone(),
|
||||||
|
mem_reads: mem_reads.into_iter().flatten().map(|x| (x,0)).collect(), // TODO: add read values
|
||||||
|
release: x.0,
|
||||||
|
response: x.1,
|
||||||
|
exec_ticks: ticks_per_abb.iter().sum(),
|
||||||
|
ticks_per_abb: ticks_per_abb,
|
||||||
|
abbs: abbs,
|
||||||
|
hash_cache: 0
|
||||||
|
}
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
println!("Instances: {:?}",&job_instances);
|
||||||
let observer = &self;
|
let observer = &self;
|
||||||
let mut worst_case_per_task = HashMap::new();
|
let mut worst_case_per_task = HashMap::new();
|
||||||
observer.job_instances.iter().for_each(|x| {
|
observer.job_instances.iter().for_each(|x| {
|
||||||
@ -507,7 +524,7 @@ fn states2intervals(trace: Vec<ReducedFreeRTOSSystemState>, meta: Vec<(u64, Capt
|
|||||||
tick_spend_preempted: 0,
|
tick_spend_preempted: 0,
|
||||||
abb: None
|
abb: None
|
||||||
});
|
});
|
||||||
reads.push(meta[i].4.clone());
|
reads.push(meta[i+1].4.clone());
|
||||||
last_hash = next_hash;
|
last_hash = next_hash;
|
||||||
edges.push((meta[i].3.1, meta[i+1].3.0));
|
edges.push((meta[i].3.1, meta[i+1].3.0));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user