1use arrayvec::ArrayVec;
4use core::fmt::Debug;
5use serde::{Deserialize, Serialize};
6
7pub const REGISTER_DATA_IDENTIFIER: u8 = 0x02;
9
10pub trait RegisterData<RB: funty::Integral>: Debug {
14 fn register(&self, register: gimli::Register) -> Option<RB>;
17 fn register_ref(&self, register: gimli::Register) -> Option<&RB>;
20 fn register_mut(&mut self, register: gimli::Register) -> Option<&mut RB>;
23}
24
25#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
29pub struct ArrayRegisterData<const SIZE: usize, RB> {
30 starting_register_number: u16,
32 registers: ArrayVec<RB, SIZE>,
36}
37
38impl<const SIZE: usize, RB: funty::Integral> ArrayRegisterData<SIZE, RB> {
39 pub fn new(starting_register: gimli::Register, registers: ArrayVec<RB, SIZE>) -> Self {
44 Self {
45 starting_register_number: starting_register.0,
46 registers,
47 }
48 }
49
50 pub fn bytes(&self) -> RegisterDataBytesIterator<'_, RB> {
75 RegisterDataBytesIterator {
76 index: 0,
77 starting_register_number: self.starting_register_number,
78 registers: &self.registers,
79 }
80 }
81}
82
83impl<const SIZE: usize, RB: funty::Integral> RegisterData<RB> for ArrayRegisterData<SIZE, RB> {
84 fn register(&self, register: gimli::Register) -> Option<RB> {
85 let local_register_index = register.0.checked_sub(self.starting_register_number)?;
86 self.registers.get(local_register_index as usize).copied()
87 }
88 fn register_ref(&self, register: gimli::Register) -> Option<&RB> {
89 let local_register_index = register.0.checked_sub(self.starting_register_number)?;
90 self.registers.get(local_register_index as usize)
91 }
92 fn register_mut(&mut self, register: gimli::Register) -> Option<&mut RB> {
93 let local_register_index = register.0.checked_sub(self.starting_register_number)?;
94 self.registers.get_mut(local_register_index as usize)
95 }
96}
97
98impl<const SIZE: usize, RB> FromIterator<u8> for ArrayRegisterData<SIZE, RB>
99where
100 RB: funty::Integral,
101 RB::Bytes: for<'a> TryFrom<&'a [u8]>,
102{
103 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
104 let mut iter = iter.into_iter();
106
107 assert_eq!(
108 iter.next().unwrap(),
109 REGISTER_DATA_IDENTIFIER,
110 "The given iterator is not for register data"
111 );
112
113 let starting_register_number =
115 u16::from_le_bytes([iter.next().unwrap(), iter.next().unwrap()]);
116
117 let register_count = u16::from_le_bytes([iter.next().unwrap(), iter.next().unwrap()]);
119
120 let mut registers = ArrayVec::new();
122
123 let register_size = core::mem::size_of::<RB>();
126 let mut register_bytes_buffer = ArrayVec::<u8, 16>::new();
127
128 for byte in (0..register_count as usize * register_size).map(|_| iter.next().unwrap()) {
129 register_bytes_buffer.push(byte);
130
131 if register_bytes_buffer.len() == register_size {
132 registers.push(RB::from_le_bytes(
133 register_bytes_buffer
134 .as_slice()
135 .try_into()
136 .unwrap_or_else(|_| panic!()),
137 ));
138 register_bytes_buffer = ArrayVec::new();
139 }
140 }
141
142 assert!(register_bytes_buffer.is_empty());
143
144 Self {
145 starting_register_number,
146 registers,
147 }
148 }
149}
150
151#[cfg(feature = "std")]
153#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
154pub struct VecRegisterData<RB> {
155 starting_register_number: u16,
157 registers: Vec<RB>,
161}
162
163#[cfg(feature = "std")]
164impl<RB: funty::Integral> VecRegisterData<RB> {
165 pub fn new(starting_register: gimli::Register, registers: Vec<RB>) -> Self {
170 Self {
171 starting_register_number: starting_register.0,
172 registers,
173 }
174 }
175
176 pub fn bytes(&self) -> RegisterDataBytesIterator<'_, RB> {
201 RegisterDataBytesIterator {
202 index: 0,
203 starting_register_number: self.starting_register_number,
204 registers: &self.registers,
205 }
206 }
207}
208
209#[cfg(feature = "std")]
210impl<RB: funty::Integral> RegisterData<RB> for VecRegisterData<RB> {
211 fn register(&self, register: gimli::Register) -> Option<RB> {
212 let local_register_index = register.0.checked_sub(self.starting_register_number)?;
213 self.registers.get(local_register_index as usize).copied()
214 }
215 fn register_ref(&self, register: gimli::Register) -> Option<&RB> {
216 let local_register_index = register.0.checked_sub(self.starting_register_number)?;
217 self.registers.get(local_register_index as usize)
218 }
219 fn register_mut(&mut self, register: gimli::Register) -> Option<&mut RB> {
220 let local_register_index = register.0.checked_sub(self.starting_register_number)?;
221 self.registers.get_mut(local_register_index as usize)
222 }
223}
224
225#[cfg(feature = "std")]
226impl<RB> FromIterator<u8> for VecRegisterData<RB>
227where
228 RB: funty::Integral,
229 RB::Bytes: for<'a> TryFrom<&'a [u8]>,
230{
231 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
232 let mut iter = iter.into_iter();
233
234 assert_eq!(
235 iter.next().unwrap(),
236 REGISTER_DATA_IDENTIFIER,
237 "The given iterator is not for register data"
238 );
239
240 let starting_register_number =
241 u16::from_le_bytes([iter.next().unwrap(), iter.next().unwrap()]);
242
243 let register_count = u16::from_le_bytes([iter.next().unwrap(), iter.next().unwrap()]);
244
245 let mut registers = Vec::new();
246 let register_size = core::mem::size_of::<RB>();
247
248 let mut register_bytes_buffer = ArrayVec::<u8, 16>::new();
249
250 for byte in (0..register_count as usize * register_size).map(|_| iter.next().unwrap()) {
251 register_bytes_buffer.push(byte);
252
253 if register_bytes_buffer.len() == register_size {
254 registers.push(RB::from_le_bytes(
255 register_bytes_buffer
256 .as_slice()
257 .try_into()
258 .unwrap_or_else(|_| panic!()),
259 ));
260 register_bytes_buffer.clear();
261 }
262 }
263
264 assert!(register_bytes_buffer.is_empty());
265
266 Self {
267 starting_register_number,
268 registers,
269 }
270 }
271}
272
273pub struct RegisterDataBytesIterator<'a, RB: funty::Integral> {
275 starting_register_number: u16,
276 registers: &'a [RB],
277 index: usize,
278}
279
280impl<'a, RB: funty::Integral> Iterator for RegisterDataBytesIterator<'a, RB> {
281 type Item = u8;
282
283 fn next(&mut self) -> Option<Self::Item> {
284 match self.index {
285 0 => {
286 self.index += 1;
287 Some(REGISTER_DATA_IDENTIFIER)
288 }
289 index @ 1..=2 => {
290 self.index += 1;
291 Some(self.starting_register_number.to_le_bytes()[index - 1])
292 }
293 index @ 3..=4 => {
294 self.index += 1;
295 Some((self.registers.len() as u16).to_le_bytes()[index - 3])
296 }
297 index => {
298 self.index += 1;
299
300 let index = index - 5;
301 let register_size = core::mem::size_of::<RB>();
302 let register_index = index / register_size;
303 let byte_index = index % register_size;
304
305 let le_register = self.registers.get(register_index)?.to_le();
307 let register_slice = unsafe {
309 core::slice::from_raw_parts(
310 &le_register as *const RB as *const u8,
311 register_size,
312 )
313 };
314 Some(register_slice[byte_index])
315 }
316 }
317 }
318
319 fn size_hint(&self) -> (usize, Option<usize>) {
320 let remaining_length = 5 + core::mem::size_of_val(self.registers) - self.index;
321 (remaining_length, Some(remaining_length))
322 }
323}
324
325impl<'a, RB: funty::Integral> ExactSizeIterator for RegisterDataBytesIterator<'a, RB> {}
326
327#[cfg(test)]
328mod tests {
329 use super::*;
330
331 #[test]
332 fn iterator() {
333 let data = VecRegisterData::new(gimli::Arm::S12, vec![1u32, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
334 let copied_data = VecRegisterData::from_iter(data.bytes());
335
336 assert_eq!(data, copied_data);
337 }
338
339 #[test]
340 fn iterator_length() {
341 let data = VecRegisterData::new(gimli::Arm::S12, vec![1u32, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
342 let iter = data.bytes();
343
344 assert_eq!(iter.len(), iter.count());
345
346 let mut iter = data.bytes();
347 iter.nth(10).unwrap();
348 assert_eq!(iter.len(), iter.count());
349 }
350}