diff --git a/src/abi.rs b/src/abi.rs index 93b6bc6..09238fd 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -1,5 +1,9 @@ +use core::ptr; +use gimli::Register; use libc::{c_int, c_void}; +use crate::arch::*; +use crate::find_fde::{self, FDEFinder}; use crate::frame::Frame; #[repr(transparent)] @@ -54,6 +58,7 @@ pub type UnwindTraceFn = pub struct UnwindContext<'a> { frame: &'a Frame, + ctx: &'a mut Context, } pub type PersonalityRoutine = extern "C" fn( @@ -63,3 +68,67 @@ pub type PersonalityRoutine = extern "C" fn( *mut UnwindException, *mut UnwindContext<'_>, ) -> UnwindReasonCode; + +#[no_mangle] +pub extern "C" fn _Unwind_GetGR(unwind_ctx: &mut UnwindContext<'_>, index: c_int) -> usize { + unwind_ctx.ctx[Register(index as u16)] +} + +#[no_mangle] +pub extern "C" fn _Unwind_GetCFA(unwind_ctx: &mut UnwindContext<'_>) -> usize { + unwind_ctx.ctx[Arch::SP] +} + +#[no_mangle] +pub extern "C" fn _Unwind_SetGR(unwind_ctx: &mut UnwindContext<'_>, index: c_int, value: usize) { + unwind_ctx.ctx[Register(index as u16)] = value; +} + +#[no_mangle] +pub extern "C" fn _Unwind_GetIP(unwind_ctx: &mut UnwindContext<'_>) -> usize { + unwind_ctx.ctx[Arch::RA] +} + +#[no_mangle] +pub extern "C" fn _Unwind_GetIPInfo( + unwind_ctx: &mut UnwindContext<'_>, + ip_before_insn: &mut c_int, +) -> usize { + *ip_before_insn = 0; + unwind_ctx.ctx[Arch::RA] +} + +#[no_mangle] +pub extern "C" fn _Unwind_SetIP(unwind_ctx: &mut UnwindContext<'_>, value: usize) { + unwind_ctx.ctx[Arch::RA] = value; +} + +#[no_mangle] +pub extern "C" fn _Unwind_GetLanguageSpecificData( + unwind_ctx: &mut UnwindContext<'_>, +) -> *mut c_void { + unwind_ctx.frame.lsda() as *mut c_void +} + +#[no_mangle] +pub extern "C" fn _Unwind_GetRegionStart(unwind_ctx: &mut UnwindContext<'_>) -> usize { + unwind_ctx.frame.initial_address() +} + +#[no_mangle] +pub extern "C" fn _Unwind_GetTextRelBase(unwind_ctx: &mut UnwindContext<'_>) -> usize { + unwind_ctx.frame.bases().eh_frame.text.unwrap() as _ +} + +#[no_mangle] +pub extern "C" fn _Unwind_GetDataRelBase(unwind_ctx: &mut UnwindContext<'_>) -> usize { + unwind_ctx.frame.bases().eh_frame.data.unwrap() as _ +} + +#[no_mangle] +pub extern "C" fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void { + match find_fde::get_finder().find_fde(pc as usize - 1) { + Some(v) => v.fde.initial_address() as usize as _, + None => ptr::null_mut(), + } +}