xref: /DragonOS/kernel/src/arch/x86_64/ipc/signal.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
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 pcb = ProcessManager::current_pcb();
435 
436         let mut sig_number: Signal;
437         let mut info: Option<SigInfo>;
438         let mut sigaction: Sigaction;
439         let sig_block: SigSet = *siginfo_read_guard.sig_block();
440         drop(siginfo_read_guard);
441 
442         let sig_guard = pcb.try_sig_struct_irqsave(5);
443         if unlikely(sig_guard.is_none()) {
444             return;
445         }
446         let siginfo_mut = pcb.try_siginfo_mut(5);
447         if unlikely(siginfo_mut.is_none()) {
448             return;
449         }
450 
451         let sig_guard = sig_guard.unwrap();
452         let mut siginfo_mut_guard = siginfo_mut.unwrap();
453         loop {
454             (sig_number, info) = siginfo_mut_guard.dequeue_signal(&sig_block);
455             // 如果信号非法,则直接返回
456             if sig_number == Signal::INVALID {
457                 return;
458             }
459 
460             sigaction = sig_guard.handlers[sig_number as usize - 1];
461 
462             match sigaction.action() {
463                 SigactionType::SaHandler(action_type) => match action_type {
464                     SaHandlerType::Error => {
465                         error!("Trying to handle a Sigerror on Process:{:?}", pcb.pid());
466                         return;
467                     }
468                     SaHandlerType::Default => {
469                         sigaction = Sigaction::default();
470                         break;
471                     }
472                     SaHandlerType::Ignore => continue,
473                     SaHandlerType::Customized(_) => {
474                         break;
475                     }
476                 },
477                 SigactionType::SaSigaction(_) => todo!(),
478             }
479             // 如果当前动作是忽略这个信号,就继续循环。
480         }
481 
482         let oldset = *siginfo_mut_guard.sig_block();
483         //避免死锁
484         drop(siginfo_mut_guard);
485         drop(sig_guard);
486 
487         // 做完上面的检查后,开中断
488         CurrentIrqArch::interrupt_enable();
489         let res: Result<i32, SystemError> =
490             handle_signal(sig_number, &mut sigaction, &info.unwrap(), &oldset, frame);
491         if res.is_err() {
492             error!(
493                 "Error occurred when handling signal: {}, pid={:?}, errcode={:?}",
494                 sig_number as i32,
495                 ProcessManager::current_pcb().pid(),
496                 res.as_ref().unwrap_err()
497             );
498         }
499     }
500 
sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64501     fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64 {
502         let frame = (trap_frame.rsp as usize - size_of::<u64>()) as *mut SigFrame;
503 
504         // 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击)
505         if UserBufferWriter::new(frame, size_of::<SigFrame>(), true).is_err() {
506             error!("rsp doesn't from user level");
507             let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32)
508                 .map_err(|e| e.to_posix_errno());
509             return trap_frame.rax;
510         }
511         let mut sigmask: SigSet = unsafe { (*frame).context.oldmask };
512         set_current_sig_blocked(&mut sigmask);
513         // 从用户栈恢复sigcontext
514         if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) {
515             error!("unable to restore sigcontext");
516             let _r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32)
517                 .map_err(|e| e.to_posix_errno());
518             // 如果这里返回 err 值的话会丢失上一个系统调用的返回值
519         }
520         // 由于系统调用的返回值会被系统调用模块被存放在rax寄存器,因此,为了还原原来的那个系统调用的返回值,我们需要在这里返回恢复后的rax的值
521         return trap_frame.rax;
522     }
523 }
524 
525 /// @brief 真正发送signal,执行自定义的处理函数
526 ///
527 /// @param sig 信号number
528 /// @param sigaction 信号响应动作
529 /// @param info 信号信息
530 /// @param oldset
531 /// @param regs 之前的系统调用将要返回的时候,要弹出的栈帧的拷贝
532 ///
533 /// @return Result<0,SystemError> 若Error, 则返回错误码,否则返回Ok(0)
handle_signal( sig: Signal, sigaction: &mut Sigaction, info: &SigInfo, oldset: &SigSet, frame: &mut TrapFrame, ) -> Result<i32, SystemError>534 fn handle_signal(
535     sig: Signal,
536     sigaction: &mut Sigaction,
537     info: &SigInfo,
538     oldset: &SigSet,
539     frame: &mut TrapFrame,
540 ) -> Result<i32, SystemError> {
541     // TODO 这里要补充一段逻辑,好像是为了保证引入线程之后的地址空间不会出问题。详见https://code.dragonos.org.cn/xref/linux-6.1.9/arch/mips/kernel/signal.c#830
542 
543     // 设置栈帧
544     return setup_frame(sig, sigaction, info, oldset, frame);
545 }
546 
547 /// @brief 在用户栈上开辟一块空间,并且把内核栈的栈帧以及需要在用户态执行的代码给保存进去。
548 ///
549 /// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧
setup_frame( sig: Signal, sigaction: &mut Sigaction, info: &SigInfo, oldset: &SigSet, trap_frame: &mut TrapFrame, ) -> Result<i32, SystemError>550 fn setup_frame(
551     sig: Signal,
552     sigaction: &mut Sigaction,
553     info: &SigInfo,
554     oldset: &SigSet,
555     trap_frame: &mut TrapFrame,
556 ) -> Result<i32, SystemError> {
557     let ret_code_ptr: *mut c_void;
558     let temp_handler: *mut c_void;
559     match sigaction.action() {
560         SigactionType::SaHandler(handler_type) => match handler_type {
561             SaHandlerType::Default => {
562                 sig.handle_default();
563                 return Ok(0);
564             }
565             SaHandlerType::Customized(handler) => {
566                 // 如果handler位于内核空间
567                 if handler >= MMArch::USER_END_VADDR {
568                     // 如果当前是SIGSEGV,则采用默认函数处理
569                     if sig == Signal::SIGSEGV {
570                         sig.handle_default();
571                         return Ok(0);
572                     } else {
573                         error!("attempting  to execute a signal handler from kernel");
574                         sig.handle_default();
575                         return Err(SystemError::EINVAL);
576                     }
577                 } else {
578                     // 为了与Linux的兼容性,64位程序必须由用户自行指定restorer
579                     if sigaction.flags().contains(SigFlags::SA_RESTORER) {
580                         ret_code_ptr = sigaction.restorer().unwrap().data() as *mut c_void;
581                     } else {
582                         error!(
583                             "pid-{:?} forgot to set SA_FLAG_RESTORER for signal {:?}",
584                             ProcessManager::current_pcb().pid(),
585                             sig as i32
586                         );
587                         let r = Syscall::kill(
588                             ProcessManager::current_pcb().pid(),
589                             Signal::SIGSEGV as i32,
590                         );
591                         if r.is_err() {
592                             error!("In setup_sigcontext: generate SIGSEGV signal failed");
593                         }
594                         return Err(SystemError::EINVAL);
595                     }
596                     if sigaction.restorer().is_none() {
597                         error!(
598                             "restorer in process:{:?} is not defined",
599                             ProcessManager::current_pcb().pid()
600                         );
601                         return Err(SystemError::EINVAL);
602                     }
603                     temp_handler = handler.data() as *mut c_void;
604                 }
605             }
606             SaHandlerType::Ignore => {
607                 return Ok(0);
608             }
609             _ => {
610                 return Err(SystemError::EINVAL);
611             }
612         },
613         SigactionType::SaSigaction(_) => {
614             //TODO 这里应该是可以恢复栈的,等后续来做
615             error!("trying to recover from sigaction type instead of handler");
616             return Err(SystemError::EINVAL);
617         }
618     }
619     let frame: *mut SigFrame = get_stack(trap_frame, size_of::<SigFrame>());
620     // debug!("frame=0x{:016x}", frame as usize);
621     // 要求这个frame的地址位于用户空间,因此进行校验
622     let r: Result<UserBufferWriter<'_>, SystemError> =
623         UserBufferWriter::new(frame, size_of::<SigFrame>(), true);
624     if r.is_err() {
625         // 如果地址区域位于内核空间,则直接报错
626         // todo: 生成一个sigsegv
627         let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
628         if r.is_err() {
629             error!("In setup frame: generate SIGSEGV signal failed");
630         }
631         error!("In setup frame: access check failed");
632         return Err(SystemError::EFAULT);
633     }
634 
635     // 将siginfo拷贝到用户栈
636     info.copy_siginfo_to_user(unsafe { &mut ((*frame).info) as *mut SigInfo })
637         .map_err(|e| -> SystemError {
638             let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
639             if r.is_err() {
640                 error!("In copy_siginfo_to_user: generate SIGSEGV signal failed");
641             }
642             return e;
643         })?;
644 
645     // todo: 拷贝处理程序备用栈的地址、大小、ss_flags
646 
647     unsafe {
648         (*frame)
649             .context
650             .setup_sigcontext(oldset, trap_frame)
651             .map_err(|e: SystemError| -> SystemError {
652                 let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
653                 if r.is_err() {
654                     error!("In setup_sigcontext: generate SIGSEGV signal failed");
655                 }
656                 return e;
657             })?
658     };
659 
660     unsafe {
661         // 在开头检验过sigaction.restorer是否为空了,实际上libc会保证 restorer始终不为空
662         (*frame).ret_code_ptr = ret_code_ptr;
663     }
664 
665     unsafe { (*frame).handler = temp_handler };
666     // 传入信号处理函数的第一个参数
667     trap_frame.rdi = sig as u64;
668     trap_frame.rsi = unsafe { &(*frame).info as *const SigInfo as u64 };
669     trap_frame.rsp = frame as u64;
670     trap_frame.rip = unsafe { (*frame).handler as u64 };
671     // 设置cs和ds寄存器
672     trap_frame.cs = (USER_CS.bits() | 0x3) as u64;
673     trap_frame.ds = (USER_DS.bits() | 0x3) as u64;
674 
675     // 禁用中断
676     // trap_frame.rflags &= !(0x200);
677 
678     return Ok(0);
679 }
680 
681 #[inline(always)]
get_stack(frame: &TrapFrame, size: usize) -> *mut SigFrame682 fn get_stack(frame: &TrapFrame, size: usize) -> *mut SigFrame {
683     // TODO:在 linux 中会根据 Sigaction 中的一个flag 的值来确定是否使用pcb中的 signal 处理程序备用堆栈,现在的
684     // pcb中也没有这个备用堆栈
685 
686     // 默认使用 用户栈的栈顶指针-128字节的红区-sigframe的大小 并且16字节对齐
687     let mut rsp: usize = (frame.rsp as usize) - 128 - size;
688     // 按照要求进行对齐,别问为什么减8,不减8就是错的,可以看
689     // https://sourcegraph.com/github.com/torvalds/linux@dd72f9c7e512da377074d47d990564959b772643/-/blob/arch/x86/kernel/signal.c?L124
690     // 我猜测是跟x86汇编的某些弹栈行为有关系,它可能会出于某种原因递增 rsp
691     rsp &= (!(STACK_ALIGN - 1)) as usize - 8;
692     // rsp &= (!(STACK_ALIGN - 1)) as usize;
693     return rsp as *mut SigFrame;
694 }
695 
696 /// 信号默认处理函数——终止进程
sig_terminate(sig: Signal)697 fn sig_terminate(sig: Signal) {
698     ProcessManager::exit(sig as usize);
699 }
700 
701 /// 信号默认处理函数——终止进程并生成 core dump
sig_terminate_dump(sig: Signal)702 fn sig_terminate_dump(sig: Signal) {
703     ProcessManager::exit(sig as usize);
704     // TODO 生成 coredump 文件
705 }
706 
707 /// 信号默认处理函数——暂停进程
sig_stop(sig: Signal)708 fn sig_stop(sig: Signal) {
709     let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
710     ProcessManager::mark_stop().unwrap_or_else(|e| {
711         error!(
712             "sleep error :{:?},failed to sleep process :{:?}, with signal :{:?}",
713             e,
714             ProcessManager::current_pcb(),
715             sig
716         );
717     });
718     drop(guard);
719     schedule(SchedMode::SM_NONE);
720     // TODO 暂停进程
721 }
722 /// 信号默认处理函数——继续进程
sig_continue(sig: Signal)723 fn sig_continue(sig: Signal) {
724     ProcessManager::wakeup_stop(&ProcessManager::current_pcb()).unwrap_or_else(|_| {
725         error!(
726             "Failed to wake up process pid = {:?} with signal :{:?}",
727             ProcessManager::current_pcb().pid(),
728             sig
729         );
730     });
731 }
732 /// 信号默认处理函数——忽略
sig_ignore(_sig: Signal)733 fn sig_ignore(_sig: Signal) {
734     return;
735 }
736