Implement unwind accessors

This commit is contained in:
Gary Guo 2021-08-26 02:03:28 +01:00
parent 69f47111a0
commit e588ffdf2e

View File

@ -1,5 +1,9 @@
use core::ptr;
use gimli::Register;
use libc::{c_int, c_void}; use libc::{c_int, c_void};
use crate::arch::*;
use crate::find_fde::{self, FDEFinder};
use crate::frame::Frame; use crate::frame::Frame;
#[repr(transparent)] #[repr(transparent)]
@ -54,6 +58,7 @@ pub type UnwindTraceFn =
pub struct UnwindContext<'a> { pub struct UnwindContext<'a> {
frame: &'a Frame, frame: &'a Frame,
ctx: &'a mut Context,
} }
pub type PersonalityRoutine = extern "C" fn( pub type PersonalityRoutine = extern "C" fn(
@ -63,3 +68,67 @@ pub type PersonalityRoutine = extern "C" fn(
*mut UnwindException, *mut UnwindException,
*mut UnwindContext<'_>, *mut UnwindContext<'_>,
) -> UnwindReasonCode; ) -> 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(),
}
}