diff --git a/src/abi.rs b/src/abi.rs new file mode 100644 index 0000000..93b6bc6 --- /dev/null +++ b/src/abi.rs @@ -0,0 +1,65 @@ +use libc::{c_int, c_void}; + +use crate::frame::Frame; + +#[repr(transparent)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct UnwindReasonCode(c_int); + +#[allow(unused)] +impl UnwindReasonCode { + pub const NO_REASON: Self = Self(0); + pub const FOREIGN_EXCEPTION_CAUGHT: Self = Self(1); + pub const FATAL_PHASE2_ERROR: Self = Self(2); + pub const FATAL_PHASE1_ERROR: Self = Self(3); + pub const NORMAL_STOP: Self = Self(4); + pub const END_OF_STACK: Self = Self(5); + pub const HANDLER_FOUND: Self = Self(6); + pub const INSTALL_CONTEXT: Self = Self(7); + pub const CONTINUE_UNWIND: Self = Self(8); +} + +#[repr(transparent)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct UnwindAction(c_int); + +#[allow(unused)] +impl UnwindAction { + pub const SEARCH_PHASE: Self = Self(1); + pub const CLEANUP_PHASE: Self = Self(2); + pub const HANDLER_FRAME: Self = Self(4); + pub const FORCE_UNWIND: Self = Self(8); + pub const END_OF_STACK: Self = Self(16); +} + +pub type UnwindExceptionCleanupFn = extern "C" fn(UnwindReasonCode, *mut UnwindException); + +pub type UnwindStopFn = extern "C" fn( + c_int, + UnwindAction, + u64, + *mut UnwindException, + *mut UnwindContext<'_>, + *mut c_void, +); + +#[repr(C)] +pub struct UnwindException { + pub exception_class: u64, + pub exception_cleanup: Option, +} + +pub type UnwindTraceFn = + extern "C" fn(ctx: &mut UnwindContext<'_>, arg: *mut c_void) -> UnwindReasonCode; + +pub struct UnwindContext<'a> { + frame: &'a Frame, +} + +pub type PersonalityRoutine = extern "C" fn( + c_int, + UnwindAction, + u64, + *mut UnwindException, + *mut UnwindContext<'_>, +) -> UnwindReasonCode; diff --git a/src/frame.rs b/src/frame.rs index 40e1473..3a0bcdb 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -6,6 +6,7 @@ use gimli::{ use crate::arch::*; use crate::find_fde::{self, FDEFinder, FDESearchResult}; use crate::util::*; +use crate::abi::PersonalityRoutine; #[derive(Debug)] pub struct Frame { @@ -121,11 +122,12 @@ impl Frame { &self.fde_result.bases } - pub fn personality(&self) -> Option { + pub fn personality(&self) -> Option { self.fde_result .fde .personality() .map(|x| unsafe { deref_pointer(x) }) + .map(|x| unsafe { core::mem::transmute(x) }) } pub fn lsda(&self) -> usize { diff --git a/src/lib.rs b/src/lib.rs index d04e2b1..0bd4776 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ #![warn(rust_2018_idioms)] #![warn(unsafe_op_in_unsafe_fn)] +mod abi; mod arch; mod find_fde; mod frame;