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 read(
15 &self,
16 address_range: core::ops::Range<u64>,
17 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError>;
18
19 fn read_u8(&self, address: u64) -> Result<Option<u8>, crate::device_memory::MemoryReadError> {
21 Ok(self.read(address..address + 1)?.map(|b| b[0]))
22 }
23
24 fn read_u32(
26 &self,
27 address: u64,
28 endianness: gimli::RunTimeEndian,
29 ) -> Result<Option<u32>, crate::device_memory::MemoryReadError> {
30 if let Some(slice) = self
31 .read(address..address + 4)?
32 .map(|slice| slice[..].try_into().unwrap())
33 {
34 if gimli::Endianity::is_little_endian(endianness) {
35 Ok(Some(u32::from_le_bytes(slice)))
36 } else {
37 Ok(Some(u32::from_be_bytes(slice)))
38 }
39 } else {
40 Ok(None)
41 }
42 }
43}
44
45#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
47pub struct ArrayMemoryRegion<const SIZE: usize> {
48 start_address: u64,
49 data: ArrayVec<u8, SIZE>,
50}
51
52impl<const SIZE: usize> ArrayMemoryRegion<SIZE> {
53 pub fn new(start_address: u64, data: ArrayVec<u8, SIZE>) -> Self {
55 Self {
56 start_address,
57 data,
58 }
59 }
60
61 pub fn bytes(&self) -> MemoryRegionIterator {
86 MemoryRegionIterator::new(self.start_address, &self.data)
87 }
88
89 pub unsafe fn copy_from_memory(&mut self, data_ptr: *const u8, data_len: usize) {
98 self.start_address = data_ptr as u64;
99 self.data.clear();
100
101 assert!(data_len <= self.data.capacity());
102
103 self.data.set_len(data_len);
104 self.data.as_mut_ptr().copy_from(data_ptr, data_len);
105 }
106}
107
108#[cfg(feature = "std")]
109impl<const SIZE: usize> MemoryRegion for ArrayMemoryRegion<SIZE> {
110 fn read(
111 &self,
112 index: core::ops::Range<u64>,
113 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError> {
114 let start = match index.start.checked_sub(self.start_address) {
115 Some(start) => start,
116 None => return Ok(None),
117 };
118 let end = match index.end.checked_sub(self.start_address) {
119 Some(end) => end,
120 None => return Ok(None),
121 };
122 Ok(self
123 .data
124 .get(start as usize..end as usize)
125 .map(|slice| slice.to_vec()))
126 }
127}
128
129impl<'a, const SIZE: usize> FromIterator<&'a u8> for ArrayMemoryRegion<SIZE> {
130 fn from_iter<T: IntoIterator<Item = &'a u8>>(iter: T) -> Self {
131 Self::from_iter(iter.into_iter().copied())
132 }
133}
134
135impl<const SIZE: usize> FromIterator<u8> for ArrayMemoryRegion<SIZE> {
136 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
137 let mut iter = iter.into_iter();
138
139 assert_eq!(
140 iter.next().unwrap(),
141 MEMORY_REGION_IDENTIFIER,
142 "The given iterator is not for a memory region"
143 );
144
145 let start_address = u64::from_le_bytes([
146 iter.next().unwrap(),
147 iter.next().unwrap(),
148 iter.next().unwrap(),
149 iter.next().unwrap(),
150 iter.next().unwrap(),
151 iter.next().unwrap(),
152 iter.next().unwrap(),
153 iter.next().unwrap(),
154 ]);
155
156 let length = u64::from_le_bytes([
157 iter.next().unwrap(),
158 iter.next().unwrap(),
159 iter.next().unwrap(),
160 iter.next().unwrap(),
161 iter.next().unwrap(),
162 iter.next().unwrap(),
163 iter.next().unwrap(),
164 iter.next().unwrap(),
165 ]);
166
167 let data = ArrayVec::from_iter(iter.take(length as usize));
168
169 Self {
170 start_address,
171 data,
172 }
173 }
174}
175
176#[cfg(feature = "std")]
178#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
179pub struct VecMemoryRegion {
180 start_address: u64,
181 data: Vec<u8>,
182}
183
184#[cfg(feature = "std")]
185impl VecMemoryRegion {
186 pub fn new(start_address: u64, data: Vec<u8>) -> Self {
188 Self {
189 start_address,
190 data,
191 }
192 }
193
194 pub fn bytes(&self) -> MemoryRegionIterator {
219 MemoryRegionIterator::new(self.start_address, &self.data)
220 }
221
222 pub unsafe fn copy_from_memory(&mut self, data_ptr: *const u8, data_len: usize) {
231 self.start_address = data_ptr as u64;
232 self.data.clear();
233 self.data.resize(data_len, 0);
234
235 self.data.as_mut_ptr().copy_from(data_ptr, data_len);
236 }
237}
238
239#[cfg(feature = "std")]
240impl MemoryRegion for VecMemoryRegion {
241 fn read(
242 &self,
243 index: core::ops::Range<u64>,
244 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError> {
245 let start = match index.start.checked_sub(self.start_address) {
246 Some(start) => start,
247 None => return Ok(None),
248 };
249 let end = match index.end.checked_sub(self.start_address) {
250 Some(end) => end,
251 None => return Ok(None),
252 };
253 Ok(self
254 .data
255 .get(start as usize..end as usize)
256 .map(|slice| slice.to_vec()))
257 }
258}
259
260#[cfg(feature = "std")]
261impl<'a> FromIterator<&'a u8> for VecMemoryRegion {
262 fn from_iter<T: IntoIterator<Item = &'a u8>>(iter: T) -> Self {
263 Self::from_iter(iter.into_iter().copied())
264 }
265}
266
267#[cfg(feature = "std")]
268impl FromIterator<u8> for VecMemoryRegion {
269 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
270 let mut iter = iter.into_iter();
271
272 assert_eq!(
273 iter.next().unwrap(),
274 MEMORY_REGION_IDENTIFIER,
275 "The given iterator is not for a memory region"
276 );
277
278 let start_address = u64::from_le_bytes([
279 iter.next().unwrap(),
280 iter.next().unwrap(),
281 iter.next().unwrap(),
282 iter.next().unwrap(),
283 iter.next().unwrap(),
284 iter.next().unwrap(),
285 iter.next().unwrap(),
286 iter.next().unwrap(),
287 ]);
288
289 let length = 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 data = Vec::from_iter(iter.take(length as usize));
301
302 Self {
303 start_address,
304 data,
305 }
306 }
307}
308
309#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
311pub struct SliceMemoryRegion<'a> {
312 data: &'a [u8],
313}
314
315impl<'a> SliceMemoryRegion<'a> {
316 pub fn new(data: &'a [u8]) -> Self {
318 Self { data }
319 }
320
321 pub fn bytes(&self) -> MemoryRegionIterator {
346 let start_address = self.data.as_ptr() as u64;
347 MemoryRegionIterator::new(start_address, self.data)
348 }
349
350 pub unsafe fn copy_from_memory(&mut self, data_ptr: *const u8, data_len: usize) {
361 self.data = core::slice::from_raw_parts(data_ptr, data_len);
362 }
363}
364
365#[cfg(feature = "std")]
366impl<'a> MemoryRegion for SliceMemoryRegion<'a> {
367 fn read(
368 &self,
369 index: core::ops::Range<u64>,
370 ) -> Result<Option<Vec<u8>>, crate::device_memory::MemoryReadError> {
371 let start_address = self.data.as_ptr() as u64;
372 let start = match index.start.checked_sub(start_address) {
373 Some(start) => start,
374 None => return Ok(None),
375 };
376 let end = match index.end.checked_sub(start_address) {
377 Some(end) => end,
378 None => return Ok(None),
379 };
380 Ok(self
381 .data
382 .get(start as usize..end as usize)
383 .map(|slice| slice.to_vec()))
384 }
385}
386
387pub struct MemoryRegionIterator<'a> {
389 start_address: u64,
390 data: &'a [u8],
391 index: usize,
392}
393
394impl<'a> MemoryRegionIterator<'a> {
395 fn new(start_address: u64, data: &'a [u8]) -> Self {
396 Self {
397 start_address,
398 data,
399 index: 0,
400 }
401 }
402}
403
404impl<'a> Iterator for MemoryRegionIterator<'a> {
405 type Item = u8;
406
407 fn next(&mut self) -> Option<Self::Item> {
408 match self.index {
409 0 => {
410 self.index += 1;
411 Some(MEMORY_REGION_IDENTIFIER)
412 }
413 index @ 1..=8 => {
414 self.index += 1;
415 Some(self.start_address.to_le_bytes()[index - 1])
416 }
417 index @ 9..=16 => {
418 self.index += 1;
419 Some((self.data.len() as u64).to_le_bytes()[index - 9])
420 }
421 index => {
422 self.index += 1;
423 self.data.get(index - 17).copied()
424 }
425 }
426 }
427
428 fn size_hint(&self) -> (usize, Option<usize>) {
429 let remaining_length = 17 + self.data.len() - self.index;
430 (remaining_length, Some(remaining_length))
431 }
432}
433
434impl<'a> ExactSizeIterator for MemoryRegionIterator<'a> {}
435
436#[cfg(test)]
437mod tests {
438 use super::*;
439
440 #[test]
441 fn iterator() {
442 let region = VecMemoryRegion::new(0x2000_0000, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
443 let copied_region = VecMemoryRegion::from_iter(region.bytes());
444
445 assert_eq!(region, copied_region);
446 }
447
448 #[test]
449 fn iterator_len() {
450 let region = VecMemoryRegion::new(0x2000_0000, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
451 let iter = region.bytes();
452 assert_eq!(iter.len(), iter.count());
453
454 let mut iter = region.bytes();
455 iter.nth(10).unwrap();
456 assert_eq!(iter.len(), iter.count());
457 }
458}