diff --git a/redox-rt/src/arch/x86_64.rs b/redox-rt/src/arch/x86_64.rs index eca4991f41..56cebb8f8c 100644 --- a/redox-rt/src/arch/x86_64.rs +++ b/redox-rt/src/arch/x86_64.rs @@ -12,7 +12,10 @@ use syscall::{ use crate::{ proc::{fork_inner, FdGuard}, - signal::{inner_c, PosixStackt, RtSigarea, SigStack, PROC_CONTROL_STRUCT}, + signal::{ + get_sigaltstack, inner_c, PosixStackt, RtSigarea, SigStack, Sigaltstack, + PROC_CONTROL_STRUCT, + }, RtTcb, Tcb, }; @@ -452,11 +455,7 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt stack.regs.rip = area.tmp_rip; } - PosixStackt { - sp: stack.regs.rsp as *mut (), - size: 0, // TODO - flags: 0, // TODO - } + get_sigaltstack(area, stack.regs.rsp).into() } pub(crate) static SUPPORTS_AVX: AtomicU8 = AtomicU8::new(0); diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index 6a8b484bae..938f8ce3dc 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -52,6 +52,34 @@ pub struct PosixStackt { pub size: usize, } +pub const SS_ONSTACK: usize = 1; +pub const SS_DISABLE: usize = 2; + +impl From for PosixStackt { + fn from(value: Sigaltstack) -> Self { + match value { + Sigaltstack::Disabled => PosixStackt { + sp: core::ptr::null_mut(), + size: 0, + flags: SS_DISABLE.try_into().unwrap(), + }, + Sigaltstack::Enabled { + onstack, + base, + size, + } => PosixStackt { + sp: base.cast(), + size, + flags: if onstack { + SS_ONSTACK.try_into().unwrap() + } else { + 0 + }, + }, + } + } +} + #[repr(C)] // TODO: This struct is for practical reasons locked to Linux's ABI, but avoid redefining // it here. Alternatively, check at compile time that the structs are equivalent. @@ -590,6 +618,19 @@ pub enum Sigaltstack { size: usize, }, } + +pub(crate) fn get_sigaltstack(tcb: &SigArea, sp: usize) -> Sigaltstack { + if tcb.altstack_bottom == 0 && tcb.altstack_top == usize::MAX { + Sigaltstack::Disabled + } else { + Sigaltstack::Enabled { + base: tcb.altstack_bottom as *mut (), + size: tcb.altstack_top - tcb.altstack_bottom, + onstack: (tcb.altstack_bottom..tcb.altstack_top).contains(&sp), + } + } +} + pub unsafe fn sigaltstack( new: Option<&Sigaltstack>, old_out: Option<&mut Sigaltstack>, @@ -597,15 +638,7 @@ pub unsafe fn sigaltstack( let _g = tmp_disable_signals(); let tcb = &mut *Tcb::current().unwrap().os_specific.arch.get(); - let old = if tcb.altstack_bottom == 0 && tcb.altstack_top == usize::MAX { - Sigaltstack::Disabled - } else { - Sigaltstack::Enabled { - base: tcb.altstack_bottom as *mut (), - size: tcb.altstack_top - tcb.altstack_bottom, - onstack: (tcb.altstack_bottom..tcb.altstack_top).contains(&crate::arch::current_sp()), - } - }; + let old = get_sigaltstack(tcb, crate::arch::current_sp()); if matches!(old, Sigaltstack::Enabled { onstack: true, .. }) && new != Some(&old) { return Err(Error::new(EPERM)); diff --git a/src/header/signal/redox.rs b/src/header/signal/redox.rs index 3ed2033f55..fe08477605 100644 --- a/src/header/signal/redox.rs +++ b/src/header/signal/redox.rs @@ -50,6 +50,15 @@ pub const SA_NOCLDSTOP: usize = 0x4000_0000; pub const SS_ONSTACK: usize = 0x00000001; pub const SS_DISABLE: usize = 0x00000002; +const _: () = { + if SS_ONSTACK != redox_rt::signal::SS_ONSTACK { + panic!(); + } + if SS_DISABLE != redox_rt::signal::SS_DISABLE { + panic!(); + } +}; + // TODO: It's just a guess based on Linux pub const MINSIGSTKSZ: usize = 2048; pub const SIGSTKSZ: usize = 8096; diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index f9aed39380..de89f58455 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -1,6 +1,6 @@ use core::mem::{self, offset_of}; use redox_rt::signal::{ - SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler, + PosixStackt, SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler, }; use syscall::{self, Result}; @@ -235,21 +235,11 @@ impl PalSignal for Sys { redox_rt::signal::sigaltstack(new.as_ref(), old.as_mut())?; if let (Some(old_c_stack), Some(old)) = (old_c, old) { - *old_c_stack = match old { - Sigaltstack::Disabled => stack_t { - ss_sp: core::ptr::null_mut(), - ss_size: 0, - ss_flags: SS_DISABLE.try_into().unwrap(), - }, - Sigaltstack::Enabled { - onstack, - base, - size, - } => stack_t { - ss_sp: base.cast(), - ss_size: size, - ss_flags: SS_ONSTACK.try_into().unwrap(), - }, + let c_stack = PosixStackt::from(old); + *old_c_stack = stack_t { + ss_sp: c_stack.sp.cast(), + ss_size: c_stack.size, + ss_flags: c_stack.flags, }; } Ok(())