starnix_core/arch/x64/
task.rs1use crate::signals::{SignalDetail, SignalInfo};
6use crate::task::{CurrentTask, ExceptionResult, PageFaultExceptionReport};
7use starnix_uapi::signals::{SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP};
8
9pub fn handle_hardware_exception(
10 current_task: &CurrentTask,
11 report: &zx::ExceptionReport,
12) -> Option<ExceptionResult> {
13 let ip = current_task.thread_state.registers.instruction_pointer_register();
14 match report.ty {
15 zx::ExceptionType::General => match report.arch.vector {
18 0 => Some(ExceptionResult::Signal(SignalInfo::with_detail(
20 SIGFPE,
21 linux_uapi::FPE_INTDIV as i32,
22 SignalDetail::SigFault { addr: ip },
23 ))),
24
25 16 | 19 => Some(ExceptionResult::Signal(SignalInfo::with_detail(
28 SIGFPE,
29 linux_uapi::FPE_FLTINV as i32,
30 SignalDetail::SigFault { addr: ip },
31 ))),
32
33 13 => Some(ExceptionResult::Signal(SignalInfo::kernel(SIGSEGV))),
35
36 _ => None,
37 },
38 zx::ExceptionType::FatalPageFault { status } => {
39 let decoded = decode_page_fault_exception_report(&report.arch);
40 Some(current_task.handle_page_fault(decoded, status))
41 }
42 zx::ExceptionType::UndefinedInstruction => {
43 Some(ExceptionResult::Signal(SignalInfo::with_detail(
44 SIGILL,
45 linux_uapi::ILL_ILLOPC as i32,
46 SignalDetail::SigFault { addr: ip },
47 )))
48 }
49 zx::ExceptionType::UnalignedAccess => {
50 Some(ExceptionResult::Signal(SignalInfo::with_detail(
51 SIGBUS,
52 linux_uapi::BUS_ADRALN as i32,
53 SignalDetail::SigFault { addr: report.arch.cr2 },
54 )))
55 }
56 zx::ExceptionType::SoftwareBreakpoint => {
57 Some(ExceptionResult::Signal(SignalInfo::kernel(SIGTRAP)))
60 }
61 zx::ExceptionType::HardwareBreakpoint => {
62 Some(ExceptionResult::Signal(SignalInfo::with_detail(
63 SIGTRAP,
64 linux_uapi::TRAP_HWBKPT as i32,
65 SignalDetail::SigFault { addr: ip },
66 )))
67 }
68 _ => None,
69 }
70}
71
72pub fn decode_page_fault_exception_report(
73 data: &zx::ExceptionArchData,
74) -> PageFaultExceptionReport {
75 let faulting_address = data.cr2;
77 let not_present = data.err_code & 0x01 == 0; let is_write = data.err_code & 0x02 != 0;
79 let is_execute = data.err_code & 0xF0 != 0;
80
81 PageFaultExceptionReport { faulting_address, not_present, is_write, is_execute }
82}