Set uc_stack properly.
POSIX does not appear to explicitly mention that this should be the sigaltstack, but other Linux appears to treat it as the sigaltstack.
This commit is contained in:
@@ -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);
|
||||
|
||||
+42
-9
@@ -52,6 +52,34 @@ pub struct PosixStackt {
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
pub const SS_ONSTACK: usize = 1;
|
||||
pub const SS_DISABLE: usize = 2;
|
||||
|
||||
impl From<Sigaltstack> 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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(())
|
||||
|
||||
Reference in New Issue
Block a user