From 3d0c0247b72e0e065241ce04ac12ab8e8502b4d8 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Mon, 28 Oct 2024 08:12:30 +0100 Subject: [PATCH] trace mem bytes read --- fuzzers/FRET/src/systemstate/helpers.rs | 11 +++++++---- fuzzers/FRET/src/systemstate/mod.rs | 2 +- fuzzers/FRET/src/systemstate/observers.rs | 12 ++++++------ fuzzers/FRET/src/systemstate/stg.rs | 8 ++++---- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/fuzzers/FRET/src/systemstate/helpers.rs b/fuzzers/FRET/src/systemstate/helpers.rs index 069d58a75f..5ab5898949 100644 --- a/fuzzers/FRET/src/systemstate/helpers.rs +++ b/fuzzers/FRET/src/systemstate/helpers.rs @@ -474,11 +474,11 @@ where } static mut INPUT_MEM : Range = 0..0; -static mut MEM_READ : Option> = None; +static mut MEM_READ : Option> = None; #[allow(unused)] pub fn trace_reads( - _hooks: &mut QemuHooks, + hooks: &mut QemuHooks, _state: Option<&mut S>, _id: u64, addr: GuestAddr, @@ -489,10 +489,13 @@ where QT: QemuHelperTuple, { if unsafe { INPUT_MEM.contains(&addr) } { + let emulator = hooks.qemu(); + let mut buf : [u8; 1] = [0]; + unsafe {emulator.read_mem(addr, &mut buf);} if unsafe { MEM_READ.is_none() } { - unsafe { MEM_READ = Some(HashSet::from([addr])) }; + unsafe { MEM_READ = Some(Vec::from([(addr, buf[0])])) }; } else { - unsafe { MEM_READ.as_mut().unwrap().insert(addr) }; + unsafe { MEM_READ.as_mut().unwrap().push((addr, buf[0])) }; } // println!("exec_read {:x} {}", addr, size); } diff --git a/fuzzers/FRET/src/systemstate/mod.rs b/fuzzers/FRET/src/systemstate/mod.rs index c76bd4b0c4..6f781c1239 100644 --- a/fuzzers/FRET/src/systemstate/mod.rs +++ b/fuzzers/FRET/src/systemstate/mod.rs @@ -61,7 +61,7 @@ pub struct RawFreeRTOSSystemState { input_counter: u32, edge: (GuestAddr,GuestAddr), capture_point: (CaptureEvent,String), - mem_reads: HashSet + mem_reads: Vec<(u32, u8)> } /// List of system state dumps from QemuHelpers static mut CURRENT_SYSTEMSTATE_VEC: Vec = vec![]; diff --git a/fuzzers/FRET/src/systemstate/observers.rs b/fuzzers/FRET/src/systemstate/observers.rs index 7561339d53..f08b604e74 100644 --- a/fuzzers/FRET/src/systemstate/observers.rs +++ b/fuzzers/FRET/src/systemstate/observers.rs @@ -39,7 +39,7 @@ pub struct QemuSystemStateObserver pub last_run: Vec, pub last_states: HashMap, pub last_trace: Vec, - pub last_reads: Vec>, + pub last_reads: Vec>, pub last_input: I, pub job_instances: Vec<(u64, u64, String)>, pub do_report: bool, @@ -83,11 +83,11 @@ where 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::>(); - 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 (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(Vec::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 + mem_reads: mem_reads.into_iter().flatten().collect(), // TODO: add read values release: x.0, response: x.1, exec_ticks: ticks_per_abb.iter().sum(), @@ -213,7 +213,7 @@ fn tcb_list_to_vec_cached(list: List_t, dump: &mut HashMap) -> /// returns: /// - a Vec of ReducedFreeRTOSSystemStates /// - a Vec of metadata tuples (qemu_tick, capture_event, capture_name, edge, mem_reads) -fn refine_system_states(mut input: Vec) -> (Vec, Vec<(u64, CaptureEvent, String, (u32, u32), HashSet)>) { +fn refine_system_states(mut input: Vec) -> (Vec, Vec<(u64, CaptureEvent, String, (u32, u32), Vec<(u32, u8)>)>) { let mut ret = (Vec::<_>::new(), Vec::<_>::new()); for mut i in input.drain(..) { let cur = RefinedTCB::from_tcb_owned(i.current_tcb); @@ -438,7 +438,7 @@ fn get_release_response_pairs(rel: &Vec<(u64, String)>, resp: &Vec<(u64, String) /// - a Vec of HashSets marking memory reads during these intervals /// - a HashMap of ReducedFreeRTOSSystemStates by hash /// - a bool indicating success -fn states2intervals(trace: Vec, meta: Vec<(u64, CaptureEvent, String, (u32, u32), HashSet)>) -> (Vec, Vec>, HashMap, bool) { +fn states2intervals(trace: Vec, meta: Vec<(u64, CaptureEvent, String, (u32, u32), Vec<(u32, u8)>)>) -> (Vec, Vec>, HashMap, bool) { if trace.len() == 0 {return (Vec::new(), Vec::new(), HashMap::new(), true);} let mut isr_stack : VecDeque = VecDeque::from([]); // 2+ = ISR, 1 = systemcall, 0 = APP. Trace starts with an ISREnd and executes the app @@ -446,7 +446,7 @@ fn states2intervals(trace: Vec, meta: Vec<(u64, Capt let mut level_of_task : HashMap<&str, u8> = HashMap::new(); let mut ret: Vec = vec![]; - let mut reads: Vec> = vec![]; + let mut reads: Vec> = vec![]; let mut edges: Vec<(u32, u32)> = vec![]; let mut last_hash : u64 = trace[0].get_hash(); let mut table : HashMap = HashMap::new(); diff --git a/fuzzers/FRET/src/systemstate/stg.rs b/fuzzers/FRET/src/systemstate/stg.rs index 8ea58e1eb6..f67a709edf 100644 --- a/fuzzers/FRET/src/systemstate/stg.rs +++ b/fuzzers/FRET/src/systemstate/stg.rs @@ -92,7 +92,7 @@ pub struct STGEdge { pub event: CaptureEvent, pub name: String, - pub worst: Option<(u64, HashSet)>, // TODO: extract bytes from input + pub worst: Option<(u64, Vec<(u32, u8)>)>, } impl STGEdge { @@ -363,8 +363,8 @@ fn get_generic_hash(input: &H) -> u64 s.finish() } -fn execinterval_to_abb_instances(trace: &Vec, read_trace: &Vec>) -> HashMap)>{ - let mut instance_time: HashMap)> = HashMap::new(); +fn execinterval_to_abb_instances(trace: &Vec, read_trace: &Vec>) -> HashMap)>{ + let mut instance_time: HashMap)> = HashMap::new(); for (_i,interval) in trace.iter().enumerate() { // Iterate intervals // sum up execution time and accesses per ABB let temp = interval.abb.as_ref().map(|abb| abb.instance_id).unwrap_or(usize::MAX); @@ -400,7 +400,7 @@ impl StgFeedback { /// newly discovered node? /// side effect: /// the graph gets new nodes and edge - fn update_stg_interval(trace: &Vec, read_trace: &Vec>, table: &HashMap, fbs: &mut STGFeedbackState) -> (Vec, Vec, bool, bool) { + fn update_stg_interval(trace: &Vec, read_trace: &Vec>, table: &HashMap, fbs: &mut STGFeedbackState) -> (Vec, Vec, bool, bool) { let mut return_node_trace = vec![fbs.entrypoint]; let mut return_edge_trace = vec![]; let mut interesting = false;