crash_context/
windows.rs

1/// Full Windows crash context
2pub struct CrashContext {
3    /// The information on the exception.
4    ///
5    /// Note that this is a pointer into the actual memory of the crashed process,
6    /// and is a pointer to an [EXCEPTION_POINTERS](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_pointers)
7    pub exception_pointers: *const EXCEPTION_POINTERS,
8    /// The top level exception code from the `exception_pointers`. This is provided
9    /// so that external processes don't need to use `ReadProcessMemory` to inspect
10    /// the exception code
11    pub exception_code: i32,
12    /// The pid of the process that crashed
13    pub process_id: u32,
14    /// The thread id on which the exception occurred
15    pub thread_id: u32,
16}
17
18#[link(name = "kernel32")]
19extern "system" {
20    #[link_name = "RtlCaptureContext"]
21    pub fn capture_context(ctx_rec: *mut CONTEXT);
22}
23
24cfg_if::cfg_if! {
25    if #[cfg(target_arch = "x86_64")] {
26        #[repr(C, align(16))]
27        pub struct M128A {
28            pub Low: u64,
29            pub High: i64,
30        }
31
32        #[repr(C)]
33        pub struct CONTEXT_0_0 {
34            pub Header: [M128A; 2],
35            pub Legacy: [M128A; 8],
36            pub Xmm0: M128A,
37            pub Xmm1: M128A,
38            pub Xmm2: M128A,
39            pub Xmm3: M128A,
40            pub Xmm4: M128A,
41            pub Xmm5: M128A,
42            pub Xmm6: M128A,
43            pub Xmm7: M128A,
44            pub Xmm8: M128A,
45            pub Xmm9: M128A,
46            pub Xmm10: M128A,
47            pub Xmm11: M128A,
48            pub Xmm12: M128A,
49            pub Xmm13: M128A,
50            pub Xmm14: M128A,
51            pub Xmm15: M128A,
52        }
53
54        #[repr(C, align(16))]
55        pub struct XSAVE_FORMAT {
56            pub ControlWord: u16,
57            pub StatusWord: u16,
58            pub TagWord: u8,
59            pub Reserved1: u8,
60            pub ErrorOpcode: u16,
61            pub ErrorOffset: u32,
62            pub ErrorSelector: u16,
63            pub Reserved2: u16,
64            pub DataOffset: u32,
65            pub DataSelector: u16,
66            pub Reserved3: u16,
67            pub MxCsr: u32,
68            pub MxCsr_Mask: u32,
69            pub FloatRegisters: [M128A; 8],
70            pub XmmRegisters: [M128A; 16],
71            pub Reserved4: [u8; 96],
72        }
73
74        #[repr(C)]
75        pub union CONTEXT_0 {
76            pub FltSave: std::mem::ManuallyDrop<XSAVE_FORMAT>,
77            pub Anonymous: std::mem::ManuallyDrop<CONTEXT_0_0>,
78        }
79
80        #[repr(C, align(16))]
81        pub struct CONTEXT {
82            pub P1Home: u64,
83            pub P2Home: u64,
84            pub P3Home: u64,
85            pub P4Home: u64,
86            pub P5Home: u64,
87            pub P6Home: u64,
88            pub ContextFlags: u32,
89            pub MxCsr: u32,
90            pub SegCs: u16,
91            pub SegDs: u16,
92            pub SegEs: u16,
93            pub SegFs: u16,
94            pub SegGs: u16,
95            pub SegSs: u16,
96            pub EFlags: u32,
97            pub Dr0: u64,
98            pub Dr1: u64,
99            pub Dr2: u64,
100            pub Dr3: u64,
101            pub Dr6: u64,
102            pub Dr7: u64,
103            pub Rax: u64,
104            pub Rcx: u64,
105            pub Rdx: u64,
106            pub Rbx: u64,
107            pub Rsp: u64,
108            pub Rbp: u64,
109            pub Rsi: u64,
110            pub Rdi: u64,
111            pub R8: u64,
112            pub R9: u64,
113            pub R10: u64,
114            pub R11: u64,
115            pub R12: u64,
116            pub R13: u64,
117            pub R14: u64,
118            pub R15: u64,
119            pub Rip: u64,
120            pub Anonymous: CONTEXT_0,
121            pub VectorRegister: [M128A; 26],
122            pub VectorControl: u64,
123            pub DebugControl: u64,
124            pub LastBranchToRip: u64,
125            pub LastBranchFromRip: u64,
126            pub LastExceptionToRip: u64,
127            pub LastExceptionFromRip: u64,
128        }
129    } else if #[cfg(target_arch = "x86")] {
130        #[repr(C)]
131        pub struct FLOATING_SAVE_AREA {
132            pub ControlWord: u32,
133            pub StatusWord: u32,
134            pub TagWord: u32,
135            pub ErrorOffset: u32,
136            pub ErrorSelector: u32,
137            pub DataOffset: u32,
138            pub DataSelector: u32,
139            pub RegisterArea: [u8; 80],
140            pub Spare0: u32,
141        }
142
143        #[repr(C, packed(4))]
144        pub struct CONTEXT {
145            pub ContextFlags: u32,
146            pub Dr0: u32,
147            pub Dr1: u32,
148            pub Dr2: u32,
149            pub Dr3: u32,
150            pub Dr6: u32,
151            pub Dr7: u32,
152            pub FloatSave: FLOATING_SAVE_AREA,
153            pub SegGs: u32,
154            pub SegFs: u32,
155            pub SegEs: u32,
156            pub SegDs: u32,
157            pub Edi: u32,
158            pub Esi: u32,
159            pub Ebx: u32,
160            pub Edx: u32,
161            pub Ecx: u32,
162            pub Eax: u32,
163            pub Ebp: u32,
164            pub Eip: u32,
165            pub SegCs: u32,
166            pub EFlags: u32,
167            pub Esp: u32,
168            pub SegSs: u32,
169            pub ExtendedRegisters: [u8; 512],
170        }
171    } else if #[cfg(target_arch = "aarch64")] {
172        #[repr(C)]
173        pub struct ARM64_NT_NEON128_0 {
174            pub Low: u64,
175            pub High: i64,
176        }
177        #[repr(C)]
178        pub union ARM64_NT_NEON128 {
179            pub Anonymous: std::mem::ManuallyDrop<ARM64_NT_NEON128_0>,
180            pub D: [f64; 2],
181            pub S: [f32; 4],
182            pub H: [u16; 8],
183            pub B: [u8; 16],
184        }
185
186        #[repr(C)]
187        pub struct CONTEXT_0_0 {
188            pub X0: u64,
189            pub X1: u64,
190            pub X2: u64,
191            pub X3: u64,
192            pub X4: u64,
193            pub X5: u64,
194            pub X6: u64,
195            pub X7: u64,
196            pub X8: u64,
197            pub X9: u64,
198            pub X10: u64,
199            pub X11: u64,
200            pub X12: u64,
201            pub X13: u64,
202            pub X14: u64,
203            pub X15: u64,
204            pub X16: u64,
205            pub X17: u64,
206            pub X18: u64,
207            pub X19: u64,
208            pub X20: u64,
209            pub X21: u64,
210            pub X22: u64,
211            pub X23: u64,
212            pub X24: u64,
213            pub X25: u64,
214            pub X26: u64,
215            pub X27: u64,
216            pub X28: u64,
217            pub Fp: u64,
218            pub Lr: u64,
219        }
220
221        #[repr(C)]
222        pub union CONTEXT_0 {
223            pub Anonymous: std::mem::ManuallyDrop<CONTEXT_0_0>,
224            pub X: [u64; 31],
225        }
226
227        #[repr(C, align(16))]
228        pub struct CONTEXT {
229            pub ContextFlags: u32,
230            pub Cpsr: u32,
231            pub Anonymous: CONTEXT_0,
232            pub Sp: u64,
233            pub Pc: u64,
234            pub V: [ARM64_NT_NEON128; 32],
235            pub Fpcr: u32,
236            pub Fpsr: u32,
237            pub Bcr: [u32; 8],
238            pub Bvr: [u64; 8],
239            pub Wcr: [u32; 2],
240            pub Wvr: [u64; 2],
241        }
242    }
243}
244
245pub type NTSTATUS = i32;
246pub type BOOL = i32;
247
248#[repr(C)]
249pub struct EXCEPTION_RECORD {
250    pub ExceptionCode: NTSTATUS,
251    pub ExceptionFlags: u32,
252    pub ExceptionRecord: *mut EXCEPTION_RECORD,
253    pub ExceptionAddress: *mut std::ffi::c_void,
254    pub NumberParameters: u32,
255    pub ExceptionInformation: [usize; 15],
256}
257
258#[repr(C)]
259pub struct EXCEPTION_POINTERS {
260    pub ExceptionRecord: *mut EXCEPTION_RECORD,
261    pub ContextRecord: *mut CONTEXT,
262}