From 0bf7b6e73b64b7ec9a858990453d4e40e514cdfe Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sat, 29 Jun 2024 13:54:02 +0200 Subject: [PATCH] Put sigaction-like struct in shmem. --- src/data.rs | 35 ++++++++++++++++++++--------------- src/flag.rs | 15 --------------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/data.rs b/src/data.rs index d96fb47d01..6db3c99c9a 100644 --- a/src/data.rs +++ b/src/data.rs @@ -359,11 +359,22 @@ impl DerefMut for SetSighandlerData { } } /// Signal runtime struct for the entire process -#[derive(Debug, Default)] -#[repr(C)] +#[derive(Debug)] +#[repr(C, align(4096))] pub struct SigProcControl { - // composed of [lo "pending" | lo "unmasked", hi "pending" | hi "unmasked"] - pub word: [AtomicU64; 2], + pub pending: AtomicU64, + pub actions: [RawAction; 64], +} +#[derive(Debug)] +#[repr(C, align(16))] +pub struct RawAction { + /// Only two MSBs are interesting for the kernel. If bit 63 is set, signal is ignored. If bit + /// 62 is set and the signal is SIGTSTP/SIGTTIN/SIGTTOU, it's equivalent to the action of + /// SIGSTOP. + pub first: AtomicU64, + /// Completely ignored by the kernel, but exists so userspace can (when 16-byte atomics exist) + /// atomically set both the handler, sigaction flags, and sigaction mask. + pub user_data: AtomicU64, } /// Signal runtime struct for a thread @@ -426,18 +437,12 @@ pub fn sig_bit(sig: usize) -> u64 { 1 << (sig - 1) } impl SigProcControl { + pub fn signal_will_ign(&self, sig: usize) -> bool { + self.actions[sig - 1].first.load(Ordering::Relaxed) & (1 << 63) != 0 + } pub fn signal_will_stop(&self, sig: usize) -> bool { - let bit = if sig == crate::SIGTSTP { - crate::SIGW0_TSTP_IS_STOP_BIT - } else if sig == crate::SIGTTIN { - crate::SIGW0_TTIN_IS_STOP_BIT - } else if sig == crate::SIGTTOU { - crate::SIGW0_TTOU_IS_STOP_BIT - } else { - panic!() - }; - - self.word[0].load(Ordering::SeqCst) & bit == bit + use crate::flag::*; + matches!(sig, SIGTSTP | SIGTTIN | SIGTTOU) && self.actions[sig - 1].first.load(Ordering::Relaxed) & (1 << 62) != 0 } } diff --git a/src/flag.rs b/src/flag.rs index 2a89411125..13f62e2103 100644 --- a/src/flag.rs +++ b/src/flag.rs @@ -333,18 +333,3 @@ bitflags! { const INHIBIT_DELIVERY = 1; } } -// SIGKILL and SIGSTOP are not considered regular signals, and are merely special codes for -// force-killing and stopping a process or individual thread, respectively. Thus, we use 3 of those -// 4 unused bits (those intended for [SIGKILL, SIGSTOP] x ["pending", "masked"]) to store whether -// SIGTSTP, SIGTTOU, and SIGTTOU, should act as SIG_DFL ("stop"). While this "stop" bit is set, -// neither the regular pending nor the mask bits are meaningful. -// -// Since it's also not meaningful for individual threads to store anything sigaction related, as -// sigaction is process-level, these bits are only used in the process sigcontrol structure (TODO). -pub const SIGW0_TSTP_IS_STOP_BIT: u64 = 1 << (SIGKILL - 1); -pub const SIGW0_TTIN_IS_STOP_BIT: u64 = 1 << (SIGSTOP - 1); -pub const SIGW0_TTOU_IS_STOP_BIT: u64 = 1 << (SIGKILL + 31); -pub const SIGW0_NOCLDSTOP_BIT: u64 = 1 << (SIGSTOP + 31); - -pub const SIGW0_UNUSED1: u64 = 1 << 31; -pub const SIGW0_UNUSED2: u64 = 1 << 63;