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!(®.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