diff --git a/lib/llvm-backend/src/platform/unix.rs b/lib/llvm-backend/src/platform/unix.rs index 6b6f8356e..585797b0a 100644 --- a/lib/llvm-backend/src/platform/unix.rs +++ b/lib/llvm-backend/src/platform/unix.rs @@ -61,81 +61,11 @@ extern "C" fn signal_trap_handler( ucontext: *mut c_void, ) { unsafe { - /// By setting the instruction pointer of the interrupted context - /// to `throw_trap` and the register of the first argument - /// to the trap ID, we can approximate throwing an exception - /// from a signal handler. - set_context_to_throw(ucontext); + /// Apparently, we can unwind from arbitary instructions, as long + /// as we don't need to catch the exception inside the function that + /// was interrupted. + /// + /// This works on macos, not sure about linux. + throw_trap(2); } } - -#[cfg(all(target_os = "linux", target_arch = "x86_64"))] -unsafe fn set_context_to_throw(ucontext: *mut c_void) { - use libc::{ucontext_t, RDI, RIP}; - - let ucontext = ucontext as *mut ucontext_t; - (*ucontext).uc_mcontext.gregs[RIP as usize] = throw_trap as u64; - (*ucontext).uc_mcontext.gregs[RDI as usize] = 2; // `MemoryOutOfBounds` variant. -} - -#[cfg(all(target_os = "macos", target_arch = "x86_64"))] -unsafe fn set_context_to_throw(ucontext: *mut c_void) { - #[allow(dead_code)] - #[repr(C)] - struct ucontext_t { - uc_onstack: u32, - uc_sigmask: u32, - uc_stack: libc::stack_t, - uc_link: *const ucontext_t, - uc_mcsize: u64, - uc_mcontext: *mut mcontext_t, - } - #[repr(C)] - struct exception_state { - trapno: u16, - cpu: u16, - err: u32, - faultvaddr: u64, - } - #[repr(C)] - struct regs { - rax: u64, - rbx: u64, - rcx: u64, - rdx: u64, - rdi: u64, - rsi: u64, - rbp: u64, - rsp: u64, - r8: u64, - r9: u64, - r10: u64, - r11: u64, - r12: u64, - r13: u64, - r14: u64, - r15: u64, - rip: u64, - rflags: u64, - cs: u64, - fs: u64, - gs: u64, - } - #[allow(dead_code)] - #[repr(C)] - struct mcontext_t { - es: exception_state, - ss: regs, - // ... - } - - let ucontext = ucontext as *mut ucontext_t; - (*(*ucontext).uc_mcontext).ss.rip = throw_trap as u64; - (*(*ucontext).uc_mcontext).ss.rdi = 2; // `MemoryOutOfBounds` variant. -} - -#[cfg(not(any( - all(target_os = "macos", target_arch = "x86_64"), - all(target_os = "linux", target_arch = "x86_64"), -)))] -compile_error!("This crate doesn't yet support compiling on operating systems other than linux and macos and architectures other than x86_64");