debug_worker/gdb/arch/x86/reg/
core32.rs1use super::F80;
5use super::X86SegmentRegs;
6use super::X87FpuInternalRegs;
7use core::convert::TryInto;
8use gdbstub::arch::Registers;
9
10#[derive(Debug, Default, Clone, PartialEq, Eq)]
15pub struct X86CoreRegs {
16 pub eax: u32,
18 pub ecx: u32,
20 pub edx: u32,
22 pub ebx: u32,
24 pub esp: u32,
26 pub ebp: u32,
28 pub esi: u32,
30 pub edi: u32,
32 pub eip: u32,
34 pub eflags: u32,
36 pub segments: X86SegmentRegs,
38 pub st: [F80; 8],
40 pub fpu: X87FpuInternalRegs,
42 pub xmm: [u128; 8],
44 pub mxcsr: u32,
46}
47
48impl Registers for X86CoreRegs {
49 type ProgramCounter = u32;
50
51 fn pc(&self) -> Self::ProgramCounter {
52 self.eip
53 }
54
55 fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {
56 macro_rules! write_bytes {
57 ($bytes:expr) => {
58 for b in $bytes {
59 write_byte(Some(*b))
60 }
61 };
62 }
63
64 macro_rules! write_regs {
65 ($($reg:ident),*) => {
66 $(
67 write_bytes!(&self.$reg.to_le_bytes());
68 )*
69 }
70 }
71
72 write_regs!(eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags);
73
74 self.segments.gdb_serialize(&mut write_byte);
75
76 for st_reg in &self.st {
78 write_bytes!(st_reg);
79 }
80
81 self.fpu.gdb_serialize(&mut write_byte);
82
83 for xmm_reg in &self.xmm {
85 write_bytes!(&xmm_reg.to_le_bytes());
86 }
87
88 write_bytes!(&self.mxcsr.to_le_bytes());
90 }
91
92 fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {
93 if bytes.len() < 0x138 {
94 return Err(());
95 }
96
97 macro_rules! parse_regs {
98 ($($reg:ident),*) => {
99 let mut regs = bytes[0..0x28]
100 .chunks_exact(4)
101 .map(|x| u32::from_le_bytes(x.try_into().unwrap()));
102 $(
103 self.$reg = regs.next().ok_or(())?;
104 )*
105 }
106 }
107
108 parse_regs!(eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags);
109
110 self.segments.gdb_deserialize(&bytes[0x28..0x40])?;
111
112 let mut regs = bytes[0x40..0x90].chunks_exact(10).map(TryInto::try_into);
113
114 for reg in self.st.iter_mut() {
115 *reg = regs.next().ok_or(())?.map_err(|_| ())?;
116 }
117
118 self.fpu.gdb_deserialize(&bytes[0x90..0xb0])?;
119
120 let mut regs = bytes[0xb0..0x130]
121 .chunks_exact(0x10)
122 .map(|x| u128::from_le_bytes(x.try_into().unwrap()));
123
124 for reg in self.xmm.iter_mut() {
125 *reg = regs.next().ok_or(())?;
126 }
127
128 self.mxcsr = u32::from_le_bytes(bytes[0x130..0x134].try_into().unwrap());
129
130 Ok(())
131 }
132}