1 //! A module to define the FFI definitions we use on Windows for `dbghelp.dll` 2 //! 3 //! This module uses a custom macro, `ffi!`, to wrap all definitions to 4 //! automatically generate tests to assert that our definitions here are the 5 //! same as `winapi`. 6 //! 7 //! This module largely exists to integrate into libstd itself where winapi is 8 //! not currently available. 9 10 #![allow(bad_style, dead_code)] 11 12 cfg_if::cfg_if! { 13 if #[cfg(feature = "verify-winapi")] { 14 pub use self::winapi::c_void; 15 pub use self::winapi::HINSTANCE; 16 pub use self::winapi::FARPROC; 17 pub use self::winapi::LPSECURITY_ATTRIBUTES; 18 #[cfg(target_pointer_width = "64")] 19 pub use self::winapi::PUNWIND_HISTORY_TABLE; 20 #[cfg(target_pointer_width = "64")] 21 pub use self::winapi::PRUNTIME_FUNCTION; 22 23 mod winapi { 24 pub use winapi::ctypes::*; 25 pub use winapi::shared::basetsd::*; 26 pub use winapi::shared::minwindef::*; 27 pub use winapi::um::dbghelp::*; 28 pub use winapi::um::fileapi::*; 29 pub use winapi::um::handleapi::*; 30 pub use winapi::um::libloaderapi::*; 31 pub use winapi::um::memoryapi::*; 32 pub use winapi::um::minwinbase::*; 33 pub use winapi::um::processthreadsapi::*; 34 pub use winapi::um::synchapi::*; 35 pub use winapi::um::tlhelp32::*; 36 pub use winapi::um::winbase::*; 37 pub use winapi::um::winnt::*; 38 } 39 } else { 40 pub use core::ffi::c_void; 41 pub type HINSTANCE = *mut c_void; 42 pub type FARPROC = *mut c_void; 43 pub type LPSECURITY_ATTRIBUTES = *mut c_void; 44 #[cfg(target_pointer_width = "64")] 45 pub type PRUNTIME_FUNCTION = *mut c_void; 46 #[cfg(target_pointer_width = "64")] 47 pub type PUNWIND_HISTORY_TABLE = *mut c_void; 48 } 49 } 50 51 macro_rules! ffi { 52 () => (); 53 54 (#[repr($($r:tt)*)] pub struct $name:ident { $(pub $field:ident: $ty:ty,)* } $($rest:tt)*) => ( 55 #[repr($($r)*)] 56 #[cfg(not(feature = "verify-winapi"))] 57 #[derive(Copy, Clone)] 58 pub struct $name { 59 $(pub $field: $ty,)* 60 } 61 62 #[cfg(feature = "verify-winapi")] 63 pub use self::winapi::$name; 64 65 #[test] 66 #[cfg(feature = "verify-winapi")] 67 fn $name() { 68 use core::mem; 69 70 #[repr($($r)*)] 71 pub struct $name { 72 $(pub $field: $ty,)* 73 } 74 75 assert_eq!( 76 mem::size_of::<$name>(), 77 mem::size_of::<winapi::$name>(), 78 concat!("size of ", stringify!($name), " is wrong"), 79 ); 80 assert_eq!( 81 mem::align_of::<$name>(), 82 mem::align_of::<winapi::$name>(), 83 concat!("align of ", stringify!($name), " is wrong"), 84 ); 85 86 type Winapi = winapi::$name; 87 88 fn assert_same<T>(_: T, _: T) {} 89 90 unsafe { 91 let a = &*(mem::align_of::<$name>() as *const $name); 92 let b = &*(mem::align_of::<Winapi>() as *const Winapi); 93 94 $( 95 ffi!(@test_fields a b $field $ty); 96 )* 97 } 98 } 99 100 ffi!($($rest)*); 101 ); 102 103 // Handling verification against unions in winapi requires some special care 104 (@test_fields $a:ident $b:ident FltSave $ty:ty) => ( 105 // Skip this field on x86_64 `CONTEXT` since it's a union and a bit funny 106 ); 107 (@test_fields $a:ident $b:ident D $ty:ty) => ({ 108 let a = &$a.D; 109 let b = $b.D(); 110 assert_same(a, b); 111 assert_eq!(a as *const $ty, b as *const $ty, "misplaced field D"); 112 }); 113 (@test_fields $a:ident $b:ident s $ty:ty) => ({ 114 let a = &$a.s; 115 let b = $b.s(); 116 assert_same(a, b); 117 assert_eq!(a as *const $ty, b as *const $ty, "misplaced field s"); 118 }); 119 120 // Otherwise test all fields normally. 121 (@test_fields $a:ident $b:ident $field:ident $ty:ty) => ({ 122 let a = &$a.$field; 123 let b = &$b.$field; 124 assert_same(a, b); 125 assert_eq!(a as *const $ty, b as *const $ty, 126 concat!("misplaced field ", stringify!($field))); 127 }); 128 129 (pub type $name:ident = $ty:ty; $($rest:tt)*) => ( 130 pub type $name = $ty; 131 132 #[cfg(feature = "verify-winapi")] 133 #[allow(dead_code)] 134 const $name: () = { 135 fn _foo() { 136 trait SameType {} 137 impl<T> SameType for (T, T) {} 138 fn assert_same<T: SameType>() {} 139 140 assert_same::<($name, winapi::$name)>(); 141 } 142 }; 143 144 ffi!($($rest)*); 145 ); 146 147 (pub const $name:ident: $ty:ty = $val:expr; $($rest:tt)*) => ( 148 pub const $name: $ty = $val; 149 150 #[cfg(feature = "verify-winapi")] 151 #[allow(unused_imports)] 152 mod $name { 153 use super::*; 154 #[test] 155 fn assert_valid() { 156 let x: $ty = winapi::$name; 157 assert_eq!(x, $val); 158 } 159 } 160 161 162 ffi!($($rest)*); 163 ); 164 165 (extern "system" { $(pub fn $name:ident($($args:tt)*) -> $ret:ty;)* } $($rest:tt)*) => ( 166 extern "system" { 167 $(pub fn $name($($args)*) -> $ret;)* 168 } 169 170 $( 171 #[cfg(feature = "verify-winapi")] 172 mod $name { 173 #[test] 174 fn assert_same() { 175 use super::*; 176 177 assert_eq!($name as usize, winapi::$name as usize); 178 let mut x: unsafe extern "system" fn($($args)*) -> $ret; 179 x = $name; 180 drop(x); 181 x = winapi::$name; 182 drop(x); 183 } 184 } 185 )* 186 187 ffi!($($rest)*); 188 ); 189 190 (impl $name:ident { $($i:tt)* } $($rest:tt)*) => ( 191 #[cfg(not(feature = "verify-winapi"))] 192 impl $name { 193 $($i)* 194 } 195 196 ffi!($($rest)*); 197 ); 198 } 199 200 ffi! { 201 #[repr(C)] 202 pub struct STACKFRAME64 { 203 pub AddrPC: ADDRESS64, 204 pub AddrReturn: ADDRESS64, 205 pub AddrFrame: ADDRESS64, 206 pub AddrStack: ADDRESS64, 207 pub AddrBStore: ADDRESS64, 208 pub FuncTableEntry: PVOID, 209 pub Params: [DWORD64; 4], 210 pub Far: BOOL, 211 pub Virtual: BOOL, 212 pub Reserved: [DWORD64; 3], 213 pub KdHelp: KDHELP64, 214 } 215 216 pub type LPSTACKFRAME64 = *mut STACKFRAME64; 217 218 #[repr(C)] 219 pub struct STACKFRAME_EX { 220 pub AddrPC: ADDRESS64, 221 pub AddrReturn: ADDRESS64, 222 pub AddrFrame: ADDRESS64, 223 pub AddrStack: ADDRESS64, 224 pub AddrBStore: ADDRESS64, 225 pub FuncTableEntry: PVOID, 226 pub Params: [DWORD64; 4], 227 pub Far: BOOL, 228 pub Virtual: BOOL, 229 pub Reserved: [DWORD64; 3], 230 pub KdHelp: KDHELP64, 231 pub StackFrameSize: DWORD, 232 pub InlineFrameContext: DWORD, 233 } 234 235 pub type LPSTACKFRAME_EX = *mut STACKFRAME_EX; 236 237 #[repr(C)] 238 pub struct IMAGEHLP_LINEW64 { 239 pub SizeOfStruct: DWORD, 240 pub Key: PVOID, 241 pub LineNumber: DWORD, 242 pub FileName: PWSTR, 243 pub Address: DWORD64, 244 } 245 246 pub type PIMAGEHLP_LINEW64 = *mut IMAGEHLP_LINEW64; 247 248 #[repr(C)] 249 pub struct SYMBOL_INFOW { 250 pub SizeOfStruct: ULONG, 251 pub TypeIndex: ULONG, 252 pub Reserved: [ULONG64; 2], 253 pub Index: ULONG, 254 pub Size: ULONG, 255 pub ModBase: ULONG64, 256 pub Flags: ULONG, 257 pub Value: ULONG64, 258 pub Address: ULONG64, 259 pub Register: ULONG, 260 pub Scope: ULONG, 261 pub Tag: ULONG, 262 pub NameLen: ULONG, 263 pub MaxNameLen: ULONG, 264 pub Name: [WCHAR; 1], 265 } 266 267 pub type PSYMBOL_INFOW = *mut SYMBOL_INFOW; 268 269 pub type PTRANSLATE_ADDRESS_ROUTINE64 = Option< 270 unsafe extern "system" fn(hProcess: HANDLE, hThread: HANDLE, lpaddr: LPADDRESS64) -> DWORD64, 271 >; 272 pub type PGET_MODULE_BASE_ROUTINE64 = 273 Option<unsafe extern "system" fn(hProcess: HANDLE, Address: DWORD64) -> DWORD64>; 274 pub type PFUNCTION_TABLE_ACCESS_ROUTINE64 = 275 Option<unsafe extern "system" fn(ahProcess: HANDLE, AddrBase: DWORD64) -> PVOID>; 276 pub type PREAD_PROCESS_MEMORY_ROUTINE64 = Option< 277 unsafe extern "system" fn( 278 hProcess: HANDLE, 279 qwBaseAddress: DWORD64, 280 lpBuffer: PVOID, 281 nSize: DWORD, 282 lpNumberOfBytesRead: LPDWORD, 283 ) -> BOOL, 284 >; 285 286 #[repr(C)] 287 pub struct ADDRESS64 { 288 pub Offset: DWORD64, 289 pub Segment: WORD, 290 pub Mode: ADDRESS_MODE, 291 } 292 293 pub type LPADDRESS64 = *mut ADDRESS64; 294 295 pub type ADDRESS_MODE = u32; 296 297 #[repr(C)] 298 pub struct KDHELP64 { 299 pub Thread: DWORD64, 300 pub ThCallbackStack: DWORD, 301 pub ThCallbackBStore: DWORD, 302 pub NextCallback: DWORD, 303 pub FramePointer: DWORD, 304 pub KiCallUserMode: DWORD64, 305 pub KeUserCallbackDispatcher: DWORD64, 306 pub SystemRangeStart: DWORD64, 307 pub KiUserExceptionDispatcher: DWORD64, 308 pub StackBase: DWORD64, 309 pub StackLimit: DWORD64, 310 pub BuildVersion: DWORD, 311 pub Reserved0: DWORD, 312 pub Reserved1: [DWORD64; 4], 313 } 314 315 #[repr(C)] 316 pub struct MODULEENTRY32W { 317 pub dwSize: DWORD, 318 pub th32ModuleID: DWORD, 319 pub th32ProcessID: DWORD, 320 pub GlblcntUsage: DWORD, 321 pub ProccntUsage: DWORD, 322 pub modBaseAddr: *mut u8, 323 pub modBaseSize: DWORD, 324 pub hModule: HMODULE, 325 pub szModule: [WCHAR; MAX_MODULE_NAME32 + 1], 326 pub szExePath: [WCHAR; MAX_PATH], 327 } 328 329 pub const MAX_SYM_NAME: usize = 2000; 330 pub const AddrModeFlat: ADDRESS_MODE = 3; 331 pub const TRUE: BOOL = 1; 332 pub const FALSE: BOOL = 0; 333 pub const PROCESS_QUERY_INFORMATION: DWORD = 0x400; 334 pub const IMAGE_FILE_MACHINE_ARM64: u16 = 43620; 335 pub const IMAGE_FILE_MACHINE_AMD64: u16 = 34404; 336 pub const IMAGE_FILE_MACHINE_I386: u16 = 332; 337 pub const IMAGE_FILE_MACHINE_ARMNT: u16 = 452; 338 pub const FILE_SHARE_READ: DWORD = 0x1; 339 pub const FILE_SHARE_WRITE: DWORD = 0x2; 340 pub const OPEN_EXISTING: DWORD = 0x3; 341 pub const GENERIC_READ: DWORD = 0x80000000; 342 pub const INFINITE: DWORD = !0; 343 pub const PAGE_READONLY: DWORD = 2; 344 pub const FILE_MAP_READ: DWORD = 4; 345 pub const TH32CS_SNAPMODULE: DWORD = 0x00000008; 346 pub const INVALID_HANDLE_VALUE: HANDLE = -1isize as HANDLE; 347 pub const MAX_MODULE_NAME32: usize = 255; 348 pub const MAX_PATH: usize = 260; 349 350 pub type DWORD = u32; 351 pub type PDWORD = *mut u32; 352 pub type BOOL = i32; 353 pub type DWORD64 = u64; 354 pub type PDWORD64 = *mut u64; 355 pub type HANDLE = *mut c_void; 356 pub type PVOID = HANDLE; 357 pub type PCWSTR = *const u16; 358 pub type LPSTR = *mut i8; 359 pub type LPCSTR = *const i8; 360 pub type PWSTR = *mut u16; 361 pub type WORD = u16; 362 pub type ULONG = u32; 363 pub type ULONG64 = u64; 364 pub type WCHAR = u16; 365 pub type PCONTEXT = *mut CONTEXT; 366 pub type LPDWORD = *mut DWORD; 367 pub type DWORDLONG = u64; 368 pub type HMODULE = HINSTANCE; 369 pub type SIZE_T = usize; 370 pub type LPVOID = *mut c_void; 371 pub type LPCVOID = *const c_void; 372 pub type LPMODULEENTRY32W = *mut MODULEENTRY32W; 373 374 extern "system" { 375 pub fn GetCurrentProcess() -> HANDLE; 376 pub fn GetCurrentThread() -> HANDLE; 377 pub fn RtlCaptureContext(ContextRecord: PCONTEXT) -> (); 378 pub fn LoadLibraryA(a: *const i8) -> HMODULE; 379 pub fn GetProcAddress(h: HMODULE, name: *const i8) -> FARPROC; 380 pub fn GetModuleHandleA(name: *const i8) -> HMODULE; 381 pub fn OpenProcess( 382 dwDesiredAccess: DWORD, 383 bInheitHandle: BOOL, 384 dwProcessId: DWORD, 385 ) -> HANDLE; 386 pub fn GetCurrentProcessId() -> DWORD; 387 pub fn CloseHandle(h: HANDLE) -> BOOL; 388 pub fn CreateFileA( 389 lpFileName: LPCSTR, 390 dwDesiredAccess: DWORD, 391 dwShareMode: DWORD, 392 lpSecurityAttributes: LPSECURITY_ATTRIBUTES, 393 dwCreationDisposition: DWORD, 394 dwFlagsAndAttributes: DWORD, 395 hTemplateFile: HANDLE, 396 ) -> HANDLE; 397 pub fn CreateMutexA( 398 attrs: LPSECURITY_ATTRIBUTES, 399 initial: BOOL, 400 name: LPCSTR, 401 ) -> HANDLE; 402 pub fn ReleaseMutex(hMutex: HANDLE) -> BOOL; 403 pub fn WaitForSingleObjectEx( 404 hHandle: HANDLE, 405 dwMilliseconds: DWORD, 406 bAlertable: BOOL, 407 ) -> DWORD; 408 pub fn CreateFileMappingA( 409 hFile: HANDLE, 410 lpFileMappingAttributes: LPSECURITY_ATTRIBUTES, 411 flProtect: DWORD, 412 dwMaximumSizeHigh: DWORD, 413 dwMaximumSizeLow: DWORD, 414 lpName: LPCSTR, 415 ) -> HANDLE; 416 pub fn MapViewOfFile( 417 hFileMappingObject: HANDLE, 418 dwDesiredAccess: DWORD, 419 dwFileOffsetHigh: DWORD, 420 dwFileOffsetLow: DWORD, 421 dwNumberOfBytesToMap: SIZE_T, 422 ) -> LPVOID; 423 pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL; 424 pub fn CreateToolhelp32Snapshot( 425 dwFlags: DWORD, 426 th32ProcessID: DWORD, 427 ) -> HANDLE; 428 pub fn Module32FirstW( 429 hSnapshot: HANDLE, 430 lpme: LPMODULEENTRY32W, 431 ) -> BOOL; 432 pub fn Module32NextW( 433 hSnapshot: HANDLE, 434 lpme: LPMODULEENTRY32W, 435 ) -> BOOL; 436 } 437 } 438 439 #[cfg(target_pointer_width = "64")] 440 ffi! { 441 extern "system" { 442 pub fn RtlLookupFunctionEntry( 443 ControlPc: DWORD64, 444 ImageBase: PDWORD64, 445 HistoryTable: PUNWIND_HISTORY_TABLE, 446 ) -> PRUNTIME_FUNCTION; 447 } 448 } 449 450 #[cfg(target_arch = "aarch64")] 451 ffi! { 452 #[repr(C, align(16))] 453 pub struct CONTEXT { 454 pub ContextFlags: DWORD, 455 pub Cpsr: DWORD, 456 pub u: CONTEXT_u, 457 pub Sp: u64, 458 pub Pc: u64, 459 pub V: [ARM64_NT_NEON128; 32], 460 pub Fpcr: DWORD, 461 pub Fpsr: DWORD, 462 pub Bcr: [DWORD; ARM64_MAX_BREAKPOINTS], 463 pub Bvr: [DWORD64; ARM64_MAX_BREAKPOINTS], 464 pub Wcr: [DWORD; ARM64_MAX_WATCHPOINTS], 465 pub Wvr: [DWORD64; ARM64_MAX_WATCHPOINTS], 466 } 467 468 #[repr(C)] 469 pub struct CONTEXT_u { 470 pub s: CONTEXT_u_s, 471 } 472 473 impl CONTEXT_u { 474 pub unsafe fn s(&self) -> &CONTEXT_u_s { 475 &self.s 476 } 477 } 478 479 #[repr(C)] 480 pub struct CONTEXT_u_s { 481 pub X0: u64, 482 pub X1: u64, 483 pub X2: u64, 484 pub X3: u64, 485 pub X4: u64, 486 pub X5: u64, 487 pub X6: u64, 488 pub X7: u64, 489 pub X8: u64, 490 pub X9: u64, 491 pub X10: u64, 492 pub X11: u64, 493 pub X12: u64, 494 pub X13: u64, 495 pub X14: u64, 496 pub X15: u64, 497 pub X16: u64, 498 pub X17: u64, 499 pub X18: u64, 500 pub X19: u64, 501 pub X20: u64, 502 pub X21: u64, 503 pub X22: u64, 504 pub X23: u64, 505 pub X24: u64, 506 pub X25: u64, 507 pub X26: u64, 508 pub X27: u64, 509 pub X28: u64, 510 pub Fp: u64, 511 pub Lr: u64, 512 } 513 514 pub const ARM64_MAX_BREAKPOINTS: usize = 8; 515 pub const ARM64_MAX_WATCHPOINTS: usize = 2; 516 517 #[repr(C)] 518 pub struct ARM64_NT_NEON128 { 519 pub D: [f64; 2], 520 } 521 } 522 523 #[cfg(target_arch = "x86")] 524 ffi! { 525 #[repr(C)] 526 pub struct CONTEXT { 527 pub ContextFlags: DWORD, 528 pub Dr0: DWORD, 529 pub Dr1: DWORD, 530 pub Dr2: DWORD, 531 pub Dr3: DWORD, 532 pub Dr6: DWORD, 533 pub Dr7: DWORD, 534 pub FloatSave: FLOATING_SAVE_AREA, 535 pub SegGs: DWORD, 536 pub SegFs: DWORD, 537 pub SegEs: DWORD, 538 pub SegDs: DWORD, 539 pub Edi: DWORD, 540 pub Esi: DWORD, 541 pub Ebx: DWORD, 542 pub Edx: DWORD, 543 pub Ecx: DWORD, 544 pub Eax: DWORD, 545 pub Ebp: DWORD, 546 pub Eip: DWORD, 547 pub SegCs: DWORD, 548 pub EFlags: DWORD, 549 pub Esp: DWORD, 550 pub SegSs: DWORD, 551 pub ExtendedRegisters: [u8; 512], 552 } 553 554 #[repr(C)] 555 pub struct FLOATING_SAVE_AREA { 556 pub ControlWord: DWORD, 557 pub StatusWord: DWORD, 558 pub TagWord: DWORD, 559 pub ErrorOffset: DWORD, 560 pub ErrorSelector: DWORD, 561 pub DataOffset: DWORD, 562 pub DataSelector: DWORD, 563 pub RegisterArea: [u8; 80], 564 pub Spare0: DWORD, 565 } 566 } 567 568 #[cfg(target_arch = "x86_64")] 569 ffi! { 570 #[repr(C, align(8))] 571 pub struct CONTEXT { 572 pub P1Home: DWORDLONG, 573 pub P2Home: DWORDLONG, 574 pub P3Home: DWORDLONG, 575 pub P4Home: DWORDLONG, 576 pub P5Home: DWORDLONG, 577 pub P6Home: DWORDLONG, 578 579 pub ContextFlags: DWORD, 580 pub MxCsr: DWORD, 581 582 pub SegCs: WORD, 583 pub SegDs: WORD, 584 pub SegEs: WORD, 585 pub SegFs: WORD, 586 pub SegGs: WORD, 587 pub SegSs: WORD, 588 pub EFlags: DWORD, 589 590 pub Dr0: DWORDLONG, 591 pub Dr1: DWORDLONG, 592 pub Dr2: DWORDLONG, 593 pub Dr3: DWORDLONG, 594 pub Dr6: DWORDLONG, 595 pub Dr7: DWORDLONG, 596 597 pub Rax: DWORDLONG, 598 pub Rcx: DWORDLONG, 599 pub Rdx: DWORDLONG, 600 pub Rbx: DWORDLONG, 601 pub Rsp: DWORDLONG, 602 pub Rbp: DWORDLONG, 603 pub Rsi: DWORDLONG, 604 pub Rdi: DWORDLONG, 605 pub R8: DWORDLONG, 606 pub R9: DWORDLONG, 607 pub R10: DWORDLONG, 608 pub R11: DWORDLONG, 609 pub R12: DWORDLONG, 610 pub R13: DWORDLONG, 611 pub R14: DWORDLONG, 612 pub R15: DWORDLONG, 613 614 pub Rip: DWORDLONG, 615 616 pub FltSave: FLOATING_SAVE_AREA, 617 618 pub VectorRegister: [M128A; 26], 619 pub VectorControl: DWORDLONG, 620 621 pub DebugControl: DWORDLONG, 622 pub LastBranchToRip: DWORDLONG, 623 pub LastBranchFromRip: DWORDLONG, 624 pub LastExceptionToRip: DWORDLONG, 625 pub LastExceptionFromRip: DWORDLONG, 626 } 627 628 #[repr(C)] 629 pub struct M128A { 630 pub Low: u64, 631 pub High: i64, 632 } 633 } 634 635 #[repr(C)] 636 #[cfg(target_arch = "x86_64")] 637 #[derive(Copy, Clone)] 638 pub struct FLOATING_SAVE_AREA { 639 _Dummy: [u8; 512], 640 } 641 642 #[cfg(target_arch = "arm")] 643 ffi! { 644 // #[repr(C)] 645 // pub struct NEON128 { 646 // pub Low: ULONG64, 647 // pub High: LONG64, 648 // } 649 650 // pub type PNEON128 = *mut NEON128; 651 652 #[repr(C)] 653 pub struct CONTEXT_u { 654 // pub Q: [NEON128; 16], 655 pub D: [ULONG64; 32], 656 // pub S: [DWORD; 32], 657 } 658 659 pub const ARM_MAX_BREAKPOINTS: usize = 8; 660 pub const ARM_MAX_WATCHPOINTS: usize = 1; 661 662 #[repr(C)] 663 pub struct CONTEXT { 664 pub ContextFlags: DWORD, 665 pub R0: DWORD, 666 pub R1: DWORD, 667 pub R2: DWORD, 668 pub R3: DWORD, 669 pub R4: DWORD, 670 pub R5: DWORD, 671 pub R6: DWORD, 672 pub R7: DWORD, 673 pub R8: DWORD, 674 pub R9: DWORD, 675 pub R10: DWORD, 676 pub R11: DWORD, 677 pub R12: DWORD, 678 pub Sp: DWORD, 679 pub Lr: DWORD, 680 pub Pc: DWORD, 681 pub Cpsr: DWORD, 682 pub Fpsrc: DWORD, 683 pub Padding: DWORD, 684 pub u: CONTEXT_u, 685 pub Bvr: [DWORD; ARM_MAX_BREAKPOINTS], 686 pub Bcr: [DWORD; ARM_MAX_BREAKPOINTS], 687 pub Wvr: [DWORD; ARM_MAX_WATCHPOINTS], 688 pub Wcr: [DWORD; ARM_MAX_WATCHPOINTS], 689 pub Padding2: [DWORD; 2], 690 } 691 } // IFDEF(arm) 692