std: unsafe-wrap gcc::rust_eh_personality and impl
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user