1use arrayvec::ArrayVec;
4use serde::{Deserialize, Serialize};
5
6pub const MEMORY_REGION_IDENTIFIER: u8 = 0x01;
8
9#[cfg(feature = "std")]
11pub trait MemoryRegion {
12 fn range(&self) -> std::ops::Range<u64>;
14
15 fn read(
18 &self,
19 address_range: core::ops::Range<u64>,
20 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError>;
21
22 fn read_u8(&self, address: u64) -> Result<Option<u8>, crate::device_memory::MemoryReadError> {
24 Ok(self.read(address..address + 1)?.map(|b| b[0]))
25 }
26
27 fn read_u32(
29 &self,
30 address: u64,
31 endianness: gimli::RunTimeEndian,
32 ) -> Result<Option<u32>, crate::device_memory::MemoryReadError> {
33 if let Some(slice) = self
34 .read(address..address + 4)?
35 .map(|slice| slice[..].try_into().unwrap())
36 {
37 if gimli::Endianity::is_little_endian(endianness) {
38 Ok(Some(u32::from_le_bytes(slice)))
39 } else {
40 Ok(Some(u32::from_be_bytes(slice)))
41 }
42 } else {
43 Ok(None)
44 }
45 }
46}
47
48#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
50pub struct ArrayMemoryRegion<const SIZE: usize> {
51 start_address: u64,
52 data: ArrayVec<u8, SIZE>,
53}
54
55impl<const SIZE: usize> ArrayMemoryRegion<SIZE> {
56 pub fn new(start_address: u64, data: ArrayVec<u8, SIZE>) -> Self {
58 Self {
59 start_address,
60 data,
61 }
62 }
63
64 pub fn bytes(&self) -> MemoryRegionIterator<'_> {
89 MemoryRegionIterator::new(self.start_address, &self.data)
90 }
91
92 pub unsafe fn copy_from_memory(&mut self, data_ptr: *const u8, data_len: usize) {
101 self.start_address = data_ptr as u64;
102 self.data.clear();
103
104 assert!(data_len <= self.data.capacity());
105
106 self.data.set_len(data_len);
107 self.data.as_mut_ptr().copy_from(data_ptr, data_len);
108 }
109}
110
111#[cfg(feature = "std")]
112impl<const SIZE: usize> MemoryRegion for ArrayMemoryRegion<SIZE> {
113 fn range(&self) -> std::ops::Range<u64> {
114 self.start_address..self.start_address + self.data.len() as u64
115 }
116
117 fn read(
118 &self,
119 index: core::ops::Range<u64>,
120 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError> {
121 let start = match index.start.checked_sub(self.start_address) {
122 Some(start) => start,
123 None => return Ok(None),
124 };
125 let end = match index.end.checked_sub(self.start_address) {
126 Some(end) => end,
127 None => return Ok(None),
128 };
129 Ok(self
130 .data
131 .get(start as usize..end as usize)
132 .map(|slice| slice.to_vec()))
133 }
134}
135
136impl<'a, const SIZE: usize> FromIterator<&'a u8> for ArrayMemoryRegion<SIZE> {
137 fn from_iter<T: IntoIterator<Item = &'a u8>>(iter: T) -> Self {
138 Self::from_iter(iter.into_iter().copied())
139 }
140}
141
142impl<const SIZE: usize> FromIterator<u8> for ArrayMemoryRegion<SIZE> {
143 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
144 let mut iter = iter.into_iter();
145
146 assert_eq!(
147 iter.next().unwrap(),
148 MEMORY_REGION_IDENTIFIER,
149 "The given iterator is not for a memory region"
150 );
151
152 let start_address = u64::from_le_bytes([
153 iter.next().unwrap(),
154 iter.next().unwrap(),
155 iter.next().unwrap(),
156 iter.next().unwrap(),
157 iter.next().unwrap(),
158 iter.next().unwrap(),
159 iter.next().unwrap(),
160 iter.next().unwrap(),
161 ]);
162
163 let length = u64::from_le_bytes([
164 iter.next().unwrap(),
165 iter.next().unwrap(),
166 iter.next().unwrap(),
167 iter.next().unwrap(),
168 iter.next().unwrap(),
169 iter.next().unwrap(),
170 iter.next().unwrap(),
171 iter.next().unwrap(),
172 ]);
173
174 let data = ArrayVec::from_iter(iter.take(length as usize));
175
176 Self {
177 start_address,
178 data,
179 }
180 }
181}
182
183#[cfg(feature = "std")]
185#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
186pub struct VecMemoryRegion {
187 start_address: u64,
188 data: Vec<u8>,
189}
190
191#[cfg(feature = "std")]
192impl VecMemoryRegion {
193 pub fn new(start_address: u64, data: Vec<u8>) -> Self {
195 Self {
196 start_address,
197 data,
198 }
199 }
200
201 pub fn bytes(&self) -> MemoryRegionIterator<'_> {
226 MemoryRegionIterator::new(self.start_address, &self.data)
227 }
228
229 pub unsafe fn copy_from_memory(&mut self, data_ptr: *const u8, data_len: usize) {
238 self.start_address = data_ptr as u64;
239 self.data.clear();
240 self.data.resize(data_len, 0);
241
242 self.data.as_mut_ptr().copy_from(data_ptr, data_len);
243 }
244}
245
246#[cfg(feature = "std")]
247impl MemoryRegion for VecMemoryRegion {
248 fn range(&self) -> std::ops::Range<u64> {
249 self.start_address..self.start_address + self.data.len() as u64
250 }
251
252 fn read(
253 &self,
254 index: core::ops::Range<u64>,
255 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError> {
256 let start = match index.start.checked_sub(self.start_address) {
257 Some(start) => start,
258 None => return Ok(None),
259 };
260 let end = match index.end.checked_sub(self.start_address) {
261 Some(end) => end,
262 None => return Ok(None),
263 };
264 Ok(self
265 .data
266 .get(start as usize..end as usize)
267 .map(|slice| slice.to_vec()))
268 }
269}
270
271#[cfg(feature = "std")]
272impl<'a> FromIterator<&'a u8> for VecMemoryRegion {
273 fn from_iter<T: IntoIterator<Item = &'a u8>>(iter: T) -> Self {
274 Self::from_iter(iter.into_iter().copied())
275 }
276}
277
278#[cfg(feature = "std")]
279impl FromIterator<u8> for VecMemoryRegion {
280 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
281 let mut iter = iter.into_iter();
282
283 assert_eq!(
284 iter.next().unwrap(),
285 MEMORY_REGION_IDENTIFIER,
286 "The given iterator is not for a memory region"
287 );
288
289 let start_address = u64::from_le_bytes([
290 iter.next().unwrap(),
291 iter.next().unwrap(),
292 iter.next().unwrap(),
293 iter.next().unwrap(),
294 iter.next().unwrap(),
295 iter.next().unwrap(),
296 iter.next().unwrap(),
297 iter.next().unwrap(),
298 ]);
299
300 let length = u64::from_le_bytes([
301 iter.next().unwrap(),
302 iter.next().unwrap(),
303 iter.next().unwrap(),
304 iter.next().unwrap(),
305 iter.next().unwrap(),
306 iter.next().unwrap(),
307 iter.next().unwrap(),
308 iter.next().unwrap(),
309 ]);
310
311 let data = Vec::from_iter(iter.take(length as usize));
312
313 Self {
314 start_address,
315 data,
316 }
317 }
318}
319
320#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
322pub struct SliceMemoryRegion<'a> {
323 data: &'a [u8],
324}
325
326impl<'a> SliceMemoryRegion<'a> {
327 pub fn new(data: &'a [u8]) -> Self {
329 Self { data }
330 }
331
332 pub fn bytes(&self) -> MemoryRegionIterator<'_> {
357 let start_address = self.data.as_ptr() as u64;
358 MemoryRegionIterator::new(start_address, self.data)
359 }
360
361 pub unsafe fn copy_from_memory(&mut self, data_ptr: *const u8, data_len: usize) {
372 self.data = core::slice::from_raw_parts(data_ptr, data_len);
373 }
374}
375
376#[cfg(feature = "std")]
377impl<'a> MemoryRegion for SliceMemoryRegion<'a> {
378 fn range(&self) -> std::ops::Range<u64> {
379 let range = self.data.as_ptr_range();
380 range.start as u64..range.end as u64
381 }
382
383 fn read(
384 &self,
385 index: core::ops::Range<u64>,
386 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError> {
387 let start_address = self.data.as_ptr() as u64;
388 let start = match index.start.checked_sub(start_address) {
389 Some(start) => start,
390 None => return Ok(None),
391 };
392 let end = match index.end.checked_sub(start_address) {
393 Some(end) => end,
394 None => return Ok(None),
395 };
396 Ok(self
397 .data
398 .get(start as usize..end as usize)
399 .map(|slice| slice.to_vec()))
400 }
401}
402
403pub struct MemoryRegionIterator<'a> {
405 start_address: u64,
406 data: &'a [u8],
407 index: usize,
408}
409
410impl<'a> MemoryRegionIterator<'a> {
411 fn new(start_address: u64, data: &'a [u8]) -> Self {
412 Self {
413 start_address,
414 data,
415 index: 0,
416 }
417 }
418}
419
420impl<'a> Iterator for MemoryRegionIterator<'a> {
421 type Item = u8;
422
423 fn next(&mut self) -> Option<Self::Item> {
424 match self.index {
425 0 => {
426 self.index += 1;
427 Some(MEMORY_REGION_IDENTIFIER)
428 }
429 index @ 1..=8 => {
430 self.index += 1;
431 Some(self.start_address.to_le_bytes()[index - 1])
432 }
433 index @ 9..=16 => {
434 self.index += 1;
435 Some((self.data.len() as u64).to_le_bytes()[index - 9])
436 }
437 index => {
438 self.index += 1;
439 self.data.get(index - 17).copied()
440 }
441 }
442 }
443
444 fn size_hint(&self) -> (usize, Option<usize>) {
445 let remaining_length = 17 + self.data.len() - self.index;
446 (remaining_length, Some(remaining_length))
447 }
448}
449
450impl<'a> ExactSizeIterator for MemoryRegionIterator<'a> {}
451
452#[cfg(test)]
453mod tests {
454 use super::*;
455
456 #[test]
457 fn iterator() {
458 let region = VecMemoryRegion::new(0x2000_0000, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
459 let copied_region = VecMemoryRegion::from_iter(region.bytes());
460
461 assert_eq!(region, copied_region);
462 }
463
464 #[test]
465 fn iterator_len() {
466 let region = VecMemoryRegion::new(0x2000_0000, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
467 let iter = region.bytes();
468 assert_eq!(iter.len(), iter.count());
469
470 let mut iter = region.bytes();
471 iter.nth(10).unwrap();
472 assert_eq!(iter.len(), iter.count());
473 }
474}