1
0
mirror of https://github.com/rcore-os/rCore.git synced 2025-01-18 17:07:04 +04:00

Document and cleanup signal code

This commit is contained in:
Jiajie Chen 2020-06-29 11:49:03 +08:00
parent 68609a0f7c
commit 7ba001a0fa
3 changed files with 41 additions and 40 deletions

View File

@ -134,7 +134,7 @@ pub fn handle_signal(thread: &Arc<Thread>, tf: &mut UserContext) -> bool {
.iter()
.enumerate()
.find_map(|(idx, &(info, tid))| {
if tid == -1
if (tid == -1 || tid as usize == thread.tid)
&& !thread
.inner
.lock()
@ -184,15 +184,27 @@ pub fn handle_signal(thread: &Arc<Thread>, tf: &mut UserContext) -> bool {
_ => {
info!("goto handler at {:#x}", action.handler);
thread.inner.lock().signal_alternate_stack.flags |=
SignalStackFlags::ONSTACK.bits();
// save original signal alternate stack
let stack = thread.inner.lock().signal_alternate_stack;
let sig_sp = {
// use signal alternate stack when SA_ONSTACK is set
// fallback to default stack when unavailable
// man sigaction(2)
if action_flags.contains(SignalActionFlags::ONSTACK) {
let stack_flags = SignalStackFlags::from_bits_truncate(stack.flags);
if stack_flags.contains(SignalStackFlags::DISABLE) {
tf.get_sp()
} else {
let mut inner = thread.inner.lock();
inner.signal_alternate_stack.flags |= SignalStackFlags::ONSTACK.bits();
// handle auto disarm
if stack_flags.contains(SignalStackFlags::AUTODISARM) {
inner.signal_alternate_stack.flags |=
SignalStackFlags::DISABLE.bits();
}
// top of stack
stack.sp + stack.size
}
@ -268,6 +280,7 @@ pub struct SignalStack {
impl Default for SignalStack {
fn default() -> Self {
// default to disabled
SignalStack {
sp: 0,
flags: SignalStackFlags::DISABLE.bits,

View File

@ -258,6 +258,11 @@ impl Syscall<'_> {
// Modify exec path
proc.exec_path = path.clone();
// reset disposition (man signal(7))
for d in proc.dispositions.iter_mut() {
*d = SignalAction::default();
}
drop(proc);
// Modify the TrapFrame

View File

@ -47,42 +47,18 @@ impl Syscall<'_> {
pub fn sys_rt_sigreturn(&mut self) -> SysResult {
info!("rt_sigreturn");
// FIXME: adapt arch
//let frame = unsafe { &*((self.tf.get_sp() - 8) as *mut SignalFrame) };
let frame: SignalFrame = todo!();
// frame.info.signo
/*
{
let mut process = self.process();
process.sigaltstack.flags ^=
process.sigaltstack.flags & SignalStackFlags::ONSTACK.bits();
}
*/
// 8: return addr
let ptr: UserInPtr<SignalFrame> = UserInPtr::from(self.context.get_sp() - 8);
let frame: SignalFrame = ptr.read()?;
// *self.tf = TrapFrame::from_mcontext(&frame.ucontext.mcontext);
todo!();
//*self.tf = frame.tf.clone();
/*
let mc = &frame.ucontext.mcontext;
self.tf.general.r15 = mc.r15;
self.tf.general.r14 = mc.r14;
self.tf.general.r13 = mc.r13;
self.tf.general.r12 = mc.r12;
self.tf.general.rbp = mc.rbp;
self.tf.general.rbx = mc.rbx;
self.tf.general.r11 = mc.r11;
self.tf.general.r10 = mc.r10;
self.tf.general.r9 = mc.r9;
self.tf.general.r8 = mc.r8;
self.tf.general.rsi = mc.rsi;
self.tf.general.rdi = mc.rdi;
self.tf.general.rdx = mc.rdx;
self.tf.general.rcx = mc.rcx;
self.tf.general.rax = mc.rax;
self.tf.general.rip = mc.rip;
self.tf.general.rsp = mc.rsp;
*/
// restore signal alternate stack
let mut inner = self.thread.inner.lock();
inner.signal_alternate_stack = frame.ucontext.stack;
drop(inner);
*self.context = frame.ucontext.context;
// small hack: don't change ret when restoring
let ret = self.context.get_syscall_ret() as isize;
if ret >= 0 {
Ok(ret as usize)
@ -224,12 +200,17 @@ impl Syscall<'_> {
let ss = ss.read()?;
info!("new stack: {:?}", ss);
// check stack size when not disable
const MINSIGSTKSZ: usize = 2048;
if ss.flags & 2 != 0 && ss.size < MINSIGSTKSZ {
if ss.flags & SignalStackFlags::DISABLE.bits() != 0 && ss.size < MINSIGSTKSZ {
return Err(ENOMEM);
}
// only allow SS_AUTODISARM or SS_DISABLE
if ss.flags != ss.flags & 0x8000002 {
// only allow SS_AUTODISARM and SS_DISABLE
if ss.flags
!= ss.flags
& (SignalStackFlags::AUTODISARM.bits() | SignalStackFlags::DISABLE.bits())
{
return Err(EINVAL);
}
@ -237,6 +218,8 @@ impl Syscall<'_> {
let old_ss = &mut inner.signal_alternate_stack;
let flags = SignalStackFlags::from_bits_truncate(old_ss.flags);
if flags.contains(SignalStackFlags::ONSTACK) {
// cannot change signal alternate stack when we are on it
// see man sigaltstack(2)
return Err(EPERM);
}
*old_ss = ss;