170a4e555SLoGin use core::{ffi::c_void, intrinsics::unlikely, mem::size_of}; 23c82aa56SChiichen 3*91e9d4abSLoGin use system_error::SystemError; 4*91e9d4abSLoGin 53c82aa56SChiichen use crate::{ 63c82aa56SChiichen arch::{ 73c82aa56SChiichen fpu::FpState, 83c82aa56SChiichen interrupt::TrapFrame, 93c82aa56SChiichen process::table::{USER_CS, USER_DS}, 103c82aa56SChiichen sched::sched, 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 kerror, 193c82aa56SChiichen mm::MemoryManagementArch, 203c82aa56SChiichen process::ProcessManager, 21*91e9d4abSLoGin 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 { 783c82aa56SChiichen fn eq(&self, other: &Signal) -> bool { 793c82aa56SChiichen *self as usize == *other as usize 803c82aa56SChiichen } 813c82aa56SChiichen } 823c82aa56SChiichen 833c82aa56SChiichen impl From<usize> for Signal { 843c82aa56SChiichen 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 { 893c82aa56SChiichen kerror!("Try to convert an invalid number to Signal"); 903c82aa56SChiichen return Signal::INVALID; 913c82aa56SChiichen } 923c82aa56SChiichen } 933c82aa56SChiichen } 943c82aa56SChiichen 953c82aa56SChiichen impl Into<usize> for Signal { 963c82aa56SChiichen fn into(self) -> usize { 973c82aa56SChiichen self as usize 983c82aa56SChiichen } 993c82aa56SChiichen } 1003c82aa56SChiichen 1013c82aa56SChiichen impl From<i32> for Signal { 1023c82aa56SChiichen fn from(value: i32) -> Self { 1033c82aa56SChiichen if value < 0 { 1043c82aa56SChiichen kerror!("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 1123c82aa56SChiichen impl Into<SigSet> for Signal { 1133c82aa56SChiichen fn into(self) -> SigSet { 1143c82aa56SChiichen SigSet { 1153c82aa56SChiichen bits: (1 << (self as usize - 1) as u64), 1163c82aa56SChiichen } 1173c82aa56SChiichen } 1183c82aa56SChiichen } 1193c82aa56SChiichen impl Signal { 1203c82aa56SChiichen /// 判断一个数字是否为可用的信号 1213c82aa56SChiichen #[inline] 1223c82aa56SChiichen pub fn is_valid(&self) -> bool { 1233c82aa56SChiichen return (*self) as usize <= MAX_SIG_NUM; 1243c82aa56SChiichen } 1253c82aa56SChiichen 1263c82aa56SChiichen /// const convertor between `Signal` and `SigSet` 1273c82aa56SChiichen 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] 1403c82aa56SChiichen pub fn is_rt_signal(&self) -> bool { 1413c82aa56SChiichen return (*self) as usize >= Signal::SIGRTMIN.into(); 1423c82aa56SChiichen } 1433c82aa56SChiichen 1443c82aa56SChiichen /// 调用信号的默认处理函数 1453c82aa56SChiichen pub fn handle_default(&self) { 1463c82aa56SChiichen match self { 1473c82aa56SChiichen Signal::INVALID => { 1483c82aa56SChiichen kerror!("attempting to handler an Invalid"); 1493c82aa56SChiichen } 1503c82aa56SChiichen Signal::SIGHUP => sig_terminate(self.clone()), 1513c82aa56SChiichen Signal::SIGINT => sig_terminate(self.clone()), 1523c82aa56SChiichen Signal::SIGQUIT => sig_terminate_dump(self.clone()), 1533c82aa56SChiichen Signal::SIGILL => sig_terminate_dump(self.clone()), 1543c82aa56SChiichen Signal::SIGTRAP => sig_terminate_dump(self.clone()), 1553c82aa56SChiichen Signal::SIGABRT_OR_IOT => sig_terminate_dump(self.clone()), 1563c82aa56SChiichen Signal::SIGBUS => sig_terminate_dump(self.clone()), 1573c82aa56SChiichen Signal::SIGFPE => sig_terminate_dump(self.clone()), 1583c82aa56SChiichen Signal::SIGKILL => sig_terminate(self.clone()), 1593c82aa56SChiichen Signal::SIGUSR1 => sig_terminate(self.clone()), 1603c82aa56SChiichen Signal::SIGSEGV => sig_terminate_dump(self.clone()), 1613c82aa56SChiichen Signal::SIGUSR2 => sig_terminate(self.clone()), 1623c82aa56SChiichen Signal::SIGPIPE => sig_terminate(self.clone()), 1633c82aa56SChiichen Signal::SIGALRM => sig_terminate(self.clone()), 1643c82aa56SChiichen Signal::SIGTERM => sig_terminate(self.clone()), 1653c82aa56SChiichen Signal::SIGSTKFLT => sig_terminate(self.clone()), 1663c82aa56SChiichen Signal::SIGCHLD => sig_ignore(self.clone()), 1673c82aa56SChiichen Signal::SIGCONT => sig_continue(self.clone()), 1683c82aa56SChiichen Signal::SIGSTOP => sig_stop(self.clone()), 1693c82aa56SChiichen Signal::SIGTSTP => sig_stop(self.clone()), 1703c82aa56SChiichen Signal::SIGTTIN => sig_stop(self.clone()), 1713c82aa56SChiichen Signal::SIGTTOU => sig_stop(self.clone()), 1723c82aa56SChiichen Signal::SIGURG => sig_ignore(self.clone()), 1733c82aa56SChiichen Signal::SIGXCPU => sig_terminate_dump(self.clone()), 1743c82aa56SChiichen Signal::SIGXFSZ => sig_terminate_dump(self.clone()), 1753c82aa56SChiichen Signal::SIGVTALRM => sig_terminate(self.clone()), 1763c82aa56SChiichen Signal::SIGPROF => sig_terminate(self.clone()), 1773c82aa56SChiichen Signal::SIGWINCH => sig_ignore(self.clone()), 1783c82aa56SChiichen Signal::SIGIO_OR_POLL => sig_terminate(self.clone()), 1793c82aa56SChiichen Signal::SIGPWR => sig_terminate(self.clone()), 1803c82aa56SChiichen Signal::SIGSYS => sig_terminate(self.clone()), 1813c82aa56SChiichen Signal::SIGRTMIN => sig_terminate(self.clone()), 1823c82aa56SChiichen Signal::SIGRTMAX => sig_terminate(self.clone()), 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)] 2113c82aa56SChiichen 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 写上实时信号 2783c82aa56SChiichen 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 312bf4a4899SLoGin impl Into<i32> for SigChildCode { 313bf4a4899SLoGin fn into(self) -> i32 { 314bf4a4899SLoGin self 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)` (暂时不会返回错误) 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; 3663c82aa56SChiichen self.frame = frame.clone(); 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 }; 3703c82aa56SChiichen self.reserved_for_x87_state = archinfo_guard.fp_state().clone(); 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` -> 执行失败 3853c82aa56SChiichen pub fn restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool { 3863c82aa56SChiichen let guard = ProcessManager::current_pcb(); 3873c82aa56SChiichen let mut arch_info = guard.arch_info(); 3883c82aa56SChiichen (*frame) = self.frame.clone(); 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中 3933c82aa56SChiichen *arch_info.fp_state_mut() = self.reserved_for_x87_state.clone(); 3943c82aa56SChiichen arch_info.restore_fp_state(); 3953c82aa56SChiichen return true; 3963c82aa56SChiichen } 3973c82aa56SChiichen } 3983c82aa56SChiichen /// @brief 信号处理备用栈的信息 3993c82aa56SChiichen #[derive(Debug, Clone, Copy)] 4003c82aa56SChiichen pub struct SigStack { 4013c82aa56SChiichen pub sp: *mut c_void, 4023c82aa56SChiichen pub flags: u32, 4033c82aa56SChiichen pub size: u32, 4043c82aa56SChiichen pub fpstate: FpState, 4053c82aa56SChiichen } 4063c82aa56SChiichen 4073c82aa56SChiichen #[no_mangle] 4083c82aa56SChiichen unsafe extern "C" fn do_signal(frame: &mut TrapFrame) { 4093c82aa56SChiichen X86_64SignalArch::do_signal(frame); 41070a4e555SLoGin return; 4113c82aa56SChiichen } 4123c82aa56SChiichen 4133c82aa56SChiichen pub struct X86_64SignalArch; 4143c82aa56SChiichen 4153c82aa56SChiichen impl SignalArch for X86_64SignalArch { 4163c82aa56SChiichen unsafe fn do_signal(frame: &mut TrapFrame) { 41716033951SGnoCiYeH let pcb = ProcessManager::current_pcb(); 41816033951SGnoCiYeH let siginfo = pcb.try_siginfo(5); 41916033951SGnoCiYeH 42070a4e555SLoGin if unlikely(siginfo.is_none()) { 4213c82aa56SChiichen return; 4223c82aa56SChiichen } 4233c82aa56SChiichen 42470a4e555SLoGin let siginfo_read_guard = siginfo.unwrap(); 42570a4e555SLoGin 42670a4e555SLoGin // 检查sigpending是否为0 42770a4e555SLoGin if siginfo_read_guard.sig_pending().signal().bits() == 0 || !frame.from_user() { 42870a4e555SLoGin // 若没有正在等待处理的信号,或者将要返回到的是内核态,则返回 42970a4e555SLoGin return; 43070a4e555SLoGin } 43170a4e555SLoGin 4323c82aa56SChiichen let pcb = ProcessManager::current_pcb(); 43370a4e555SLoGin 4343c82aa56SChiichen let mut sig_number: Signal; 4353c82aa56SChiichen let mut info: Option<SigInfo>; 4363c82aa56SChiichen let mut sigaction: Sigaction; 43770a4e555SLoGin let sig_block: SigSet = siginfo_read_guard.sig_block().clone(); 43870a4e555SLoGin drop(siginfo_read_guard); 43970a4e555SLoGin 44070a4e555SLoGin let sig_guard = pcb.try_sig_struct_irq(5); 44170a4e555SLoGin if unlikely(sig_guard.is_none()) { 44270a4e555SLoGin return; 44370a4e555SLoGin } 44470a4e555SLoGin let siginfo_mut = pcb.try_siginfo_mut(5); 44570a4e555SLoGin if unlikely(siginfo_mut.is_none()) { 44670a4e555SLoGin return; 44770a4e555SLoGin } 44870a4e555SLoGin 44970a4e555SLoGin let sig_guard = sig_guard.unwrap(); 45070a4e555SLoGin let mut siginfo_mut_guard = siginfo_mut.unwrap(); 4513c82aa56SChiichen loop { 45270a4e555SLoGin (sig_number, info) = siginfo_mut_guard.dequeue_signal(&sig_block); 4533c82aa56SChiichen // 如果信号非法,则直接返回 4543c82aa56SChiichen if sig_number == Signal::INVALID { 4553c82aa56SChiichen return; 4563c82aa56SChiichen } 4573c82aa56SChiichen 4583c82aa56SChiichen sigaction = sig_guard.handlers[sig_number as usize - 1]; 45970a4e555SLoGin 4603c82aa56SChiichen match sigaction.action() { 4613c82aa56SChiichen SigactionType::SaHandler(action_type) => match action_type { 4623c82aa56SChiichen SaHandlerType::SigError => { 4633c82aa56SChiichen kerror!("Trying to handle a Sigerror on Process:{:?}", pcb.pid()); 4643c82aa56SChiichen return; 4653c82aa56SChiichen } 4663c82aa56SChiichen SaHandlerType::SigDefault => { 4673c82aa56SChiichen sigaction = Sigaction::default(); 4683c82aa56SChiichen break; 4693c82aa56SChiichen } 4703c82aa56SChiichen SaHandlerType::SigIgnore => continue, 4713c82aa56SChiichen SaHandlerType::SigCustomized(_) => { 4723c82aa56SChiichen break; 4733c82aa56SChiichen } 4743c82aa56SChiichen }, 4753c82aa56SChiichen SigactionType::SaSigaction(_) => todo!(), 4763c82aa56SChiichen } 4773c82aa56SChiichen // 如果当前动作是忽略这个信号,就继续循环。 4783c82aa56SChiichen } 47970a4e555SLoGin 48070a4e555SLoGin let oldset = siginfo_mut_guard.sig_block().clone(); 4813c82aa56SChiichen //避免死锁 48270a4e555SLoGin drop(siginfo_mut_guard); 4833c82aa56SChiichen drop(sig_guard); 48470a4e555SLoGin 48570a4e555SLoGin // 做完上面的检查后,开中断 48670a4e555SLoGin CurrentIrqArch::interrupt_enable(); 4873c82aa56SChiichen let res: Result<i32, SystemError> = 4883c82aa56SChiichen handle_signal(sig_number, &mut sigaction, &info.unwrap(), &oldset, frame); 4893c82aa56SChiichen if res.is_err() { 4903c82aa56SChiichen kerror!( 4913c82aa56SChiichen "Error occurred when handling signal: {}, pid={:?}, errcode={:?}", 4923c82aa56SChiichen sig_number as i32, 4933c82aa56SChiichen ProcessManager::current_pcb().pid(), 4943c82aa56SChiichen res.unwrap_err() 4953c82aa56SChiichen ); 4963c82aa56SChiichen } 4973c82aa56SChiichen } 4983c82aa56SChiichen 4993c82aa56SChiichen fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64 { 5008612b6ceSLoGin let frame = (trap_frame.rsp as usize - size_of::<u64>()) as *mut SigFrame; 5013c82aa56SChiichen 5023c82aa56SChiichen // 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击) 5033c82aa56SChiichen if UserBufferWriter::new(frame, size_of::<SigFrame>(), true).is_err() { 5043c82aa56SChiichen kerror!("rsp doesn't from user level"); 5053c82aa56SChiichen let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32) 5063c82aa56SChiichen .map_err(|e| e.to_posix_errno()); 5073c82aa56SChiichen return trap_frame.rax; 5083c82aa56SChiichen } 5093c82aa56SChiichen let mut sigmask: SigSet = unsafe { (*frame).context.oldmask }; 5103c82aa56SChiichen set_current_sig_blocked(&mut sigmask); 5113c82aa56SChiichen // 从用户栈恢复sigcontext 5123c82aa56SChiichen if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) { 5133c82aa56SChiichen kerror!("unable to restore sigcontext"); 5143c82aa56SChiichen let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32) 5153c82aa56SChiichen .map_err(|e| e.to_posix_errno()); 5163c82aa56SChiichen // 如果这里返回 err 值的话会丢失上一个系统调用的返回值 5173c82aa56SChiichen } 5183c82aa56SChiichen // 由于系统调用的返回值会被系统调用模块被存放在rax寄存器,因此,为了还原原来的那个系统调用的返回值,我们需要在这里返回恢复后的rax的值 5193c82aa56SChiichen return trap_frame.rax; 5203c82aa56SChiichen } 5213c82aa56SChiichen } 5223c82aa56SChiichen 5233c82aa56SChiichen /// @brief 真正发送signal,执行自定义的处理函数 5243c82aa56SChiichen /// 5253c82aa56SChiichen /// @param sig 信号number 5263c82aa56SChiichen /// @param sigaction 信号响应动作 5273c82aa56SChiichen /// @param info 信号信息 5283c82aa56SChiichen /// @param oldset 5293c82aa56SChiichen /// @param regs 之前的系统调用将要返回的时候,要弹出的栈帧的拷贝 5303c82aa56SChiichen /// 5313c82aa56SChiichen /// @return Result<0,SystemError> 若Error, 则返回错误码,否则返回Ok(0) 5323c82aa56SChiichen fn handle_signal( 5333c82aa56SChiichen sig: Signal, 5343c82aa56SChiichen sigaction: &mut Sigaction, 5353c82aa56SChiichen info: &SigInfo, 5363c82aa56SChiichen oldset: &SigSet, 5373c82aa56SChiichen frame: &mut TrapFrame, 5383c82aa56SChiichen ) -> Result<i32, SystemError> { 5393c82aa56SChiichen // TODO 这里要补充一段逻辑,好像是为了保证引入线程之后的地址空间不会出问题。详见https://opengrok.ringotek.cn/xref/linux-6.1.9/arch/mips/kernel/signal.c#830 5403c82aa56SChiichen 5413c82aa56SChiichen // 设置栈帧 5423c82aa56SChiichen return setup_frame(sig, sigaction, info, oldset, frame); 5433c82aa56SChiichen } 5443c82aa56SChiichen 5453c82aa56SChiichen /// @brief 在用户栈上开辟一块空间,并且把内核栈的栈帧以及需要在用户态执行的代码给保存进去。 5463c82aa56SChiichen /// 5473c82aa56SChiichen /// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧 5483c82aa56SChiichen fn setup_frame( 5493c82aa56SChiichen sig: Signal, 5503c82aa56SChiichen sigaction: &mut Sigaction, 5513c82aa56SChiichen info: &SigInfo, 5523c82aa56SChiichen oldset: &SigSet, 5533c82aa56SChiichen trap_frame: &mut TrapFrame, 5543c82aa56SChiichen ) -> Result<i32, SystemError> { 5553c82aa56SChiichen let ret_code_ptr: *mut c_void; 5563c82aa56SChiichen let temp_handler: *mut c_void; 5573c82aa56SChiichen match sigaction.action() { 5583c82aa56SChiichen SigactionType::SaHandler(handler_type) => match handler_type { 5593c82aa56SChiichen SaHandlerType::SigDefault => { 5603c82aa56SChiichen sig.handle_default(); 5613c82aa56SChiichen return Ok(0); 5623c82aa56SChiichen } 5633c82aa56SChiichen SaHandlerType::SigCustomized(handler) => { 5643c82aa56SChiichen // 如果handler位于内核空间 5653c82aa56SChiichen if handler >= MMArch::USER_END_VADDR { 5663c82aa56SChiichen // 如果当前是SIGSEGV,则采用默认函数处理 5673c82aa56SChiichen if sig == Signal::SIGSEGV { 5683c82aa56SChiichen sig.handle_default(); 5693c82aa56SChiichen return Ok(0); 5703c82aa56SChiichen } else { 5713c82aa56SChiichen kerror!("attempting to execute a signal handler from kernel"); 5723c82aa56SChiichen sig.handle_default(); 5733c82aa56SChiichen return Err(SystemError::EINVAL); 5743c82aa56SChiichen } 5753c82aa56SChiichen } else { 5763c82aa56SChiichen // 为了与Linux的兼容性,64位程序必须由用户自行指定restorer 5773c82aa56SChiichen if sigaction.flags().contains(SigFlags::SA_RESTORER) { 5783c82aa56SChiichen ret_code_ptr = sigaction.restorer().unwrap().data() as *mut c_void; 5793c82aa56SChiichen } else { 5803c82aa56SChiichen kerror!( 5813c82aa56SChiichen "pid-{:?} forgot to set SA_FLAG_RESTORER for signal {:?}", 5823c82aa56SChiichen ProcessManager::current_pcb().pid(), 5833c82aa56SChiichen sig as i32 5843c82aa56SChiichen ); 5853c82aa56SChiichen let r = Syscall::kill( 5863c82aa56SChiichen ProcessManager::current_pcb().pid(), 5873c82aa56SChiichen Signal::SIGSEGV as i32, 5883c82aa56SChiichen ); 5893c82aa56SChiichen if r.is_err() { 5903c82aa56SChiichen kerror!("In setup_sigcontext: generate SIGSEGV signal failed"); 5913c82aa56SChiichen } 5923c82aa56SChiichen return Err(SystemError::EINVAL); 5933c82aa56SChiichen } 5943c82aa56SChiichen if sigaction.restorer().is_none() { 5953c82aa56SChiichen kerror!( 5963c82aa56SChiichen "restorer in process:{:?} is not defined", 5973c82aa56SChiichen ProcessManager::current_pcb().pid() 5983c82aa56SChiichen ); 5993c82aa56SChiichen return Err(SystemError::EINVAL); 6003c82aa56SChiichen } 6013c82aa56SChiichen temp_handler = handler.data() as *mut c_void; 6023c82aa56SChiichen } 6033c82aa56SChiichen } 6043c82aa56SChiichen SaHandlerType::SigIgnore => { 6053c82aa56SChiichen return Ok(0); 6063c82aa56SChiichen } 6073c82aa56SChiichen _ => { 6083c82aa56SChiichen return Err(SystemError::EINVAL); 6093c82aa56SChiichen } 6103c82aa56SChiichen }, 6113c82aa56SChiichen SigactionType::SaSigaction(_) => { 6123c82aa56SChiichen //TODO 这里应该是可以恢复栈的,等后续来做 6133c82aa56SChiichen kerror!("trying to recover from sigaction type instead of handler"); 6143c82aa56SChiichen return Err(SystemError::EINVAL); 6153c82aa56SChiichen } 6163c82aa56SChiichen } 6173c82aa56SChiichen let frame: *mut SigFrame = get_stack(&trap_frame, size_of::<SigFrame>()); 6183c82aa56SChiichen // kdebug!("frame=0x{:016x}", frame as usize); 6193c82aa56SChiichen // 要求这个frame的地址位于用户空间,因此进行校验 62070a4e555SLoGin let r: Result<UserBufferWriter<'_>, SystemError> = 62170a4e555SLoGin UserBufferWriter::new(frame, size_of::<SigFrame>(), true); 6223c82aa56SChiichen if r.is_err() { 6233c82aa56SChiichen // 如果地址区域位于内核空间,则直接报错 6243c82aa56SChiichen // todo: 生成一个sigsegv 6253c82aa56SChiichen let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32); 6263c82aa56SChiichen if r.is_err() { 6273c82aa56SChiichen kerror!("In setup frame: generate SIGSEGV signal failed"); 6283c82aa56SChiichen } 6293c82aa56SChiichen kerror!("In setup frame: access check failed"); 6303c82aa56SChiichen return Err(SystemError::EFAULT); 6313c82aa56SChiichen } 6323c82aa56SChiichen 6333c82aa56SChiichen // 将siginfo拷贝到用户栈 6343c82aa56SChiichen info.copy_siginfo_to_user(unsafe { &mut ((*frame).info) as *mut SigInfo }) 6353c82aa56SChiichen .map_err(|e| -> SystemError { 6363c82aa56SChiichen let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32); 6373c82aa56SChiichen if r.is_err() { 6383c82aa56SChiichen kerror!("In copy_siginfo_to_user: generate SIGSEGV signal failed"); 6393c82aa56SChiichen } 6403c82aa56SChiichen return e; 6413c82aa56SChiichen })?; 6423c82aa56SChiichen 6433c82aa56SChiichen // todo: 拷贝处理程序备用栈的地址、大小、ss_flags 6443c82aa56SChiichen 6453c82aa56SChiichen unsafe { 6463c82aa56SChiichen (*frame) 6473c82aa56SChiichen .context 6483c82aa56SChiichen .setup_sigcontext(oldset, &trap_frame) 6493c82aa56SChiichen .map_err(|e: SystemError| -> SystemError { 6503c82aa56SChiichen let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32); 6513c82aa56SChiichen if r.is_err() { 6523c82aa56SChiichen kerror!("In setup_sigcontext: generate SIGSEGV signal failed"); 6533c82aa56SChiichen } 6543c82aa56SChiichen return e; 6553c82aa56SChiichen })? 6563c82aa56SChiichen }; 6573c82aa56SChiichen 6583c82aa56SChiichen unsafe { 6593c82aa56SChiichen // 在开头检验过sigaction.restorer是否为空了,实际上libc会保证 restorer始终不为空 6603c82aa56SChiichen (*frame).ret_code_ptr = ret_code_ptr; 6613c82aa56SChiichen } 6623c82aa56SChiichen 6633c82aa56SChiichen unsafe { (*frame).handler = temp_handler }; 6643c82aa56SChiichen // 传入信号处理函数的第一个参数 6653c82aa56SChiichen trap_frame.rdi = sig as u64; 6663c82aa56SChiichen trap_frame.rsi = unsafe { &(*frame).info as *const SigInfo as u64 }; 6673c82aa56SChiichen trap_frame.rsp = frame as u64; 6683c82aa56SChiichen trap_frame.rip = unsafe { (*frame).handler as u64 }; 6693c82aa56SChiichen // 设置cs和ds寄存器 6703c82aa56SChiichen trap_frame.cs = (USER_CS.bits() | 0x3) as u64; 6713c82aa56SChiichen trap_frame.ds = (USER_DS.bits() | 0x3) as u64; 6723c82aa56SChiichen 6733c82aa56SChiichen // 禁用中断 6743c82aa56SChiichen // trap_frame.rflags &= !(0x200); 6753c82aa56SChiichen 6763c82aa56SChiichen return Ok(0); 6773c82aa56SChiichen } 6783c82aa56SChiichen 6793c82aa56SChiichen #[inline(always)] 6803c82aa56SChiichen fn get_stack(frame: &TrapFrame, size: usize) -> *mut SigFrame { 6813c82aa56SChiichen // TODO:在 linux 中会根据 Sigaction 中的一个flag 的值来确定是否使用pcb中的 signal 处理程序备用堆栈,现在的 6823c82aa56SChiichen // pcb中也没有这个备用堆栈 6833c82aa56SChiichen 6843c82aa56SChiichen // 默认使用 用户栈的栈顶指针-128字节的红区-sigframe的大小 并且16字节对齐 6853c82aa56SChiichen let mut rsp: usize = (frame.rsp as usize) - 128 - size; 6863c82aa56SChiichen // 按照要求进行对齐,别问为什么减8,不减8就是错的,可以看 6873c82aa56SChiichen // https://sourcegraph.com/github.com/torvalds/linux@dd72f9c7e512da377074d47d990564959b772643/-/blob/arch/x86/kernel/signal.c?L124 6883c82aa56SChiichen // 我猜测是跟x86汇编的某些弹栈行为有关系,它可能会出于某种原因递增 rsp 6893c82aa56SChiichen rsp &= (!(STACK_ALIGN - 1)) as usize - 8; 6903c82aa56SChiichen // rsp &= (!(STACK_ALIGN - 1)) as usize; 6913c82aa56SChiichen return rsp as *mut SigFrame; 6923c82aa56SChiichen } 6933c82aa56SChiichen 6943c82aa56SChiichen /// 信号默认处理函数——终止进程 6953c82aa56SChiichen fn sig_terminate(sig: Signal) { 6963c82aa56SChiichen ProcessManager::exit(sig as usize); 6973c82aa56SChiichen } 6983c82aa56SChiichen 6993c82aa56SChiichen /// 信号默认处理函数——终止进程并生成 core dump 7003c82aa56SChiichen fn sig_terminate_dump(sig: Signal) { 7013c82aa56SChiichen ProcessManager::exit(sig as usize); 7023c82aa56SChiichen // TODO 生成 coredump 文件 7033c82aa56SChiichen } 7043c82aa56SChiichen 7053c82aa56SChiichen /// 信号默认处理函数——暂停进程 7063c82aa56SChiichen fn sig_stop(sig: Signal) { 7073c82aa56SChiichen let guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 7083c82aa56SChiichen ProcessManager::mark_stop().unwrap_or_else(|e| { 7093c82aa56SChiichen kerror!( 7103c82aa56SChiichen "sleep error :{:?},failed to sleep process :{:?}, with signal :{:?}", 7113c82aa56SChiichen e, 7123c82aa56SChiichen ProcessManager::current_pcb(), 7133c82aa56SChiichen sig 7143c82aa56SChiichen ); 7153c82aa56SChiichen }); 7163c82aa56SChiichen drop(guard); 7173c82aa56SChiichen sched(); 7183c82aa56SChiichen // TODO 暂停进程 7193c82aa56SChiichen } 7203c82aa56SChiichen /// 信号默认处理函数——继续进程 7213c82aa56SChiichen fn sig_continue(sig: Signal) { 7223c82aa56SChiichen ProcessManager::wakeup_stop(&ProcessManager::current_pcb()).unwrap_or_else(|_| { 7233c82aa56SChiichen kerror!( 7243c82aa56SChiichen "Failed to wake up process pid = {:?} with signal :{:?}", 7253c82aa56SChiichen ProcessManager::current_pcb().pid(), 7263c82aa56SChiichen sig 7273c82aa56SChiichen ); 7283c82aa56SChiichen }); 7293c82aa56SChiichen } 7303c82aa56SChiichen /// 信号默认处理函数——忽略 7313c82aa56SChiichen fn sig_ignore(_sig: Signal) { 7323c82aa56SChiichen return; 7333c82aa56SChiichen } 734