Skip to main content

ax_cpu/trap/
diagnostics.rs

1//! Runtime-owned diagnostics for CPU exception reports.
2
3use core::fmt;
4
5/// Saved machine registers, without any claim that their addresses are readable.
6#[derive(Clone, Copy, Debug)]
7pub struct BacktraceRegisters {
8    /// Saved frame pointer.
9    pub fp: usize,
10    /// Interrupted instruction address.
11    pub pc: usize,
12    /// Saved return address, or zero on architectures without a link register.
13    pub ra: usize,
14}
15
16impl BacktraceRegisters {
17    pub(crate) const fn new(fp: usize, pc: usize, ra: usize) -> Self {
18        Self { fp, pc, ra }
19    }
20}
21
22/// Diagnostic service supplied once by the final runtime.
23///
24/// Calls can occur in fatal exception context with interrupts disabled. The
25/// implementation must not block or assume the saved addresses are readable;
26/// stack bounds and protected memory access belong to the runtime unwinder.
27#[trait_ffi::def_extern_trait(mod_path = "trap::diagnostics")]
28pub trait TrapDiagnostics {
29    /// Formats a trap backtrace without retaining the formatter or stack memory.
30    fn format_backtrace(
31        registers: BacktraceRegisters,
32        output: &mut fmt::Formatter<'_>,
33    ) -> fmt::Result;
34}
35
36pub(crate) struct BacktraceDisplay(pub BacktraceRegisters);
37
38impl fmt::Display for BacktraceDisplay {
39    fn fmt(&self, output: &mut fmt::Formatter<'_>) -> fmt::Result {
40        trap_diagnostics::format_backtrace(self.0, output)
41    }
42}