trace executed abbs, instead of states
This commit is contained in:
parent
88c5c8a19f
commit
3f9a2ed6c0
@ -214,7 +214,7 @@ impl HasRefCnt for FreeRTOSSystemStateMetadata {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(FreeRTOSSystemStateMetadata);
|
libafl_bolts::impl_serdeany!(FreeRTOSSystemStateMetadata);
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Clone)]
|
#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct AtomicBasicBlock {
|
pub struct AtomicBasicBlock {
|
||||||
start: GuestAddr,
|
start: GuestAddr,
|
||||||
ends: HashSet<GuestAddr>,
|
ends: HashSet<GuestAddr>,
|
||||||
@ -249,6 +249,37 @@ impl fmt::Debug for AtomicBasicBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for AtomicBasicBlock {
|
||||||
|
fn partial_cmp(&self, other: &AtomicBasicBlock) -> Option<std::cmp::Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for AtomicBasicBlock {
|
||||||
|
fn cmp(&self, other: &AtomicBasicBlock) -> std::cmp::Ordering {
|
||||||
|
if self.start.cmp(&other.start) == std::cmp::Ordering::Equal {
|
||||||
|
// If the start addresses are equal, compare by 'ends'
|
||||||
|
let end1 = if self.ends.len() == 1 { *self.ends.iter().next().unwrap() as u64 } else {
|
||||||
|
let mut temp = self.ends.iter().collect::<Vec<_>>().into_iter().collect::<Vec<&GuestAddr>>();
|
||||||
|
temp.sort_unstable();
|
||||||
|
let mut h = DefaultHasher::new();
|
||||||
|
temp.hash(&mut h);
|
||||||
|
h.finish()
|
||||||
|
};
|
||||||
|
let end2 = if other.ends.len() == 1 { *self.ends.iter().next().unwrap() as u64 } else {
|
||||||
|
let mut temp = other.ends.iter().collect::<Vec<_>>().into_iter().collect::<Vec<&GuestAddr>>();
|
||||||
|
temp.sort_unstable();
|
||||||
|
let mut h = DefaultHasher::new();
|
||||||
|
temp.hash(&mut h);
|
||||||
|
h.finish()
|
||||||
|
};
|
||||||
|
end1.cmp(&end2)
|
||||||
|
} else {
|
||||||
|
// If the start addresses are not equal, compare by 'start'
|
||||||
|
self.start.cmp(&other.start)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn get_task_names(trace: &Vec<RefinedFreeRTOSSystemState>) -> HashSet<String> {
|
fn get_task_names(trace: &Vec<RefinedFreeRTOSSystemState>) -> HashSet<String> {
|
||||||
@ -363,8 +394,9 @@ fn extract_abbs_from_trace(trace: &Vec<RefinedFreeRTOSSystemState>) -> HashMap<S
|
|||||||
abbs_of_task
|
abbs_of_task
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns (name, abb, index, ticks)
|
/// returns (name, abb, index, ticks, Option<total abb ticks iff abb termiates here>)
|
||||||
fn trace_to_state_abb(trace: &Vec<RefinedFreeRTOSSystemState>) -> Vec<(String, Rc<AtomicBasicBlock>, usize, u64)> {
|
fn trace_to_state_abb(trace: &Vec<RefinedFreeRTOSSystemState>) -> (Vec<(String, Rc<AtomicBasicBlock>, usize, u64)>, Vec<(AtomicBasicBlock, u64)>) {
|
||||||
|
let mut abbs_in_exec_order : Vec<(usize,AtomicBasicBlock,u64)> = vec![]; // indices in trace where an abb ends, along with it's time
|
||||||
let mut has_started : HashSet<String> = HashSet::new();
|
let mut has_started : HashSet<String> = HashSet::new();
|
||||||
let mut abb_begin_end : HashMap<usize,usize> = HashMap::new();
|
let mut abb_begin_end : HashMap<usize,usize> = HashMap::new();
|
||||||
let mut last_abb_of_task : HashMap<String, usize> = HashMap::new();
|
let mut last_abb_of_task : HashMap<String, usize> = HashMap::new();
|
||||||
@ -429,19 +461,23 @@ fn trace_to_state_abb(trace: &Vec<RefinedFreeRTOSSystemState>) -> Vec<(String, R
|
|||||||
let abb = Rc::new(AtomicBasicBlock {start, ends: HashSet::from([end])});
|
let abb = Rc::new(AtomicBasicBlock {start, ends: HashSet::from([end])});
|
||||||
// find intervalls where the abb is actually running, not preempted
|
// find intervalls where the abb is actually running, not preempted
|
||||||
// count up exec time
|
// count up exec time
|
||||||
|
let mut sum_of_pieces = 0;
|
||||||
for i in s..e {
|
for i in s..e {
|
||||||
if trace[i].current_task.0.task_name == curr_name {
|
if trace[i].current_task.0.task_name == curr_name {
|
||||||
match trace[i].capture_point.0 {
|
match trace[i].capture_point.0 {
|
||||||
CaptureEvent::APIEnd => {chunks.push((curr_name.clone(), abb.clone(), i, trace[i+1].end_tick-trace[i].end_tick));},
|
CaptureEvent::APIEnd => {chunks.push((curr_name.clone(), abb.clone(), i, trace[i+1].end_tick-trace[i].end_tick)); sum_of_pieces+=trace[i+1].end_tick-trace[i].end_tick;},
|
||||||
CaptureEvent::ISRStart => (),
|
CaptureEvent::ISRStart => (),
|
||||||
CaptureEvent::ISREnd => {chunks.push((curr_name.clone(), abb.clone(), i, trace[i+1].end_tick-trace[i].end_tick));},
|
CaptureEvent::ISREnd => {chunks.push((curr_name.clone(), abb.clone(), i, trace[i+1].end_tick-trace[i].end_tick)); sum_of_pieces+=trace[i+1].end_tick-trace[i].end_tick;},
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
abbs_in_exec_order.push((e,(*abb).clone(), sum_of_pieces));
|
||||||
}
|
}
|
||||||
|
abbs_in_exec_order.sort_by_key(|x| x.0);
|
||||||
|
let abbs_in_exec_order : Vec<_> = abbs_in_exec_order.into_iter().map(|(_x,y,z)| (y,z)).collect();
|
||||||
chunks.sort_by_key(|x| x.2);
|
chunks.sort_by_key(|x| x.2);
|
||||||
chunks
|
(chunks, abbs_in_exec_order)
|
||||||
}
|
}
|
||||||
|
|
||||||
libafl_bolts::impl_serdeany!(AtomicBasicBlock);
|
libafl_bolts::impl_serdeany!(AtomicBasicBlock);
|
@ -44,7 +44,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
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 = post_process_trace(refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC));}
|
unsafe {self.last_run = remove_ineffective_isr(refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC));}
|
||||||
self.last_input=_input.target_bytes().as_slice().to_owned();
|
self.last_input=_input.target_bytes().as_slice().to_owned();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -171,8 +171,8 @@ fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> Vec<RefinedF
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_process_trace(mut trace: Vec<RefinedFreeRTOSSystemState>) -> Vec<RefinedFreeRTOSSystemState> {
|
fn remove_ineffective_isr(mut trace: Vec<RefinedFreeRTOSSystemState>) -> Vec<RefinedFreeRTOSSystemState> {
|
||||||
// remove subsequent pairs of equal states where an ISRStart follows an ISREnd
|
// remove subsequent pairs of equal states where an ISREnd follows an ISRStart. If the interrupt had no effect on the system we, are not interested.
|
||||||
let mut ret : Vec<RefinedFreeRTOSSystemState> = Vec::new();
|
let mut ret : Vec<RefinedFreeRTOSSystemState> = Vec::new();
|
||||||
ret.push(trace[0].clone());
|
ret.push(trace[0].clone());
|
||||||
let mut i = 1;
|
let mut i = 1;
|
||||||
|
@ -92,7 +92,7 @@ pub struct STGFeedbackState
|
|||||||
entrypoint: NodeIndex,
|
entrypoint: NodeIndex,
|
||||||
exit: NodeIndex,
|
exit: NodeIndex,
|
||||||
// Metadata about aggregated traces. aggegated meaning, order has been removed
|
// Metadata about aggregated traces. aggegated meaning, order has been removed
|
||||||
worst_observed_per_aggegated_path: HashMap<Vec<NodeIndex>,u64>
|
worst_observed_per_aggegated_path: HashMap<Vec<AtomicBasicBlock>,u64>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for STGFeedbackState {
|
impl Default for STGFeedbackState {
|
||||||
@ -256,12 +256,13 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let abbs = trace_to_state_abb(&observer.last_run);
|
let (abbs, ordered) = trace_to_state_abb(&observer.last_run);
|
||||||
// println!("{:?}",abbs);
|
// println!("{:?}",abbs);
|
||||||
let (trace, _, mut interesting) = StgFeedback::update_stg(&observer.last_run, abbs, feedbackstate);
|
let (_trace, _, mut interesting) = StgFeedback::update_stg(&observer.last_run, abbs, feedbackstate);
|
||||||
if INTEREST_AGGREGATE {
|
if INTEREST_AGGREGATE {
|
||||||
|
let (it1, _it2) : (Vec<_>, Vec<_>) = ordered.into_iter().unzip();
|
||||||
// aggegation by sorting, order of states is not relevant
|
// aggegation by sorting, order of states is not relevant
|
||||||
let mut tmp = trace.clone();
|
let mut tmp : Vec<_> = it1;
|
||||||
tmp.sort();
|
tmp.sort();
|
||||||
if let Some(x) = feedbackstate.worst_observed_per_aggegated_path.get_mut(&tmp) {
|
if let Some(x) = feedbackstate.worst_observed_per_aggegated_path.get_mut(&tmp) {
|
||||||
let t = clock_observer.last_runtime();
|
let t = clock_observer.last_runtime();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user