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 }
91
92 #[repr(C)]
93 #[derive(Clone)]
94 #[doc(hidden)]
95 pub struct mcontext_t {
96 pub gregs: [i64; 23],
97 pub fpregs: *mut fpregset_t,
98 __reserved: [u64; 8],
99 }
100
101 #[repr(C)]
102 #[derive(Clone)]
103 #[doc(hidden)]
104 pub struct fpregset_t {
105 pub cwd: u16,
106 pub swd: u16,
107 pub ftw: u16,
108 pub fop: u16,
109 pub rip: u64,
110 pub rdp: u64,
111 pub mxcsr: u32,
112 pub mxcr_mask: u32,
113 pub st_space: [u32; 32],
114 pub xmm_space: [u32; 64],
115 __padding: [u64; 12],
116 }
117 } else if #[cfg(target_arch = "x86")] {
118 #[repr(C)]
119 #[derive(Clone)]
120 #[doc(hidden)]
121 pub struct ucontext_t {
122 pub uc_flags: u32,
123 uc_link: *mut ucontext_t,
124 pub uc_stack: stack_t,
125 pub uc_mcontext: mcontext_t,
126 pub uc_sigmask: sigset_t,
127 pub __fpregs_mem: [u32; 28],
128 }
129
130 #[repr(C)]
131 #[derive(Clone)]
132 #[doc(hidden)]
133 pub struct mcontext_t {
134 pub gregs: [i32; 23],
135 pub fpregs: *mut fpregset_t,
136 pub oldmask: u32,
137 pub cr2: u32,
138 }
139
140 #[repr(C)]
141 #[derive(Clone)]
142 #[doc(hidden)]
143 pub struct fpreg_t {
144 pub significand: [u16; 4],
145 pub exponent: u16,
146 }
147
148 #[repr(C)]
149 #[derive(Clone)]
150 #[doc(hidden)]
151 pub struct fpregset_t {
152 pub cw: u32,
153 pub sw: u32,
154 pub tag: u32,
155 pub ipoff: u32,
156 pub cssel: u32,
157 pub dataoff: u32,
158 pub datasel: u32,
159 pub _st: [fpreg_t; 8],
160 pub status: u32,
161 }
162 } else if #[cfg(target_arch = "aarch64")] {
163 #[repr(C)]
164 #[derive(Clone)]
165 #[doc(hidden)]
166 pub struct ucontext_t {
167 pub uc_flags: u64,
168 uc_link: *mut ucontext_t,
169 pub uc_stack: stack_t,
170 pub uc_sigmask: sigset_t,
171 pub uc_mcontext: mcontext_t,
172 }
173
174 #[repr(C)]
180 #[derive(Clone)]
181 #[doc(hidden)]
182 pub struct mcontext_t {
183 pub fault_address: u64,
185 pub regs: [u64; 31],
186 pub sp: u64,
187 pub pc: u64,
188 pub pstate: u64,
189 pub __reserved: [u128; 256],
192 }
193
194 #[doc(hidden)]
196 pub const FPSIMD_MAGIC: u32 = 0x46508001;
197
198 #[repr(C)]
199 #[derive(Clone)]
200 #[doc(hidden)]
201 pub struct _aarch64_ctx {
202 pub magic: u32,
203 pub size: u32,
204 }
205
206 #[repr(C)]
207 #[derive(Clone)]
208 #[doc(hidden)]
209 pub struct fpsimd_context {
210 pub head: _aarch64_ctx,
211 pub fpsr: u32,
212 pub fpcr: u32,
213 pub vregs: [u128; 32],
214 }
215
216 #[doc(hidden)]
217 pub type fpregset_t = fpsimd_context;
218 } else if #[cfg(target_arch = "arm")] {
219 #[repr(C)]
220 #[derive(Clone)]
221 #[doc(hidden)]
222 pub struct ucontext_t {
223 pub uc_flags: u32,
224 uc_link: *mut ucontext_t,
225 pub uc_stack: stack_t,
226 pub uc_mcontext: mcontext_t,
229 pub uc_sigmask: sigset_t,
230 pub uc_regspace: [u64; 64],
231 }
232
233 #[repr(C)]
234 #[derive(Clone)]
235 #[doc(hidden)]
236 pub struct mcontext_t {
237 pub trap_no: u32,
238 pub error_code: u32,
239 pub oldmask: u32,
240 pub arm_r0: u32,
241 pub arm_r1: u32,
242 pub arm_r2: u32,
243 pub arm_r3: u32,
244 pub arm_r4: u32,
245 pub arm_r5: u32,
246 pub arm_r6: u32,
247 pub arm_r7: u32,
248 pub arm_r8: u32,
249 pub arm_r9: u32,
250 pub arm_r10: u32,
251 pub arm_fp: u32,
252 pub arm_ip: u32,
253 pub arm_sp: u32,
254 pub arm_lr: u32,
255 pub arm_pc: u32,
256 pub arm_cpsr: u32,
257 pub fault_address: u32,
258 }
259 }
260}
261
262#[cfg(test)]
263mod test {
264 #[cfg(not(target_env = "musl"))]
266 #[test]
267 fn matches_libc() {
268 assert_eq!(
269 std::mem::size_of::<libc::ucontext_t>(),
270 std::mem::size_of::<super::ucontext_t>()
271 );
272 }
273}