1mod getcontext;
2
3pub use getcontext::crash_context_getcontext;
4
5#[repr(C)]
7#[derive(Clone)]
8pub struct CrashContext {
9 pub context: ucontext_t,
26 #[cfg(not(target_arch = "arm"))]
30 pub float_state: fpregset_t,
31 pub siginfo: libc::signalfd_siginfo,
33 pub pid: libc::pid_t,
35 pub tid: libc::pid_t,
37}
38
39unsafe impl Send for CrashContext {}
40
41impl CrashContext {
42 pub fn as_bytes(&self) -> &[u8] {
43 unsafe {
44 let size = std::mem::size_of_val(self);
45 let ptr = (self as *const Self).cast();
46 std::slice::from_raw_parts(ptr, size)
47 }
48 }
49
50 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
51 if bytes.len() != std::mem::size_of::<Self>() {
52 return None;
53 }
54
55 unsafe { Some((*bytes.as_ptr().cast::<Self>()).clone()) }
56 }
57}
58
59#[repr(C)]
60#[derive(Clone)]
61#[doc(hidden)]
62pub struct sigset_t {
63 #[cfg(target_pointer_width = "32")]
64 __val: [u32; 32],
65 #[cfg(target_pointer_width = "64")]
66 __val: [u64; 16],
67}
68
69#[repr(C)]
70#[derive(Clone)]
71#[doc(hidden)]
72pub struct stack_t {
73 pub ss_sp: *mut std::ffi::c_void,
74 pub ss_flags: i32,
75 pub ss_size: usize,
76}
77
78cfg_if::cfg_if! {
79 if #[cfg(target_arch = "x86_64")] {
80 #[repr(C)]
81 #[derive(Clone)]
82 #[doc(hidden)]
83 pub struct ucontext_t {
84 pub uc_flags: u64,
85 uc_link: *mut ucontext_t,
86 pub uc_stack: stack_t,
87 pub uc_mcontext: mcontext_t,
88 pub uc_sigmask: sigset_t,
89 __private: [u8; 512],
90 __ssp: [u64; 4],
92 }
93
94 #[repr(C)]
95 #[derive(Clone)]
96 #[doc(hidden)]
97 pub struct mcontext_t {
98 pub gregs: [i64; 23],
99 pub fpregs: *mut fpregset_t,
100 __reserved: [u64; 8],
101 }
102
103 #[repr(C)]
104 #[derive(Clone)]
105 #[doc(hidden)]
106 pub struct fpregset_t {
107 pub cwd: u16,
108 pub swd: u16,
109 pub ftw: u16,
110 pub fop: u16,
111 pub rip: u64,
112 pub rdp: u64,
113 pub mxcsr: u32,
114 pub mxcr_mask: u32,
115 pub st_space: [u32; 32],
116 pub xmm_space: [u32; 64],
117 __padding: [u64; 12],
118 }
119 } else if #[cfg(target_arch = "x86")] {
120 #[repr(C)]
121 #[derive(Clone)]
122 #[doc(hidden)]
123 pub struct ucontext_t {
124 pub uc_flags: u32,
125 uc_link: *mut ucontext_t,
126 pub uc_stack: stack_t,
127 pub uc_mcontext: mcontext_t,
128 pub uc_sigmask: sigset_t,
129 pub __fpregs_mem: [u32; 28],
130 }
131
132 #[repr(C)]
133 #[derive(Clone)]
134 #[doc(hidden)]
135 pub struct mcontext_t {
136 pub gregs: [i32; 23],
137 pub fpregs: *mut fpregset_t,
138 pub oldmask: u32,
139 pub cr2: u32,
140 }
141
142 #[repr(C)]
143 #[derive(Clone)]
144 #[doc(hidden)]
145 pub struct fpreg_t {
146 pub significand: [u16; 4],
147 pub exponent: u16,
148 }
149
150 #[repr(C)]
151 #[derive(Clone)]
152 #[doc(hidden)]
153 pub struct fpregset_t {
154 pub cw: u32,
155 pub sw: u32,
156 pub tag: u32,
157 pub ipoff: u32,
158 pub cssel: u32,
159 pub dataoff: u32,
160 pub datasel: u32,
161 pub _st: [fpreg_t; 8],
162 pub status: u32,
163 }
164 } else if #[cfg(target_arch = "aarch64")] {
165 #[repr(C)]
166 #[derive(Clone)]
167 #[doc(hidden)]
168 pub struct ucontext_t {
169 pub uc_flags: u64,
170 uc_link: *mut ucontext_t,
171 pub uc_stack: stack_t,
172 pub uc_sigmask: sigset_t,
173 pub uc_mcontext: mcontext_t,
174 }
175
176 #[repr(C)]
182 #[derive(Clone)]
183 #[doc(hidden)]
184 pub struct mcontext_t {
185 pub fault_address: u64,
187 pub regs: [u64; 31],
188 pub sp: u64,
189 pub pc: u64,
190 pub pstate: u64,
191 pub __reserved: [u128; 256],
194 }
195
196 #[doc(hidden)]
198 pub const FPSIMD_MAGIC: u32 = 0x46508001;
199
200 #[repr(C)]
201 #[derive(Clone)]
202 #[doc(hidden)]
203 pub struct _aarch64_ctx {
204 pub magic: u32,
205 pub size: u32,
206 }
207
208 #[repr(C)]
209 #[derive(Clone)]
210 #[doc(hidden)]
211 pub struct fpsimd_context {
212 pub head: _aarch64_ctx,
213 pub fpsr: u32,
214 pub fpcr: u32,
215 pub vregs: [u128; 32],
216 }
217
218 #[doc(hidden)]
219 pub type fpregset_t = fpsimd_context;
220 } else if #[cfg(target_arch = "arm")] {
221 #[repr(C)]
222 #[derive(Clone)]
223 #[doc(hidden)]
224 pub struct ucontext_t {
225 pub uc_flags: u32,
226 uc_link: *mut ucontext_t,
227 pub uc_stack: stack_t,
228 pub uc_mcontext: mcontext_t,
231 pub uc_sigmask: sigset_t,
232 pub uc_regspace: [u64; 64],
233 }
234
235 #[repr(C)]
236 #[derive(Clone)]
237 #[doc(hidden)]
238 pub struct mcontext_t {
239 pub trap_no: u32,
240 pub error_code: u32,
241 pub oldmask: u32,
242 pub arm_r0: u32,
243 pub arm_r1: u32,
244 pub arm_r2: u32,
245 pub arm_r3: u32,
246 pub arm_r4: u32,
247 pub arm_r5: u32,
248 pub arm_r6: u32,
249 pub arm_r7: u32,
250 pub arm_r8: u32,
251 pub arm_r9: u32,
252 pub arm_r10: u32,
253 pub arm_fp: u32,
254 pub arm_ip: u32,
255 pub arm_sp: u32,
256 pub arm_lr: u32,
257 pub arm_pc: u32,
258 pub arm_cpsr: u32,
259 pub fault_address: u32,
260 }
261 } else if #[cfg(target_arch = "riscv64")] {
262 #[repr(C)]
263 #[derive(Clone)]
264 #[doc(hidden)]
265 pub struct ucontext_t {
266 pub __uc_flags: u64,
267 pub uc_link: *mut ucontext_t,
268 pub uc_stack: stack_t,
269 pub uc_sigmask: sigset_t,
270 pub uc_mcontext: mcontext_t,
271 }
272
273 #[repr(C, align(16))]
274 #[derive(Clone)]
275 #[doc(hidden)]
276 pub struct mcontext_t {
277 pub __gregs: [u64; 32],
278 pub __fpregs: __riscv_mc_fp_state,
279 }
280
281 #[repr(C)]
282 #[derive(Clone, Copy)]
283 #[doc(hidden)]
284 pub union __riscv_mc_fp_state {
285 pub __f: __riscv_mc_f_ext_state,
286 pub __d: __riscv_mc_d_ext_state,
287 pub __q: __riscv_mc_q_ext_state,
288 }
289
290 #[repr(C)]
291 #[derive(Clone, Copy)]
292 #[doc(hidden)]
293 pub struct __riscv_mc_f_ext_state {
294 pub __f: [u32; 32],
295 pub __fcsr: u32,
296 }
297
298 #[repr(C)]
299 #[derive(Clone, Copy)]
300 #[doc(hidden)]
301 pub struct __riscv_mc_d_ext_state {
302 pub __f: [u64; 32],
303 pub __fcsr: u32,
304 }
305
306 #[repr(C, align(16))]
307 #[derive(Clone, Copy)]
308 #[doc(hidden)]
309 pub struct __riscv_mc_q_ext_state {
310 pub __f: [u64; 64],
311 pub __fcsr: u32,
312 pub __reserved: [u32; 3],
313 }
314
315 pub type fpregset_t = __riscv_mc_fp_state;
316 } else if #[cfg(target_arch = "s390x")] {
317 #[repr(C)]
318 #[derive(Clone)]
319 #[doc(hidden)]
320 pub struct ucontext_t {
321 pub uc_flags: u64,
322 pub uc_link: *mut ucontext_t,
323 pub uc_stack: stack_t,
324 pub uc_mcontext: mcontext_t,
325 pub uc_sigmask: sigset_t,
326 }
327
328 #[repr(C, align(8))]
329 #[derive(Clone,Copy)]
330 #[doc(hidden)]
331 pub struct mcontext_t {
332 pub psw: psw_t,
333 pub gregs: [u64; 16],
334 pub aregs: [u32; 16],
335 pub __fpregs: fpregset_t,
336 }
337
338 #[repr(C)]
339 #[derive(Clone,Copy)]
340 #[doc(hidden)]
341 pub struct fpregset_t {
342 pub fpc: u32,
343 __pad: u32,
344 pub fprs: [fpreg_t; 16],
345 }
346
347 #[repr(C)]
348 #[derive(Clone,Copy)]
349 #[doc(hidden)]
350 pub struct fpreg_t {
351 pub d: f64,
352 }
354
355 #[repr(C)]
356 #[derive(Clone,Copy)]
357 #[doc(hidden)]
358 pub struct psw_t {
359 pub mask: u64,
360 pub addr: u64,
361 }
362 }
363}
364
365#[cfg(test)]
366mod test {
367 #[cfg(not(target_env = "musl"))]
369 #[test]
370 fn matches_libc() {
371 assert_eq!(
372 std::mem::size_of::<libc::ucontext_t>(),
373 std::mem::size_of::<super::ucontext_t>()
374 );
375 }
376}