|  | //! A module to define the FFI definitions we use on Windows for `dbghelp.dll` | 
|  | //! | 
|  | //! This module uses a custom macro, `ffi!`, to wrap all definitions to | 
|  | //! automatically generate tests to assert that our definitions here are the | 
|  | //! same as `winapi`. | 
|  | //! | 
|  | //! This module largely exists to integrate into libstd itself where winapi is | 
|  | //! not currently available. | 
|  |  | 
|  | #![allow(bad_style, dead_code)] | 
|  |  | 
|  | cfg_if::cfg_if! { | 
|  | if #[cfg(feature = "verify-winapi")] { | 
|  | pub use self::winapi::c_void; | 
|  | pub use self::winapi::HINSTANCE; | 
|  | pub use self::winapi::FARPROC; | 
|  | pub use self::winapi::LPSECURITY_ATTRIBUTES; | 
|  | #[cfg(target_pointer_width = "64")] | 
|  | pub use self::winapi::PUNWIND_HISTORY_TABLE; | 
|  | #[cfg(target_pointer_width = "64")] | 
|  | pub use self::winapi::PRUNTIME_FUNCTION; | 
|  |  | 
|  | mod winapi { | 
|  | pub use winapi::ctypes::*; | 
|  | pub use winapi::shared::basetsd::*; | 
|  | pub use winapi::shared::minwindef::*; | 
|  | pub use winapi::um::dbghelp::*; | 
|  | pub use winapi::um::handleapi::*; | 
|  | pub use winapi::um::libloaderapi::*; | 
|  | pub use winapi::um::processthreadsapi::*; | 
|  | pub use winapi::um::winbase::*; | 
|  | pub use winapi::um::winnt::*; | 
|  | pub use winapi::um::fileapi::*; | 
|  | pub use winapi::um::minwinbase::*; | 
|  | pub use winapi::um::synchapi::*; | 
|  | } | 
|  | } else { | 
|  | pub use core::ffi::c_void; | 
|  | pub type HINSTANCE = *mut c_void; | 
|  | pub type FARPROC = *mut c_void; | 
|  | pub type LPSECURITY_ATTRIBUTES = *mut c_void; | 
|  | #[cfg(target_pointer_width = "64")] | 
|  | pub type PRUNTIME_FUNCTION = *mut c_void; | 
|  | #[cfg(target_pointer_width = "64")] | 
|  | pub type PUNWIND_HISTORY_TABLE = *mut c_void; | 
|  | } | 
|  | } | 
|  |  | 
|  | macro_rules! ffi { | 
|  | () => (); | 
|  |  | 
|  | (#[repr($($r:tt)*)] pub struct $name:ident { $(pub $field:ident: $ty:ty,)* } $($rest:tt)*) => ( | 
|  | #[repr($($r)*)] | 
|  | #[cfg(not(feature = "verify-winapi"))] | 
|  | #[derive(Copy, Clone)] | 
|  | pub struct $name { | 
|  | $(pub $field: $ty,)* | 
|  | } | 
|  |  | 
|  | #[cfg(feature = "verify-winapi")] | 
|  | pub use self::winapi::$name; | 
|  |  | 
|  | #[test] | 
|  | #[cfg(feature = "verify-winapi")] | 
|  | fn $name() { | 
|  | use core::mem; | 
|  |  | 
|  | #[repr($($r)*)] | 
|  | pub struct $name { | 
|  | $(pub $field: $ty,)* | 
|  | } | 
|  |  | 
|  | assert_eq!( | 
|  | mem::size_of::<$name>(), | 
|  | mem::size_of::<winapi::$name>(), | 
|  | concat!("size of ", stringify!($name), " is wrong"), | 
|  | ); | 
|  | assert_eq!( | 
|  | mem::align_of::<$name>(), | 
|  | mem::align_of::<winapi::$name>(), | 
|  | concat!("align of ", stringify!($name), " is wrong"), | 
|  | ); | 
|  |  | 
|  | type Winapi = winapi::$name; | 
|  |  | 
|  | fn assert_same<T>(_: T, _: T) {} | 
|  |  | 
|  | unsafe { | 
|  | let a = &*(mem::align_of::<$name>() as *const $name); | 
|  | let b = &*(mem::align_of::<Winapi>() as *const Winapi); | 
|  |  | 
|  | $( | 
|  | ffi!(@test_fields a b $field $ty); | 
|  | )* | 
|  | } | 
|  | } | 
|  |  | 
|  | ffi!($($rest)*); | 
|  | ); | 
|  |  | 
|  | // Handling verification against unions in winapi requires some special care | 
|  | (@test_fields $a:ident $b:ident FltSave $ty:ty) => ( | 
|  | // Skip this field on x86_64 `CONTEXT` since it's a union and a bit funny | 
|  | ); | 
|  | (@test_fields $a:ident $b:ident D $ty:ty) => ({ | 
|  | let a = &$a.D; | 
|  | let b = $b.D(); | 
|  | assert_same(a, b); | 
|  | assert_eq!(a as *const $ty, b as *const $ty, "misplaced field D"); | 
|  | }); | 
|  | (@test_fields $a:ident $b:ident s $ty:ty) => ({ | 
|  | let a = &$a.s; | 
|  | let b = $b.s(); | 
|  | assert_same(a, b); | 
|  | assert_eq!(a as *const $ty, b as *const $ty, "misplaced field s"); | 
|  | }); | 
|  |  | 
|  | // Otherwise test all fields normally. | 
|  | (@test_fields $a:ident $b:ident $field:ident $ty:ty) => ({ | 
|  | let a = &$a.$field; | 
|  | let b = &$b.$field; | 
|  | assert_same(a, b); | 
|  | assert_eq!(a as *const $ty, b as *const $ty, | 
|  | concat!("misplaced field ", stringify!($field))); | 
|  | }); | 
|  |  | 
|  | (pub type $name:ident = $ty:ty; $($rest:tt)*) => ( | 
|  | pub type $name = $ty; | 
|  |  | 
|  | #[cfg(feature = "verify-winapi")] | 
|  | #[allow(dead_code)] | 
|  | const $name: () = { | 
|  | fn _foo() { | 
|  | trait SameType {} | 
|  | impl<T> SameType for (T, T) {} | 
|  | fn assert_same<T: SameType>() {} | 
|  |  | 
|  | assert_same::<($name, winapi::$name)>(); | 
|  | } | 
|  | }; | 
|  |  | 
|  | ffi!($($rest)*); | 
|  | ); | 
|  |  | 
|  | (pub const $name:ident: $ty:ty = $val:expr; $($rest:tt)*) => ( | 
|  | pub const $name: $ty = $val; | 
|  |  | 
|  | #[cfg(feature = "verify-winapi")] | 
|  | #[allow(unused_imports)] | 
|  | mod $name { | 
|  | use super::*; | 
|  | #[test] | 
|  | fn assert_valid() { | 
|  | let x: $ty = winapi::$name; | 
|  | assert_eq!(x, $val); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | ffi!($($rest)*); | 
|  | ); | 
|  |  | 
|  | (extern "system" { $(pub fn $name:ident($($args:tt)*) -> $ret:ty;)* } $($rest:tt)*) => ( | 
|  | extern "system" { | 
|  | $(pub fn $name($($args)*) -> $ret;)* | 
|  | } | 
|  |  | 
|  | $( | 
|  | #[cfg(feature = "verify-winapi")] | 
|  | mod $name { | 
|  | #[test] | 
|  | fn assert_same() { | 
|  | use super::*; | 
|  |  | 
|  | assert_eq!($name as usize, winapi::$name as usize); | 
|  | let mut x: unsafe extern "system" fn($($args)*) -> $ret; | 
|  | x = $name; | 
|  | drop(x); | 
|  | x = winapi::$name; | 
|  | drop(x); | 
|  | } | 
|  | } | 
|  | )* | 
|  |  | 
|  | ffi!($($rest)*); | 
|  | ); | 
|  |  | 
|  | (impl $name:ident { $($i:tt)* } $($rest:tt)*) => ( | 
|  | #[cfg(not(feature = "verify-winapi"))] | 
|  | impl $name { | 
|  | $($i)* | 
|  | } | 
|  |  | 
|  | ffi!($($rest)*); | 
|  | ); | 
|  | } | 
|  |  | 
|  | ffi! { | 
|  | #[repr(C)] | 
|  | pub struct STACKFRAME64 { | 
|  | pub AddrPC: ADDRESS64, | 
|  | pub AddrReturn: ADDRESS64, | 
|  | pub AddrFrame: ADDRESS64, | 
|  | pub AddrStack: ADDRESS64, | 
|  | pub AddrBStore: ADDRESS64, | 
|  | pub FuncTableEntry: PVOID, | 
|  | pub Params: [DWORD64; 4], | 
|  | pub Far: BOOL, | 
|  | pub Virtual: BOOL, | 
|  | pub Reserved: [DWORD64; 3], | 
|  | pub KdHelp: KDHELP64, | 
|  | } | 
|  |  | 
|  | pub type LPSTACKFRAME64 = *mut STACKFRAME64; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct STACKFRAME_EX { | 
|  | pub AddrPC: ADDRESS64, | 
|  | pub AddrReturn: ADDRESS64, | 
|  | pub AddrFrame: ADDRESS64, | 
|  | pub AddrStack: ADDRESS64, | 
|  | pub AddrBStore: ADDRESS64, | 
|  | pub FuncTableEntry: PVOID, | 
|  | pub Params: [DWORD64; 4], | 
|  | pub Far: BOOL, | 
|  | pub Virtual: BOOL, | 
|  | pub Reserved: [DWORD64; 3], | 
|  | pub KdHelp: KDHELP64, | 
|  | pub StackFrameSize: DWORD, | 
|  | pub InlineFrameContext: DWORD, | 
|  | } | 
|  |  | 
|  | pub type LPSTACKFRAME_EX = *mut STACKFRAME_EX; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct IMAGEHLP_LINEW64 { | 
|  | pub SizeOfStruct: DWORD, | 
|  | pub Key: PVOID, | 
|  | pub LineNumber: DWORD, | 
|  | pub FileName: PWSTR, | 
|  | pub Address: DWORD64, | 
|  | } | 
|  |  | 
|  | pub type PIMAGEHLP_LINEW64 = *mut IMAGEHLP_LINEW64; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct SYMBOL_INFOW { | 
|  | pub SizeOfStruct: ULONG, | 
|  | pub TypeIndex: ULONG, | 
|  | pub Reserved: [ULONG64; 2], | 
|  | pub Index: ULONG, | 
|  | pub Size: ULONG, | 
|  | pub ModBase: ULONG64, | 
|  | pub Flags: ULONG, | 
|  | pub Value: ULONG64, | 
|  | pub Address: ULONG64, | 
|  | pub Register: ULONG, | 
|  | pub Scope: ULONG, | 
|  | pub Tag: ULONG, | 
|  | pub NameLen: ULONG, | 
|  | pub MaxNameLen: ULONG, | 
|  | pub Name: [WCHAR; 1], | 
|  | } | 
|  |  | 
|  | pub type PSYMBOL_INFOW = *mut SYMBOL_INFOW; | 
|  |  | 
|  | pub type PTRANSLATE_ADDRESS_ROUTINE64 = Option< | 
|  | unsafe extern "system" fn(hProcess: HANDLE, hThread: HANDLE, lpaddr: LPADDRESS64) -> DWORD64, | 
|  | >; | 
|  | pub type PGET_MODULE_BASE_ROUTINE64 = | 
|  | Option<unsafe extern "system" fn(hProcess: HANDLE, Address: DWORD64) -> DWORD64>; | 
|  | pub type PFUNCTION_TABLE_ACCESS_ROUTINE64 = | 
|  | Option<unsafe extern "system" fn(ahProcess: HANDLE, AddrBase: DWORD64) -> PVOID>; | 
|  | pub type PREAD_PROCESS_MEMORY_ROUTINE64 = Option< | 
|  | unsafe extern "system" fn( | 
|  | hProcess: HANDLE, | 
|  | qwBaseAddress: DWORD64, | 
|  | lpBuffer: PVOID, | 
|  | nSize: DWORD, | 
|  | lpNumberOfBytesRead: LPDWORD, | 
|  | ) -> BOOL, | 
|  | >; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct ADDRESS64 { | 
|  | pub Offset: DWORD64, | 
|  | pub Segment: WORD, | 
|  | pub Mode: ADDRESS_MODE, | 
|  | } | 
|  |  | 
|  | pub type LPADDRESS64 = *mut ADDRESS64; | 
|  |  | 
|  | pub type ADDRESS_MODE = u32; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct KDHELP64 { | 
|  | pub Thread: DWORD64, | 
|  | pub ThCallbackStack: DWORD, | 
|  | pub ThCallbackBStore: DWORD, | 
|  | pub NextCallback: DWORD, | 
|  | pub FramePointer: DWORD, | 
|  | pub KiCallUserMode: DWORD64, | 
|  | pub KeUserCallbackDispatcher: DWORD64, | 
|  | pub SystemRangeStart: DWORD64, | 
|  | pub KiUserExceptionDispatcher: DWORD64, | 
|  | pub StackBase: DWORD64, | 
|  | pub StackLimit: DWORD64, | 
|  | pub BuildVersion: DWORD, | 
|  | pub Reserved0: DWORD, | 
|  | pub Reserved1: [DWORD64; 4], | 
|  | } | 
|  |  | 
|  | pub const MAX_SYM_NAME: usize = 2000; | 
|  | pub const AddrModeFlat: ADDRESS_MODE = 3; | 
|  | pub const TRUE: BOOL = 1; | 
|  | pub const FALSE: BOOL = 0; | 
|  | pub const PROCESS_QUERY_INFORMATION: DWORD = 0x400; | 
|  | pub const IMAGE_FILE_MACHINE_ARM64: u16 = 43620; | 
|  | pub const IMAGE_FILE_MACHINE_AMD64: u16 = 34404; | 
|  | pub const IMAGE_FILE_MACHINE_I386: u16 = 332; | 
|  | pub const IMAGE_FILE_MACHINE_ARMNT: u16 = 452; | 
|  | pub const FILE_SHARE_READ: DWORD = 0x1; | 
|  | pub const FILE_SHARE_WRITE: DWORD = 0x2; | 
|  | pub const OPEN_EXISTING: DWORD = 0x3; | 
|  | pub const GENERIC_READ: DWORD = 0x80000000; | 
|  | pub const INFINITE: DWORD = !0; | 
|  |  | 
|  | pub type DWORD = u32; | 
|  | pub type PDWORD = *mut u32; | 
|  | pub type BOOL = i32; | 
|  | pub type DWORD64 = u64; | 
|  | pub type PDWORD64 = *mut u64; | 
|  | pub type HANDLE = *mut c_void; | 
|  | pub type PVOID = HANDLE; | 
|  | pub type PCWSTR = *const u16; | 
|  | pub type LPSTR = *mut i8; | 
|  | pub type LPCSTR = *const i8; | 
|  | pub type PWSTR = *mut u16; | 
|  | pub type WORD = u16; | 
|  | pub type ULONG = u32; | 
|  | pub type ULONG64 = u64; | 
|  | pub type WCHAR = u16; | 
|  | pub type PCONTEXT = *mut CONTEXT; | 
|  | pub type LPDWORD = *mut DWORD; | 
|  | pub type DWORDLONG = u64; | 
|  | pub type HMODULE = HINSTANCE; | 
|  |  | 
|  | extern "system" { | 
|  | pub fn GetCurrentProcess() -> HANDLE; | 
|  | pub fn GetCurrentThread() -> HANDLE; | 
|  | pub fn RtlCaptureContext(ContextRecord: PCONTEXT) -> (); | 
|  | pub fn LoadLibraryA(a: *const i8) -> HMODULE; | 
|  | pub fn GetProcAddress(h: HMODULE, name: *const i8) -> FARPROC; | 
|  | pub fn GetModuleHandleA(name: *const i8) -> HMODULE; | 
|  | pub fn OpenProcess( | 
|  | dwDesiredAccess: DWORD, | 
|  | bInheitHandle: BOOL, | 
|  | dwProcessId: DWORD, | 
|  | ) -> HANDLE; | 
|  | pub fn GetCurrentProcessId() -> DWORD; | 
|  | pub fn CloseHandle(h: HANDLE) -> BOOL; | 
|  | pub fn CreateFileA( | 
|  | lpFileName: LPCSTR, | 
|  | dwDesiredAccess: DWORD, | 
|  | dwShareMode: DWORD, | 
|  | lpSecurityAttributes: LPSECURITY_ATTRIBUTES, | 
|  | dwCreationDisposition: DWORD, | 
|  | dwFlagsAndAttributes: DWORD, | 
|  | hTemplateFile: HANDLE, | 
|  | ) -> HANDLE; | 
|  | pub fn CreateMutexA( | 
|  | attrs: LPSECURITY_ATTRIBUTES, | 
|  | initial: BOOL, | 
|  | name: LPCSTR, | 
|  | ) -> HANDLE; | 
|  | pub fn ReleaseMutex(hMutex: HANDLE) -> BOOL; | 
|  | pub fn WaitForSingleObjectEx( | 
|  | hHandle: HANDLE, | 
|  | dwMilliseconds: DWORD, | 
|  | bAlertable: BOOL, | 
|  | ) -> DWORD; | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(target_pointer_width = "64")] | 
|  | ffi! { | 
|  | extern "system" { | 
|  | pub fn RtlLookupFunctionEntry( | 
|  | ControlPc: DWORD64, | 
|  | ImageBase: PDWORD64, | 
|  | HistoryTable: PUNWIND_HISTORY_TABLE, | 
|  | ) -> PRUNTIME_FUNCTION; | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(target_arch = "aarch64")] | 
|  | ffi! { | 
|  | #[repr(C, align(16))] | 
|  | pub struct CONTEXT { | 
|  | pub ContextFlags: DWORD, | 
|  | pub Cpsr: DWORD, | 
|  | pub u: CONTEXT_u, | 
|  | pub Sp: u64, | 
|  | pub Pc: u64, | 
|  | pub V: [ARM64_NT_NEON128; 32], | 
|  | pub Fpcr: DWORD, | 
|  | pub Fpsr: DWORD, | 
|  | pub Bcr: [DWORD; ARM64_MAX_BREAKPOINTS], | 
|  | pub Bvr: [DWORD64; ARM64_MAX_BREAKPOINTS], | 
|  | pub Wcr: [DWORD; ARM64_MAX_WATCHPOINTS], | 
|  | pub Wvr: [DWORD64; ARM64_MAX_WATCHPOINTS], | 
|  | } | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct CONTEXT_u { | 
|  | pub s: CONTEXT_u_s, | 
|  | } | 
|  |  | 
|  | impl CONTEXT_u { | 
|  | pub unsafe fn s(&self) -> &CONTEXT_u_s { | 
|  | &self.s | 
|  | } | 
|  | } | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct CONTEXT_u_s { | 
|  | pub X0: u64, | 
|  | pub X1: u64, | 
|  | pub X2: u64, | 
|  | pub X3: u64, | 
|  | pub X4: u64, | 
|  | pub X5: u64, | 
|  | pub X6: u64, | 
|  | pub X7: u64, | 
|  | pub X8: u64, | 
|  | pub X9: u64, | 
|  | pub X10: u64, | 
|  | pub X11: u64, | 
|  | pub X12: u64, | 
|  | pub X13: u64, | 
|  | pub X14: u64, | 
|  | pub X15: u64, | 
|  | pub X16: u64, | 
|  | pub X17: u64, | 
|  | pub X18: u64, | 
|  | pub X19: u64, | 
|  | pub X20: u64, | 
|  | pub X21: u64, | 
|  | pub X22: u64, | 
|  | pub X23: u64, | 
|  | pub X24: u64, | 
|  | pub X25: u64, | 
|  | pub X26: u64, | 
|  | pub X27: u64, | 
|  | pub X28: u64, | 
|  | pub Fp: u64, | 
|  | pub Lr: u64, | 
|  | } | 
|  |  | 
|  | pub const ARM64_MAX_BREAKPOINTS: usize = 8; | 
|  | pub const ARM64_MAX_WATCHPOINTS: usize = 2; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct ARM64_NT_NEON128 { | 
|  | pub D: [f64; 2], | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(target_arch = "x86")] | 
|  | ffi! { | 
|  | #[repr(C)] | 
|  | pub struct CONTEXT { | 
|  | pub ContextFlags: DWORD, | 
|  | pub Dr0: DWORD, | 
|  | pub Dr1: DWORD, | 
|  | pub Dr2: DWORD, | 
|  | pub Dr3: DWORD, | 
|  | pub Dr6: DWORD, | 
|  | pub Dr7: DWORD, | 
|  | pub FloatSave: FLOATING_SAVE_AREA, | 
|  | pub SegGs: DWORD, | 
|  | pub SegFs: DWORD, | 
|  | pub SegEs: DWORD, | 
|  | pub SegDs: DWORD, | 
|  | pub Edi: DWORD, | 
|  | pub Esi: DWORD, | 
|  | pub Ebx: DWORD, | 
|  | pub Edx: DWORD, | 
|  | pub Ecx: DWORD, | 
|  | pub Eax: DWORD, | 
|  | pub Ebp: DWORD, | 
|  | pub Eip: DWORD, | 
|  | pub SegCs: DWORD, | 
|  | pub EFlags: DWORD, | 
|  | pub Esp: DWORD, | 
|  | pub SegSs: DWORD, | 
|  | pub ExtendedRegisters: [u8; 512], | 
|  | } | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct FLOATING_SAVE_AREA { | 
|  | pub ControlWord: DWORD, | 
|  | pub StatusWord: DWORD, | 
|  | pub TagWord: DWORD, | 
|  | pub ErrorOffset: DWORD, | 
|  | pub ErrorSelector: DWORD, | 
|  | pub DataOffset: DWORD, | 
|  | pub DataSelector: DWORD, | 
|  | pub RegisterArea: [u8; 80], | 
|  | pub Spare0: DWORD, | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(target_arch = "x86_64")] | 
|  | ffi! { | 
|  | #[repr(C, align(8))] | 
|  | pub struct CONTEXT { | 
|  | pub P1Home: DWORDLONG, | 
|  | pub P2Home: DWORDLONG, | 
|  | pub P3Home: DWORDLONG, | 
|  | pub P4Home: DWORDLONG, | 
|  | pub P5Home: DWORDLONG, | 
|  | pub P6Home: DWORDLONG, | 
|  |  | 
|  | pub ContextFlags: DWORD, | 
|  | pub MxCsr: DWORD, | 
|  |  | 
|  | pub SegCs: WORD, | 
|  | pub SegDs: WORD, | 
|  | pub SegEs: WORD, | 
|  | pub SegFs: WORD, | 
|  | pub SegGs: WORD, | 
|  | pub SegSs: WORD, | 
|  | pub EFlags: DWORD, | 
|  |  | 
|  | pub Dr0: DWORDLONG, | 
|  | pub Dr1: DWORDLONG, | 
|  | pub Dr2: DWORDLONG, | 
|  | pub Dr3: DWORDLONG, | 
|  | pub Dr6: DWORDLONG, | 
|  | pub Dr7: DWORDLONG, | 
|  |  | 
|  | pub Rax: DWORDLONG, | 
|  | pub Rcx: DWORDLONG, | 
|  | pub Rdx: DWORDLONG, | 
|  | pub Rbx: DWORDLONG, | 
|  | pub Rsp: DWORDLONG, | 
|  | pub Rbp: DWORDLONG, | 
|  | pub Rsi: DWORDLONG, | 
|  | pub Rdi: DWORDLONG, | 
|  | pub R8:  DWORDLONG, | 
|  | pub R9:  DWORDLONG, | 
|  | pub R10: DWORDLONG, | 
|  | pub R11: DWORDLONG, | 
|  | pub R12: DWORDLONG, | 
|  | pub R13: DWORDLONG, | 
|  | pub R14: DWORDLONG, | 
|  | pub R15: DWORDLONG, | 
|  |  | 
|  | pub Rip: DWORDLONG, | 
|  |  | 
|  | pub FltSave: FLOATING_SAVE_AREA, | 
|  |  | 
|  | pub VectorRegister: [M128A; 26], | 
|  | pub VectorControl: DWORDLONG, | 
|  |  | 
|  | pub DebugControl: DWORDLONG, | 
|  | pub LastBranchToRip: DWORDLONG, | 
|  | pub LastBranchFromRip: DWORDLONG, | 
|  | pub LastExceptionToRip: DWORDLONG, | 
|  | pub LastExceptionFromRip: DWORDLONG, | 
|  | } | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct M128A { | 
|  | pub Low: u64, | 
|  | pub High: i64, | 
|  | } | 
|  | } | 
|  |  | 
|  | #[repr(C)] | 
|  | #[cfg(target_arch = "x86_64")] | 
|  | #[derive(Copy, Clone)] | 
|  | pub struct FLOATING_SAVE_AREA { | 
|  | _Dummy: [u8; 512], | 
|  | } | 
|  |  | 
|  | #[cfg(target_arch = "arm")] | 
|  | ffi! { | 
|  | // #[repr(C)] | 
|  | // pub struct NEON128 { | 
|  | //     pub Low: ULONG64, | 
|  | //     pub High: LONG64, | 
|  | // } | 
|  |  | 
|  | // pub type PNEON128 = *mut NEON128; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct CONTEXT_u { | 
|  | // pub Q: [NEON128; 16], | 
|  | pub D: [ULONG64; 32], | 
|  | // pub S: [DWORD; 32], | 
|  | } | 
|  |  | 
|  | pub const ARM_MAX_BREAKPOINTS: usize = 8; | 
|  | pub const ARM_MAX_WATCHPOINTS: usize = 1; | 
|  |  | 
|  | #[repr(C)] | 
|  | pub struct CONTEXT { | 
|  | pub ContextFlags: DWORD, | 
|  | pub R0: DWORD, | 
|  | pub R1: DWORD, | 
|  | pub R2: DWORD, | 
|  | pub R3: DWORD, | 
|  | pub R4: DWORD, | 
|  | pub R5: DWORD, | 
|  | pub R6: DWORD, | 
|  | pub R7: DWORD, | 
|  | pub R8: DWORD, | 
|  | pub R9: DWORD, | 
|  | pub R10: DWORD, | 
|  | pub R11: DWORD, | 
|  | pub R12: DWORD, | 
|  | pub Sp: DWORD, | 
|  | pub Lr: DWORD, | 
|  | pub Pc: DWORD, | 
|  | pub Cpsr: DWORD, | 
|  | pub Fpsrc: DWORD, | 
|  | pub Padding: DWORD, | 
|  | pub u: CONTEXT_u, | 
|  | pub Bvr: [DWORD; ARM_MAX_BREAKPOINTS], | 
|  | pub Bcr: [DWORD; ARM_MAX_BREAKPOINTS], | 
|  | pub Wvr: [DWORD; ARM_MAX_WATCHPOINTS], | 
|  | pub Wcr: [DWORD; ARM_MAX_WATCHPOINTS], | 
|  | pub Padding2: [DWORD; 2], | 
|  | } | 
|  | } // IFDEF(arm) |