Skip to main content

jmp_scape/
glibc_compat.rs

1use core::marker::PhantomData;
2
3// glibc `__jmp_buf` is architecture-specific (see e.g. sysdeps/*/bits/setjmp.h).
4// Linux aarch64 uses `unsigned long long __jmp_buf[22]`; x86_64 uses `long long[8]`.
5// This module is only used as `struct_defs` on Linux (`lib.rs`); other OSes still
6// compile it with a placeholder length.
7#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
8const JMP_BUF_U64_LEN: usize = 22;
9#[cfg(all(target_os = "linux", not(target_arch = "aarch64")))]
10const JMP_BUF_U64_LEN: usize = 8;
11#[cfg(not(target_os = "linux"))]
12const JMP_BUF_U64_LEN: usize = 8;
13
14/// `JmpBufFields` are the accessible fields when viewed via a JmpBuf pointer.
15/// But also: You shouldn't be poking at these!
16#[repr(C)]
17pub struct JmpBufFields {
18    _buf: [u64; JMP_BUF_U64_LEN],
19    _neither_send_nor_sync: PhantomData<*const u8>,
20}
21
22/// `SigJmpBufFields` are the accessible fields when viewed via a SigJmpBuf pointer.
23/// But also: You shouldn't be poking at these!
24#[repr(C)]
25pub struct SigJmpBufFields {
26    // This *must* be the first field. We allow `SigJmpBuf` to be transmuted to
27    // a `JmpBuf` and then back again depending on the host libc. (e.g. glibc
28    // has setjmp as a shallow wrapper around sigsetjmp, and will write to
29    // fields past the `__jmp_buf`).
30    __jmp_buf: JmpBufFields,
31    __mask_was_saved: isize,
32    __saved_mask: libc::sigset_t,
33}
34
35/// This is the type you use to allocate a JmpBuf on the stack.
36/// (Glibc puns the two.)
37pub type JmpBufStruct = SigJmpBufFields;
38
39/// This is the type you use to allocate a SigJmpBuf on the stack.
40pub type SigJmpBufStruct = SigJmpBufFields;