1 //! `Register` structs for x86 architectures. 2 3 use core::convert::TryInto; 4 5 use crate::arch::Registers; 6 7 /// `RegId` definitions for x86 architectures. 8 pub mod id; 9 10 mod core32; 11 mod core64; 12 13 pub use core32::X86CoreRegs; 14 pub use core64::X86_64CoreRegs; 15 16 /// 80-bit floating point value 17 pub type F80 = [u8; 10]; 18 19 /// FPU registers 20 #[derive(Debug, Default, Clone, PartialEq)] 21 pub struct X87FpuInternalRegs { 22 /// Floating-point control register 23 pub fctrl: u32, 24 /// Floating-point status register 25 pub fstat: u32, 26 /// Tag word 27 pub ftag: u32, 28 /// FPU instruction pointer segment 29 pub fiseg: u32, 30 /// FPU intstruction pointer offset 31 pub fioff: u32, 32 /// FPU operand segment 33 pub foseg: u32, 34 /// FPU operand offset 35 pub fooff: u32, 36 /// Floating-point opcode 37 pub fop: u32, 38 } 39 40 impl Registers for X87FpuInternalRegs { gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>))41 fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) { 42 macro_rules! write_bytes { 43 ($bytes:expr) => { 44 for b in $bytes { 45 write_byte(Some(*b)) 46 } 47 }; 48 } 49 50 // Note: GDB section names don't make sense unless you read x87 FPU section 8.1: 51 // https://web.archive.org/web/20150123212110/http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf 52 write_bytes!(&self.fctrl.to_le_bytes()); 53 write_bytes!(&self.fstat.to_le_bytes()); 54 write_bytes!(&self.ftag.to_le_bytes()); 55 write_bytes!(&self.fiseg.to_le_bytes()); 56 write_bytes!(&self.fioff.to_le_bytes()); 57 write_bytes!(&self.foseg.to_le_bytes()); 58 write_bytes!(&self.fooff.to_le_bytes()); 59 write_bytes!(&self.fop.to_le_bytes()); 60 } 61 gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()>62 fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> { 63 if bytes.len() != 0x20 { 64 return Err(()); 65 } 66 67 let mut regs = bytes 68 .chunks_exact(4) 69 .map(|x| u32::from_le_bytes(x.try_into().unwrap())); 70 71 self.fctrl = regs.next().ok_or(())?; 72 self.fstat = regs.next().ok_or(())?; 73 self.ftag = regs.next().ok_or(())?; 74 self.fiseg = regs.next().ok_or(())?; 75 self.fioff = regs.next().ok_or(())?; 76 self.foseg = regs.next().ok_or(())?; 77 self.fooff = regs.next().ok_or(())?; 78 self.fop = regs.next().ok_or(())?; 79 80 Ok(()) 81 } 82 } 83