170a4e555SLoGin use core::{ffi::c_void, intrinsics::unlikely, mem::size_of};
23c82aa56SChiichen
32eab6dd7S曾俊 use log::error;
491e9d4abSLoGin use system_error::SystemError;
591e9d4abSLoGin
63c82aa56SChiichen use crate::{
73c82aa56SChiichen arch::{
83c82aa56SChiichen fpu::FpState,
93c82aa56SChiichen interrupt::TrapFrame,
103c82aa56SChiichen process::table::{USER_CS, USER_DS},
113c82aa56SChiichen CurrentIrqArch, MMArch,
123c82aa56SChiichen },
133c82aa56SChiichen exception::InterruptArch,
143c82aa56SChiichen ipc::{
153c82aa56SChiichen signal::set_current_sig_blocked,
163c82aa56SChiichen signal_types::{SaHandlerType, SigInfo, Sigaction, SigactionType, SignalArch},
173c82aa56SChiichen },
183c82aa56SChiichen mm::MemoryManagementArch,
193c82aa56SChiichen process::ProcessManager,
20f0c87a89SGnoCiYeH sched::{schedule, SchedMode},
2191e9d4abSLoGin syscall::{user_access::UserBufferWriter, Syscall},
223c82aa56SChiichen };
233c82aa56SChiichen
243c82aa56SChiichen /// 信号处理的栈的栈指针的最小对齐数量
253c82aa56SChiichen pub const STACK_ALIGN: u64 = 16;
263c82aa56SChiichen /// 信号最大值
273c82aa56SChiichen pub const MAX_SIG_NUM: usize = 64;
283c82aa56SChiichen #[allow(dead_code)]
29393f6915SLoGin #[derive(Eq)]
303c82aa56SChiichen #[repr(usize)]
313c82aa56SChiichen #[allow(non_camel_case_types)]
32393f6915SLoGin #[atomic_enum]
333c82aa56SChiichen pub enum Signal {
343c82aa56SChiichen INVALID = 0,
353c82aa56SChiichen SIGHUP = 1,
363c82aa56SChiichen SIGINT,
373c82aa56SChiichen SIGQUIT,
383c82aa56SChiichen SIGILL,
393c82aa56SChiichen SIGTRAP,
403c82aa56SChiichen /// SIGABRT和SIGIOT共用这个号码
413c82aa56SChiichen SIGABRT_OR_IOT,
423c82aa56SChiichen SIGBUS,
433c82aa56SChiichen SIGFPE,
443c82aa56SChiichen SIGKILL,
453c82aa56SChiichen SIGUSR1,
463c82aa56SChiichen
473c82aa56SChiichen SIGSEGV = 11,
483c82aa56SChiichen SIGUSR2,
493c82aa56SChiichen SIGPIPE,
503c82aa56SChiichen SIGALRM,
513c82aa56SChiichen SIGTERM,
523c82aa56SChiichen SIGSTKFLT,
533c82aa56SChiichen SIGCHLD,
543c82aa56SChiichen SIGCONT,
553c82aa56SChiichen SIGSTOP,
563c82aa56SChiichen SIGTSTP,
573c82aa56SChiichen
583c82aa56SChiichen SIGTTIN = 21,
593c82aa56SChiichen SIGTTOU,
603c82aa56SChiichen SIGURG,
613c82aa56SChiichen SIGXCPU,
623c82aa56SChiichen SIGXFSZ,
633c82aa56SChiichen SIGVTALRM,
643c82aa56SChiichen SIGPROF,
653c82aa56SChiichen SIGWINCH,
663c82aa56SChiichen /// SIGIO和SIGPOLL共用这个号码
673c82aa56SChiichen SIGIO_OR_POLL,
683c82aa56SChiichen SIGPWR,
693c82aa56SChiichen
703c82aa56SChiichen SIGSYS = 31,
713c82aa56SChiichen
723c82aa56SChiichen SIGRTMIN = 32,
733c82aa56SChiichen SIGRTMAX = 64,
743c82aa56SChiichen }
753c82aa56SChiichen
763c82aa56SChiichen /// 为Signal实现判断相等的trait
773c82aa56SChiichen impl PartialEq for Signal {
eq(&self, other: &Signal) -> bool783c82aa56SChiichen fn eq(&self, other: &Signal) -> bool {
793c82aa56SChiichen *self as usize == *other as usize
803c82aa56SChiichen }
813c82aa56SChiichen }
823c82aa56SChiichen
833c82aa56SChiichen impl From<usize> for Signal {
from(value: usize) -> Self843c82aa56SChiichen fn from(value: usize) -> Self {
853c82aa56SChiichen if value <= MAX_SIG_NUM {
863c82aa56SChiichen let ret: Signal = unsafe { core::mem::transmute(value) };
873c82aa56SChiichen return ret;
883c82aa56SChiichen } else {
892eab6dd7S曾俊 error!("Try to convert an invalid number to Signal");
903c82aa56SChiichen return Signal::INVALID;
913c82aa56SChiichen }
923c82aa56SChiichen }
933c82aa56SChiichen }
943c82aa56SChiichen
95b5b571e0SLoGin impl From<Signal> for usize {
from(val: Signal) -> Self96b5b571e0SLoGin fn from(val: Signal) -> Self {
97b5b571e0SLoGin val as usize
983c82aa56SChiichen }
993c82aa56SChiichen }
1003c82aa56SChiichen
1013c82aa56SChiichen impl From<i32> for Signal {
from(value: i32) -> Self1023c82aa56SChiichen fn from(value: i32) -> Self {
1033c82aa56SChiichen if value < 0 {
1042eab6dd7S曾俊 error!("Try to convert an invalid number to Signal");
1053c82aa56SChiichen return Signal::INVALID;
1063c82aa56SChiichen } else {
1073c82aa56SChiichen return Self::from(value as usize);
1083c82aa56SChiichen }
1093c82aa56SChiichen }
1103c82aa56SChiichen }
1113c82aa56SChiichen
112b5b571e0SLoGin impl From<Signal> for SigSet {
from(val: Signal) -> Self113b5b571e0SLoGin fn from(val: Signal) -> Self {
1143c82aa56SChiichen SigSet {
115b5b571e0SLoGin bits: (1 << (val as usize - 1) as u64),
1163c82aa56SChiichen }
1173c82aa56SChiichen }
1183c82aa56SChiichen }
1193c82aa56SChiichen impl Signal {
1203c82aa56SChiichen /// 判断一个数字是否为可用的信号
1213c82aa56SChiichen #[inline]
is_valid(&self) -> bool1223c82aa56SChiichen pub fn is_valid(&self) -> bool {
1233c82aa56SChiichen return (*self) as usize <= MAX_SIG_NUM;
1243c82aa56SChiichen }
1253c82aa56SChiichen
1263c82aa56SChiichen /// const convertor between `Signal` and `SigSet`
into_sigset(self) -> SigSet1273c82aa56SChiichen pub const fn into_sigset(self) -> SigSet {
1283c82aa56SChiichen SigSet {
1293c82aa56SChiichen bits: (1 << (self as usize - 1) as u64),
1303c82aa56SChiichen }
1313c82aa56SChiichen }
1323c82aa56SChiichen
1333c82aa56SChiichen /// 判断一个信号是不是实时信号
1343c82aa56SChiichen ///
1353c82aa56SChiichen /// ## 返回值
1363c82aa56SChiichen ///
1373c82aa56SChiichen /// - `true` 这个信号是实时信号
1383c82aa56SChiichen /// - `false` 这个信号不是实时信号
1393c82aa56SChiichen #[inline]
is_rt_signal(&self) -> bool1403c82aa56SChiichen pub fn is_rt_signal(&self) -> bool {
1413c82aa56SChiichen return (*self) as usize >= Signal::SIGRTMIN.into();
1423c82aa56SChiichen }
1433c82aa56SChiichen
1443c82aa56SChiichen /// 调用信号的默认处理函数
handle_default(&self)1453c82aa56SChiichen pub fn handle_default(&self) {
1463c82aa56SChiichen match self {
1473c82aa56SChiichen Signal::INVALID => {
1482eab6dd7S曾俊 error!("attempting to handler an Invalid");
1493c82aa56SChiichen }
150b5b571e0SLoGin Signal::SIGHUP => sig_terminate(*self),
151b5b571e0SLoGin Signal::SIGINT => sig_terminate(*self),
152b5b571e0SLoGin Signal::SIGQUIT => sig_terminate_dump(*self),
153b5b571e0SLoGin Signal::SIGILL => sig_terminate_dump(*self),
154b5b571e0SLoGin Signal::SIGTRAP => sig_terminate_dump(*self),
155b5b571e0SLoGin Signal::SIGABRT_OR_IOT => sig_terminate_dump(*self),
156b5b571e0SLoGin Signal::SIGBUS => sig_terminate_dump(*self),
157b5b571e0SLoGin Signal::SIGFPE => sig_terminate_dump(*self),
158b5b571e0SLoGin Signal::SIGKILL => sig_terminate(*self),
159b5b571e0SLoGin Signal::SIGUSR1 => sig_terminate(*self),
160b5b571e0SLoGin Signal::SIGSEGV => sig_terminate_dump(*self),
161b5b571e0SLoGin Signal::SIGUSR2 => sig_terminate(*self),
162b5b571e0SLoGin Signal::SIGPIPE => sig_terminate(*self),
163b5b571e0SLoGin Signal::SIGALRM => sig_terminate(*self),
164b5b571e0SLoGin Signal::SIGTERM => sig_terminate(*self),
165b5b571e0SLoGin Signal::SIGSTKFLT => sig_terminate(*self),
166b5b571e0SLoGin Signal::SIGCHLD => sig_ignore(*self),
167b5b571e0SLoGin Signal::SIGCONT => sig_continue(*self),
168b5b571e0SLoGin Signal::SIGSTOP => sig_stop(*self),
169b5b571e0SLoGin Signal::SIGTSTP => sig_stop(*self),
170b5b571e0SLoGin Signal::SIGTTIN => sig_stop(*self),
171b5b571e0SLoGin Signal::SIGTTOU => sig_stop(*self),
172b5b571e0SLoGin Signal::SIGURG => sig_ignore(*self),
173b5b571e0SLoGin Signal::SIGXCPU => sig_terminate_dump(*self),
174b5b571e0SLoGin Signal::SIGXFSZ => sig_terminate_dump(*self),
175b5b571e0SLoGin Signal::SIGVTALRM => sig_terminate(*self),
176b5b571e0SLoGin Signal::SIGPROF => sig_terminate(*self),
177b5b571e0SLoGin Signal::SIGWINCH => sig_ignore(*self),
178b5b571e0SLoGin Signal::SIGIO_OR_POLL => sig_terminate(*self),
179b5b571e0SLoGin Signal::SIGPWR => sig_terminate(*self),
180b5b571e0SLoGin Signal::SIGSYS => sig_terminate(*self),
181b5b571e0SLoGin Signal::SIGRTMIN => sig_terminate(*self),
182b5b571e0SLoGin Signal::SIGRTMAX => sig_terminate(*self),
1833c82aa56SChiichen }
1843c82aa56SChiichen }
1853c82aa56SChiichen }
1863c82aa56SChiichen
1873c82aa56SChiichen /// siginfo中的si_code的可选值
1883c82aa56SChiichen /// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态
1893c82aa56SChiichen #[derive(Copy, Debug, Clone)]
1903c82aa56SChiichen #[repr(i32)]
1913c82aa56SChiichen pub enum SigCode {
1923c82aa56SChiichen /// sent by kill, sigsend, raise
1933c82aa56SChiichen User = 0,
1943c82aa56SChiichen /// sent by kernel from somewhere
1953c82aa56SChiichen Kernel = 0x80,
1963c82aa56SChiichen /// 通过sigqueue发送
1973c82aa56SChiichen Queue = -1,
1983c82aa56SChiichen /// 定时器过期时发送
1993c82aa56SChiichen Timer = -2,
2003c82aa56SChiichen /// 当实时消息队列的状态发生改变时发送
2013c82aa56SChiichen Mesgq = -3,
2023c82aa56SChiichen /// 当异步IO完成时发送
2033c82aa56SChiichen AsyncIO = -4,
2043c82aa56SChiichen /// sent by queued SIGIO
2053c82aa56SChiichen SigIO = -5,
2063c82aa56SChiichen }
2073c82aa56SChiichen
2083c82aa56SChiichen impl SigCode {
2093c82aa56SChiichen /// 为SigCode这个枚举类型实现从i32转换到枚举类型的转换函数
2103c82aa56SChiichen #[allow(dead_code)]
from_i32(x: i32) -> SigCode2113c82aa56SChiichen pub fn from_i32(x: i32) -> SigCode {
2123c82aa56SChiichen match x {
2133c82aa56SChiichen 0 => Self::User,
2143c82aa56SChiichen 0x80 => Self::Kernel,
2153c82aa56SChiichen -1 => Self::Queue,
2163c82aa56SChiichen -2 => Self::Timer,
2173c82aa56SChiichen -3 => Self::Mesgq,
2183c82aa56SChiichen -4 => Self::AsyncIO,
2193c82aa56SChiichen -5 => Self::SigIO,
2203c82aa56SChiichen _ => panic!("signal code not valid"),
2213c82aa56SChiichen }
2223c82aa56SChiichen }
2233c82aa56SChiichen }
2243c82aa56SChiichen
2253c82aa56SChiichen bitflags! {
2263c82aa56SChiichen #[repr(C,align(8))]
2273c82aa56SChiichen #[derive(Default)]
2283c82aa56SChiichen pub struct SigFlags:u32{
2293c82aa56SChiichen const SA_NOCLDSTOP = 1;
2303c82aa56SChiichen const SA_NOCLDWAIT = 2;
2313c82aa56SChiichen const SA_SIGINFO = 4;
2323c82aa56SChiichen const SA_ONSTACK = 0x08000000;
2333c82aa56SChiichen const SA_RESTART = 0x10000000;
2343c82aa56SChiichen const SA_NODEFER = 0x40000000;
2353c82aa56SChiichen const SA_RESETHAND = 0x80000000;
2363c82aa56SChiichen const SA_RESTORER =0x04000000;
2373c82aa56SChiichen const SA_ALL = Self::SA_NOCLDSTOP.bits()|Self::SA_NOCLDWAIT.bits()|Self::SA_NODEFER.bits()|Self::SA_ONSTACK.bits()|Self::SA_RESETHAND.bits()|Self::SA_RESTART.bits()|Self::SA_SIGINFO.bits()|Self::SA_RESTORER.bits();
2383c82aa56SChiichen }
2393c82aa56SChiichen
2403c82aa56SChiichen /// 请注意,sigset 这个bitmap, 第0位表示sig=1的信号。也就是说,Signal-1才是sigset_t中对应的位
2413c82aa56SChiichen #[derive(Default)]
2423c82aa56SChiichen pub struct SigSet:u64{
2433c82aa56SChiichen const SIGHUP = 1<<0;
2443c82aa56SChiichen const SIGINT = 1<<1;
2453c82aa56SChiichen const SIGQUIT = 1<<2;
2463c82aa56SChiichen const SIGILL = 1<<3;
2473c82aa56SChiichen const SIGTRAP = 1<<4;
2483c82aa56SChiichen /// SIGABRT和SIGIOT共用这个号码
2493c82aa56SChiichen const SIGABRT_OR_IOT = 1<<5;
2503c82aa56SChiichen const SIGBUS = 1<<6;
2513c82aa56SChiichen const SIGFPE = 1<<7;
2523c82aa56SChiichen const SIGKILL = 1<<8;
2533c82aa56SChiichen const SIGUSR = 1<<9;
2543c82aa56SChiichen const SIGSEGV = 1<<10;
2553c82aa56SChiichen const SIGUSR2 = 1<<11;
2563c82aa56SChiichen const SIGPIPE = 1<<12;
2573c82aa56SChiichen const SIGALRM = 1<<13;
2583c82aa56SChiichen const SIGTERM = 1<<14;
2593c82aa56SChiichen const SIGSTKFLT= 1<<15;
2603c82aa56SChiichen const SIGCHLD = 1<<16;
2613c82aa56SChiichen const SIGCONT = 1<<17;
2623c82aa56SChiichen const SIGSTOP = 1<<18;
2633c82aa56SChiichen const SIGTSTP = 1<<19;
2643c82aa56SChiichen const SIGTTIN = 1<<20;
2653c82aa56SChiichen const SIGTTOU = 1<<21;
2663c82aa56SChiichen const SIGURG = 1<<22;
2673c82aa56SChiichen const SIGXCPU = 1<<23;
2683c82aa56SChiichen const SIGXFSZ = 1<<24;
2693c82aa56SChiichen const SIGVTALRM= 1<<25;
2703c82aa56SChiichen const SIGPROF = 1<<26;
2713c82aa56SChiichen const SIGWINCH = 1<<27;
2723c82aa56SChiichen /// SIGIO和SIGPOLL共用这个号码
2733c82aa56SChiichen const SIGIO_OR_POLL = 1<<28;
2743c82aa56SChiichen const SIGPWR = 1<<29;
2753c82aa56SChiichen const SIGSYS = 1<<30;
2763c82aa56SChiichen const SIGRTMIN = 1<<31;
2773c82aa56SChiichen // TODO 写上实时信号
278b5b571e0SLoGin const SIGRTMAX = 1 << (MAX_SIG_NUM-1);
2793c82aa56SChiichen }
2803c82aa56SChiichen }
2813c82aa56SChiichen
282bf4a4899SLoGin /// SIGCHLD si_codes
283bf4a4899SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq, ToPrimitive)]
284bf4a4899SLoGin #[allow(dead_code)]
285bf4a4899SLoGin pub enum SigChildCode {
286bf4a4899SLoGin /// child has exited
287bf4a4899SLoGin ///
288bf4a4899SLoGin /// CLD_EXITED
289bf4a4899SLoGin Exited = 1,
290bf4a4899SLoGin /// child was killed
291bf4a4899SLoGin ///
292bf4a4899SLoGin /// CLD_KILLED
293bf4a4899SLoGin Killed = 2,
294bf4a4899SLoGin /// child terminated abnormally
295bf4a4899SLoGin ///
296bf4a4899SLoGin /// CLD_DUMPED
297bf4a4899SLoGin Dumped = 3,
298bf4a4899SLoGin /// traced child has trapped
299bf4a4899SLoGin ///
300bf4a4899SLoGin /// CLD_TRAPPED
301bf4a4899SLoGin Trapped = 4,
302bf4a4899SLoGin /// child has stopped
303bf4a4899SLoGin ///
304bf4a4899SLoGin /// CLD_STOPPED
305bf4a4899SLoGin Stopped = 5,
306bf4a4899SLoGin /// stopped child has continued
307bf4a4899SLoGin ///
308bf4a4899SLoGin /// CLD_CONTINUED
309bf4a4899SLoGin Continued = 6,
310bf4a4899SLoGin }
311bf4a4899SLoGin
312b5b571e0SLoGin impl From<SigChildCode> for i32 {
from(value: SigChildCode) -> Self313b5b571e0SLoGin fn from(value: SigChildCode) -> Self {
314b5b571e0SLoGin value as i32
315bf4a4899SLoGin }
316bf4a4899SLoGin }
317bf4a4899SLoGin
3183c82aa56SChiichen #[repr(C, align(16))]
3193c82aa56SChiichen #[derive(Debug, Clone, Copy)]
3203c82aa56SChiichen pub struct SigFrame {
3213c82aa56SChiichen // pub pedding: u64,
3223c82aa56SChiichen /// 指向restorer的地址的指针。(该变量必须放在sigframe的第一位,因为这样才能在handler返回的时候,跳转到对应的代码,执行sigreturn)
3233c82aa56SChiichen pub ret_code_ptr: *mut core::ffi::c_void,
3243c82aa56SChiichen pub handler: *mut c_void,
3253c82aa56SChiichen pub info: SigInfo,
3263c82aa56SChiichen pub context: SigContext,
3273c82aa56SChiichen }
3283c82aa56SChiichen
3293c82aa56SChiichen #[repr(C, align(16))]
3303c82aa56SChiichen #[derive(Debug, Clone, Copy)]
3313c82aa56SChiichen pub struct SigContext {
3323c82aa56SChiichen /// sigcontext的标志位
3333c82aa56SChiichen pub sc_flags: u64,
3343c82aa56SChiichen pub sc_stack: SigStack, // 信号处理程序备用栈信息
3353c82aa56SChiichen pub frame: TrapFrame, // 暂存的系统调用/中断返回时,原本要弹出的内核栈帧
3363c82aa56SChiichen // pub trap_num: u64, // 用来保存线程结构体中的trap_num字段
3373c82aa56SChiichen pub oldmask: SigSet, // 暂存的执行信号处理函数之前的,被设置block的信号
3383c82aa56SChiichen pub cr2: u64, // 用来保存线程结构体中的cr2字段
3393c82aa56SChiichen // pub err_code: u64, // 用来保存线程结构体中的err_code字段
3403c82aa56SChiichen pub reserved_for_x87_state: Option<FpState>,
3413c82aa56SChiichen pub reserved: [u64; 8],
3423c82aa56SChiichen }
3433c82aa56SChiichen
3443c82aa56SChiichen impl SigContext {
3453c82aa56SChiichen /// 设置sigcontext
3463c82aa56SChiichen ///
3473c82aa56SChiichen /// ## 参数
3483c82aa56SChiichen ///
3493c82aa56SChiichen /// - `mask` 要被暂存的信号mask标志位
3503c82aa56SChiichen /// - `regs` 进入信号处理流程前,Restore all要弹出的内核栈栈帧
3513c82aa56SChiichen ///
3523c82aa56SChiichen /// ## 返回值
3533c82aa56SChiichen ///
3543c82aa56SChiichen /// - `Ok(0)`
3553c82aa56SChiichen /// - `Err(Systemerror)` (暂时不会返回错误)
setup_sigcontext( &mut self, mask: &SigSet, frame: &TrapFrame, ) -> Result<i32, SystemError>3563c82aa56SChiichen pub fn setup_sigcontext(
3573c82aa56SChiichen &mut self,
3583c82aa56SChiichen mask: &SigSet,
3593c82aa56SChiichen frame: &TrapFrame,
3603c82aa56SChiichen ) -> Result<i32, SystemError> {
3613c82aa56SChiichen //TODO 引入线程后补上
3623c82aa56SChiichen // let current_thread = ProcessManager::current_pcb().thread;
3633c82aa56SChiichen let pcb = ProcessManager::current_pcb();
36470a4e555SLoGin let mut archinfo_guard = pcb.arch_info_irqsave();
3653c82aa56SChiichen self.oldmask = *mask;
366b5b571e0SLoGin self.frame = *frame;
3673c82aa56SChiichen // context.trap_num = unsafe { (*current_thread).trap_num };
3683c82aa56SChiichen // context.err_code = unsafe { (*current_thread).err_code };
3693c82aa56SChiichen // context.cr2 = unsafe { (*current_thread).cr2 };
370b5b571e0SLoGin self.reserved_for_x87_state = *archinfo_guard.fp_state();
3713c82aa56SChiichen
3723c82aa56SChiichen // 保存完毕后,清空fp_state,以免下次save的时候,出现SIMD exception
3733c82aa56SChiichen archinfo_guard.clear_fp_state();
3743c82aa56SChiichen return Ok(0);
3753c82aa56SChiichen }
3763c82aa56SChiichen
3773c82aa56SChiichen /// 指定的sigcontext恢复到当前进程的内核栈帧中,并将当前线程结构体的几个参数进行恢复
3783c82aa56SChiichen ///
3793c82aa56SChiichen /// ## 参数
3803c82aa56SChiichen /// - `frame` 目标栈帧(也就是把context恢复到这个栈帧中)
3813c82aa56SChiichen ///
3823c82aa56SChiichen /// ##返回值
3833c82aa56SChiichen /// - `true` -> 成功恢复
3843c82aa56SChiichen /// - `false` -> 执行失败
restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool3853c82aa56SChiichen pub fn restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool {
3863c82aa56SChiichen let guard = ProcessManager::current_pcb();
3870d6cf65aSLoGin let mut arch_info = guard.arch_info_irqsave();
388b5b571e0SLoGin (*frame) = self.frame;
3893c82aa56SChiichen // (*current_thread).trap_num = (*context).trap_num;
3903c82aa56SChiichen *arch_info.cr2_mut() = self.cr2 as usize;
3913c82aa56SChiichen // (*current_thread).err_code = (*context).err_code;
3923c82aa56SChiichen // 如果当前进程有fpstate,则将其恢复到pcb的fp_state中
393b5b571e0SLoGin *arch_info.fp_state_mut() = self.reserved_for_x87_state;
3943c82aa56SChiichen arch_info.restore_fp_state();
3953c82aa56SChiichen return true;
3963c82aa56SChiichen }
3973c82aa56SChiichen }
3983c82aa56SChiichen /// @brief 信号处理备用栈的信息
399*bd70d2d1SLoGin #[allow(dead_code)]
4003c82aa56SChiichen #[derive(Debug, Clone, Copy)]
4013c82aa56SChiichen pub struct SigStack {
4023c82aa56SChiichen pub sp: *mut c_void,
4033c82aa56SChiichen pub flags: u32,
4043c82aa56SChiichen pub size: u32,
4053c82aa56SChiichen pub fpstate: FpState,
4063c82aa56SChiichen }
4073c82aa56SChiichen
4083c82aa56SChiichen #[no_mangle]
do_signal(frame: &mut TrapFrame)4093c82aa56SChiichen unsafe extern "C" fn do_signal(frame: &mut TrapFrame) {
4103c82aa56SChiichen X86_64SignalArch::do_signal(frame);
41170a4e555SLoGin return;
4123c82aa56SChiichen }
4133c82aa56SChiichen
4143c82aa56SChiichen pub struct X86_64SignalArch;
4153c82aa56SChiichen
4163c82aa56SChiichen impl SignalArch for X86_64SignalArch {
do_signal(frame: &mut TrapFrame)4173c82aa56SChiichen unsafe fn do_signal(frame: &mut TrapFrame) {
41816033951SGnoCiYeH let pcb = ProcessManager::current_pcb();
41952bcb59eSGnoCiYeH
42052bcb59eSGnoCiYeH let siginfo = pcb.try_siginfo_irqsave(5);
42116033951SGnoCiYeH
42270a4e555SLoGin if unlikely(siginfo.is_none()) {
4233c82aa56SChiichen return;
4243c82aa56SChiichen }
4253c82aa56SChiichen
42670a4e555SLoGin let siginfo_read_guard = siginfo.unwrap();
42770a4e555SLoGin
42870a4e555SLoGin // 检查sigpending是否为0
429b5b571e0SLoGin if siginfo_read_guard.sig_pending().signal().bits() == 0 || !frame.is_from_user() {
43070a4e555SLoGin // 若没有正在等待处理的信号,或者将要返回到的是内核态,则返回
43170a4e555SLoGin return;
43270a4e555SLoGin }
43370a4e555SLoGin
4343c82aa56SChiichen let pcb = ProcessManager::current_pcb();
43570a4e555SLoGin
4363c82aa56SChiichen let mut sig_number: Signal;
4373c82aa56SChiichen let mut info: Option<SigInfo>;
4383c82aa56SChiichen let mut sigaction: Sigaction;
439b5b571e0SLoGin let sig_block: SigSet = *siginfo_read_guard.sig_block();
44070a4e555SLoGin drop(siginfo_read_guard);
44170a4e555SLoGin
44252bcb59eSGnoCiYeH let sig_guard = pcb.try_sig_struct_irqsave(5);
44370a4e555SLoGin if unlikely(sig_guard.is_none()) {
44470a4e555SLoGin return;
44570a4e555SLoGin }
44670a4e555SLoGin let siginfo_mut = pcb.try_siginfo_mut(5);
44770a4e555SLoGin if unlikely(siginfo_mut.is_none()) {
44870a4e555SLoGin return;
44970a4e555SLoGin }
45070a4e555SLoGin
45170a4e555SLoGin let sig_guard = sig_guard.unwrap();
45270a4e555SLoGin let mut siginfo_mut_guard = siginfo_mut.unwrap();
4533c82aa56SChiichen loop {
45470a4e555SLoGin (sig_number, info) = siginfo_mut_guard.dequeue_signal(&sig_block);
4553c82aa56SChiichen // 如果信号非法,则直接返回
4563c82aa56SChiichen if sig_number == Signal::INVALID {
4573c82aa56SChiichen return;
4583c82aa56SChiichen }
4593c82aa56SChiichen
4603c82aa56SChiichen sigaction = sig_guard.handlers[sig_number as usize - 1];
46170a4e555SLoGin
4623c82aa56SChiichen match sigaction.action() {
4633c82aa56SChiichen SigactionType::SaHandler(action_type) => match action_type {
464b5b571e0SLoGin SaHandlerType::Error => {
4652eab6dd7S曾俊 error!("Trying to handle a Sigerror on Process:{:?}", pcb.pid());
4663c82aa56SChiichen return;
4673c82aa56SChiichen }
468b5b571e0SLoGin SaHandlerType::Default => {
4693c82aa56SChiichen sigaction = Sigaction::default();
4703c82aa56SChiichen break;
4713c82aa56SChiichen }
472b5b571e0SLoGin SaHandlerType::Ignore => continue,
473b5b571e0SLoGin SaHandlerType::Customized(_) => {
4743c82aa56SChiichen break;
4753c82aa56SChiichen }
4763c82aa56SChiichen },
4773c82aa56SChiichen SigactionType::SaSigaction(_) => todo!(),
4783c82aa56SChiichen }
4793c82aa56SChiichen // 如果当前动作是忽略这个信号,就继续循环。
4803c82aa56SChiichen }
48170a4e555SLoGin
482b5b571e0SLoGin let oldset = *siginfo_mut_guard.sig_block();
4833c82aa56SChiichen //避免死锁
48470a4e555SLoGin drop(siginfo_mut_guard);
4853c82aa56SChiichen drop(sig_guard);
48670a4e555SLoGin
48770a4e555SLoGin // 做完上面的检查后,开中断
48870a4e555SLoGin CurrentIrqArch::interrupt_enable();
4893c82aa56SChiichen let res: Result<i32, SystemError> =
4903c82aa56SChiichen handle_signal(sig_number, &mut sigaction, &info.unwrap(), &oldset, frame);
4913c82aa56SChiichen if res.is_err() {
4922eab6dd7S曾俊 error!(
4933c82aa56SChiichen "Error occurred when handling signal: {}, pid={:?}, errcode={:?}",
4943c82aa56SChiichen sig_number as i32,
4953c82aa56SChiichen ProcessManager::current_pcb().pid(),
4968d72b68dSJomo res.as_ref().unwrap_err()
4973c82aa56SChiichen );
4983c82aa56SChiichen }
4993c82aa56SChiichen }
5003c82aa56SChiichen
sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u645013c82aa56SChiichen fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64 {
5028612b6ceSLoGin let frame = (trap_frame.rsp as usize - size_of::<u64>()) as *mut SigFrame;
5033c82aa56SChiichen
5043c82aa56SChiichen // 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击)
5053c82aa56SChiichen if UserBufferWriter::new(frame, size_of::<SigFrame>(), true).is_err() {
5062eab6dd7S曾俊 error!("rsp doesn't from user level");
5073c82aa56SChiichen let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32)
5083c82aa56SChiichen .map_err(|e| e.to_posix_errno());
5093c82aa56SChiichen return trap_frame.rax;
5103c82aa56SChiichen }
5113c82aa56SChiichen let mut sigmask: SigSet = unsafe { (*frame).context.oldmask };
5123c82aa56SChiichen set_current_sig_blocked(&mut sigmask);
5133c82aa56SChiichen // 从用户栈恢复sigcontext
5143c82aa56SChiichen if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) {
5152eab6dd7S曾俊 error!("unable to restore sigcontext");
5163c82aa56SChiichen let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32)
5173c82aa56SChiichen .map_err(|e| e.to_posix_errno());
5183c82aa56SChiichen // 如果这里返回 err 值的话会丢失上一个系统调用的返回值
5193c82aa56SChiichen }
5203c82aa56SChiichen // 由于系统调用的返回值会被系统调用模块被存放在rax寄存器,因此,为了还原原来的那个系统调用的返回值,我们需要在这里返回恢复后的rax的值
5213c82aa56SChiichen return trap_frame.rax;
5223c82aa56SChiichen }
5233c82aa56SChiichen }
5243c82aa56SChiichen
5253c82aa56SChiichen /// @brief 真正发送signal,执行自定义的处理函数
5263c82aa56SChiichen ///
5273c82aa56SChiichen /// @param sig 信号number
5283c82aa56SChiichen /// @param sigaction 信号响应动作
5293c82aa56SChiichen /// @param info 信号信息
5303c82aa56SChiichen /// @param oldset
5313c82aa56SChiichen /// @param regs 之前的系统调用将要返回的时候,要弹出的栈帧的拷贝
5323c82aa56SChiichen ///
5333c82aa56SChiichen /// @return Result<0,SystemError> 若Error, 则返回错误码,否则返回Ok(0)
handle_signal( sig: Signal, sigaction: &mut Sigaction, info: &SigInfo, oldset: &SigSet, frame: &mut TrapFrame, ) -> Result<i32, SystemError>5343c82aa56SChiichen fn handle_signal(
5353c82aa56SChiichen sig: Signal,
5363c82aa56SChiichen sigaction: &mut Sigaction,
5373c82aa56SChiichen info: &SigInfo,
5383c82aa56SChiichen oldset: &SigSet,
5393c82aa56SChiichen frame: &mut TrapFrame,
5403c82aa56SChiichen ) -> Result<i32, SystemError> {
541e7071df6SLoGin // TODO 这里要补充一段逻辑,好像是为了保证引入线程之后的地址空间不会出问题。详见https://code.dragonos.org.cn/xref/linux-6.1.9/arch/mips/kernel/signal.c#830
5423c82aa56SChiichen
5433c82aa56SChiichen // 设置栈帧
5443c82aa56SChiichen return setup_frame(sig, sigaction, info, oldset, frame);
5453c82aa56SChiichen }
5463c82aa56SChiichen
5473c82aa56SChiichen /// @brief 在用户栈上开辟一块空间,并且把内核栈的栈帧以及需要在用户态执行的代码给保存进去。
5483c82aa56SChiichen ///
5493c82aa56SChiichen /// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧
setup_frame( sig: Signal, sigaction: &mut Sigaction, info: &SigInfo, oldset: &SigSet, trap_frame: &mut TrapFrame, ) -> Result<i32, SystemError>5503c82aa56SChiichen fn setup_frame(
5513c82aa56SChiichen sig: Signal,
5523c82aa56SChiichen sigaction: &mut Sigaction,
5533c82aa56SChiichen info: &SigInfo,
5543c82aa56SChiichen oldset: &SigSet,
5553c82aa56SChiichen trap_frame: &mut TrapFrame,
5563c82aa56SChiichen ) -> Result<i32, SystemError> {
5573c82aa56SChiichen let ret_code_ptr: *mut c_void;
5583c82aa56SChiichen let temp_handler: *mut c_void;
5593c82aa56SChiichen match sigaction.action() {
5603c82aa56SChiichen SigactionType::SaHandler(handler_type) => match handler_type {
561b5b571e0SLoGin SaHandlerType::Default => {
5623c82aa56SChiichen sig.handle_default();
5633c82aa56SChiichen return Ok(0);
5643c82aa56SChiichen }
565b5b571e0SLoGin SaHandlerType::Customized(handler) => {
5663c82aa56SChiichen // 如果handler位于内核空间
5673c82aa56SChiichen if handler >= MMArch::USER_END_VADDR {
5683c82aa56SChiichen // 如果当前是SIGSEGV,则采用默认函数处理
5693c82aa56SChiichen if sig == Signal::SIGSEGV {
5703c82aa56SChiichen sig.handle_default();
5713c82aa56SChiichen return Ok(0);
5723c82aa56SChiichen } else {
5732eab6dd7S曾俊 error!("attempting to execute a signal handler from kernel");
5743c82aa56SChiichen sig.handle_default();
5753c82aa56SChiichen return Err(SystemError::EINVAL);
5763c82aa56SChiichen }
5773c82aa56SChiichen } else {
5783c82aa56SChiichen // 为了与Linux的兼容性,64位程序必须由用户自行指定restorer
5793c82aa56SChiichen if sigaction.flags().contains(SigFlags::SA_RESTORER) {
5803c82aa56SChiichen ret_code_ptr = sigaction.restorer().unwrap().data() as *mut c_void;
5813c82aa56SChiichen } else {
5822eab6dd7S曾俊 error!(
5833c82aa56SChiichen "pid-{:?} forgot to set SA_FLAG_RESTORER for signal {:?}",
5843c82aa56SChiichen ProcessManager::current_pcb().pid(),
5853c82aa56SChiichen sig as i32
5863c82aa56SChiichen );
5873c82aa56SChiichen let r = Syscall::kill(
5883c82aa56SChiichen ProcessManager::current_pcb().pid(),
5893c82aa56SChiichen Signal::SIGSEGV as i32,
5903c82aa56SChiichen );
5913c82aa56SChiichen if r.is_err() {
5922eab6dd7S曾俊 error!("In setup_sigcontext: generate SIGSEGV signal failed");
5933c82aa56SChiichen }
5943c82aa56SChiichen return Err(SystemError::EINVAL);
5953c82aa56SChiichen }
5963c82aa56SChiichen if sigaction.restorer().is_none() {
5972eab6dd7S曾俊 error!(
5983c82aa56SChiichen "restorer in process:{:?} is not defined",
5993c82aa56SChiichen ProcessManager::current_pcb().pid()
6003c82aa56SChiichen );
6013c82aa56SChiichen return Err(SystemError::EINVAL);
6023c82aa56SChiichen }
6033c82aa56SChiichen temp_handler = handler.data() as *mut c_void;
6043c82aa56SChiichen }
6053c82aa56SChiichen }
606b5b571e0SLoGin SaHandlerType::Ignore => {
6073c82aa56SChiichen return Ok(0);
6083c82aa56SChiichen }
6093c82aa56SChiichen _ => {
6103c82aa56SChiichen return Err(SystemError::EINVAL);
6113c82aa56SChiichen }
6123c82aa56SChiichen },
6133c82aa56SChiichen SigactionType::SaSigaction(_) => {
6143c82aa56SChiichen //TODO 这里应该是可以恢复栈的,等后续来做
6152eab6dd7S曾俊 error!("trying to recover from sigaction type instead of handler");
6163c82aa56SChiichen return Err(SystemError::EINVAL);
6173c82aa56SChiichen }
6183c82aa56SChiichen }
619b5b571e0SLoGin let frame: *mut SigFrame = get_stack(trap_frame, size_of::<SigFrame>());
6202eab6dd7S曾俊 // debug!("frame=0x{:016x}", frame as usize);
6213c82aa56SChiichen // 要求这个frame的地址位于用户空间,因此进行校验
62270a4e555SLoGin let r: Result<UserBufferWriter<'_>, SystemError> =
62370a4e555SLoGin UserBufferWriter::new(frame, size_of::<SigFrame>(), true);
6243c82aa56SChiichen if r.is_err() {
6253c82aa56SChiichen // 如果地址区域位于内核空间,则直接报错
6263c82aa56SChiichen // todo: 生成一个sigsegv
6273c82aa56SChiichen let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
6283c82aa56SChiichen if r.is_err() {
6292eab6dd7S曾俊 error!("In setup frame: generate SIGSEGV signal failed");
6303c82aa56SChiichen }
6312eab6dd7S曾俊 error!("In setup frame: access check failed");
6323c82aa56SChiichen return Err(SystemError::EFAULT);
6333c82aa56SChiichen }
6343c82aa56SChiichen
6353c82aa56SChiichen // 将siginfo拷贝到用户栈
6363c82aa56SChiichen info.copy_siginfo_to_user(unsafe { &mut ((*frame).info) as *mut SigInfo })
6373c82aa56SChiichen .map_err(|e| -> SystemError {
6383c82aa56SChiichen let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
6393c82aa56SChiichen if r.is_err() {
6402eab6dd7S曾俊 error!("In copy_siginfo_to_user: generate SIGSEGV signal failed");
6413c82aa56SChiichen }
6423c82aa56SChiichen return e;
6433c82aa56SChiichen })?;
6443c82aa56SChiichen
6453c82aa56SChiichen // todo: 拷贝处理程序备用栈的地址、大小、ss_flags
6463c82aa56SChiichen
6473c82aa56SChiichen unsafe {
6483c82aa56SChiichen (*frame)
6493c82aa56SChiichen .context
650b5b571e0SLoGin .setup_sigcontext(oldset, trap_frame)
6513c82aa56SChiichen .map_err(|e: SystemError| -> SystemError {
6523c82aa56SChiichen let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
6533c82aa56SChiichen if r.is_err() {
6542eab6dd7S曾俊 error!("In setup_sigcontext: generate SIGSEGV signal failed");
6553c82aa56SChiichen }
6563c82aa56SChiichen return e;
6573c82aa56SChiichen })?
6583c82aa56SChiichen };
6593c82aa56SChiichen
6603c82aa56SChiichen unsafe {
6613c82aa56SChiichen // 在开头检验过sigaction.restorer是否为空了,实际上libc会保证 restorer始终不为空
6623c82aa56SChiichen (*frame).ret_code_ptr = ret_code_ptr;
6633c82aa56SChiichen }
6643c82aa56SChiichen
6653c82aa56SChiichen unsafe { (*frame).handler = temp_handler };
6663c82aa56SChiichen // 传入信号处理函数的第一个参数
6673c82aa56SChiichen trap_frame.rdi = sig as u64;
6683c82aa56SChiichen trap_frame.rsi = unsafe { &(*frame).info as *const SigInfo as u64 };
6693c82aa56SChiichen trap_frame.rsp = frame as u64;
6703c82aa56SChiichen trap_frame.rip = unsafe { (*frame).handler as u64 };
6713c82aa56SChiichen // 设置cs和ds寄存器
6723c82aa56SChiichen trap_frame.cs = (USER_CS.bits() | 0x3) as u64;
6733c82aa56SChiichen trap_frame.ds = (USER_DS.bits() | 0x3) as u64;
6743c82aa56SChiichen
6753c82aa56SChiichen // 禁用中断
6763c82aa56SChiichen // trap_frame.rflags &= !(0x200);
6773c82aa56SChiichen
6783c82aa56SChiichen return Ok(0);
6793c82aa56SChiichen }
6803c82aa56SChiichen
6813c82aa56SChiichen #[inline(always)]
get_stack(frame: &TrapFrame, size: usize) -> *mut SigFrame6823c82aa56SChiichen fn get_stack(frame: &TrapFrame, size: usize) -> *mut SigFrame {
6833c82aa56SChiichen // TODO:在 linux 中会根据 Sigaction 中的一个flag 的值来确定是否使用pcb中的 signal 处理程序备用堆栈,现在的
6843c82aa56SChiichen // pcb中也没有这个备用堆栈
6853c82aa56SChiichen
6863c82aa56SChiichen // 默认使用 用户栈的栈顶指针-128字节的红区-sigframe的大小 并且16字节对齐
6873c82aa56SChiichen let mut rsp: usize = (frame.rsp as usize) - 128 - size;
6883c82aa56SChiichen // 按照要求进行对齐,别问为什么减8,不减8就是错的,可以看
6893c82aa56SChiichen // https://sourcegraph.com/github.com/torvalds/linux@dd72f9c7e512da377074d47d990564959b772643/-/blob/arch/x86/kernel/signal.c?L124
6903c82aa56SChiichen // 我猜测是跟x86汇编的某些弹栈行为有关系,它可能会出于某种原因递增 rsp
6913c82aa56SChiichen rsp &= (!(STACK_ALIGN - 1)) as usize - 8;
6923c82aa56SChiichen // rsp &= (!(STACK_ALIGN - 1)) as usize;
6933c82aa56SChiichen return rsp as *mut SigFrame;
6943c82aa56SChiichen }
6953c82aa56SChiichen
6963c82aa56SChiichen /// 信号默认处理函数——终止进程
sig_terminate(sig: Signal)6973c82aa56SChiichen fn sig_terminate(sig: Signal) {
6983c82aa56SChiichen ProcessManager::exit(sig as usize);
6993c82aa56SChiichen }
7003c82aa56SChiichen
7013c82aa56SChiichen /// 信号默认处理函数——终止进程并生成 core dump
sig_terminate_dump(sig: Signal)7023c82aa56SChiichen fn sig_terminate_dump(sig: Signal) {
7033c82aa56SChiichen ProcessManager::exit(sig as usize);
7043c82aa56SChiichen // TODO 生成 coredump 文件
7053c82aa56SChiichen }
7063c82aa56SChiichen
7073c82aa56SChiichen /// 信号默认处理函数——暂停进程
sig_stop(sig: Signal)7083c82aa56SChiichen fn sig_stop(sig: Signal) {
7093c82aa56SChiichen let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
7103c82aa56SChiichen ProcessManager::mark_stop().unwrap_or_else(|e| {
7112eab6dd7S曾俊 error!(
7123c82aa56SChiichen "sleep error :{:?},failed to sleep process :{:?}, with signal :{:?}",
7133c82aa56SChiichen e,
7143c82aa56SChiichen ProcessManager::current_pcb(),
7153c82aa56SChiichen sig
7163c82aa56SChiichen );
7173c82aa56SChiichen });
7183c82aa56SChiichen drop(guard);
719f0c87a89SGnoCiYeH schedule(SchedMode::SM_NONE);
7203c82aa56SChiichen // TODO 暂停进程
7213c82aa56SChiichen }
7223c82aa56SChiichen /// 信号默认处理函数——继续进程
sig_continue(sig: Signal)7233c82aa56SChiichen fn sig_continue(sig: Signal) {
7243c82aa56SChiichen ProcessManager::wakeup_stop(&ProcessManager::current_pcb()).unwrap_or_else(|_| {
7252eab6dd7S曾俊 error!(
7263c82aa56SChiichen "Failed to wake up process pid = {:?} with signal :{:?}",
7273c82aa56SChiichen ProcessManager::current_pcb().pid(),
7283c82aa56SChiichen sig
7293c82aa56SChiichen );
7303c82aa56SChiichen });
7313c82aa56SChiichen }
7323c82aa56SChiichen /// 信号默认处理函数——忽略
sig_ignore(_sig: Signal)7333c82aa56SChiichen fn sig_ignore(_sig: Signal) {
7343c82aa56SChiichen return;
7353c82aa56SChiichen }
736