track api calls and isrs
This commit is contained in:
parent
5d9bcba0e6
commit
a045b7bcd6
@ -78,6 +78,37 @@ pub fn try_load_symbol(elf : &EasyElf, symbol : &str, do_translation : bool) ->
|
|||||||
} else {ret}
|
} else {ret}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_function_range(elf: &EasyElf, symbol: &'static str) -> Option<std::ops::Range<GuestAddr>> {
|
||||||
|
let gob = elf.goblin();
|
||||||
|
|
||||||
|
let mut funcs : Vec<_> = gob.syms.iter().filter(|x| x.is_function()).collect();
|
||||||
|
funcs.sort_unstable_by(|x,y| x.st_value.cmp(&y.st_value));
|
||||||
|
|
||||||
|
for sym in &gob.syms {
|
||||||
|
if let Some(sym_name) = gob.strtab.get_at(sym.st_name) {
|
||||||
|
if sym_name == symbol {
|
||||||
|
if sym.st_value == 0 {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
//#[cfg(cpu_target = "arm")]
|
||||||
|
// Required because of arm interworking addresses aka bit(0) for thumb mode
|
||||||
|
let addr = (sym.st_value as GuestAddr) & !(0x1 as GuestAddr);
|
||||||
|
//#[cfg(not(cpu_target = "arm"))]
|
||||||
|
//let addr = sym.st_value as GuestAddr;
|
||||||
|
// look for first function after addr
|
||||||
|
let sym_end = funcs.iter().find(|x| x.st_value > sym.st_value);
|
||||||
|
if let Some(sym_end) = sym_end {
|
||||||
|
println!("{} {:#x}..{} {:#x}", gob.strtab.get_at(sym.st_name).unwrap_or(""),addr, gob.strtab.get_at(sym_end.st_name).unwrap_or(""),sym_end.st_value & !0x1);
|
||||||
|
return Some(addr..((sym_end.st_value & !0x1) as GuestAddr));
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static mut libafl_interrupt_offsets : [u32; 32];
|
static mut libafl_interrupt_offsets : [u32; 32];
|
||||||
static mut libafl_num_interrupts : usize;
|
static mut libafl_num_interrupts : usize;
|
||||||
@ -350,6 +381,19 @@ pub fn fuzz() {
|
|||||||
api_addreses.insert(sb,s);
|
api_addreses.insert(sb,s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "systemstate")]
|
||||||
|
let mut isr_addreses : HashMap<GuestAddr,&'static str> = HashMap::new();
|
||||||
|
#[cfg(feature = "systemstate")]
|
||||||
|
for s in systemstate::helpers::ISR_SYMBOLS {
|
||||||
|
if let Some(sb) = try_load_symbol(&elf, &s, false) {
|
||||||
|
isr_addreses.insert(sb & !1,s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "systemstate")]
|
||||||
|
let mut api_ranges : Vec<(&'static str,std::ops::Range<GuestAddr>)> = systemstate::helpers::API_SYMBOLS.iter().filter_map(|x| get_function_range(&elf, x).map(|y| (*x,y))).collect();
|
||||||
|
#[cfg(feature = "systemstate")]
|
||||||
|
let mut isr_ranges : Vec<(&'static str,std::ops::Range<GuestAddr>)> = systemstate::helpers::ISR_SYMBOLS.iter().filter_map(|x| get_function_range(&elf, x).map(|y| (*x,y))).collect();
|
||||||
|
|
||||||
// Client setup ================================================================================
|
// Client setup ================================================================================
|
||||||
|
|
||||||
@ -545,7 +589,7 @@ pub fn fuzz() {
|
|||||||
let qhelpers = tuple_list!(
|
let qhelpers = tuple_list!(
|
||||||
QemuEdgeCoverageHelper::default(),
|
QemuEdgeCoverageHelper::default(),
|
||||||
QemuStateRestoreHelper::new(),
|
QemuStateRestoreHelper::new(),
|
||||||
QemuSystemStateHelper::new(api_addreses,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,input_counter_ptr,app_range.clone())
|
QemuSystemStateHelper::new(api_addreses,api_ranges,isr_addreses,isr_ranges,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,input_counter_ptr,app_range.clone())
|
||||||
);
|
);
|
||||||
let mut hooks = QemuHooks::new(emu.clone(),qhelpers);
|
let mut hooks = QemuHooks::new(emu.clone(),qhelpers);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ use super::freertos::TCB_t;
|
|||||||
use super::freertos::rtos_struct::List_Item_struct;
|
use super::freertos::rtos_struct::List_Item_struct;
|
||||||
use super::freertos::rtos_struct::*;
|
use super::freertos::rtos_struct::*;
|
||||||
use super::freertos;
|
use super::freertos;
|
||||||
|
use super::CaptureEvent;
|
||||||
|
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
helper::{QemuHelper, QemuHelperTuple},
|
helper::{QemuHelper, QemuHelperTuple},
|
||||||
@ -35,7 +36,7 @@ pub static mut NEXT_INPUT : Vec<u8> = Vec::new();
|
|||||||
|
|
||||||
//============================= API symbols
|
//============================= API symbols
|
||||||
|
|
||||||
pub static API_SYMBOLS : &'static [&str] = &[
|
pub const API_SYMBOLS : &'static [&'static str] = &[
|
||||||
// Task Creation
|
// Task Creation
|
||||||
"xTaskCreate", "xTaskCreateStatic", "vTaskDelete", "xTaskGetStaticBuffers",
|
"xTaskCreate", "xTaskCreateStatic", "vTaskDelete", "xTaskGetStaticBuffers",
|
||||||
// Task Control
|
// Task Control
|
||||||
@ -65,7 +66,13 @@ pub static API_SYMBOLS : &'static [&str] = &[
|
|||||||
// Co-routines
|
// Co-routines
|
||||||
"xCoRoutineCreate","crDELAY","crQUEUE_SEND","crQUEUE_RECEIVE","crQUEUE_SEND_FROM_ISR","crQUEUE_RECEIVE_FROM_ISR","vCoRoutineSchedule",
|
"xCoRoutineCreate","crDELAY","crQUEUE_SEND","crQUEUE_RECEIVE","crQUEUE_SEND_FROM_ISR","crQUEUE_RECEIVE_FROM_ISR","vCoRoutineSchedule",
|
||||||
// Custom resolved macros
|
// Custom resolved macros
|
||||||
"vPortEnterCritical","vPortExitCritical","xTaskGenericNotify","xTaskGenericNotifyFromISR","xQueueGenericSend","xQueueGenericReset"
|
"vPortEnterCritical","vPortExitCritical","xTaskGenericNotify","xTaskGenericNotifyFromISR","xQueueGenericSend","xQueueGenericReset","ulTaskGenericNotifyTake","xTimerCreateTimerTask",
|
||||||
|
"pvPortMalloc","prvAddNewTaskToReadyList","prvUnlockQueue","prvCheckForValidListAndQueue","prvProcessTimerOrBlockTask","prvInitialiseNewQueue","prvSampleTimeNow"
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const ISR_SYMBOLS : &'static [&'static str] = &[
|
||||||
|
// ISRs
|
||||||
|
"Reset_Handler","Default_Handler","Default_Handler2","Default_Handler3","Default_Handler4","Default_Handler5","Default_Handler6","vPortSVCHandler","xPortPendSVHandler","xPortSysTickHandler","isr_starter"
|
||||||
];
|
];
|
||||||
|
|
||||||
//============================= Qemu Helper
|
//============================= Qemu Helper
|
||||||
@ -73,7 +80,12 @@ pub static API_SYMBOLS : &'static [&str] = &[
|
|||||||
/// A Qemu Helper with reads FreeRTOS specific structs from Qemu whenever certain syscalls occur, also inject inputs
|
/// A Qemu Helper with reads FreeRTOS specific structs from Qemu whenever certain syscalls occur, also inject inputs
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct QemuSystemStateHelper {
|
pub struct QemuSystemStateHelper {
|
||||||
watchaddr: HashMap<GuestAddr, &'static str>,
|
// Address of API functions
|
||||||
|
api_fn_addrs: HashMap<GuestAddr, &'static str>,
|
||||||
|
api_fn_ranges: Vec<(&'static str, std::ops::Range<GuestAddr>)>,
|
||||||
|
// Address of interrupt routines
|
||||||
|
isr_addrs: HashMap<GuestAddr, &'static str>,
|
||||||
|
isr_ranges: Vec<(&'static str, std::ops::Range<GuestAddr>)>,
|
||||||
tcb_addr: GuestAddr,
|
tcb_addr: GuestAddr,
|
||||||
ready_queues: GuestAddr,
|
ready_queues: GuestAddr,
|
||||||
delay_queue: GuestAddr,
|
delay_queue: GuestAddr,
|
||||||
@ -85,7 +97,10 @@ pub struct QemuSystemStateHelper {
|
|||||||
impl QemuSystemStateHelper {
|
impl QemuSystemStateHelper {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
watchaddr: HashMap<GuestAddr, &'static str>,
|
api_fn_addrs: HashMap<GuestAddr, &'static str>,
|
||||||
|
api_fn_ranges: Vec<(&'static str, std::ops::Range<GuestAddr>)>,
|
||||||
|
isr_addrs: HashMap<GuestAddr, &'static str>,
|
||||||
|
isr_ranges: Vec<(&'static str, std::ops::Range<GuestAddr>)>,
|
||||||
tcb_addr: GuestAddr,
|
tcb_addr: GuestAddr,
|
||||||
ready_queues: GuestAddr,
|
ready_queues: GuestAddr,
|
||||||
delay_queue: GuestAddr,
|
delay_queue: GuestAddr,
|
||||||
@ -94,7 +109,10 @@ impl QemuSystemStateHelper {
|
|||||||
app_range: Range<GuestAddr>,
|
app_range: Range<GuestAddr>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
QemuSystemStateHelper {
|
QemuSystemStateHelper {
|
||||||
watchaddr: watchaddr,
|
api_fn_addrs,
|
||||||
|
api_fn_ranges,
|
||||||
|
isr_addrs,
|
||||||
|
isr_ranges,
|
||||||
tcb_addr: tcb_addr,
|
tcb_addr: tcb_addr,
|
||||||
ready_queues: ready_queues,
|
ready_queues: ready_queues,
|
||||||
delay_queue,
|
delay_queue,
|
||||||
@ -113,10 +131,13 @@ where
|
|||||||
where
|
where
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
{
|
{
|
||||||
for wp in self.watchaddr.keys() {
|
for wp in self.api_fn_addrs.keys() {
|
||||||
_hooks.instruction(*wp, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
_hooks.instruction(*wp, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "trace_abbs")]
|
for wp in self.isr_addrs.keys() {
|
||||||
|
_hooks.instruction(*wp, Hook::Function(exec_isr_hook::<QT, S>), false);
|
||||||
|
}
|
||||||
|
//#[cfg(feature = "trace_abbs")]
|
||||||
_hooks.jmps(Hook::Function(gen_jmp_is_syscall::<QT, S>), Hook::Function(trace_api_call::<QT, S>));
|
_hooks.jmps(Hook::Function(gen_jmp_is_syscall::<QT, S>), Hook::Function(trace_api_call::<QT, S>));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +151,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn post_exec<OT>(&mut self, emulator: &Emulator, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind) {
|
fn post_exec<OT>(&mut self, emulator: &Emulator, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind) {
|
||||||
trigger_collection(emulator,0, self);
|
trigger_collection(emulator,(None, None), self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +187,7 @@ fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &Emul
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn trigger_collection(emulator: &Emulator, pc: GuestAddr, h: &QemuSystemStateHelper) {
|
fn trigger_collection(emulator: &Emulator, edge: (Option<GuestAddr>,Option<GuestAddr>), h: &QemuSystemStateHelper) {
|
||||||
let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
||||||
let mut systemstate = RawFreeRTOSSystemState::default();
|
let mut systemstate = RawFreeRTOSSystemState::default();
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -190,16 +211,6 @@ fn trigger_collection(emulator: &Emulator, pc: GuestAddr, h: &QemuSystemStateHel
|
|||||||
};
|
};
|
||||||
systemstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
|
systemstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
|
||||||
|
|
||||||
unsafe {
|
|
||||||
LAST_API_CALL.with(|x|
|
|
||||||
match *x.get() {
|
|
||||||
Some(s) => {
|
|
||||||
systemstate.last_pc = Some(s.0 as u64);
|
|
||||||
},
|
|
||||||
None => (),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
||||||
|
|
||||||
// Extract delay list
|
// Extract delay list
|
||||||
@ -218,11 +229,63 @@ fn trigger_collection(emulator: &Emulator, pc: GuestAddr, h: &QemuSystemStateHel
|
|||||||
systemstate.prio_ready_lists[i] = read_freertos_list(&mut systemstate, emulator, target);
|
systemstate.prio_ready_lists[i] = read_freertos_list(&mut systemstate, emulator, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
systemstate.capture_point = h.watchaddr.get(&pc).unwrap_or(&"unknown");
|
// Note type of capture
|
||||||
|
match edge.1 {
|
||||||
|
None => { // No destination set, must be ISR Return
|
||||||
|
// ISR End
|
||||||
|
if let Some(src) = edge.0 {
|
||||||
|
if let Some(s) = h.isr_addrs.get(&src) {
|
||||||
|
systemstate.capture_point=(CaptureEvent::ISREnd, s);
|
||||||
|
} else {
|
||||||
|
println!("ISR Ret Not found: {:#x}", src);
|
||||||
|
systemstate.capture_point=(CaptureEvent::ISREnd, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(dest) => {
|
||||||
|
if let Some(src) = edge.0 { // Bot set, can be API Call/Ret
|
||||||
|
if let Some(s) = h.api_fn_addrs.get(&src) { // API End
|
||||||
|
systemstate.capture_point=(CaptureEvent::APIEnd, s);
|
||||||
|
} else if let Some(s) = h.api_fn_addrs.get(&dest) { // API Call
|
||||||
|
systemstate.capture_point=(CaptureEvent::APIStart, s);
|
||||||
|
} else {
|
||||||
|
println!("API Not found: {:#x}", src);
|
||||||
|
}
|
||||||
|
} else { // No source, must be ISR
|
||||||
|
if let Some(s) = h.isr_addrs.get(&dest) { // ISR Start
|
||||||
|
systemstate.capture_point=(CaptureEvent::ISRStart, s);
|
||||||
|
} else {
|
||||||
|
println!("ISR call Not found: {:#x}", dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if systemstate.capture_point.0 == CaptureEvent::Undefined {
|
||||||
|
println!("Not found: {:#x} {:#x}", edge.0.unwrap_or(0), edge.1.unwrap_or(0));
|
||||||
|
}
|
||||||
|
systemstate.edge = edge;
|
||||||
|
|
||||||
unsafe { CURRENT_SYSTEMSTATE_VEC.push(systemstate); }
|
unsafe { CURRENT_SYSTEMSTATE_VEC.push(systemstate); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================= Trace interrupt service routines
|
||||||
|
|
||||||
|
pub fn exec_isr_hook<QT, S>(
|
||||||
|
hooks: &mut QemuHooks<QT, S>,
|
||||||
|
_state: Option<&mut S>,
|
||||||
|
pc: GuestAddr,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
S: UsesInput,
|
||||||
|
QT: QemuHelperTuple<S>,
|
||||||
|
{
|
||||||
|
let emulator = hooks.emulator();
|
||||||
|
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
|
trigger_collection(emulator, (None,Some(pc)), h);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================= Trace syscall execution
|
||||||
|
|
||||||
pub fn exec_syscall_hook<QT, S>(
|
pub fn exec_syscall_hook<QT, S>(
|
||||||
hooks: &mut QemuHooks<QT, S>,
|
hooks: &mut QemuHooks<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
@ -234,9 +297,25 @@ where
|
|||||||
{
|
{
|
||||||
let emulator = hooks.emulator();
|
let emulator = hooks.emulator();
|
||||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
trigger_collection(emulator, pc, h);
|
|
||||||
|
let mut edge = (None, Some(pc));
|
||||||
|
unsafe {
|
||||||
|
LAST_API_CALL.with(|x| {
|
||||||
|
match *x.get() {
|
||||||
|
Some(s) => {
|
||||||
|
edge.0=Some(s.0);
|
||||||
|
trigger_collection(emulator, edge, h);
|
||||||
|
},
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
*x.get()=None;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================= Trace jumps to syscalls
|
||||||
|
|
||||||
thread_local!(static LAST_API_CALL : UnsafeCell<Option<(GuestAddr,GuestAddr)>> = UnsafeCell::new(None));
|
thread_local!(static LAST_API_CALL : UnsafeCell<Option<(GuestAddr,GuestAddr)>> = UnsafeCell::new(None));
|
||||||
|
|
||||||
pub fn gen_jmp_is_syscall<QT, S>(
|
pub fn gen_jmp_is_syscall<QT, S>(
|
||||||
@ -251,15 +330,27 @@ where
|
|||||||
{
|
{
|
||||||
if let Some(h) = hooks.helpers().match_first_type::<QemuSystemStateHelper>() {
|
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) {
|
||||||
|
if let Some(_) = in_any_range(&h.api_fn_ranges,dest) {
|
||||||
// println!("New jmp {:x} {:x}", src, dest);
|
// println!("New jmp {:x} {:x}", src, dest);
|
||||||
|
// println!("API Call Edge");
|
||||||
return Some(1);
|
return Some(1);
|
||||||
}
|
}
|
||||||
|
} else if !h.app_range.contains(&src) && dest == 0 {
|
||||||
|
if let Some(_) = in_any_range(&h.api_fn_ranges, src) {
|
||||||
|
// println!("API Return Edge {:#x}", src);
|
||||||
|
return Some(2);
|
||||||
|
}
|
||||||
|
if let Some(_) = in_any_range(&h.isr_ranges, src) {
|
||||||
|
// println!("ISR Return Edge {:#x}", src);
|
||||||
|
return Some(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trace_api_call<QT, S>(
|
pub fn trace_api_call<QT, S>(
|
||||||
_hooks: &mut QemuHooks<QT, S>,
|
hooks: &mut QemuHooks<QT, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
src: GuestAddr, dest: GuestAddr, id: u64
|
src: GuestAddr, dest: GuestAddr, id: u64
|
||||||
)
|
)
|
||||||
@ -267,9 +358,39 @@ where
|
|||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
{
|
{
|
||||||
|
if id == 1 { // API call
|
||||||
unsafe {
|
unsafe {
|
||||||
let p = LAST_API_CALL.with(|x| x.get());
|
let p = LAST_API_CALL.with(|x| x.get());
|
||||||
*p = Some((src,dest));
|
*p = Some((src,dest));
|
||||||
// print!("*");
|
// println!("Jump {:#x} {:#x}", src, dest);
|
||||||
|
}
|
||||||
|
} else if id == 2 { // API return
|
||||||
|
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
|
if in_any_range(&h.api_fn_ranges, dest).is_none() {
|
||||||
|
let emulator = hooks.emulator();
|
||||||
|
|
||||||
|
let mut edge = (None, None);
|
||||||
|
edge.0=Some(in_any_range(&h.api_fn_ranges, src).unwrap().start);
|
||||||
|
edge.1=Some(dest);
|
||||||
|
|
||||||
|
trigger_collection(emulator, edge, h);
|
||||||
|
// println!("Exec API Return Edge {:#x} {:#x}", src, dest);
|
||||||
|
}
|
||||||
|
} else if id == 3 { // ISR return
|
||||||
|
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||||
|
let emulator = hooks.emulator();
|
||||||
|
|
||||||
|
let mut edge = (None, None);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn in_any_range<'a>(ranges: &'a Vec<(&str, Range<u32>)>, addr : GuestAddr) -> Option<&'a std::ops::Range<GuestAddr>> {
|
||||||
|
for (_,r) in ranges {
|
||||||
|
if r.contains(&addr) {return Some(r);}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
@ -27,8 +27,21 @@ pub mod schedulers;
|
|||||||
const NUM_PRIOS: usize = 5;
|
const NUM_PRIOS: usize = 5;
|
||||||
|
|
||||||
//============================= Struct definitions
|
//============================= Struct definitions
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
|
||||||
|
pub enum CaptureEvent {
|
||||||
|
APIStart,
|
||||||
|
APIEnd,
|
||||||
|
ISRStart,
|
||||||
|
ISREnd,
|
||||||
|
End,
|
||||||
|
#[default]
|
||||||
|
Undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Raw info Dump from Qemu
|
/// Raw info Dump from Qemu
|
||||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
#[derive(Debug, Default)]
|
||||||
pub struct RawFreeRTOSSystemState {
|
pub struct RawFreeRTOSSystemState {
|
||||||
qemu_tick: u64,
|
qemu_tick: u64,
|
||||||
current_tcb: TCB_t,
|
current_tcb: TCB_t,
|
||||||
@ -37,8 +50,8 @@ pub struct RawFreeRTOSSystemState {
|
|||||||
delay_list_overflow: freertos::List_t,
|
delay_list_overflow: freertos::List_t,
|
||||||
dumping_ground: HashMap<u32,freertos::rtos_struct>,
|
dumping_ground: HashMap<u32,freertos::rtos_struct>,
|
||||||
input_counter: u32,
|
input_counter: u32,
|
||||||
last_pc: Option<u64>,
|
edge: (Option<GuestAddr>,Option<GuestAddr>),
|
||||||
capture_point: &'static str
|
capture_point: (CaptureEvent,&'static str)
|
||||||
}
|
}
|
||||||
/// List of system state dumps from QemuHelpers
|
/// List of system state dumps from QemuHelpers
|
||||||
static mut CURRENT_SYSTEMSTATE_VEC: Vec<RawFreeRTOSSystemState> = vec![];
|
static mut CURRENT_SYSTEMSTATE_VEC: Vec<RawFreeRTOSSystemState> = vec![];
|
||||||
@ -110,12 +123,13 @@ impl RefinedTCB {
|
|||||||
pub struct RefinedFreeRTOSSystemState {
|
pub struct RefinedFreeRTOSSystemState {
|
||||||
pub start_tick: u64,
|
pub start_tick: u64,
|
||||||
pub end_tick: u64,
|
pub end_tick: u64,
|
||||||
last_pc: Option<u64>,
|
edge: (Option<GuestAddr>,Option<GuestAddr>),
|
||||||
input_counter: u32,
|
input_counter: u32,
|
||||||
pub current_task: (RefinedTCB, u32),
|
pub current_task: (RefinedTCB, u32),
|
||||||
ready_list_after: Vec<(RefinedTCB, u32)>,
|
ready_list_after: Vec<(RefinedTCB, u32)>,
|
||||||
delay_list_after: Vec<(RefinedTCB, u32)>,
|
delay_list_after: Vec<(RefinedTCB, u32)>,
|
||||||
pub capture_point: String
|
// pub capture_point: String
|
||||||
|
pub capture_point: (CaptureEvent,String)
|
||||||
}
|
}
|
||||||
impl PartialEq for RefinedFreeRTOSSystemState {
|
impl PartialEq for RefinedFreeRTOSSystemState {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
@ -162,8 +162,8 @@ fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> Vec<RefinedF
|
|||||||
ready_list_after: collector,
|
ready_list_after: collector,
|
||||||
delay_list_after: delay_list,
|
delay_list_after: delay_list,
|
||||||
input_counter: i.input_counter,//+IRQ_INPUT_BYTES_NUMBER,
|
input_counter: i.input_counter,//+IRQ_INPUT_BYTES_NUMBER,
|
||||||
last_pc: i.last_pc,
|
edge: i.edge,
|
||||||
capture_point: i.capture_point.to_string()
|
capture_point: (i.capture_point.0,i.capture_point.1.to_string()),
|
||||||
});
|
});
|
||||||
start_tick=i.qemu_tick;
|
start_tick=i.qemu_tick;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user