// SPDX-License-Identifier: MPL-2.0 use ostd::cpu::{ CpuException, CpuExceptionInfo, ALIGNMENT_CHECK, BOUND_RANGE_EXCEEDED, DIVIDE_BY_ZERO, GENERAL_PROTECTION_FAULT, INVALID_OPCODE, PAGE_FAULT, SIMD_FLOATING_POINT_EXCEPTION, X87_FLOATING_POINT_EXCEPTION, }; use super::Signal; use crate::{ prelude::*, process::signal::{c_types::siginfo_t, constants::*, sig_num::SigNum}, }; #[derive(Debug, Clone, Copy, PartialEq)] pub struct FaultSignal { num: SigNum, code: i32, addr: Option, } impl FaultSignal { pub fn new(trap_info: &CpuExceptionInfo) -> FaultSignal { debug!("Trap id: {}", trap_info.id); let exception = CpuException::to_cpu_exception(trap_info.id as u16).unwrap(); let (num, code, addr) = match *exception { DIVIDE_BY_ZERO => (SIGFPE, FPE_INTDIV, None), X87_FLOATING_POINT_EXCEPTION | SIMD_FLOATING_POINT_EXCEPTION => { (SIGFPE, FPE_FLTDIV, None) } BOUND_RANGE_EXCEEDED => (SIGSEGV, SEGV_BNDERR, None), ALIGNMENT_CHECK => (SIGBUS, BUS_ADRALN, None), INVALID_OPCODE => (SIGILL, ILL_ILLOPC, None), GENERAL_PROTECTION_FAULT => (SIGBUS, BUS_ADRERR, None), PAGE_FAULT => { const PF_ERR_FLAG_PRESENT: usize = 1usize << 0; let code = if trap_info.error_code & PF_ERR_FLAG_PRESENT != 0 { SEGV_ACCERR } else { SEGV_MAPERR }; let addr = Some(trap_info.page_fault_addr as u64); (SIGSEGV, code, addr) } _ => panic!("Exception cannot be a signal"), }; FaultSignal { num, code, addr } } } impl Signal for FaultSignal { fn num(&self) -> SigNum { self.num } fn to_info(&self) -> siginfo_t { siginfo_t::new(self.num, self.code) // info.set_si_addr(self.addr.unwrap_or_default() as *const c_void); // info } }