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