trace mem bytes read

This commit is contained in:
Alwin Berger 2024-10-28 08:12:30 +01:00
parent d89d5e3e5e
commit 3d0c0247b7
4 changed files with 18 additions and 15 deletions

View File

@ -474,11 +474,11 @@ where
}
static mut INPUT_MEM : Range<GuestAddr> = 0..0;
static mut MEM_READ : Option<HashSet<GuestAddr>> = None;
static mut MEM_READ : Option<Vec<(GuestAddr, u8)>> = None;
#[allow(unused)]
pub fn trace_reads<QT, S>(
_hooks: &mut QemuHooks<QT, S>,
hooks: &mut QemuHooks<QT, S>,
_state: Option<&mut S>,
_id: u64,
addr: GuestAddr,
@ -489,10 +489,13 @@ where
QT: QemuHelperTuple<S>,
{
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);
}

View File

@ -61,7 +61,7 @@ pub struct RawFreeRTOSSystemState {
input_counter: u32,
edge: (GuestAddr,GuestAddr),
capture_point: (CaptureEvent,String),
mem_reads: HashSet<u32>
mem_reads: Vec<(u32, u8)>
}
/// List of system state dumps from QemuHelpers
static mut CURRENT_SYSTEMSTATE_VEC: Vec<RawFreeRTOSSystemState> = vec![];

View File

@ -39,7 +39,7 @@ pub struct QemuSystemStateObserver<I>
pub last_run: Vec<ReducedFreeRTOSSystemState>,
pub last_states: HashMap<u64, ReducedFreeRTOSSystemState>,
pub last_trace: Vec<ExecInterval>,
pub last_reads: Vec<HashSet<u32>>,
pub last_reads: Vec<Vec<(u32, u8)>>,
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::<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 (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<u32,rtos_struct>) ->
/// 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<RawFreeRTOSSystemState>) -> (Vec<ReducedFreeRTOSSystemState>, Vec<(u64, CaptureEvent, String, (u32, u32), HashSet<u32>)>) {
fn refine_system_states(mut input: Vec<RawFreeRTOSSystemState>) -> (Vec<ReducedFreeRTOSSystemState>, 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<ReducedFreeRTOSSystemState>, meta: Vec<(u64, CaptureEvent, String, (u32, u32), HashSet<u32>)>) -> (Vec<ExecInterval>, Vec<HashSet<u32>>, HashMap<u64, ReducedFreeRTOSSystemState>, bool) {
fn states2intervals(trace: Vec<ReducedFreeRTOSSystemState>, meta: Vec<(u64, CaptureEvent, String, (u32, u32), Vec<(u32, u8)>)>) -> (Vec<ExecInterval>, Vec<Vec<(u32, u8)>>, HashMap<u64, ReducedFreeRTOSSystemState>, bool) {
if trace.len() == 0 {return (Vec::new(), Vec::new(), HashMap::new(), true);}
let mut isr_stack : VecDeque<u8> = 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<ReducedFreeRTOSSystemState>, meta: Vec<(u64, Capt
let mut level_of_task : HashMap<&str, u8> = HashMap::new();
let mut ret: Vec<ExecInterval> = vec![];
let mut reads: Vec<HashSet<u32>> = vec![];
let mut reads: Vec<Vec<(u32, u8)>> = vec![];
let mut edges: Vec<(u32, u32)> = vec![];
let mut last_hash : u64 = trace[0].get_hash();
let mut table : HashMap<u64, ReducedFreeRTOSSystemState> = HashMap::new();

View File

@ -92,7 +92,7 @@ pub struct STGEdge
{
pub event: CaptureEvent,
pub name: String,
pub worst: Option<(u64, HashSet<u32>)>, // TODO: extract bytes from input
pub worst: Option<(u64, Vec<(u32, u8)>)>,
}
impl STGEdge {
@ -363,8 +363,8 @@ fn get_generic_hash<H>(input: &H) -> u64
s.finish()
}
fn execinterval_to_abb_instances(trace: &Vec<ExecInterval>, read_trace: &Vec<HashSet<u32>>) -> HashMap<usize, (u64, HashSet<u32>)>{
let mut instance_time: HashMap<usize, (u64, HashSet<u32>)> = HashMap::new();
fn execinterval_to_abb_instances(trace: &Vec<ExecInterval>, read_trace: &Vec<Vec<(u32, u8)>>) -> HashMap<usize, (u64, Vec<(u32, u8)>)>{
let mut instance_time: HashMap<usize, (u64, Vec<(u32, u8)>)> = 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<ExecInterval>, read_trace: &Vec<HashSet<u32>>, table: &HashMap<u64, ReducedFreeRTOSSystemState>, fbs: &mut STGFeedbackState) -> (Vec<NodeIndex>, Vec<EdgeIndex>, bool, bool) {
fn update_stg_interval(trace: &Vec<ExecInterval>, read_trace: &Vec<Vec<(u32, u8)>>, table: &HashMap<u64, ReducedFreeRTOSSystemState>, fbs: &mut STGFeedbackState) -> (Vec<NodeIndex>, Vec<EdgeIndex>, bool, bool) {
let mut return_node_trace = vec![fbs.entrypoint];
let mut return_edge_trace = vec![];
let mut interesting = false;