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