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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::{
memory_region::MemoryRegion,
register_data::{RegisterBacking, RegisterData},
};
use std::{fmt::Display, ops::Range};
#[derive(Debug, Clone, Copy)]
pub struct MissingRegisterError(gimli::Register);
impl Display for MissingRegisterError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Missing register: {}",
gimli::Arm::register_name(self.0)
.map(|n| n.to_string())
.unwrap_or_else(|| format!("{}", self.0 .0))
)
}
}
impl std::error::Error for MissingRegisterError {}
pub struct DeviceMemory<RB: RegisterBacking> {
register_data: Vec<Box<dyn RegisterData<RB>>>,
memory_regions: Vec<Box<dyn MemoryRegion>>,
}
impl<RB: RegisterBacking> DeviceMemory<RB> {
pub fn new() -> Self {
Self {
register_data: Vec::new(),
memory_regions: Vec::new(),
}
}
pub fn add_memory_region<M: MemoryRegion + 'static>(&mut self, region: M) {
self.memory_regions.push(Box::new(region));
}
pub fn add_memory_region_boxed(&mut self, region: Box<dyn MemoryRegion>) {
self.memory_regions.push(region);
}
pub fn add_register_data<RD: RegisterData<RB> + 'static>(&mut self, data: RD) {
self.register_data.push(Box::new(data));
}
pub fn add_register_data_boxed(&mut self, data: Box<dyn RegisterData<RB>>) {
self.register_data.push(data);
}
pub fn read_slice(&self, address_range: Range<u64>) -> Option<&[u8]> {
self.memory_regions
.iter()
.find_map(|mr| mr.read_slice(address_range.clone()))
}
pub fn read_u8(&self, address: u64) -> Option<u8> {
self.memory_regions
.iter()
.find_map(|mr| mr.read_u8(address))
}
pub fn read_u32(&self, address: u64, endianness: gimli::RunTimeEndian) -> Option<u32> {
self.memory_regions
.iter()
.find_map(|mr| mr.read_u32(address, endianness))
}
pub fn register(&self, register: gimli::Register) -> Result<RB, MissingRegisterError> {
self.register_data
.iter()
.find_map(|registers| registers.register(register))
.ok_or(MissingRegisterError(register))
}
pub fn register_ref(&self, register: gimli::Register) -> Result<&RB, MissingRegisterError> {
self.register_data
.iter()
.find_map(|registers| registers.register_ref(register))
.ok_or(MissingRegisterError(register))
}
pub fn register_mut(
&mut self,
register: gimli::Register,
) -> Result<&mut RB, MissingRegisterError> {
self.register_data
.iter_mut()
.find_map(|registers| registers.register_mut(register))
.ok_or(MissingRegisterError(register))
}
}
impl<RB: RegisterBacking> Default for DeviceMemory<RB> {
fn default() -> Self {
Self::new()
}
}