xref: /DragonOS/kernel/src/arch/x86_64/ipc/signal.rs (revision 3c82aa56d1b784ea7371100b3e906365be8332fd)
1*3c82aa56SChiichen use core::{ffi::c_void, mem::size_of};
2*3c82aa56SChiichen 
3*3c82aa56SChiichen use crate::{
4*3c82aa56SChiichen     arch::{
5*3c82aa56SChiichen         fpu::FpState,
6*3c82aa56SChiichen         interrupt::TrapFrame,
7*3c82aa56SChiichen         process::table::{USER_CS, USER_DS},
8*3c82aa56SChiichen         sched::sched,
9*3c82aa56SChiichen         CurrentIrqArch, MMArch,
10*3c82aa56SChiichen     },
11*3c82aa56SChiichen     exception::InterruptArch,
12*3c82aa56SChiichen     ipc::{
13*3c82aa56SChiichen         signal::set_current_sig_blocked,
14*3c82aa56SChiichen         signal_types::{SaHandlerType, SigInfo, Sigaction, SigactionType, SignalArch},
15*3c82aa56SChiichen     },
16*3c82aa56SChiichen     kerror,
17*3c82aa56SChiichen     mm::MemoryManagementArch,
18*3c82aa56SChiichen     process::ProcessManager,
19*3c82aa56SChiichen     syscall::{user_access::UserBufferWriter, Syscall, SystemError},
20*3c82aa56SChiichen };
21*3c82aa56SChiichen 
22*3c82aa56SChiichen /// 信号处理的栈的栈指针的最小对齐数量
23*3c82aa56SChiichen pub const STACK_ALIGN: u64 = 16;
24*3c82aa56SChiichen /// 信号最大值
25*3c82aa56SChiichen pub const MAX_SIG_NUM: usize = 64;
26*3c82aa56SChiichen #[allow(dead_code)]
27*3c82aa56SChiichen #[derive(Debug, Clone, Copy, Eq)]
28*3c82aa56SChiichen #[repr(usize)]
29*3c82aa56SChiichen #[allow(non_camel_case_types)]
30*3c82aa56SChiichen pub enum Signal {
31*3c82aa56SChiichen     INVALID = 0,
32*3c82aa56SChiichen     SIGHUP = 1,
33*3c82aa56SChiichen     SIGINT,
34*3c82aa56SChiichen     SIGQUIT,
35*3c82aa56SChiichen     SIGILL,
36*3c82aa56SChiichen     SIGTRAP,
37*3c82aa56SChiichen     /// SIGABRT和SIGIOT共用这个号码
38*3c82aa56SChiichen     SIGABRT_OR_IOT,
39*3c82aa56SChiichen     SIGBUS,
40*3c82aa56SChiichen     SIGFPE,
41*3c82aa56SChiichen     SIGKILL,
42*3c82aa56SChiichen     SIGUSR1,
43*3c82aa56SChiichen 
44*3c82aa56SChiichen     SIGSEGV = 11,
45*3c82aa56SChiichen     SIGUSR2,
46*3c82aa56SChiichen     SIGPIPE,
47*3c82aa56SChiichen     SIGALRM,
48*3c82aa56SChiichen     SIGTERM,
49*3c82aa56SChiichen     SIGSTKFLT,
50*3c82aa56SChiichen     SIGCHLD,
51*3c82aa56SChiichen     SIGCONT,
52*3c82aa56SChiichen     SIGSTOP,
53*3c82aa56SChiichen     SIGTSTP,
54*3c82aa56SChiichen 
55*3c82aa56SChiichen     SIGTTIN = 21,
56*3c82aa56SChiichen     SIGTTOU,
57*3c82aa56SChiichen     SIGURG,
58*3c82aa56SChiichen     SIGXCPU,
59*3c82aa56SChiichen     SIGXFSZ,
60*3c82aa56SChiichen     SIGVTALRM,
61*3c82aa56SChiichen     SIGPROF,
62*3c82aa56SChiichen     SIGWINCH,
63*3c82aa56SChiichen     /// SIGIO和SIGPOLL共用这个号码
64*3c82aa56SChiichen     SIGIO_OR_POLL,
65*3c82aa56SChiichen     SIGPWR,
66*3c82aa56SChiichen 
67*3c82aa56SChiichen     SIGSYS = 31,
68*3c82aa56SChiichen 
69*3c82aa56SChiichen     SIGRTMIN = 32,
70*3c82aa56SChiichen     SIGRTMAX = 64,
71*3c82aa56SChiichen }
72*3c82aa56SChiichen 
73*3c82aa56SChiichen /// 为Signal实现判断相等的trait
74*3c82aa56SChiichen impl PartialEq for Signal {
75*3c82aa56SChiichen     fn eq(&self, other: &Signal) -> bool {
76*3c82aa56SChiichen         *self as usize == *other as usize
77*3c82aa56SChiichen     }
78*3c82aa56SChiichen }
79*3c82aa56SChiichen 
80*3c82aa56SChiichen impl From<usize> for Signal {
81*3c82aa56SChiichen     fn from(value: usize) -> Self {
82*3c82aa56SChiichen         if value <= MAX_SIG_NUM {
83*3c82aa56SChiichen             let ret: Signal = unsafe { core::mem::transmute(value) };
84*3c82aa56SChiichen             return ret;
85*3c82aa56SChiichen         } else {
86*3c82aa56SChiichen             kerror!("Try to convert an invalid number to Signal");
87*3c82aa56SChiichen             return Signal::INVALID;
88*3c82aa56SChiichen         }
89*3c82aa56SChiichen     }
90*3c82aa56SChiichen }
91*3c82aa56SChiichen 
92*3c82aa56SChiichen impl Into<usize> for Signal {
93*3c82aa56SChiichen     fn into(self) -> usize {
94*3c82aa56SChiichen         self as usize
95*3c82aa56SChiichen     }
96*3c82aa56SChiichen }
97*3c82aa56SChiichen 
98*3c82aa56SChiichen impl From<i32> for Signal {
99*3c82aa56SChiichen     fn from(value: i32) -> Self {
100*3c82aa56SChiichen         if value < 0 {
101*3c82aa56SChiichen             kerror!("Try to convert an invalid number to Signal");
102*3c82aa56SChiichen             return Signal::INVALID;
103*3c82aa56SChiichen         } else {
104*3c82aa56SChiichen             return Self::from(value as usize);
105*3c82aa56SChiichen         }
106*3c82aa56SChiichen     }
107*3c82aa56SChiichen }
108*3c82aa56SChiichen 
109*3c82aa56SChiichen impl Into<SigSet> for Signal {
110*3c82aa56SChiichen     fn into(self) -> SigSet {
111*3c82aa56SChiichen         SigSet {
112*3c82aa56SChiichen             bits: (1 << (self as usize - 1) as u64),
113*3c82aa56SChiichen         }
114*3c82aa56SChiichen     }
115*3c82aa56SChiichen }
116*3c82aa56SChiichen impl Signal {
117*3c82aa56SChiichen     /// 判断一个数字是否为可用的信号
118*3c82aa56SChiichen     #[inline]
119*3c82aa56SChiichen     pub fn is_valid(&self) -> bool {
120*3c82aa56SChiichen         return (*self) as usize <= MAX_SIG_NUM;
121*3c82aa56SChiichen     }
122*3c82aa56SChiichen 
123*3c82aa56SChiichen     /// const convertor between `Signal` and `SigSet`
124*3c82aa56SChiichen     pub const fn into_sigset(self) -> SigSet {
125*3c82aa56SChiichen         SigSet {
126*3c82aa56SChiichen             bits: (1 << (self as usize - 1) as u64),
127*3c82aa56SChiichen         }
128*3c82aa56SChiichen     }
129*3c82aa56SChiichen 
130*3c82aa56SChiichen     /// 判断一个信号是不是实时信号
131*3c82aa56SChiichen     ///
132*3c82aa56SChiichen     /// ## 返回值
133*3c82aa56SChiichen     ///
134*3c82aa56SChiichen     /// - `true` 这个信号是实时信号
135*3c82aa56SChiichen     /// - `false` 这个信号不是实时信号
136*3c82aa56SChiichen     #[inline]
137*3c82aa56SChiichen     pub fn is_rt_signal(&self) -> bool {
138*3c82aa56SChiichen         return (*self) as usize >= Signal::SIGRTMIN.into();
139*3c82aa56SChiichen     }
140*3c82aa56SChiichen 
141*3c82aa56SChiichen     /// 调用信号的默认处理函数
142*3c82aa56SChiichen     pub fn handle_default(&self) {
143*3c82aa56SChiichen         match self {
144*3c82aa56SChiichen             Signal::INVALID => {
145*3c82aa56SChiichen                 kerror!("attempting to handler an Invalid");
146*3c82aa56SChiichen             }
147*3c82aa56SChiichen             Signal::SIGHUP => sig_terminate(self.clone()),
148*3c82aa56SChiichen             Signal::SIGINT => sig_terminate(self.clone()),
149*3c82aa56SChiichen             Signal::SIGQUIT => sig_terminate_dump(self.clone()),
150*3c82aa56SChiichen             Signal::SIGILL => sig_terminate_dump(self.clone()),
151*3c82aa56SChiichen             Signal::SIGTRAP => sig_terminate_dump(self.clone()),
152*3c82aa56SChiichen             Signal::SIGABRT_OR_IOT => sig_terminate_dump(self.clone()),
153*3c82aa56SChiichen             Signal::SIGBUS => sig_terminate_dump(self.clone()),
154*3c82aa56SChiichen             Signal::SIGFPE => sig_terminate_dump(self.clone()),
155*3c82aa56SChiichen             Signal::SIGKILL => sig_terminate(self.clone()),
156*3c82aa56SChiichen             Signal::SIGUSR1 => sig_terminate(self.clone()),
157*3c82aa56SChiichen             Signal::SIGSEGV => sig_terminate_dump(self.clone()),
158*3c82aa56SChiichen             Signal::SIGUSR2 => sig_terminate(self.clone()),
159*3c82aa56SChiichen             Signal::SIGPIPE => sig_terminate(self.clone()),
160*3c82aa56SChiichen             Signal::SIGALRM => sig_terminate(self.clone()),
161*3c82aa56SChiichen             Signal::SIGTERM => sig_terminate(self.clone()),
162*3c82aa56SChiichen             Signal::SIGSTKFLT => sig_terminate(self.clone()),
163*3c82aa56SChiichen             Signal::SIGCHLD => sig_ignore(self.clone()),
164*3c82aa56SChiichen             Signal::SIGCONT => sig_continue(self.clone()),
165*3c82aa56SChiichen             Signal::SIGSTOP => sig_stop(self.clone()),
166*3c82aa56SChiichen             Signal::SIGTSTP => sig_stop(self.clone()),
167*3c82aa56SChiichen             Signal::SIGTTIN => sig_stop(self.clone()),
168*3c82aa56SChiichen             Signal::SIGTTOU => sig_stop(self.clone()),
169*3c82aa56SChiichen             Signal::SIGURG => sig_ignore(self.clone()),
170*3c82aa56SChiichen             Signal::SIGXCPU => sig_terminate_dump(self.clone()),
171*3c82aa56SChiichen             Signal::SIGXFSZ => sig_terminate_dump(self.clone()),
172*3c82aa56SChiichen             Signal::SIGVTALRM => sig_terminate(self.clone()),
173*3c82aa56SChiichen             Signal::SIGPROF => sig_terminate(self.clone()),
174*3c82aa56SChiichen             Signal::SIGWINCH => sig_ignore(self.clone()),
175*3c82aa56SChiichen             Signal::SIGIO_OR_POLL => sig_terminate(self.clone()),
176*3c82aa56SChiichen             Signal::SIGPWR => sig_terminate(self.clone()),
177*3c82aa56SChiichen             Signal::SIGSYS => sig_terminate(self.clone()),
178*3c82aa56SChiichen             Signal::SIGRTMIN => sig_terminate(self.clone()),
179*3c82aa56SChiichen             Signal::SIGRTMAX => sig_terminate(self.clone()),
180*3c82aa56SChiichen         }
181*3c82aa56SChiichen     }
182*3c82aa56SChiichen }
183*3c82aa56SChiichen 
184*3c82aa56SChiichen /// siginfo中的si_code的可选值
185*3c82aa56SChiichen /// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态
186*3c82aa56SChiichen #[derive(Copy, Debug, Clone)]
187*3c82aa56SChiichen #[repr(i32)]
188*3c82aa56SChiichen pub enum SigCode {
189*3c82aa56SChiichen     /// sent by kill, sigsend, raise
190*3c82aa56SChiichen     User = 0,
191*3c82aa56SChiichen     /// sent by kernel from somewhere
192*3c82aa56SChiichen     Kernel = 0x80,
193*3c82aa56SChiichen     /// 通过sigqueue发送
194*3c82aa56SChiichen     Queue = -1,
195*3c82aa56SChiichen     /// 定时器过期时发送
196*3c82aa56SChiichen     Timer = -2,
197*3c82aa56SChiichen     /// 当实时消息队列的状态发生改变时发送
198*3c82aa56SChiichen     Mesgq = -3,
199*3c82aa56SChiichen     /// 当异步IO完成时发送
200*3c82aa56SChiichen     AsyncIO = -4,
201*3c82aa56SChiichen     /// sent by queued SIGIO
202*3c82aa56SChiichen     SigIO = -5,
203*3c82aa56SChiichen }
204*3c82aa56SChiichen 
205*3c82aa56SChiichen impl SigCode {
206*3c82aa56SChiichen     /// 为SigCode这个枚举类型实现从i32转换到枚举类型的转换函数
207*3c82aa56SChiichen     #[allow(dead_code)]
208*3c82aa56SChiichen     pub fn from_i32(x: i32) -> SigCode {
209*3c82aa56SChiichen         match x {
210*3c82aa56SChiichen             0 => Self::User,
211*3c82aa56SChiichen             0x80 => Self::Kernel,
212*3c82aa56SChiichen             -1 => Self::Queue,
213*3c82aa56SChiichen             -2 => Self::Timer,
214*3c82aa56SChiichen             -3 => Self::Mesgq,
215*3c82aa56SChiichen             -4 => Self::AsyncIO,
216*3c82aa56SChiichen             -5 => Self::SigIO,
217*3c82aa56SChiichen             _ => panic!("signal code not valid"),
218*3c82aa56SChiichen         }
219*3c82aa56SChiichen     }
220*3c82aa56SChiichen }
221*3c82aa56SChiichen 
222*3c82aa56SChiichen bitflags! {
223*3c82aa56SChiichen     #[repr(C,align(8))]
224*3c82aa56SChiichen     #[derive(Default)]
225*3c82aa56SChiichen     pub struct SigFlags:u32{
226*3c82aa56SChiichen         const SA_NOCLDSTOP =  1;
227*3c82aa56SChiichen         const SA_NOCLDWAIT = 2;
228*3c82aa56SChiichen         const SA_SIGINFO   = 4;
229*3c82aa56SChiichen         const SA_ONSTACK   = 0x08000000;
230*3c82aa56SChiichen         const SA_RESTART   = 0x10000000;
231*3c82aa56SChiichen         const SA_NODEFER  = 0x40000000;
232*3c82aa56SChiichen         const SA_RESETHAND = 0x80000000;
233*3c82aa56SChiichen         const SA_RESTORER   =0x04000000;
234*3c82aa56SChiichen         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();
235*3c82aa56SChiichen     }
236*3c82aa56SChiichen 
237*3c82aa56SChiichen     /// 请注意,sigset 这个bitmap, 第0位表示sig=1的信号。也就是说,Signal-1才是sigset_t中对应的位
238*3c82aa56SChiichen     #[derive(Default)]
239*3c82aa56SChiichen     pub struct SigSet:u64{
240*3c82aa56SChiichen         const SIGHUP   =  1<<0;
241*3c82aa56SChiichen         const SIGINT   =  1<<1;
242*3c82aa56SChiichen         const SIGQUIT  =  1<<2;
243*3c82aa56SChiichen         const SIGILL   =  1<<3;
244*3c82aa56SChiichen         const SIGTRAP  =  1<<4;
245*3c82aa56SChiichen         /// SIGABRT和SIGIOT共用这个号码
246*3c82aa56SChiichen         const SIGABRT_OR_IOT    =    1<<5;
247*3c82aa56SChiichen         const SIGBUS   =  1<<6;
248*3c82aa56SChiichen         const SIGFPE   =  1<<7;
249*3c82aa56SChiichen         const SIGKILL  =  1<<8;
250*3c82aa56SChiichen         const SIGUSR   =  1<<9;
251*3c82aa56SChiichen         const SIGSEGV  =  1<<10;
252*3c82aa56SChiichen         const SIGUSR2  =  1<<11;
253*3c82aa56SChiichen         const SIGPIPE  =  1<<12;
254*3c82aa56SChiichen         const SIGALRM  =  1<<13;
255*3c82aa56SChiichen         const SIGTERM  =  1<<14;
256*3c82aa56SChiichen         const SIGSTKFLT=  1<<15;
257*3c82aa56SChiichen         const SIGCHLD  =  1<<16;
258*3c82aa56SChiichen         const SIGCONT  =  1<<17;
259*3c82aa56SChiichen         const SIGSTOP  =  1<<18;
260*3c82aa56SChiichen         const SIGTSTP  =  1<<19;
261*3c82aa56SChiichen         const SIGTTIN  =  1<<20;
262*3c82aa56SChiichen         const SIGTTOU  =  1<<21;
263*3c82aa56SChiichen         const SIGURG   =  1<<22;
264*3c82aa56SChiichen         const SIGXCPU  =  1<<23;
265*3c82aa56SChiichen         const SIGXFSZ  =  1<<24;
266*3c82aa56SChiichen         const SIGVTALRM=  1<<25;
267*3c82aa56SChiichen         const SIGPROF  =  1<<26;
268*3c82aa56SChiichen         const SIGWINCH =  1<<27;
269*3c82aa56SChiichen         /// SIGIO和SIGPOLL共用这个号码
270*3c82aa56SChiichen         const SIGIO_OR_POLL    =   1<<28;
271*3c82aa56SChiichen         const SIGPWR   =  1<<29;
272*3c82aa56SChiichen         const SIGSYS   =  1<<30;
273*3c82aa56SChiichen         const SIGRTMIN =  1<<31;
274*3c82aa56SChiichen         // TODO 写上实时信号
275*3c82aa56SChiichen         const SIGRTMAX =  1<<MAX_SIG_NUM-1;
276*3c82aa56SChiichen     }
277*3c82aa56SChiichen }
278*3c82aa56SChiichen 
279*3c82aa56SChiichen #[repr(C, align(16))]
280*3c82aa56SChiichen #[derive(Debug, Clone, Copy)]
281*3c82aa56SChiichen pub struct SigFrame {
282*3c82aa56SChiichen     // pub pedding: u64,
283*3c82aa56SChiichen     /// 指向restorer的地址的指针。(该变量必须放在sigframe的第一位,因为这样才能在handler返回的时候,跳转到对应的代码,执行sigreturn)
284*3c82aa56SChiichen     pub ret_code_ptr: *mut core::ffi::c_void,
285*3c82aa56SChiichen     pub handler: *mut c_void,
286*3c82aa56SChiichen     pub info: SigInfo,
287*3c82aa56SChiichen     pub context: SigContext,
288*3c82aa56SChiichen }
289*3c82aa56SChiichen 
290*3c82aa56SChiichen #[repr(C, align(16))]
291*3c82aa56SChiichen #[derive(Debug, Clone, Copy)]
292*3c82aa56SChiichen pub struct SigContext {
293*3c82aa56SChiichen     /// sigcontext的标志位
294*3c82aa56SChiichen     pub sc_flags: u64,
295*3c82aa56SChiichen     pub sc_stack: SigStack, // 信号处理程序备用栈信息
296*3c82aa56SChiichen     pub frame: TrapFrame,   // 暂存的系统调用/中断返回时,原本要弹出的内核栈帧
297*3c82aa56SChiichen     // pub trap_num: u64,    // 用来保存线程结构体中的trap_num字段
298*3c82aa56SChiichen     pub oldmask: SigSet, // 暂存的执行信号处理函数之前的,被设置block的信号
299*3c82aa56SChiichen     pub cr2: u64,        // 用来保存线程结构体中的cr2字段
300*3c82aa56SChiichen     // pub err_code: u64,    // 用来保存线程结构体中的err_code字段
301*3c82aa56SChiichen     pub reserved_for_x87_state: Option<FpState>,
302*3c82aa56SChiichen     pub reserved: [u64; 8],
303*3c82aa56SChiichen }
304*3c82aa56SChiichen 
305*3c82aa56SChiichen impl SigContext {
306*3c82aa56SChiichen     /// 设置sigcontext
307*3c82aa56SChiichen     ///
308*3c82aa56SChiichen     /// ## 参数
309*3c82aa56SChiichen     ///
310*3c82aa56SChiichen     /// - `mask` 要被暂存的信号mask标志位
311*3c82aa56SChiichen     /// - `regs` 进入信号处理流程前,Restore all要弹出的内核栈栈帧
312*3c82aa56SChiichen     ///
313*3c82aa56SChiichen     /// ## 返回值
314*3c82aa56SChiichen     ///
315*3c82aa56SChiichen     /// - `Ok(0)`
316*3c82aa56SChiichen     /// - `Err(Systemerror)` (暂时不会返回错误)
317*3c82aa56SChiichen     pub fn setup_sigcontext(
318*3c82aa56SChiichen         &mut self,
319*3c82aa56SChiichen         mask: &SigSet,
320*3c82aa56SChiichen         frame: &TrapFrame,
321*3c82aa56SChiichen     ) -> Result<i32, SystemError> {
322*3c82aa56SChiichen         //TODO 引入线程后补上
323*3c82aa56SChiichen         // let current_thread = ProcessManager::current_pcb().thread;
324*3c82aa56SChiichen         let pcb = ProcessManager::current_pcb();
325*3c82aa56SChiichen         let mut archinfo_guard = pcb.arch_info();
326*3c82aa56SChiichen         self.oldmask = *mask;
327*3c82aa56SChiichen         self.frame = frame.clone();
328*3c82aa56SChiichen         // context.trap_num = unsafe { (*current_thread).trap_num };
329*3c82aa56SChiichen         // context.err_code = unsafe { (*current_thread).err_code };
330*3c82aa56SChiichen         // context.cr2 = unsafe { (*current_thread).cr2 };
331*3c82aa56SChiichen         self.reserved_for_x87_state = archinfo_guard.fp_state().clone();
332*3c82aa56SChiichen 
333*3c82aa56SChiichen         // 保存完毕后,清空fp_state,以免下次save的时候,出现SIMD exception
334*3c82aa56SChiichen         archinfo_guard.clear_fp_state();
335*3c82aa56SChiichen         return Ok(0);
336*3c82aa56SChiichen     }
337*3c82aa56SChiichen 
338*3c82aa56SChiichen     /// 指定的sigcontext恢复到当前进程的内核栈帧中,并将当前线程结构体的几个参数进行恢复
339*3c82aa56SChiichen     ///
340*3c82aa56SChiichen     /// ## 参数
341*3c82aa56SChiichen     /// - `frame` 目标栈帧(也就是把context恢复到这个栈帧中)
342*3c82aa56SChiichen     ///
343*3c82aa56SChiichen     /// ##返回值
344*3c82aa56SChiichen     /// - `true` -> 成功恢复
345*3c82aa56SChiichen     /// - `false` -> 执行失败
346*3c82aa56SChiichen     pub fn restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool {
347*3c82aa56SChiichen         let guard = ProcessManager::current_pcb();
348*3c82aa56SChiichen         let mut arch_info = guard.arch_info();
349*3c82aa56SChiichen         (*frame) = self.frame.clone();
350*3c82aa56SChiichen         // (*current_thread).trap_num = (*context).trap_num;
351*3c82aa56SChiichen         *arch_info.cr2_mut() = self.cr2 as usize;
352*3c82aa56SChiichen         // (*current_thread).err_code = (*context).err_code;
353*3c82aa56SChiichen         // 如果当前进程有fpstate,则将其恢复到pcb的fp_state中
354*3c82aa56SChiichen         *arch_info.fp_state_mut() = self.reserved_for_x87_state.clone();
355*3c82aa56SChiichen         arch_info.restore_fp_state();
356*3c82aa56SChiichen         return true;
357*3c82aa56SChiichen     }
358*3c82aa56SChiichen }
359*3c82aa56SChiichen /// @brief 信号处理备用栈的信息
360*3c82aa56SChiichen #[derive(Debug, Clone, Copy)]
361*3c82aa56SChiichen pub struct SigStack {
362*3c82aa56SChiichen     pub sp: *mut c_void,
363*3c82aa56SChiichen     pub flags: u32,
364*3c82aa56SChiichen     pub size: u32,
365*3c82aa56SChiichen     pub fpstate: FpState,
366*3c82aa56SChiichen }
367*3c82aa56SChiichen 
368*3c82aa56SChiichen #[no_mangle]
369*3c82aa56SChiichen unsafe extern "C" fn do_signal(frame: &mut TrapFrame) {
370*3c82aa56SChiichen     X86_64SignalArch::do_signal(frame);
371*3c82aa56SChiichen }
372*3c82aa56SChiichen 
373*3c82aa56SChiichen pub struct X86_64SignalArch;
374*3c82aa56SChiichen 
375*3c82aa56SChiichen impl SignalArch for X86_64SignalArch {
376*3c82aa56SChiichen     unsafe fn do_signal(frame: &mut TrapFrame) {
377*3c82aa56SChiichen         // 检查sigpending是否为0
378*3c82aa56SChiichen         if ProcessManager::current_pcb()
379*3c82aa56SChiichen             .sig_info()
380*3c82aa56SChiichen             .sig_pending()
381*3c82aa56SChiichen             .signal()
382*3c82aa56SChiichen             .bits()
383*3c82aa56SChiichen             == 0
384*3c82aa56SChiichen             || !frame.from_user()
385*3c82aa56SChiichen         {
386*3c82aa56SChiichen             // 若没有正在等待处理的信号,或者将要返回到的是内核态,则启用中断,然后返回
387*3c82aa56SChiichen             CurrentIrqArch::interrupt_enable();
388*3c82aa56SChiichen             return;
389*3c82aa56SChiichen         }
390*3c82aa56SChiichen 
391*3c82aa56SChiichen         // 做完上面的检查后,开中断
392*3c82aa56SChiichen         CurrentIrqArch::interrupt_enable();
393*3c82aa56SChiichen         let pcb = ProcessManager::current_pcb();
394*3c82aa56SChiichen         let sig_guard = pcb.sig_struct();
395*3c82aa56SChiichen         let mut sig_number: Signal;
396*3c82aa56SChiichen         let mut info: Option<SigInfo>;
397*3c82aa56SChiichen         let mut sigaction: Sigaction;
398*3c82aa56SChiichen         let reader = pcb.sig_info();
399*3c82aa56SChiichen         let sig_block: SigSet = reader.sig_block().clone();
400*3c82aa56SChiichen         drop(reader);
401*3c82aa56SChiichen         loop {
402*3c82aa56SChiichen             (sig_number, info) = pcb.sig_info_mut().dequeue_signal(&sig_block);
403*3c82aa56SChiichen             // 如果信号非法,则直接返回
404*3c82aa56SChiichen             if sig_number == Signal::INVALID {
405*3c82aa56SChiichen                 return;
406*3c82aa56SChiichen             }
407*3c82aa56SChiichen 
408*3c82aa56SChiichen             sigaction = sig_guard.handlers[sig_number as usize - 1];
409*3c82aa56SChiichen             match sigaction.action() {
410*3c82aa56SChiichen                 SigactionType::SaHandler(action_type) => match action_type {
411*3c82aa56SChiichen                     SaHandlerType::SigError => {
412*3c82aa56SChiichen                         kerror!("Trying to handle a Sigerror on Process:{:?}", pcb.pid());
413*3c82aa56SChiichen                         return;
414*3c82aa56SChiichen                     }
415*3c82aa56SChiichen                     SaHandlerType::SigDefault => {
416*3c82aa56SChiichen                         sigaction = Sigaction::default();
417*3c82aa56SChiichen                         break;
418*3c82aa56SChiichen                     }
419*3c82aa56SChiichen                     SaHandlerType::SigIgnore => continue,
420*3c82aa56SChiichen                     SaHandlerType::SigCustomized(_) => {
421*3c82aa56SChiichen                         break;
422*3c82aa56SChiichen                     }
423*3c82aa56SChiichen                 },
424*3c82aa56SChiichen                 SigactionType::SaSigaction(_) => todo!(),
425*3c82aa56SChiichen             }
426*3c82aa56SChiichen             // 如果当前动作是忽略这个信号,就继续循环。
427*3c82aa56SChiichen         }
428*3c82aa56SChiichen         // 所有的信号都处理完了
429*3c82aa56SChiichen         let reader = pcb.sig_info();
430*3c82aa56SChiichen         let oldset = reader.sig_block().clone();
431*3c82aa56SChiichen         //避免死锁
432*3c82aa56SChiichen         drop(reader);
433*3c82aa56SChiichen         drop(sig_guard);
434*3c82aa56SChiichen         let res: Result<i32, SystemError> =
435*3c82aa56SChiichen             handle_signal(sig_number, &mut sigaction, &info.unwrap(), &oldset, frame);
436*3c82aa56SChiichen         if res.is_err() {
437*3c82aa56SChiichen             kerror!(
438*3c82aa56SChiichen                 "Error occurred when handling signal: {}, pid={:?}, errcode={:?}",
439*3c82aa56SChiichen                 sig_number as i32,
440*3c82aa56SChiichen                 ProcessManager::current_pcb().pid(),
441*3c82aa56SChiichen                 res.unwrap_err()
442*3c82aa56SChiichen             );
443*3c82aa56SChiichen         }
444*3c82aa56SChiichen     }
445*3c82aa56SChiichen 
446*3c82aa56SChiichen     fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64 {
447*3c82aa56SChiichen         let frame = (trap_frame.rsp as usize) as *mut SigFrame;
448*3c82aa56SChiichen 
449*3c82aa56SChiichen         // 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击)
450*3c82aa56SChiichen         if UserBufferWriter::new(frame, size_of::<SigFrame>(), true).is_err() {
451*3c82aa56SChiichen             kerror!("rsp doesn't from user level");
452*3c82aa56SChiichen             let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32)
453*3c82aa56SChiichen                 .map_err(|e| e.to_posix_errno());
454*3c82aa56SChiichen             return trap_frame.rax;
455*3c82aa56SChiichen         }
456*3c82aa56SChiichen         let mut sigmask: SigSet = unsafe { (*frame).context.oldmask };
457*3c82aa56SChiichen         set_current_sig_blocked(&mut sigmask);
458*3c82aa56SChiichen         // 从用户栈恢复sigcontext
459*3c82aa56SChiichen         if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) {
460*3c82aa56SChiichen             kerror!("unable to restore sigcontext");
461*3c82aa56SChiichen             let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32)
462*3c82aa56SChiichen                 .map_err(|e| e.to_posix_errno());
463*3c82aa56SChiichen             // 如果这里返回 err 值的话会丢失上一个系统调用的返回值
464*3c82aa56SChiichen         }
465*3c82aa56SChiichen         // 由于系统调用的返回值会被系统调用模块被存放在rax寄存器,因此,为了还原原来的那个系统调用的返回值,我们需要在这里返回恢复后的rax的值
466*3c82aa56SChiichen         return trap_frame.rax;
467*3c82aa56SChiichen     }
468*3c82aa56SChiichen }
469*3c82aa56SChiichen 
470*3c82aa56SChiichen /// @brief 真正发送signal,执行自定义的处理函数
471*3c82aa56SChiichen ///
472*3c82aa56SChiichen /// @param sig 信号number
473*3c82aa56SChiichen /// @param sigaction 信号响应动作
474*3c82aa56SChiichen /// @param info 信号信息
475*3c82aa56SChiichen /// @param oldset
476*3c82aa56SChiichen /// @param regs 之前的系统调用将要返回的时候,要弹出的栈帧的拷贝
477*3c82aa56SChiichen ///
478*3c82aa56SChiichen /// @return Result<0,SystemError> 若Error, 则返回错误码,否则返回Ok(0)
479*3c82aa56SChiichen fn handle_signal(
480*3c82aa56SChiichen     sig: Signal,
481*3c82aa56SChiichen     sigaction: &mut Sigaction,
482*3c82aa56SChiichen     info: &SigInfo,
483*3c82aa56SChiichen     oldset: &SigSet,
484*3c82aa56SChiichen     frame: &mut TrapFrame,
485*3c82aa56SChiichen ) -> Result<i32, SystemError> {
486*3c82aa56SChiichen     // TODO 这里要补充一段逻辑,好像是为了保证引入线程之后的地址空间不会出问题。详见https://opengrok.ringotek.cn/xref/linux-6.1.9/arch/mips/kernel/signal.c#830
487*3c82aa56SChiichen 
488*3c82aa56SChiichen     // 设置栈帧
489*3c82aa56SChiichen     return setup_frame(sig, sigaction, info, oldset, frame);
490*3c82aa56SChiichen }
491*3c82aa56SChiichen 
492*3c82aa56SChiichen /// @brief 在用户栈上开辟一块空间,并且把内核栈的栈帧以及需要在用户态执行的代码给保存进去。
493*3c82aa56SChiichen ///
494*3c82aa56SChiichen /// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧
495*3c82aa56SChiichen fn setup_frame(
496*3c82aa56SChiichen     sig: Signal,
497*3c82aa56SChiichen     sigaction: &mut Sigaction,
498*3c82aa56SChiichen     info: &SigInfo,
499*3c82aa56SChiichen     oldset: &SigSet,
500*3c82aa56SChiichen     trap_frame: &mut TrapFrame,
501*3c82aa56SChiichen ) -> Result<i32, SystemError> {
502*3c82aa56SChiichen     let ret_code_ptr: *mut c_void;
503*3c82aa56SChiichen     let temp_handler: *mut c_void;
504*3c82aa56SChiichen     match sigaction.action() {
505*3c82aa56SChiichen         SigactionType::SaHandler(handler_type) => match handler_type {
506*3c82aa56SChiichen             SaHandlerType::SigDefault => {
507*3c82aa56SChiichen                 sig.handle_default();
508*3c82aa56SChiichen                 return Ok(0);
509*3c82aa56SChiichen             }
510*3c82aa56SChiichen             SaHandlerType::SigCustomized(handler) => {
511*3c82aa56SChiichen                 // 如果handler位于内核空间
512*3c82aa56SChiichen                 if handler >= MMArch::USER_END_VADDR {
513*3c82aa56SChiichen                     // 如果当前是SIGSEGV,则采用默认函数处理
514*3c82aa56SChiichen                     if sig == Signal::SIGSEGV {
515*3c82aa56SChiichen                         sig.handle_default();
516*3c82aa56SChiichen                         return Ok(0);
517*3c82aa56SChiichen                     } else {
518*3c82aa56SChiichen                         kerror!("attempting  to execute a signal handler from kernel");
519*3c82aa56SChiichen                         sig.handle_default();
520*3c82aa56SChiichen                         return Err(SystemError::EINVAL);
521*3c82aa56SChiichen                     }
522*3c82aa56SChiichen                 } else {
523*3c82aa56SChiichen                     // 为了与Linux的兼容性,64位程序必须由用户自行指定restorer
524*3c82aa56SChiichen                     if sigaction.flags().contains(SigFlags::SA_RESTORER) {
525*3c82aa56SChiichen                         ret_code_ptr = sigaction.restorer().unwrap().data() as *mut c_void;
526*3c82aa56SChiichen                     } else {
527*3c82aa56SChiichen                         kerror!(
528*3c82aa56SChiichen                             "pid-{:?} forgot to set SA_FLAG_RESTORER for signal {:?}",
529*3c82aa56SChiichen                             ProcessManager::current_pcb().pid(),
530*3c82aa56SChiichen                             sig as i32
531*3c82aa56SChiichen                         );
532*3c82aa56SChiichen                         let r = Syscall::kill(
533*3c82aa56SChiichen                             ProcessManager::current_pcb().pid(),
534*3c82aa56SChiichen                             Signal::SIGSEGV as i32,
535*3c82aa56SChiichen                         );
536*3c82aa56SChiichen                         if r.is_err() {
537*3c82aa56SChiichen                             kerror!("In setup_sigcontext: generate SIGSEGV signal failed");
538*3c82aa56SChiichen                         }
539*3c82aa56SChiichen                         return Err(SystemError::EINVAL);
540*3c82aa56SChiichen                     }
541*3c82aa56SChiichen                     if sigaction.restorer().is_none() {
542*3c82aa56SChiichen                         kerror!(
543*3c82aa56SChiichen                             "restorer in process:{:?} is not defined",
544*3c82aa56SChiichen                             ProcessManager::current_pcb().pid()
545*3c82aa56SChiichen                         );
546*3c82aa56SChiichen                         return Err(SystemError::EINVAL);
547*3c82aa56SChiichen                     }
548*3c82aa56SChiichen                     temp_handler = handler.data() as *mut c_void;
549*3c82aa56SChiichen                 }
550*3c82aa56SChiichen             }
551*3c82aa56SChiichen             SaHandlerType::SigIgnore => {
552*3c82aa56SChiichen                 return Ok(0);
553*3c82aa56SChiichen             }
554*3c82aa56SChiichen             _ => {
555*3c82aa56SChiichen                 return Err(SystemError::EINVAL);
556*3c82aa56SChiichen             }
557*3c82aa56SChiichen         },
558*3c82aa56SChiichen         SigactionType::SaSigaction(_) => {
559*3c82aa56SChiichen             //TODO 这里应该是可以恢复栈的,等后续来做
560*3c82aa56SChiichen             kerror!("trying to recover from sigaction type instead of handler");
561*3c82aa56SChiichen             return Err(SystemError::EINVAL);
562*3c82aa56SChiichen         }
563*3c82aa56SChiichen     }
564*3c82aa56SChiichen     let frame: *mut SigFrame = get_stack(&trap_frame, size_of::<SigFrame>());
565*3c82aa56SChiichen     // kdebug!("frame=0x{:016x}", frame as usize);
566*3c82aa56SChiichen     // 要求这个frame的地址位于用户空间,因此进行校验
567*3c82aa56SChiichen     let r = UserBufferWriter::new(frame, size_of::<SigFrame>(), true);
568*3c82aa56SChiichen     if r.is_err() {
569*3c82aa56SChiichen         // 如果地址区域位于内核空间,则直接报错
570*3c82aa56SChiichen         // todo: 生成一个sigsegv
571*3c82aa56SChiichen         let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
572*3c82aa56SChiichen         if r.is_err() {
573*3c82aa56SChiichen             kerror!("In setup frame: generate SIGSEGV signal failed");
574*3c82aa56SChiichen         }
575*3c82aa56SChiichen         kerror!("In setup frame: access check failed");
576*3c82aa56SChiichen         return Err(SystemError::EFAULT);
577*3c82aa56SChiichen     }
578*3c82aa56SChiichen 
579*3c82aa56SChiichen     // 将siginfo拷贝到用户栈
580*3c82aa56SChiichen     info.copy_siginfo_to_user(unsafe { &mut ((*frame).info) as *mut SigInfo })
581*3c82aa56SChiichen         .map_err(|e| -> SystemError {
582*3c82aa56SChiichen             let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
583*3c82aa56SChiichen             if r.is_err() {
584*3c82aa56SChiichen                 kerror!("In copy_siginfo_to_user: generate SIGSEGV signal failed");
585*3c82aa56SChiichen             }
586*3c82aa56SChiichen             return e;
587*3c82aa56SChiichen         })?;
588*3c82aa56SChiichen 
589*3c82aa56SChiichen     // todo: 拷贝处理程序备用栈的地址、大小、ss_flags
590*3c82aa56SChiichen 
591*3c82aa56SChiichen     unsafe {
592*3c82aa56SChiichen         (*frame)
593*3c82aa56SChiichen             .context
594*3c82aa56SChiichen             .setup_sigcontext(oldset, &trap_frame)
595*3c82aa56SChiichen             .map_err(|e: SystemError| -> SystemError {
596*3c82aa56SChiichen                 let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
597*3c82aa56SChiichen                 if r.is_err() {
598*3c82aa56SChiichen                     kerror!("In setup_sigcontext: generate SIGSEGV signal failed");
599*3c82aa56SChiichen                 }
600*3c82aa56SChiichen                 return e;
601*3c82aa56SChiichen             })?
602*3c82aa56SChiichen     };
603*3c82aa56SChiichen 
604*3c82aa56SChiichen     unsafe {
605*3c82aa56SChiichen         // 在开头检验过sigaction.restorer是否为空了,实际上libc会保证 restorer始终不为空
606*3c82aa56SChiichen         (*frame).ret_code_ptr = ret_code_ptr;
607*3c82aa56SChiichen     }
608*3c82aa56SChiichen 
609*3c82aa56SChiichen     unsafe { (*frame).handler = temp_handler };
610*3c82aa56SChiichen     // 传入信号处理函数的第一个参数
611*3c82aa56SChiichen     trap_frame.rdi = sig as u64;
612*3c82aa56SChiichen     trap_frame.rsi = unsafe { &(*frame).info as *const SigInfo as u64 };
613*3c82aa56SChiichen     trap_frame.rsp = frame as u64;
614*3c82aa56SChiichen     trap_frame.rip = unsafe { (*frame).handler as u64 };
615*3c82aa56SChiichen     // 设置cs和ds寄存器
616*3c82aa56SChiichen     trap_frame.cs = (USER_CS.bits() | 0x3) as u64;
617*3c82aa56SChiichen     trap_frame.ds = (USER_DS.bits() | 0x3) as u64;
618*3c82aa56SChiichen 
619*3c82aa56SChiichen     // 禁用中断
620*3c82aa56SChiichen     // trap_frame.rflags &= !(0x200);
621*3c82aa56SChiichen 
622*3c82aa56SChiichen     return Ok(0);
623*3c82aa56SChiichen }
624*3c82aa56SChiichen 
625*3c82aa56SChiichen #[inline(always)]
626*3c82aa56SChiichen fn get_stack(frame: &TrapFrame, size: usize) -> *mut SigFrame {
627*3c82aa56SChiichen     // TODO:在 linux 中会根据 Sigaction 中的一个flag 的值来确定是否使用pcb中的 signal 处理程序备用堆栈,现在的
628*3c82aa56SChiichen     // pcb中也没有这个备用堆栈
629*3c82aa56SChiichen 
630*3c82aa56SChiichen     // 默认使用 用户栈的栈顶指针-128字节的红区-sigframe的大小 并且16字节对齐
631*3c82aa56SChiichen     let mut rsp: usize = (frame.rsp as usize) - 128 - size;
632*3c82aa56SChiichen     // 按照要求进行对齐,别问为什么减8,不减8就是错的,可以看
633*3c82aa56SChiichen     // https://sourcegraph.com/github.com/torvalds/linux@dd72f9c7e512da377074d47d990564959b772643/-/blob/arch/x86/kernel/signal.c?L124
634*3c82aa56SChiichen     // 我猜测是跟x86汇编的某些弹栈行为有关系,它可能会出于某种原因递增 rsp
635*3c82aa56SChiichen     rsp &= (!(STACK_ALIGN - 1)) as usize - 8;
636*3c82aa56SChiichen     // rsp &= (!(STACK_ALIGN - 1)) as usize;
637*3c82aa56SChiichen     return rsp as *mut SigFrame;
638*3c82aa56SChiichen }
639*3c82aa56SChiichen 
640*3c82aa56SChiichen /// 信号默认处理函数——终止进程
641*3c82aa56SChiichen fn sig_terminate(sig: Signal) {
642*3c82aa56SChiichen     ProcessManager::exit(sig as usize);
643*3c82aa56SChiichen }
644*3c82aa56SChiichen 
645*3c82aa56SChiichen /// 信号默认处理函数——终止进程并生成 core dump
646*3c82aa56SChiichen fn sig_terminate_dump(sig: Signal) {
647*3c82aa56SChiichen     ProcessManager::exit(sig as usize);
648*3c82aa56SChiichen     // TODO 生成 coredump 文件
649*3c82aa56SChiichen }
650*3c82aa56SChiichen 
651*3c82aa56SChiichen /// 信号默认处理函数——暂停进程
652*3c82aa56SChiichen fn sig_stop(sig: Signal) {
653*3c82aa56SChiichen     let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
654*3c82aa56SChiichen     ProcessManager::mark_stop().unwrap_or_else(|e| {
655*3c82aa56SChiichen         kerror!(
656*3c82aa56SChiichen             "sleep error :{:?},failed to sleep process :{:?}, with signal :{:?}",
657*3c82aa56SChiichen             e,
658*3c82aa56SChiichen             ProcessManager::current_pcb(),
659*3c82aa56SChiichen             sig
660*3c82aa56SChiichen         );
661*3c82aa56SChiichen     });
662*3c82aa56SChiichen     drop(guard);
663*3c82aa56SChiichen     sched();
664*3c82aa56SChiichen     // TODO 暂停进程
665*3c82aa56SChiichen }
666*3c82aa56SChiichen /// 信号默认处理函数——继续进程
667*3c82aa56SChiichen fn sig_continue(sig: Signal) {
668*3c82aa56SChiichen     ProcessManager::wakeup_stop(&ProcessManager::current_pcb()).unwrap_or_else(|_| {
669*3c82aa56SChiichen         kerror!(
670*3c82aa56SChiichen             "Failed to wake up process pid = {:?} with signal :{:?}",
671*3c82aa56SChiichen             ProcessManager::current_pcb().pid(),
672*3c82aa56SChiichen             sig
673*3c82aa56SChiichen         );
674*3c82aa56SChiichen     });
675*3c82aa56SChiichen }
676*3c82aa56SChiichen /// 信号默认处理函数——忽略
677*3c82aa56SChiichen fn sig_ignore(_sig: Signal) {
678*3c82aa56SChiichen     return;
679*3c82aa56SChiichen }
680