From 98a2a566d91e1f6c3431b0e180c8208a6d0e9e79 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 23 Jun 2024 23:30:34 +0200 Subject: [PATCH] Almost succeed at repeatedly accepting signals. --- redox-rt/src/arch/x86_64.rs | 26 +++++++++++++++----------- redox-rt/src/proc.rs | 14 ++++++++------ redox-rt/src/signal.rs | 19 ++++++++++++------- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/redox-rt/src/arch/x86_64.rs b/redox-rt/src/arch/x86_64.rs index 54a57ae1..7349809f 100644 --- a/redox-rt/src/arch/x86_64.rs +++ b/redox-rt/src/arch/x86_64.rs @@ -150,13 +150,13 @@ asmfunction!(__relibc_internal_sigentry: [" and eax, ecx and eax, {SIGW1_PENDING_MASK} bsf eax, eax - jnz 4f + jnz 7f add eax, 32 2: // By now we have selected a signal, stored in eax (6-bit). We now need to choose whether or // not to switch to the alternate signal stack. If SA_ONSTACK is clear for this signal, then // skip the sigaltstack logic. - bt fs:[{tcb_sa_off} + {sa_onstack}], edx + bt fs:[{tcb_sa_off} + {sa_onstack}], eax jc 3f // Otherwise, the altstack is already active. The sigaltstack being disabled, is equivalent @@ -180,10 +180,10 @@ asmfunction!(__relibc_internal_sigentry: [" 4: // Now that we have a stack, we can finally start initializing the signal stack! - push 0 // SS + push 0x23 // SS push fs:[{tcb_sc_off} + {sc_saved_rsp}] push fs:[{tcb_sc_off} + {sc_saved_rflags}] - push 0 // CS + push 0x2b // CS push fs:[{tcb_sc_off} + {sc_saved_rip}] push rdi @@ -202,7 +202,7 @@ asmfunction!(__relibc_internal_sigentry: [" push r14 push r15 - push rdx // selected signal + push rax // selected signal sub rsp, 4096 + 24 @@ -214,7 +214,7 @@ asmfunction!(__relibc_internal_sigentry: [" // TODO: self-modifying? cmp byte ptr [rip + {supports_xsave}], 0 - je 3f + je 6f mov eax, 0xffffffff mov edx, eax @@ -227,8 +227,8 @@ asmfunction!(__relibc_internal_sigentry: [" mov edx, eax xrstor [rsp] - add rsp, 4096 + 24 -2: +5: + add rsp, 4096 + 32 pop r15 pop r14 pop r13 @@ -245,20 +245,24 @@ asmfunction!(__relibc_internal_sigentry: [" pop rsi pop rdi + iretq + /* pop qword ptr fs:[{tcb_sa_off} + {sa_tmp}] add rsp, 8 popfq pop rsp jmp qword ptr fs:[{tcb_sa_off} + {sa_tmp}] -3: + */ +6: fxsave64 [rsp] mov rdi, rsp call {inner} fxrstor64 [rsp] - jmp 2b -4: + jmp 5b +7: + ud2 // Spurious signal "] <= [ inner = sym inner_c, diff --git a/redox-rt/src/proc.rs b/redox-rt/src/proc.rs index 218bf18d..e4564bb7 100644 --- a/redox-rt/src/proc.rs +++ b/redox-rt/src/proc.rs @@ -795,6 +795,14 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { } } + let buf = create_set_addr_space_buf( + *new_addr_space_fd, + __relibc_internal_fork_ret as usize, + initial_rsp as usize, + ); + let _ = syscall::write(*new_addr_space_sel_fd, &buf)?; + } + { // Reuse the same sigaltstack and signal entry (all memory will be re-mapped CoW later). // // Do this after the address space is cloned, since the kernel will get a shared @@ -804,12 +812,6 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { let _ = syscall::write(*new_sighandler_fd, &crate::signal::current_setsighandler_struct())?; } - let buf = create_set_addr_space_buf( - *new_addr_space_fd, - __relibc_internal_fork_ret as usize, - initial_rsp as usize, - ); - let _ = syscall::write(*new_addr_space_sel_fd, &buf)?; } copy_env_regs(*cur_pid_fd, *new_pid_fd)?; } diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index d90c2c89..2ec1e76c 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -2,7 +2,7 @@ use core::cell::{Cell, UnsafeCell}; use core::ffi::c_int; use core::sync::atomic::{AtomicU64, Ordering}; -use syscall::{Error, IntRegisters, Result, SetSighandlerData, SigProcControl, Sigcontrol, EINVAL, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGW0_NOCLDSTOP_BIT, SIGW0_TSTP_IS_STOP_BIT, SIGW0_TTIN_IS_STOP_BIT, SIGW0_TTOU_IS_STOP_BIT, SIGWINCH}; +use syscall::{Error, IntRegisters, Result, SetSighandlerData, SigProcControl, Sigcontrol, SigcontrolFlags, EINVAL, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGW0_NOCLDSTOP_BIT, SIGW0_TSTP_IS_STOP_BIT, SIGW0_TTIN_IS_STOP_BIT, SIGW0_TTOU_IS_STOP_BIT, SIGWINCH}; use crate::{arch::*, Tcb}; use crate::sync::Mutex; @@ -28,25 +28,30 @@ pub fn sighandler_function() -> usize { #[repr(C)] pub struct SigStack { - sa_handler: usize, - sig_num: usize, - #[cfg(target_arch = "x86_64")] fx: [u8; 4096], #[cfg(target_arch = "x86")] fx: [u8; 512], - _pad: [usize; 4], // pad to 192 = 3 * 64 bytes + _pad: [usize; 3], // pad to 192 = 3 * 64 = 168 + 24 bytes + sig_num: usize, regs: IntRegisters, // 160 bytes currently } #[inline(always)] unsafe fn inner(stack: &mut SigStack) { + // TODO: Set procmask based on SA_NODEFER, SA_RESETHAND, and sa_mask. + + // Re-enable signals again. + let control_flags = &Tcb::current().unwrap().os_specific.control.control_flags; + control_flags.store(control_flags.load(Ordering::Relaxed) & !SigcontrolFlags::INHIBIT_DELIVERY.bits(), Ordering::Release); + core::sync::atomic::compiler_fence(Ordering::Acquire); + let _ = syscall::write(1, b"INNER SIGNAL HANDLER\n"); - loop {} + /*loop {} let handler: extern "C" fn(c_int) = core::mem::transmute(stack.sa_handler); - handler(stack.sig_num as c_int) + handler(stack.sig_num as c_int)*/ } #[cfg(not(target_arch = "x86"))] pub(crate) unsafe extern "C" fn inner_c(stack: usize) { -- GitLab