Skip to content

Commit e0fbf1b

Browse files
committed
generic-sandbox: Fix signal handling on macOS
ucontext_t is different on macOS and Linux. On macOS, SIGSEGV is not sent for page faults, instead SIGBUS is sent. This commit updates the signal handler to check for SIGBUS on macOS. Finally, we also fix the page fault address extraction on macOS. Signed-off-by: Aman <[email protected]>
1 parent d4219f8 commit e0fbf1b

File tree

1 file changed

+74
-19
lines changed

1 file changed

+74
-19
lines changed

crates/polkavm/src/sandbox/generic.rs

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,61 @@ unsafe extern "C" fn signal_handler(signal: c_int, info: &sys::siginfo_t, contex
325325

326326
let vmctx = THREAD_VMCTX.with(|thread_ctx| *thread_ctx.get());
327327
if !vmctx.is_null() {
328+
#[cfg(target_os = "macos")]
329+
macro_rules! macos_reg_field {
330+
(rax) => {
331+
(*context.uc_mcontext).__ss.__rax
332+
};
333+
(rbx) => {
334+
(*context.uc_mcontext).__ss.__rbx
335+
};
336+
(rcx) => {
337+
(*context.uc_mcontext).__ss.__rcx
338+
};
339+
(rdx) => {
340+
(*context.uc_mcontext).__ss.__rdx
341+
};
342+
(rdi) => {
343+
(*context.uc_mcontext).__ss.__rdi
344+
};
345+
(rsi) => {
346+
(*context.uc_mcontext).__ss.__rsi
347+
};
348+
(rbp) => {
349+
(*context.uc_mcontext).__ss.__rbp
350+
};
351+
(rsp) => {
352+
(*context.uc_mcontext).__ss.__rsp
353+
};
354+
(r8) => {
355+
(*context.uc_mcontext).__ss.__r8
356+
};
357+
(r9) => {
358+
(*context.uc_mcontext).__ss.__r9
359+
};
360+
(r10) => {
361+
(*context.uc_mcontext).__ss.__r10
362+
};
363+
(r11) => {
364+
(*context.uc_mcontext).__ss.__r11
365+
};
366+
(r12) => {
367+
(*context.uc_mcontext).__ss.__r12
368+
};
369+
(r13) => {
370+
(*context.uc_mcontext).__ss.__r13
371+
};
372+
(r14) => {
373+
(*context.uc_mcontext).__ss.__r14
374+
};
375+
(r15) => {
376+
(*context.uc_mcontext).__ss.__r15
377+
};
378+
(rip) => {
379+
(*context.uc_mcontext).__ss.__rip
380+
};
381+
}
382+
328383
macro_rules! fetch_reg {
329384
($reg:ident) => {{
330385
#[cfg(target_os = "linux")]
@@ -333,7 +388,7 @@ unsafe extern "C" fn signal_handler(signal: c_int, info: &sys::siginfo_t, contex
333388
}
334389
#[cfg(target_os = "macos")]
335390
{
336-
(*context.uc_mcontext).__ss.$reg as u64
391+
macos_reg_field!($reg) as u64
337392
}
338393
#[cfg(target_os = "freebsd")]
339394
{
@@ -343,19 +398,19 @@ unsafe extern "C" fn signal_handler(signal: c_int, info: &sys::siginfo_t, contex
343398
}
344399

345400
const X86_TRAP_PF: u64 = 14;
346-
let is_page_fault = signal == sys::SIGSEGV && {
401+
let is_page_fault = {
347402
#[cfg(target_os = "linux")]
348403
{
349-
context.uc_mcontext.trapno == X86_TRAP_PF
404+
signal == sys::SIGSEGV && context.uc_mcontext.trapno == X86_TRAP_PF
405+
}
406+
#[cfg(target_os = "macos")]
407+
{
408+
signal == sys::SIGBUS && (*context.uc_mcontext).__es.__trapno as u64 == X86_TRAP_PF
409+
}
410+
#[cfg(target_os = "freebsd")]
411+
{
412+
signal == sys::SIGBUS && context.uc_mcontext.mc_trapno == X86_TRAP_PF
350413
}
351-
// #[cfg(target_os = "macos")]
352-
// {
353-
// (*context.uc_mcontext).__ss.trapno == X86_TRAP_PF
354-
// }
355-
// #[cfg(target_os = "freebsd")]
356-
// {
357-
// context.uc_mcontext.mc_trapno == X86_TRAP_PF
358-
// }
359414
};
360415

361416
let rip = fetch_reg!(rip);
@@ -401,14 +456,14 @@ unsafe extern "C" fn signal_handler(signal: c_int, info: &sys::siginfo_t, contex
401456
{
402457
info.__bindgen_anon_1.__bindgen_anon_1._sifields._sigfault._addr as u64
403458
}
404-
// #[cfg(target_os = "macos")]
405-
// {
406-
// info.si_addr as u64
407-
// }
408-
// #[cfg(target_os = "freebsd")]
409-
// {
410-
// info.si_addr as u64
411-
// }
459+
#[cfg(target_os = "macos")]
460+
{
461+
info.si_addr as u64
462+
}
463+
#[cfg(target_os = "freebsd")]
464+
{
465+
info.si_addr as u64
466+
}
412467
};
413468

414469
log::trace!("Page fault at 0x{fault_address:x} (rip: 0x{rip:x})");

0 commit comments

Comments
 (0)