mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 04:55:03 +00:00
61 lines
2.0 KiB
Rust
61 lines
2.0 KiB
Rust
// 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<u64>,
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|