1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use probe_rs::MemoryInterface;
use stackdump_core::{
device_memory::MemoryReadError, memory_region::MemoryRegion, register_data::VecRegisterData,
};
use std::{cell::RefCell, rc::Rc};
pub struct StackdumpCapturer<'a, 'probe>(RefCell<&'a mut probe_rs::Core<'probe>>);
impl<'a, 'probe> StackdumpCapturer<'a, 'probe> {
pub fn new(core: &'a mut probe_rs::Core<'probe>) -> Self {
Self(RefCell::new(core))
}
pub fn capture_core_registers(&mut self) -> Result<VecRegisterData<u32>, probe_rs::Error> {
let mut register_data = Vec::new();
let registers = self.0.get_mut().registers();
for register in registers.registers() {
register_data.push(self.0.get_mut().read_core_reg(register)?)
}
let starting_register = match self.0.get_mut().architecture() {
probe_rs::Architecture::Arm => stackdump_core::gimli::Arm::R0,
probe_rs::Architecture::Riscv => stackdump_core::gimli::RiscV::X0,
};
Ok(VecRegisterData::new(starting_register, register_data))
}
}
impl<'a, 'probe> MemoryRegion for StackdumpCapturer<'a, 'probe> {
fn read(
&self,
address_range: std::ops::Range<u64>,
) -> Result<Option<Vec<u8>>, MemoryReadError> {
let mut buffer = vec![0; address_range.clone().count()];
match self
.0
.borrow_mut()
.read(address_range.start as _, &mut buffer)
{
Ok(_) => Ok(Some(buffer)),
Err(e) => Err(MemoryReadError(Rc::new(e))),
}
}
}