1 use gdbstub::arch::Registers;
2 
3 /// 32-bit ARM core registers.
4 ///
5 /// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml>
6 #[derive(Debug, Default, Clone, Eq, PartialEq)]
7 pub struct ArmCoreRegs {
8     /// General purpose registers (R0-R12)
9     pub r: [u32; 13],
10     /// Stack Pointer (R13)
11     pub sp: u32,
12     /// Link Register (R14)
13     pub lr: u32,
14     /// Program Counter (R15)
15     pub pc: u32,
16     /// Current Program Status Register (cpsr)
17     pub cpsr: u32,
18 }
19 
20 impl Registers for ArmCoreRegs {
21     type ProgramCounter = u32;
22 
pc(&self) -> Self::ProgramCounter23     fn pc(&self) -> Self::ProgramCounter {
24         self.pc
25     }
26 
gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>))27     fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {
28         macro_rules! write_bytes {
29             ($bytes:expr) => {
30                 for b in $bytes {
31                     write_byte(Some(*b))
32                 }
33             };
34         }
35 
36         for reg in self.r.iter() {
37             write_bytes!(&reg.to_le_bytes());
38         }
39         write_bytes!(&self.sp.to_le_bytes());
40         write_bytes!(&self.lr.to_le_bytes());
41         write_bytes!(&self.pc.to_le_bytes());
42 
43         // Floating point registers (unused)
44         for _ in 0..25 {
45             (0..4).for_each(|_| write_byte(None))
46         }
47 
48         write_bytes!(&self.cpsr.to_le_bytes());
49     }
50 
gdb_deserialize(&mut self, mut bytes: &[u8]) -> Result<(), ()>51     fn gdb_deserialize(&mut self, mut bytes: &[u8]) -> Result<(), ()> {
52         if bytes.len() != (17 + 25) * 4 {
53             return Err(());
54         }
55 
56         let mut next_reg = || {
57             if bytes.len() < 4 {
58                 Err(())
59             } else {
60                 use core::convert::TryInto;
61 
62                 let (next, rest) = bytes.split_at(4);
63                 bytes = rest;
64                 Ok(u32::from_le_bytes(next.try_into().unwrap()))
65             }
66         };
67 
68         for reg in self.r.iter_mut() {
69             *reg = next_reg()?
70         }
71         self.sp = next_reg()?;
72         self.lr = next_reg()?;
73         self.pc = next_reg()?;
74 
75         // Floating point registers (unused)
76         for _ in 0..25 {
77             next_reg()?;
78         }
79 
80         self.cpsr = next_reg()?;
81 
82         if next_reg().is_ok() {
83             return Err(());
84         }
85 
86         Ok(())
87     }
88 }
89