timeshift variable, handle nested isr+api, bump max_interrupts
This commit is contained in:
parent
c7bf1be8b1
commit
b9e388d9d5
@ -40,6 +40,16 @@ use std::path::PathBuf;
|
||||
|
||||
pub static mut FUZZ_START_TIMESTAMP : SystemTime = UNIX_EPOCH;
|
||||
|
||||
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_USEC : u32 = QEMU_ISNS_PER_SEC / 1000000;
|
||||
pub const QEMU_NS_PER_ISN : u32 = 1 << QEMU_ICOUNT_SHIFT;
|
||||
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_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 QEMU_SYSCLK_PER_TARGET_SEC : u32 = (TARGET_SYSCLK_FREQ as f32 * TARGET_MHZ_PER_MIPS) as u32;
|
||||
|
||||
//========== Metadata
|
||||
#[derive(Debug, SerdeAny, Serialize, Deserialize)]
|
||||
pub struct QemuIcountMetadata {
|
||||
@ -222,7 +232,7 @@ where
|
||||
{
|
||||
// TODO Replace with match_name_type when stable
|
||||
let observer = observers.match_name::<QemuClockObserver>(self.name()).unwrap();
|
||||
self.exec_time = Some(Duration::from_nanos(observer.last_runtime() << 4)); // Assume a somewhat realistic multiplier of clock, it does not matter
|
||||
self.exec_time = Some(Duration::from_nanos(observer.last_runtime() << QEMU_ICOUNT_SHIFT)); // Assume a somewhat realistic multiplier of clock, it does not matter
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ use petgraph::graph::EdgeIndex;
|
||||
use petgraph::graph::NodeIndex;
|
||||
use petgraph::prelude::DiGraph;
|
||||
use crate::systemstate::stg::STGFeedbackState;
|
||||
use crate::clock::QEMU_ICOUNT_SHIFT;
|
||||
|
||||
// Constants ================================================================================
|
||||
|
||||
@ -32,8 +33,8 @@ pub static mut RNG_SEED: u64 = 1;
|
||||
pub static mut LIMIT : u32 = u32::MAX;
|
||||
pub const FIRST_INT : u32 = 500000;
|
||||
|
||||
pub const MAX_NUM_INTERRUPT: usize = 32;
|
||||
pub const DO_NUM_INTERRUPT: usize = 32;
|
||||
pub const MAX_NUM_INTERRUPT: usize = 128;
|
||||
pub const DO_NUM_INTERRUPT: usize = 128;
|
||||
pub static mut MAX_INPUT_SIZE: usize = 32;
|
||||
/// Read ELF program headers to resolve physical load addresses.
|
||||
fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr {
|
||||
@ -116,7 +117,7 @@ pub fn get_all_fn_symbol_ranges(elf: &EasyElf, api_range: std::ops::Range<GuestA
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
static mut libafl_interrupt_offsets : [u32; 32];
|
||||
static mut libafl_interrupt_offsets : [u32; MAX_NUM_INTERRUPT];
|
||||
static mut libafl_num_interrupts : usize;
|
||||
}
|
||||
|
||||
@ -368,12 +369,15 @@ pub fn fuzz() {
|
||||
}
|
||||
|
||||
let mut api_ranges = get_all_fn_symbol_ranges(&elf, api_range);
|
||||
let app_fn_ranges = get_all_fn_symbol_ranges(&elf, app_range.clone());
|
||||
|
||||
let mut isr_ranges : HashMap<String,std::ops::Range<GuestAddr>> = systemstate::helpers::ISR_SYMBOLS.iter().filter_map(|x| (api_ranges.get(&x.to_string()).map(|y| (x.to_string(),y.clone())))).collect();
|
||||
systemstate::helpers::ISR_SYMBOLS.iter().for_each(|x| {let _ =(app_fn_ranges.get(&x.to_string()).map(|y| (x.to_string(),y.clone()))).map(|y| isr_ranges.insert(y.0,y.1));}); // add used defined isr
|
||||
let denylist=isr_ranges.values().map(|x| x.clone()).collect();
|
||||
let denylist = QemuInstrumentationFilter::DenyList(denylist); // do not count isr jumps, which are useless
|
||||
#[cfg(feature = "observe_systemstate")]
|
||||
let mut isr_addreses : HashMap<GuestAddr, String> = systemstate::helpers::ISR_SYMBOLS.iter().filter_map(|x| (api_ranges.remove(&x.to_string()).map(|y| (y.start,x.to_string())))).collect();
|
||||
systemstate::helpers::ISR_SYMBOLS.iter().for_each(|x| {let _ =(app_fn_ranges.get(&x.to_string()).map(|y| (x.to_string(),y.clone()))).map(|y| isr_addreses.insert(y.1.start, y.0));}); // add used defined isr
|
||||
|
||||
#[cfg(feature = "observe_systemstate")]
|
||||
for i in systemstate::helpers::ISR_SYMBOLS {
|
||||
@ -400,9 +404,11 @@ pub fn fuzz() {
|
||||
let args: Vec<String> = vec![
|
||||
"target/debug/fret",
|
||||
"-icount",
|
||||
"shift=4,align=off,sleep=off",
|
||||
&format!("shift={},align=off,sleep=off", QEMU_ICOUNT_SHIFT),
|
||||
"-machine",
|
||||
"mps2-an385",
|
||||
"-cpu",
|
||||
"cortex-m3",
|
||||
"-monitor",
|
||||
"null",
|
||||
"-kernel",
|
||||
@ -411,9 +417,9 @@ pub fn fuzz() {
|
||||
"null",
|
||||
"-nographic",
|
||||
"-S",
|
||||
"-semihosting",
|
||||
"--semihosting-config",
|
||||
"enable=on,target=native",
|
||||
// "-semihosting",
|
||||
// "--semihosting-config",
|
||||
// "enable=on,target=native",
|
||||
"-snapshot",
|
||||
"-drive",
|
||||
"if=none,format=qcow2,file=dummy.qcow2",
|
||||
@ -447,6 +453,9 @@ pub fn fuzz() {
|
||||
buf = &buf[libafl_num_interrupts*4..];
|
||||
len = buf.len();
|
||||
}
|
||||
// for i in 0 .. libafl_num_interrupts {
|
||||
// libafl_interrupt_offsets[i] = FIRST_INT+TryInto::<u32>::try_into(i).unwrap()*MINIMUM_INTER_ARRIVAL_TIME;
|
||||
// }
|
||||
// println!("Load: {:?}", libafl_interrupt_offsets[0..libafl_num_interrupts].to_vec());
|
||||
}
|
||||
if len > MAX_INPUT_SIZE {
|
||||
|
@ -13,9 +13,9 @@ use libafl::{
|
||||
corpus::{self, Corpus}, fuzzer::Evaluator, mark_feature_time, prelude::{new_hash_feedback, CorpusId, HasBytesVec, MutationResult, Mutator, UsesInput}, stages::Stage, start_timer, state::{HasCorpus, HasMetadata, HasNamedMetadata, HasRand, MaybeHasClientPerfMonitor, UsesState}, Error
|
||||
};
|
||||
use libafl::prelude::State;
|
||||
use crate::{clock::IcHist, fuzzer::{DO_NUM_INTERRUPT, FIRST_INT}, systemstate::{stg::{STGFeedbackState, STGNodeMetadata}, CaptureEvent, ExecInterval, FreeRTOSSystemStateMetadata, ReducedFreeRTOSSystemState}};
|
||||
use crate::{clock::{IcHist, QEMU_ISNS_PER_USEC}, fuzzer::{DO_NUM_INTERRUPT, FIRST_INT}, systemstate::{stg::{STGFeedbackState, STGNodeMetadata}, CaptureEvent, ExecInterval, FreeRTOSSystemStateMetadata, ReducedFreeRTOSSystemState}};
|
||||
|
||||
pub static mut MINIMUM_INTER_ARRIVAL_TIME : u32 = 1000 /*ms*/ * 62500;
|
||||
pub static mut MINIMUM_INTER_ARRIVAL_TIME : u32 = 1000 /*us*/ * QEMU_ISNS_PER_USEC;
|
||||
// one isn per 2**4 ns
|
||||
// virtual insn/sec 62500000 = 1/16 GHz
|
||||
// 1ms = 62500 insn
|
||||
|
@ -109,9 +109,9 @@ where
|
||||
where
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
for wp in self.api_fn_addrs.keys() {
|
||||
_hooks.instruction(*wp, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
||||
}
|
||||
// for wp in self.api_fn_addrs.keys() {
|
||||
// _hooks.instruction(*wp, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
||||
// }
|
||||
for wp in self.isr_addrs.keys() {
|
||||
_hooks.instruction(*wp, Hook::Function(exec_isr_hook::<QT, S>), false);
|
||||
}
|
||||
@ -213,7 +213,11 @@ fn trigger_collection(emulator: &Emulator, edge: (Option<GuestAddr>,Option<Guest
|
||||
println!("API Not found: {:#x} {:#x}", src, dest);
|
||||
}
|
||||
} else if let Some(s) = h.api_fn_addrs.get(&dest) { // API Call
|
||||
// if let None = in_any_range(&h.isr_ranges, src) {
|
||||
systemstate.capture_point=(CaptureEvent::APIStart, s.to_string());
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
} else {
|
||||
println!("API Not found: {:#x}", src);
|
||||
}
|
||||
@ -315,14 +319,13 @@ where
|
||||
let mut edge = (None, Some(pc));
|
||||
unsafe {
|
||||
LAST_API_CALL.with(|x| {
|
||||
match *x.get() {
|
||||
match (*x.get()).take() {
|
||||
Some(s) => {
|
||||
edge.0=Some(s.0);
|
||||
trigger_collection(emulator, edge, h);
|
||||
},
|
||||
None => (),
|
||||
}
|
||||
*x.get()=None;
|
||||
});
|
||||
}
|
||||
|
||||
@ -343,11 +346,13 @@ where
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
if let Some(h) = hooks.helpers().match_first_type::<QemuSystemStateHelper>() {
|
||||
if h.app_range.contains(&src) && !h.app_range.contains(&dest) {
|
||||
if h.app_range.contains(&src) && !h.app_range.contains(&dest) && in_any_range(&h.isr_ranges,src).is_none() {
|
||||
if let Some(_) = in_any_range(&h.api_fn_ranges,dest) {
|
||||
// println!("New jmp {:x} {:x}", src, dest);
|
||||
// println!("API Call Edge {:x} {:x}", src, dest);
|
||||
return Some(1);
|
||||
// TODO: trigger collection right here
|
||||
// otherwise there can be a race-condition, where LAST_API_CALL is set before the api starts, if the interrupt handler calls an api function, it will misidentify the callsite of that api call
|
||||
}
|
||||
} else if dest == 0 { // !h.app_range.contains(&src) &&
|
||||
if let Some(_) = in_any_range(&h.api_fn_ranges, src) {
|
||||
@ -363,6 +368,18 @@ where
|
||||
return None;
|
||||
}
|
||||
|
||||
fn get_icount(emulator : &Emulator) -> u64 {
|
||||
unsafe {
|
||||
// TODO: investigate why can_do_io is not set sometimes, as this is just a workaround
|
||||
let c = emulator.cpu_from_index(0);
|
||||
let can_do_io = (*c.raw_ptr()).neg.can_do_io;
|
||||
(*c.raw_ptr()).neg.can_do_io = true;
|
||||
let r = emu::icount_get_raw();
|
||||
(*c.raw_ptr()).neg.can_do_io = can_do_io;
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trace_api_call<QT, S>(
|
||||
hooks: &mut QemuHooks<QT, S>,
|
||||
_state: Option<&mut S>,
|
||||
@ -373,11 +390,10 @@ where
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
if id == 1 { // API call
|
||||
unsafe {
|
||||
let p = LAST_API_CALL.with(|x| x.get());
|
||||
*p = Some((src,dest));
|
||||
// println!("Jump {:#x} {:#x}", src, dest);
|
||||
}
|
||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||
let emulator = hooks.emulator();
|
||||
trigger_collection(emulator, (Some(src), Some(dest)), h);
|
||||
// println!("Exec API Call {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
||||
} else if id == 2 { // API return
|
||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||
// Ignore returns to other APIs or ISRs. We only account for the first call depth of API calls from user space.
|
||||
@ -389,7 +405,7 @@ where
|
||||
edge.1=Some(dest);
|
||||
|
||||
trigger_collection(emulator, edge, h);
|
||||
// println!("Exec API Return Edge {:#x} {:#x}", src, dest);
|
||||
// println!("Exec API Return Edge {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
||||
}
|
||||
} else if id == 3 { // ISR return
|
||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||
@ -399,7 +415,7 @@ where
|
||||
edge.0=Some(in_any_range(&h.isr_ranges, src).unwrap().start);
|
||||
|
||||
trigger_collection(emulator, edge, h);
|
||||
// println!("Exec ISR Return Edge {:#x} {:#x}", src, dest);
|
||||
// println!("Exec ISR Return Edge {:#x} {:#x} {}", src, dest, get_icount(emulator));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ where
|
||||
// unsafe {self.last_run = invalidate_ineffective_isr(refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC));}
|
||||
unsafe {
|
||||
let mut temp = refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC);
|
||||
fix_broken_trace(&mut temp.1);
|
||||
// fix_broken_trace(&mut temp.1);
|
||||
self.last_run = temp.0.clone();
|
||||
// println!("{:?}",temp);
|
||||
let mut temp = states2intervals(temp.0, temp.1);
|
||||
@ -154,6 +154,7 @@ fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> (Vec<Reduced
|
||||
delay_list_after: delay_list,
|
||||
// input_counter: i.input_counter,//+IRQ_INPUT_BYTES_NUMBER,
|
||||
});
|
||||
// println!("Refine: {:?} {:?} {:x}-{:x}",i.capture_point.0, i.capture_point.1.to_string(), i.edge.0.unwrap_or(0), i.edge.1.unwrap_or(0));
|
||||
ret.1.push((i.qemu_tick, i.capture_point.0, i.capture_point.1.to_string(), i.edge));
|
||||
}
|
||||
return ret;
|
||||
@ -161,6 +162,7 @@ fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> (Vec<Reduced
|
||||
|
||||
/// Transform the states and metadata into a list of ExecIntervals
|
||||
fn states2intervals(trace: Vec<ReducedFreeRTOSSystemState>, meta: Vec<(u64, CaptureEvent, String, (Option<u32>, Option<u32>))>) -> (Vec<ExecInterval>, HashMap<u64, ReducedFreeRTOSSystemState>) {
|
||||
if trace.len() == 0 {return (Vec::new(), HashMap::new());}
|
||||
let mut isr_stack : VecDeque<u8> = VecDeque::from([]); // 2+ = ISR, 1 = systemcall, 0 = APP. Trace starts with an ISREnd and executes the app
|
||||
|
||||
|
||||
@ -179,11 +181,11 @@ fn states2intervals(trace: Vec<ReducedFreeRTOSSystemState>, meta: Vec<(u64, Capt
|
||||
level_of_task.insert(curr_name, 0);
|
||||
}
|
||||
*level_of_task.get_mut(curr_name).unwrap()=0;
|
||||
&0
|
||||
0
|
||||
},
|
||||
CaptureEvent::APIStart => { // API start can only be called in the app
|
||||
*level_of_task.get_mut(curr_name).unwrap()=1;
|
||||
&1
|
||||
1
|
||||
},
|
||||
CaptureEvent::ISREnd => {
|
||||
// special case where the next block is an app start
|
||||
@ -192,12 +194,12 @@ fn states2intervals(trace: Vec<ReducedFreeRTOSSystemState>, meta: Vec<(u64, Capt
|
||||
}
|
||||
// nested isr, TODO: Test level > 2
|
||||
if isr_stack.len() > 1 {
|
||||
isr_stack.pop_back();
|
||||
isr_stack.back().unwrap()
|
||||
isr_stack.pop_back().unwrap();
|
||||
*isr_stack.back().unwrap()
|
||||
} else {
|
||||
isr_stack.pop_back();
|
||||
// possibly go back to an api call that is still running for this task
|
||||
level_of_task.get(curr_name).unwrap()
|
||||
*level_of_task.get(curr_name).unwrap()
|
||||
}
|
||||
},
|
||||
CaptureEvent::ISRStart => {
|
||||
@ -207,16 +209,16 @@ fn states2intervals(trace: Vec<ReducedFreeRTOSSystemState>, meta: Vec<(u64, Capt
|
||||
// } else {
|
||||
// regular case
|
||||
if isr_stack.len() > 0 {
|
||||
let l = isr_stack.back().unwrap();
|
||||
isr_stack.push_back(*l);
|
||||
isr_stack.back().unwrap()
|
||||
let l = *isr_stack.back().unwrap();
|
||||
isr_stack.push_back(l+1);
|
||||
l+1
|
||||
} else {
|
||||
isr_stack.push_back(2);
|
||||
&2
|
||||
2
|
||||
}
|
||||
// }
|
||||
}
|
||||
_ => &100
|
||||
_ => 100
|
||||
};
|
||||
// if trace[i].2 == CaptureEvent::End {break;}
|
||||
let next_hash=trace[i+1].get_hash();
|
||||
@ -230,7 +232,7 @@ fn states2intervals(trace: Vec<ReducedFreeRTOSSystemState>, meta: Vec<(u64, Capt
|
||||
end_state: next_hash,
|
||||
start_capture: (meta[i].1, meta[i].2.clone()),
|
||||
end_capture: (meta[i+1].1, meta[i+1].2.clone()),
|
||||
level: *level,
|
||||
level: level,
|
||||
tick_spend_preempted: 0,
|
||||
abb: None
|
||||
});
|
||||
@ -250,8 +252,9 @@ fn add_abb_info(trace: &mut Vec<ExecInterval>, table: &HashMap<u64, ReducedFreeR
|
||||
let curr_name = &table[&trace[i].start_state].current_task.task_name;
|
||||
// let last : Option<&usize> = last_abb_start_of_task.get(&curr_name);
|
||||
|
||||
let open_abb = open_abb_at_this_task_or_level.get(&(trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()})).to_owned(); // apps/apis are differentiated by task name, isrs by nested level
|
||||
let open_abb = open_abb_at_this_task_or_level.get(&(trace[i].level, if trace[i].level<2 {&curr_name} else {""})).to_owned(); // apps/apis are differentiated by task name, isrs by nested level
|
||||
|
||||
// println!("Edge {:x}-{:x}", edges[i].0.unwrap_or(0xffff), edges[i].1.unwrap_or(0xffff));
|
||||
|
||||
match (&trace[i].start_capture.0, &trace[i].end_capture.0) {
|
||||
// case with abb to block correspondence
|
||||
@ -269,35 +272,38 @@ fn add_abb_info(trace: &mut Vec<ExecInterval>, table: &HashMap<u64, ReducedFreeR
|
||||
match trace[i].start_capture.0 {
|
||||
// generic api abb start
|
||||
CaptureEvent::APIStart => {
|
||||
// assert_eq!(open_abb, None);
|
||||
assert_eq!(open_abb, None);
|
||||
open_abb_at_this_task_or_level.insert((trace[i].level, if trace[i].level<2 {&curr_name} else {""}), i);
|
||||
wip_abb_trace.push(Rc::new(RefCell::new(AtomicBasicBlock{start: edges[i].0.unwrap(), ends: HashSet::new(), level: if trace[i].level<2 {trace[i].level} else {2}})));
|
||||
},
|
||||
// generic isr abb start
|
||||
CaptureEvent::ISRStart => {
|
||||
// assert_eq!(open_abb, None);
|
||||
open_abb_at_this_task_or_level.insert( (trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()}) , i);
|
||||
assert_eq!(open_abb, None);
|
||||
open_abb_at_this_task_or_level.insert( (trace[i].level, if trace[i].level<2 {&curr_name} else {""}) , i);
|
||||
wip_abb_trace.push(Rc::new(RefCell::new(AtomicBasicBlock{start: edges[i].0.unwrap(), ends: HashSet::new(), level: if trace[i].level<2 {trace[i].level} else {2}})));
|
||||
},
|
||||
// generic app abb start
|
||||
CaptureEvent::APIEnd => {
|
||||
// assert_eq!(open_abb, None);
|
||||
open_abb_at_this_task_or_level.insert( (trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()}) , i);
|
||||
assert_eq!(open_abb, None);
|
||||
open_abb_at_this_task_or_level.insert( (trace[i].level, if trace[i].level<2 {&curr_name} else {""}) , i);
|
||||
wip_abb_trace.push(Rc::new(RefCell::new(AtomicBasicBlock{start: edges[i].0.unwrap(), ends: HashSet::new(), level: if trace[i].level<2 {trace[i].level} else {2}})));
|
||||
},
|
||||
// generic continued blocks
|
||||
CaptureEvent::ISREnd => {
|
||||
// special case app abb start
|
||||
if trace[i].start_capture.1=="xPortPendSVHandler" && !task_has_started.contains(curr_name) {
|
||||
// assert_eq!(open_abb, None);
|
||||
assert_eq!(open_abb, None);
|
||||
wip_abb_trace.push(Rc::new(RefCell::new(AtomicBasicBlock{start: 0, ends: HashSet::new(), level: if trace[i].level<2 {trace[i].level} else {2}})));
|
||||
open_abb_at_this_task_or_level.insert( (trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()}) , i);
|
||||
open_abb_at_this_task_or_level.insert( (trace[i].level, if trace[i].level<2 {&curr_name} else {""}) , i);
|
||||
task_has_started.insert(curr_name.clone());
|
||||
} else {
|
||||
if let Some(last) = open_abb_at_this_task_or_level.get(&(trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()})) {
|
||||
// assert_ne!(open_abb,None);
|
||||
if let Some(last) = open_abb_at_this_task_or_level.get(&(trace[i].level, if trace[i].level<2 {&curr_name} else {""})) {
|
||||
wip_abb_trace.push(wip_abb_trace[*last].clone());
|
||||
} else {
|
||||
eprintln!("Continued block with no start {} {:?} {:?} {} {}", trace[i].start_tick, trace[i].start_capture, trace[i].end_capture, task_has_started.contains(curr_name),trace[i].level);
|
||||
// panic!();
|
||||
eprintln!("Continued block with no start {} {:?} {:?} {:x}-{:x} {} {}", trace[i].start_tick, trace[i].start_capture, trace[i].end_capture, edges[i].0.unwrap_or(0xffff), edges[i].1.unwrap_or(0xffff),task_has_started.contains(curr_name),trace[i].level);
|
||||
panic!();
|
||||
wip_abb_trace.push(Rc::new(RefCell::new(AtomicBasicBlock{start: edges[i].1.unwrap_or(0), ends: HashSet::new(), level: if trace[i].level<2 {trace[i].level} else {2}})))
|
||||
}
|
||||
}
|
||||
@ -309,29 +315,29 @@ fn add_abb_info(trace: &mut Vec<ExecInterval>, table: &HashMap<u64, ReducedFreeR
|
||||
CaptureEvent::APIStart => {
|
||||
let _t = &wip_abb_trace[i];
|
||||
RefCell::borrow_mut(&*wip_abb_trace[i]).ends.insert(edges[i].1.unwrap());
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()}));
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {""}));
|
||||
},
|
||||
// generic api abb end
|
||||
CaptureEvent::APIEnd => {
|
||||
RefCell::borrow_mut(&*wip_abb_trace[i]).ends.insert(edges[i].1.unwrap());
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()}));
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {""}));
|
||||
},
|
||||
// generic isr abb end
|
||||
CaptureEvent::ISREnd => {
|
||||
RefCell::borrow_mut(&*wip_abb_trace[i]).ends.insert(edges[i].1.unwrap());
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()}));
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {""}));
|
||||
},
|
||||
// end anything
|
||||
CaptureEvent::End => {
|
||||
RefCell::borrow_mut(&*wip_abb_trace[i]).ends.insert(edges[i].1.unwrap());
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {trace[i].start_capture.1.as_str()}));
|
||||
open_abb_at_this_task_or_level.remove(&(trace[i].level, if trace[i].level<2 {&curr_name} else {""}));
|
||||
},
|
||||
CaptureEvent::ISRStart => (),
|
||||
_ => panic!("Undefined block end")
|
||||
}
|
||||
}
|
||||
}
|
||||
// println!("{} {} {:x}-{:x} {:x}-{:X} {:?} {:?} {}",curr_name, trace[i].level, edges[i].0.unwrap_or(0xffff), edges[i].1.unwrap_or(0xffff), ((*wip_abb_trace[i])).borrow().start, ((*wip_abb_trace[i])).borrow().ends.iter().next().unwrap_or(&0xffff), trace[i].start_capture, trace[i].end_capture, trace[i].start_tick);
|
||||
// println!("{} {} {:x}-{:x} {:x}-{:x} {:?} {:?} {}",curr_name, trace[i].level, edges[i].0.unwrap_or(0xffff), edges[i].1.unwrap_or(0xffff), ((*wip_abb_trace[i])).borrow().start, ((*wip_abb_trace[i])).borrow().ends.iter().next().unwrap_or(&0xffff), trace[i].start_capture, trace[i].end_capture, trace[i].start_tick);
|
||||
}
|
||||
drop(open_abb_at_this_task_or_level);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user