debug_worker/gdb/arch/x86/reg/
core32.rsuse super::F80;
use super::X86SegmentRegs;
use super::X87FpuInternalRegs;
use core::convert::TryInto;
use gdbstub::arch::Registers;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct X86CoreRegs {
pub eax: u32,
pub ecx: u32,
pub edx: u32,
pub ebx: u32,
pub esp: u32,
pub ebp: u32,
pub esi: u32,
pub edi: u32,
pub eip: u32,
pub eflags: u32,
pub segments: X86SegmentRegs,
pub st: [F80; 8],
pub fpu: X87FpuInternalRegs,
pub xmm: [u128; 8],
pub mxcsr: u32,
}
impl Registers for X86CoreRegs {
type ProgramCounter = u32;
fn pc(&self) -> Self::ProgramCounter {
self.eip
}
fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) {
macro_rules! write_bytes {
($bytes:expr) => {
for b in $bytes {
write_byte(Some(*b))
}
};
}
macro_rules! write_regs {
($($reg:ident),*) => {
$(
write_bytes!(&self.$reg.to_le_bytes());
)*
}
}
write_regs!(eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags);
self.segments.gdb_serialize(&mut write_byte);
for st_reg in &self.st {
write_bytes!(st_reg);
}
self.fpu.gdb_serialize(&mut write_byte);
for xmm_reg in &self.xmm {
write_bytes!(&xmm_reg.to_le_bytes());
}
write_bytes!(&self.mxcsr.to_le_bytes());
}
fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> {
if bytes.len() < 0x138 {
return Err(());
}
macro_rules! parse_regs {
($($reg:ident),*) => {
let mut regs = bytes[0..0x28]
.chunks_exact(4)
.map(|x| u32::from_le_bytes(x.try_into().unwrap()));
$(
self.$reg = regs.next().ok_or(())?;
)*
}
}
parse_regs!(eax, ecx, edx, ebx, esp, ebp, esi, edi, eip, eflags);
self.segments.gdb_deserialize(&bytes[0x28..0x40])?;
let mut regs = bytes[0x40..0x90].chunks_exact(10).map(TryInto::try_into);
for reg in self.st.iter_mut() {
*reg = regs.next().ok_or(())?.map_err(|_| ())?;
}
self.fpu.gdb_deserialize(&bytes[0x90..0xb0])?;
let mut regs = bytes[0xb0..0x130]
.chunks_exact(0x10)
.map(|x| u128::from_le_bytes(x.try_into().unwrap()));
for reg in self.xmm.iter_mut() {
*reg = regs.next().ok_or(())?;
}
self.mxcsr = u32::from_le_bytes(bytes[0x130..0x134].try_into().unwrap());
Ok(())
}
}