use std::ops::ControlFlow;
use probe_rs_target::CoreType;
use crate::{debug::unwind_pc_without_debuginfo, MemoryInterface};
use super::{DebugError, DebugInfo, DebugRegisters, StackFrame};
pub(crate) mod armv6m;
pub(crate) mod armv6m_armv7m_shared;
pub(crate) mod armv7m;
pub(crate) mod armv8m;
pub(crate) mod xtensa;
pub fn exception_handler_for_core(core_type: CoreType) -> Box<dyn ExceptionInterface> {
use self::{armv6m, armv7m, armv8m};
match core_type {
CoreType::Armv6m => Box::new(armv6m::ArmV6MExceptionHandler),
CoreType::Armv7m | CoreType::Armv7em => Box::new(armv7m::ArmV7MExceptionHandler),
CoreType::Armv8m => Box::new(armv8m::ArmV8MExceptionHandler),
CoreType::Xtensa => Box::new(xtensa::XtensaExceptionHandler),
CoreType::Armv7a | CoreType::Armv8a | CoreType::Riscv => {
Box::new(UnimplementedExceptionHandler)
}
}
}
pub struct UnimplementedExceptionHandler;
impl ExceptionInterface for UnimplementedExceptionHandler {
fn exception_details(
&self,
_memory: &mut dyn MemoryInterface,
_stackframe_registers: &DebugRegisters,
_debug_info: &DebugInfo,
) -> Result<Option<ExceptionInfo>, DebugError> {
Ok(None)
}
fn calling_frame_registers(
&self,
_memory: &mut dyn MemoryInterface,
_stackframe_registers: &crate::debug::DebugRegisters,
_raw_exception: u32,
) -> Result<crate::debug::DebugRegisters, DebugError> {
Err(DebugError::NotImplemented("calling frame registers"))
}
fn raw_exception(
&self,
_stackframe_registers: &crate::debug::DebugRegisters,
) -> Result<u32, DebugError> {
Err(DebugError::NotImplemented("raw exception"))
}
fn exception_description(
&self,
_raw_exception: u32,
_memory: &mut dyn MemoryInterface,
) -> Result<String, DebugError> {
Err(DebugError::NotImplemented("exception description"))
}
}
#[derive(PartialEq)]
pub struct ExceptionInfo {
pub raw_exception: u32,
pub description: String,
pub handler_frame: StackFrame,
}
pub trait ExceptionInterface {
fn exception_details(
&self,
memory: &mut dyn MemoryInterface,
stackframe_registers: &DebugRegisters,
debug_info: &DebugInfo,
) -> Result<Option<ExceptionInfo>, DebugError>;
fn calling_frame_registers(
&self,
memory: &mut dyn MemoryInterface,
stackframe_registers: &crate::debug::DebugRegisters,
raw_exception: u32,
) -> Result<crate::debug::DebugRegisters, DebugError>;
fn raw_exception(
&self,
stackframe_registers: &crate::debug::DebugRegisters,
) -> Result<u32, DebugError>;
fn exception_description(
&self,
raw_exception: u32,
memory: &mut dyn MemoryInterface,
) -> Result<String, DebugError>;
fn unwind_without_debuginfo(
&self,
unwind_registers: &mut DebugRegisters,
frame_pc: u64,
stack_frames: &[StackFrame],
instruction_set: Option<crate::InstructionSet>,
memory: &mut dyn MemoryInterface,
) -> ControlFlow<Option<DebugError>> {
unwind_pc_without_debuginfo(
unwind_registers,
frame_pc,
stack_frames,
instruction_set,
memory,
)
}
}