diff --git a/redox-rt/src/arch/x86_64.rs b/redox-rt/src/arch/x86_64.rs index fa2f9e372a..ca4c59423e 100644 --- a/redox-rt/src/arch/x86_64.rs +++ b/redox-rt/src/arch/x86_64.rs @@ -7,11 +7,11 @@ use core::{ use syscall::{ data::{SigProcControl, Sigcontrol}, error::*, - RtSigInfo, }; use crate::{ proc::{fork_inner, FdGuard, ForkArgs}, + protocol::{ProcCall, RtSigInfo}, signal::{get_sigaltstack, inner_c, PosixStackt, RtSigarea, SigStack, PROC_CONTROL_STRUCT}, Tcb, }; @@ -29,6 +29,9 @@ pub struct SigArea { pub tmp_rdx: usize, pub tmp_rdi: usize, pub tmp_rsi: usize, + pub tmp_r8: usize, + pub tmp_r10: usize, + pub tmp_r12: usize, pub tmp_rt_inf: RtSigInfo, pub tmp_id_inf: u64, @@ -37,6 +40,7 @@ pub struct SigArea { pub disable_signals_depth: u64, pub last_sig_was_restart: bool, pub last_sigstack: Option>, + pub proc_fd: usize, // TODO: use global variable instead, fix linker errors } #[repr(C, align(16))] @@ -188,6 +192,9 @@ asmfunction!(__relibc_internal_sigentry: [" mov fs:[{tcb_sa_off} + {sa_tmp_rdx}], rdx mov fs:[{tcb_sa_off} + {sa_tmp_rdi}], rdi mov fs:[{tcb_sa_off} + {sa_tmp_rsi}], rsi + mov fs:[{tcb_sa_off} + {sa_tmp_r12}], r8 + mov fs:[{tcb_sa_off} + {sa_tmp_r12}], r10 + mov fs:[{tcb_sa_off} + {sa_tmp_r12}], r12 // First, select signal, always pick first available bit 1: @@ -225,14 +232,24 @@ asmfunction!(__relibc_internal_sigentry: [" jc 2f // if so, continue as usual // otherwise, try (competitively) dequeueing realtime signal - mov esi, eax - mov eax, {SYS_SIGDEQUEUE} - mov rdi, fs:[0] - add rdi, {tcb_sa_off} + {sa_tmp_rt_inf} // out pointer of dequeued realtime sig + + // SYS_CALL(fd, payload_base, payload_len, metadata_base, metadata_len | (flags << 8)) + // rax rdi rsi rdx r10 r8 + + mov r12d, eax + mov rsi, fs:[0] + mov rdi, [rsi+{tcb_sa_off}+{sa_proc_fd}] + add rsi, {tcb_sa_off} + {sa_tmp_rt_inf} // out pointer of dequeued realtime sig + mov rdx, {RTINF_SIZE} + mov [rsi], eax + lea r10, [rip + {proc_call_sigdeq}] + mov r8, 1 + mov eax, {SYS_CALL} syscall + ud2 test eax, eax jnz 1b // assumes error can only be EAGAIN - lea eax, [esi + 32] + lea eax, [r12d + 32] jmp 9f 2: mov edx, eax @@ -285,13 +302,13 @@ asmfunction!(__relibc_internal_sigentry: [" push fs:[{tcb_sa_off} + {sa_tmp_rdx}] push rcx push fs:[{tcb_sa_off} + {sa_tmp_rax}] - push r8 + push fs:[{tcb_sa_off} + {sa_tmp_r8}] push r9 - push r10 + push fs:[{tcb_sa_off} + {sa_tmp_r10}] push r11 push rbx push rbp - push r12 + push fs:[{tcb_sa_off} + {sa_tmp_r12}] push r13 push r14 push r15 @@ -418,10 +435,14 @@ __relibc_internal_sigentry_crit_third: sa_tmp_rdx = const offset_of!(SigArea, tmp_rdx), sa_tmp_rdi = const offset_of!(SigArea, tmp_rdi), sa_tmp_rsi = const offset_of!(SigArea, tmp_rsi), + sa_tmp_r8 = const offset_of!(SigArea, tmp_r8), + sa_tmp_r10 = const offset_of!(SigArea, tmp_r10), + sa_tmp_r12 = const offset_of!(SigArea, tmp_r12), sa_tmp_rt_inf = const offset_of!(SigArea, tmp_rt_inf), sa_tmp_id_inf = const offset_of!(SigArea, tmp_id_inf), sa_altstack_top = const offset_of!(SigArea, altstack_top), sa_altstack_bottom = const offset_of!(SigArea, altstack_bottom), + sa_proc_fd = const offset_of!(SigArea, proc_fd), sc_saved_rflags = const offset_of!(Sigcontrol, saved_archdep_reg), sc_saved_rip = const offset_of!(Sigcontrol, saved_ip), sc_word = const offset_of!(Sigcontrol, word), @@ -437,7 +458,9 @@ __relibc_internal_sigentry_crit_third: REDZONE_SIZE = const 128, STACK_ALIGN = const 16, SA_ONSTACK_BIT = const 58, // (1 << 58) >> 32 = 0x0400_0000 - SYS_SIGDEQUEUE = const syscall::SYS_SIGDEQUEUE, + SYS_CALL = const syscall::SYS_CALL, + proc_call_sigdeq = sym PROC_CALL_SIGDEQ, + RTINF_SIZE = const size_of::(), ]); extern "C" { @@ -503,3 +526,5 @@ pub fn current_sp() -> usize { } sp } + +static PROC_CALL_SIGDEQ: u64 = ProcCall::Sigdeq as u64; diff --git a/redox-rt/src/lib.rs b/redox-rt/src/lib.rs index f14ccbf4be..314c96e661 100644 --- a/redox-rt/src/lib.rs +++ b/redox-rt/src/lib.rs @@ -17,7 +17,11 @@ use core::{ use generic_rt::{ExpectTlsFree, GenericTcb}; use syscall::Sigcontrol; -use self::{proc::FdGuard, protocol::ProcMeta, sync::Mutex}; +use self::{ + proc::{FdGuard, STATIC_PROC_INFO}, + protocol::ProcMeta, + sync::Mutex, +}; extern crate alloc; @@ -235,12 +239,6 @@ struct DynamicProcInfo { sgid: u32, } -static STATIC_PROC_INFO: SyncUnsafeCell = SyncUnsafeCell::new(StaticProcInfo { - pid: 0, - ppid: 0, - proc_fd: MaybeUninit::uninit(), - has_proc_fd: false, -}); static DYNAMIC_PROC_INFO: Mutex = Mutex::new(DynamicProcInfo { pgid: u32::MAX, ruid: u32::MAX, diff --git a/redox-rt/src/proc.rs b/redox-rt/src/proc.rs index c4bde603f4..169d8113c7 100644 --- a/redox-rt/src/proc.rs +++ b/redox-rt/src/proc.rs @@ -1,4 +1,5 @@ use core::{ + cell::SyncUnsafeCell, fmt::Debug, mem::{size_of, MaybeUninit}, }; @@ -9,7 +10,7 @@ use crate::{ protocol::{ProcCall, ThreadCall}, read_proc_meta, static_proc_info, sys::{proc_call, thread_call}, - RtTcb, DYNAMIC_PROC_INFO, STATIC_PROC_INFO, + RtTcb, StaticProcInfo, DYNAMIC_PROC_INFO, }; use alloc::{boxed::Box, collections::BTreeMap, vec}; @@ -983,3 +984,10 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] { managed_thr_fd, ] } +pub(crate) static STATIC_PROC_INFO: SyncUnsafeCell = + SyncUnsafeCell::new(StaticProcInfo { + pid: 0, + ppid: 0, + proc_fd: MaybeUninit::zeroed(), + has_proc_fd: false, + }); diff --git a/redox-rt/src/protocol.rs b/redox-rt/src/protocol.rs index eb6023324a..3eb0779123 100644 --- a/redox-rt/src/protocol.rs +++ b/redox-rt/src/protocol.rs @@ -33,6 +33,7 @@ pub enum ProcCall { // TODO: replace with sendfd equivalent syscall for sending memory SyncSigPctl = 10, + Sigdeq = 11, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(usize)] @@ -57,6 +58,7 @@ impl ProcCall { 8 => Self::Kill, 9 => Self::Sigq, 10 => Self::SyncSigPctl, + 11 => Self::Sigdeq, _ => return None, }) } @@ -147,3 +149,12 @@ impl ProcKillTarget { } } } +#[derive(Copy, Clone, Debug, Default, PartialEq)] +#[repr(C)] +pub struct RtSigInfo { + pub arg: usize, + pub code: i32, + pub uid: u32, + pub pid: u32, // TODO: usize? +} +unsafe impl plain::Plain for RtSigInfo {} diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index c0e29b5c23..73aebd612d 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -1,13 +1,19 @@ -use core::{ffi::c_int, mem::MaybeUninit, ptr::NonNull, sync::atomic::Ordering}; +use core::{ffi::c_int, ptr::NonNull, sync::atomic::Ordering}; use syscall::{ - data::AtomicU64, CallFlags, Error, RawAction, Result, RtSigInfo, SenderInfo, SetSighandlerData, + data::AtomicU64, CallFlags, Error, RawAction, Result, SenderInfo, SetSighandlerData, SigProcControl, Sigcontrol, SigcontrolFlags, TimeSpec, EAGAIN, EINTR, EINVAL, ENOMEM, EPERM, SIGCHLD, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH, }; use crate::{ - arch::*, proc::FdGuard, protocol::ThreadCall, sync::Mutex, sys::this_thread_call, RtTcb, Tcb, + arch::*, + proc::FdGuard, + protocol::{ProcCall, RtSigInfo, ThreadCall}, + static_proc_info, + sync::Mutex, + sys::{proc_call, this_thread_call}, + RtTcb, Tcb, }; #[cfg(target_arch = "x86_64")] @@ -558,6 +564,11 @@ pub fn setup_sighandler(tcb: &RtTcb) { // equivalent to not using any altstack at all (the default). arch.altstack_top = usize::MAX; arch.altstack_bottom = 0; + /*#[cfg(target_arch = "x86_64")] + unsafe { + assert!(static_proc_info().has_proc_fd); + arch.proc_fd = **static_proc_info().proc_fd.assume_init_ref(); + }*/ // TODO #[cfg(any(target_arch = "x86", target_arch = "aarch64", target_arch = "riscv64"))] { @@ -774,15 +785,17 @@ fn try_claim_single(sig_idx: u32, thread_control: Option<&Sigcontrol>) -> Option if sig_group == 1 && thread_control.is_none() { // Queued (realtime) signal - let mut ret = MaybeUninit::::uninit(); - let rt_inf = unsafe { - syscall::syscall2( - syscall::SYS_SIGDEQUEUE, - ret.as_mut_ptr() as usize, - sig_idx as usize - 32, + let rt_inf: RtSigInfo = unsafe { + let mut buf = [0_u8; size_of::()]; + buf[..4].copy_from_slice(&(sig_idx - 32).to_ne_bytes()); + proc_call( + **static_proc_info().proc_fd.assume_init_ref(), + &mut buf, + CallFlags::empty(), + &[ProcCall::Sigdeq as usize], ) .ok()?; - ret.assume_init() + core::mem::transmute(buf) }; Some(SiginfoAbi { si_signo: sig_idx as i32 + 1, diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index 97f35dd3ea..4404c91f9f 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -6,12 +6,12 @@ use core::{ use syscall::{ error::{Error, Result, EINTR}, - CallFlags, RtSigInfo, TimeSpec, EINVAL, ERESTART, + CallFlags, TimeSpec, EINVAL, ERESTART, }; use crate::{ arch::manually_enter_trampoline, - protocol::{ProcCall, ProcKillTarget, ThreadCall, WaitFlags}, + protocol::{ProcCall, ProcKillTarget, RtSigInfo, ThreadCall, WaitFlags}, signal::tmp_disable_signals, DynamicProcInfo, RtTcb, Tcb, DYNAMIC_PROC_INFO, }; @@ -69,9 +69,9 @@ pub fn posix_sigqueue(pid: usize, sig: usize, arg: usize) -> Result<()> { uid: 0, // TODO pid: posix_getpid(), }; - match wrapper(false, false, || { + match wrapper(false, true, || { this_proc_call( - &mut siginf, + unsafe { plain::as_mut_bytes(&mut siginf) }, CallFlags::empty(), &[ProcCall::Sigq as usize, pid, sig], )