stackdump_core/
device_memory.rs1use crate::{memory_region::MemoryRegion, register_data::RegisterData};
4use std::{error::Error, fmt::Display, ops::Range, rc::Rc};
5
6#[derive(Debug, Clone, Copy)]
8pub struct MissingRegisterError(gimli::Register);
9impl Display for MissingRegisterError {
10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11 write!(
12 f,
13 "Missing register: {}",
14 gimli::Arm::register_name(self.0)
15 .map(|n| n.to_string())
16 .unwrap_or_else(|| format!("{}", self.0 .0))
17 )
18 }
19}
20impl Error for MissingRegisterError {}
21
22#[derive(Debug, Clone)]
24pub struct MemoryReadError(pub Rc<dyn Error>);
25impl Display for MemoryReadError {
26 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
27 write!(f, "Memory read error: {}", self.0)
28 }
29}
30impl Error for MemoryReadError {}
31impl PartialEq for MemoryReadError {
32 fn eq(&self, other: &Self) -> bool {
33 self.0.to_string() == other.0.to_string()
34 }
35}
36
37pub struct DeviceMemory<'memory, RB: funty::Integral> {
39 register_data: Vec<Box<dyn RegisterData<RB> + 'memory>>,
41 memory_regions: Vec<Box<dyn MemoryRegion + 'memory>>,
42}
43
44impl<'memory, RB: funty::Integral> DeviceMemory<'memory, RB> {
45 pub fn new() -> Self {
47 Self {
48 register_data: Vec::new(),
49 memory_regions: Vec::new(),
50 }
51 }
52
53 pub fn add_memory_region<M: MemoryRegion + 'memory>(&mut self, region: M) {
55 self.memory_regions.push(Box::new(region));
56 }
57
58 pub fn add_register_data<RD: RegisterData<RB> + 'memory>(&mut self, data: RD) {
60 self.register_data.push(Box::new(data));
61 }
62
63 pub fn read_slice(
66 &self,
67 address_range: Range<u64>,
68 ) -> Result<Option<Vec<u8>>, MemoryReadError> {
69 for mr in self.memory_regions.iter() {
70 if let Some(v) = mr.read(address_range.clone())? {
71 return Ok(Some(v));
72 }
73 }
74
75 Ok(None)
76 }
77
78 pub fn read_u8(&self, address: u64) -> Result<Option<u8>, MemoryReadError> {
80 for mr in self.memory_regions.iter() {
81 if let Some(v) = mr.read_u8(address)? {
82 return Ok(Some(v));
83 }
84 }
85
86 Ok(None)
87 }
88
89 pub fn read_u32(
91 &self,
92 address: u64,
93 endianness: gimli::RunTimeEndian,
94 ) -> Result<Option<u32>, MemoryReadError> {
95 for mr in self.memory_regions.iter() {
96 if let Some(v) = mr.read_u32(address, endianness)? {
97 return Ok(Some(v));
98 }
99 }
100
101 Ok(None)
102 }
103
104 pub fn register(&self, register: gimli::Register) -> Result<RB, MissingRegisterError> {
106 self.register_data
107 .iter()
108 .find_map(|registers| registers.register(register))
109 .ok_or(MissingRegisterError(register))
110 }
111
112 pub fn register_ref(&self, register: gimli::Register) -> Result<&RB, MissingRegisterError> {
114 self.register_data
115 .iter()
116 .find_map(|registers| registers.register_ref(register))
117 .ok_or(MissingRegisterError(register))
118 }
119
120 pub fn register_mut(
122 &mut self,
123 register: gimli::Register,
124 ) -> Result<&mut RB, MissingRegisterError> {
125 self.register_data
126 .iter_mut()
127 .find_map(|registers| registers.register_mut(register))
128 .ok_or(MissingRegisterError(register))
129 }
130}
131
132impl<'memory, RB: funty::Integral> Default for DeviceMemory<'memory, RB> {
133 fn default() -> Self {
134 Self::new()
135 }
136}