sjlj2/
x86_64.rs

1// rbx, rsp, rbp, lander
2#[repr(transparent)]
3pub(crate) struct Buf(pub [usize; 4]);
4
5macro_rules! set_jump_raw {
6    ($buf_ptr:expr, $func:expr, $lander:block) => {
7        core::arch::asm!(
8            "lea rax, [rip + {lander}]",
9            "mov [rdi     ], rbx",
10            "mov [rdi +  8], rsp",
11            "mov [rdi + 16], rbp",
12            "mov [rdi + 24], rax",
13            "call {func}",
14
15            in("rdi") $buf_ptr, // arg0
16            func = sym $func,
17            lander = label $lander,
18
19            // Clobber more default callee saved registers.
20            // lateout("bx") _, // LLVM reserved.
21            // lateout("sp") _, // sp
22            // lateout("bp") _, // LLVM reserved.
23            lateout("r12") _,
24            lateout("r13") _,
25            lateout("r14") _,
26            lateout("r15") _,
27
28            // Default caller saved registers.
29            clobber_abi("sysv64"),
30        )
31    };
32}
33
34#[inline]
35pub(crate) unsafe fn long_jump_raw(jp: *mut (), data: usize) -> ! {
36    unsafe {
37        maybe_strip_cfi!(
38            (core::arch::asm!),
39
40            [".cfi_remember_state"],
41            [".cfi_undefined rip"],
42            "mov rbx, [rcx     ]",
43            "mov rsp, [rcx +  8]",
44            "mov rbp, [rcx + 16]",
45            "mov [rcx], rax",
46            "jmp qword ptr [rcx + 24]",
47            [".cfi_restore_state"],
48            [],
49
50            in("cx") jp,
51            in("ax") data,
52            options(noreturn, nostack),
53        )
54    }
55}