std: unsafe-wrap gcc::rust_eh_personality and impl

This commit is contained in:
Jubilee Young
2024-07-24 11:42:31 -07:00
parent 2ccafed862
commit 2c7ae388b3

View File

@@ -35,6 +35,7 @@
//! //!
//! Once stack has been unwound down to the handler frame level, unwinding stops //! Once stack has been unwound down to the handler frame level, unwinding stops
//! and the last personality routine transfers control to the catch block. //! and the last personality routine transfers control to the catch block.
#![forbid(unsafe_op_in_unsafe_fn)]
use super::dwarf::eh::{self, EHAction, EHContext}; use super::dwarf::eh::{self, EHAction, EHContext};
use crate::ffi::c_int; use crate::ffi::c_int;
@@ -92,7 +93,11 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(all(not(all(target_vendor = "apple", not(target_os = "watchos"))), target_arch = "arm", not(target_os = "netbsd")))] { if #[cfg(all(
target_arch = "arm",
not(all(target_vendor = "apple", not(target_os = "watchos"))),
not(target_os = "netbsd"),
))] {
// ARM EHABI personality routine. // ARM EHABI personality routine.
// https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf // https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
// //
@@ -104,6 +109,7 @@ cfg_if::cfg_if! {
exception_object: *mut uw::_Unwind_Exception, exception_object: *mut uw::_Unwind_Exception,
context: *mut uw::_Unwind_Context, context: *mut uw::_Unwind_Context,
) -> uw::_Unwind_Reason_Code { ) -> uw::_Unwind_Reason_Code {
unsafe {
let state = state as c_int; let state = state as c_int;
let action = state & uw::_US_ACTION_MASK as c_int; let action = state & uw::_US_ACTION_MASK as c_int;
let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int { let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int {
@@ -176,12 +182,14 @@ cfg_if::cfg_if! {
exception_object: *mut uw::_Unwind_Exception, exception_object: *mut uw::_Unwind_Exception,
context: *mut uw::_Unwind_Context, context: *mut uw::_Unwind_Context,
) -> uw::_Unwind_Reason_Code { ) -> uw::_Unwind_Reason_Code {
unsafe {
if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON { if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON {
uw::_URC_CONTINUE_UNWIND uw::_URC_CONTINUE_UNWIND
} else { } else {
uw::_URC_FAILURE uw::_URC_FAILURE
} }
} }
}
// defined in libgcc // defined in libgcc
extern "C" { extern "C" {
fn __gnu_unwind_frame( fn __gnu_unwind_frame(
@@ -190,6 +198,7 @@ cfg_if::cfg_if! {
) -> uw::_Unwind_Reason_Code; ) -> uw::_Unwind_Reason_Code;
} }
} }
}
} else { } else {
// Default personality routine, which is used directly on most targets // Default personality routine, which is used directly on most targets
// and indirectly on Windows x86_64 via SEH. // and indirectly on Windows x86_64 via SEH.
@@ -200,6 +209,7 @@ cfg_if::cfg_if! {
exception_object: *mut uw::_Unwind_Exception, exception_object: *mut uw::_Unwind_Exception,
context: *mut uw::_Unwind_Context, context: *mut uw::_Unwind_Context,
) -> uw::_Unwind_Reason_Code { ) -> uw::_Unwind_Reason_Code {
unsafe {
if version != 1 { if version != 1 {
return uw::_URC_FATAL_PHASE1_ERROR; return uw::_URC_FATAL_PHASE1_ERROR;
} }
@@ -232,6 +242,7 @@ cfg_if::cfg_if! {
} }
} }
} }
}
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] { if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
@@ -245,6 +256,7 @@ cfg_if::cfg_if! {
contextRecord: *mut uw::CONTEXT, contextRecord: *mut uw::CONTEXT,
dispatcherContext: *mut uw::DISPATCHER_CONTEXT, dispatcherContext: *mut uw::DISPATCHER_CONTEXT,
) -> uw::EXCEPTION_DISPOSITION { ) -> uw::EXCEPTION_DISPOSITION {
unsafe {
uw::_GCC_specific_handler( uw::_GCC_specific_handler(
exceptionRecord, exceptionRecord,
establisherFrame, establisherFrame,
@@ -253,6 +265,7 @@ cfg_if::cfg_if! {
rust_eh_personality_impl, rust_eh_personality_impl,
) )
} }
}
} else { } else {
// The personality routine for most of our targets. // The personality routine for most of our targets.
#[lang = "eh_personality"] #[lang = "eh_personality"]
@@ -263,6 +276,7 @@ cfg_if::cfg_if! {
exception_object: *mut uw::_Unwind_Exception, exception_object: *mut uw::_Unwind_Exception,
context: *mut uw::_Unwind_Context, context: *mut uw::_Unwind_Context,
) -> uw::_Unwind_Reason_Code { ) -> uw::_Unwind_Reason_Code {
unsafe {
rust_eh_personality_impl( rust_eh_personality_impl(
version, version,
actions, actions,
@@ -275,8 +289,10 @@ cfg_if::cfg_if! {
} }
} }
} }
}
unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> { unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> {
unsafe {
let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8; let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8;
let mut ip_before_instr: c_int = 0; let mut ip_before_instr: c_int = 0;
let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr); let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr);
@@ -292,3 +308,4 @@ unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction,
}; };
eh::find_eh_action(lsda, &eh_context) eh::find_eh_action(lsda, &eh_context)
} }
}