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