Adjust ABI safety requirement
This commit is contained in:
parent
f5ef1d145e
commit
7477bc5b6f
22
src/abi.rs
22
src/abi.rs
@ -60,11 +60,11 @@ impl UnwindAction {
|
|||||||
|
|
||||||
pub type UnwindExceptionCleanupFn = unsafe extern "C" fn(UnwindReasonCode, *mut UnwindException);
|
pub type UnwindExceptionCleanupFn = unsafe extern "C" fn(UnwindReasonCode, *mut UnwindException);
|
||||||
|
|
||||||
pub type UnwindStopFn = extern "C" fn(
|
pub type UnwindStopFn = unsafe extern "C" fn(
|
||||||
c_int,
|
c_int,
|
||||||
UnwindAction,
|
UnwindAction,
|
||||||
u64,
|
u64,
|
||||||
&mut UnwindException,
|
*mut UnwindException,
|
||||||
&mut UnwindContext<'_>,
|
&mut UnwindContext<'_>,
|
||||||
*mut c_void,
|
*mut c_void,
|
||||||
) -> UnwindReasonCode;
|
) -> UnwindReasonCode;
|
||||||
@ -87,11 +87,11 @@ pub struct UnwindContext<'a> {
|
|||||||
phantom: core::marker::PhantomData<&'a ()>,
|
phantom: core::marker::PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PersonalityRoutine = extern "C" fn(
|
pub type PersonalityRoutine = unsafe extern "C" fn(
|
||||||
c_int,
|
c_int,
|
||||||
UnwindAction,
|
UnwindAction,
|
||||||
u64,
|
u64,
|
||||||
&mut UnwindException,
|
*mut UnwindException,
|
||||||
&mut UnwindContext<'_>,
|
&mut UnwindContext<'_>,
|
||||||
) -> UnwindReasonCode;
|
) -> UnwindReasonCode;
|
||||||
|
|
||||||
@ -134,17 +134,17 @@ binding! {
|
|||||||
extern "C" fn _Unwind_GetTextRelBase(unwind_ctx: &UnwindContext<'_>) -> usize;
|
extern "C" fn _Unwind_GetTextRelBase(unwind_ctx: &UnwindContext<'_>) -> usize;
|
||||||
extern "C" fn _Unwind_GetDataRelBase(unwind_ctx: &UnwindContext<'_>) -> usize;
|
extern "C" fn _Unwind_GetDataRelBase(unwind_ctx: &UnwindContext<'_>) -> usize;
|
||||||
extern "C" fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void;
|
extern "C" fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void;
|
||||||
extern "C-unwind" fn _Unwind_RaiseException(
|
extern "C-unwind" [unsafe] fn _Unwind_RaiseException(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
) -> UnwindReasonCode;
|
) -> UnwindReasonCode;
|
||||||
extern "C-unwind" fn _Unwind_ForcedUnwind(
|
extern "C-unwind" [unsafe] fn _Unwind_ForcedUnwind(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
stop: UnwindStopFn,
|
stop: UnwindStopFn,
|
||||||
stop_arg: *mut c_void,
|
stop_arg: *mut c_void,
|
||||||
) -> UnwindReasonCode;
|
) -> UnwindReasonCode;
|
||||||
extern "C-unwind" fn _Unwind_Resume(exception: &mut UnwindException) -> !;
|
extern "C-unwind" [unsafe] fn _Unwind_Resume(exception: *mut UnwindException) -> !;
|
||||||
extern "C-unwind" fn _Unwind_Resume_or_Rethrow(
|
extern "C-unwind" [unsafe] fn _Unwind_Resume_or_Rethrow(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
) -> UnwindReasonCode;
|
) -> UnwindReasonCode;
|
||||||
extern "C" [unsafe] fn _Unwind_DeleteException(exception: *mut UnwindException);
|
extern "C" [unsafe] fn _Unwind_DeleteException(exception: *mut UnwindException);
|
||||||
extern "C-unwind" fn _Unwind_Backtrace(
|
extern "C-unwind" fn _Unwind_Backtrace(
|
||||||
|
@ -59,10 +59,7 @@ fn stack_trace() {
|
|||||||
struct CallbackData {
|
struct CallbackData {
|
||||||
counter: usize,
|
counter: usize,
|
||||||
}
|
}
|
||||||
extern "C" fn callback(
|
extern "C" fn callback(unwind_ctx: &UnwindContext<'_>, arg: *mut c_void) -> UnwindReasonCode {
|
||||||
unwind_ctx: &UnwindContext<'_>,
|
|
||||||
arg: *mut c_void,
|
|
||||||
) -> UnwindReasonCode {
|
|
||||||
let data = unsafe { &mut *(arg as *mut CallbackData) };
|
let data = unsafe { &mut *(arg as *mut CallbackData) };
|
||||||
data.counter += 1;
|
data.counter += 1;
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
@ -149,8 +149,8 @@ macro_rules! try2 {
|
|||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C-unwind" fn _Unwind_RaiseException(
|
pub unsafe extern "C-unwind" fn _Unwind_RaiseException(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
) -> UnwindReasonCode {
|
) -> UnwindReasonCode {
|
||||||
with_context(|saved_ctx| {
|
with_context(|saved_ctx| {
|
||||||
// Phase 1: Search for handler
|
// Phase 1: Search for handler
|
||||||
@ -159,17 +159,19 @@ pub extern "C-unwind" fn _Unwind_RaiseException(
|
|||||||
loop {
|
loop {
|
||||||
if let Some(frame) = try1!(Frame::from_context(&ctx, signal)) {
|
if let Some(frame) = try1!(Frame::from_context(&ctx, signal)) {
|
||||||
if let Some(personality) = frame.personality() {
|
if let Some(personality) = frame.personality() {
|
||||||
let result = personality(
|
let result = unsafe {
|
||||||
|
personality(
|
||||||
1,
|
1,
|
||||||
UnwindAction::SEARCH_PHASE,
|
UnwindAction::SEARCH_PHASE,
|
||||||
exception.exception_class,
|
(*exception).exception_class,
|
||||||
exception,
|
exception,
|
||||||
&mut UnwindContext {
|
&mut UnwindContext {
|
||||||
frame: Some(&frame),
|
frame: Some(&frame),
|
||||||
ctx: &mut ctx,
|
ctx: &mut ctx,
|
||||||
signal,
|
signal,
|
||||||
},
|
},
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
UnwindReasonCode::CONTINUE_UNWIND => (),
|
UnwindReasonCode::CONTINUE_UNWIND => (),
|
||||||
@ -189,8 +191,10 @@ pub extern "C-unwind" fn _Unwind_RaiseException(
|
|||||||
|
|
||||||
// Disambiguate normal frame and signal frame.
|
// Disambiguate normal frame and signal frame.
|
||||||
let handler_cfa = ctx[Arch::SP] - signal as usize;
|
let handler_cfa = ctx[Arch::SP] - signal as usize;
|
||||||
exception.private_1 = None;
|
unsafe {
|
||||||
exception.private_2 = handler_cfa;
|
(*exception).private_1 = None;
|
||||||
|
(*exception).private_2 = handler_cfa;
|
||||||
|
}
|
||||||
|
|
||||||
let code = raise_exception_phase2(exception, saved_ctx, handler_cfa);
|
let code = raise_exception_phase2(exception, saved_ctx, handler_cfa);
|
||||||
match code {
|
match code {
|
||||||
@ -201,7 +205,7 @@ pub extern "C-unwind" fn _Unwind_RaiseException(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn raise_exception_phase2(
|
fn raise_exception_phase2(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
handler_cfa: usize,
|
handler_cfa: usize,
|
||||||
) -> UnwindReasonCode {
|
) -> UnwindReasonCode {
|
||||||
@ -210,7 +214,8 @@ fn raise_exception_phase2(
|
|||||||
if let Some(frame) = try2!(Frame::from_context(ctx, signal)) {
|
if let Some(frame) = try2!(Frame::from_context(ctx, signal)) {
|
||||||
let frame_cfa = ctx[Arch::SP] - signal as usize;
|
let frame_cfa = ctx[Arch::SP] - signal as usize;
|
||||||
if let Some(personality) = frame.personality() {
|
if let Some(personality) = frame.personality() {
|
||||||
let code = personality(
|
let code = unsafe {
|
||||||
|
personality(
|
||||||
1,
|
1,
|
||||||
UnwindAction::CLEANUP_PHASE
|
UnwindAction::CLEANUP_PHASE
|
||||||
| if frame_cfa == handler_cfa {
|
| if frame_cfa == handler_cfa {
|
||||||
@ -218,14 +223,15 @@ fn raise_exception_phase2(
|
|||||||
} else {
|
} else {
|
||||||
UnwindAction::empty()
|
UnwindAction::empty()
|
||||||
},
|
},
|
||||||
exception.exception_class,
|
(*exception).exception_class,
|
||||||
exception,
|
exception,
|
||||||
&mut UnwindContext {
|
&mut UnwindContext {
|
||||||
frame: Some(&frame),
|
frame: Some(&frame),
|
||||||
ctx,
|
ctx,
|
||||||
signal,
|
signal,
|
||||||
},
|
},
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
match code {
|
match code {
|
||||||
UnwindReasonCode::CONTINUE_UNWIND => (),
|
UnwindReasonCode::CONTINUE_UNWIND => (),
|
||||||
@ -247,14 +253,16 @@ fn raise_exception_phase2(
|
|||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C-unwind" fn _Unwind_ForcedUnwind(
|
pub unsafe extern "C-unwind" fn _Unwind_ForcedUnwind(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
stop: UnwindStopFn,
|
stop: UnwindStopFn,
|
||||||
stop_arg: *mut c_void,
|
stop_arg: *mut c_void,
|
||||||
) -> UnwindReasonCode {
|
) -> UnwindReasonCode {
|
||||||
with_context(|ctx| {
|
with_context(|ctx| {
|
||||||
exception.private_1 = Some(stop);
|
unsafe {
|
||||||
exception.private_2 = stop_arg as _;
|
(*exception).private_1 = Some(stop);
|
||||||
|
(*exception).private_2 = stop_arg as _;
|
||||||
|
}
|
||||||
|
|
||||||
let code = force_unwind_phase2(exception, ctx, stop, stop_arg);
|
let code = force_unwind_phase2(exception, ctx, stop, stop_arg);
|
||||||
match code {
|
match code {
|
||||||
@ -265,7 +273,7 @@ pub extern "C-unwind" fn _Unwind_ForcedUnwind(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn force_unwind_phase2(
|
fn force_unwind_phase2(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
stop: UnwindStopFn,
|
stop: UnwindStopFn,
|
||||||
stop_arg: *mut c_void,
|
stop_arg: *mut c_void,
|
||||||
@ -274,7 +282,8 @@ fn force_unwind_phase2(
|
|||||||
loop {
|
loop {
|
||||||
let frame = try2!(Frame::from_context(ctx, signal));
|
let frame = try2!(Frame::from_context(ctx, signal));
|
||||||
|
|
||||||
let code = stop(
|
let code = unsafe {
|
||||||
|
stop(
|
||||||
1,
|
1,
|
||||||
UnwindAction::FORCE_UNWIND
|
UnwindAction::FORCE_UNWIND
|
||||||
| UnwindAction::END_OF_STACK
|
| UnwindAction::END_OF_STACK
|
||||||
@ -283,7 +292,7 @@ fn force_unwind_phase2(
|
|||||||
} else {
|
} else {
|
||||||
UnwindAction::empty()
|
UnwindAction::empty()
|
||||||
},
|
},
|
||||||
exception.exception_class,
|
(*exception).exception_class,
|
||||||
exception,
|
exception,
|
||||||
&mut UnwindContext {
|
&mut UnwindContext {
|
||||||
frame: frame.as_ref(),
|
frame: frame.as_ref(),
|
||||||
@ -291,7 +300,8 @@ fn force_unwind_phase2(
|
|||||||
signal,
|
signal,
|
||||||
},
|
},
|
||||||
stop_arg,
|
stop_arg,
|
||||||
);
|
)
|
||||||
|
};
|
||||||
match code {
|
match code {
|
||||||
UnwindReasonCode::NO_REASON => (),
|
UnwindReasonCode::NO_REASON => (),
|
||||||
_ => return UnwindReasonCode::FATAL_PHASE2_ERROR,
|
_ => return UnwindReasonCode::FATAL_PHASE2_ERROR,
|
||||||
@ -299,17 +309,19 @@ fn force_unwind_phase2(
|
|||||||
|
|
||||||
if let Some(frame) = frame {
|
if let Some(frame) = frame {
|
||||||
if let Some(personality) = frame.personality() {
|
if let Some(personality) = frame.personality() {
|
||||||
let code = personality(
|
let code = unsafe {
|
||||||
|
personality(
|
||||||
1,
|
1,
|
||||||
UnwindAction::FORCE_UNWIND | UnwindAction::CLEANUP_PHASE,
|
UnwindAction::FORCE_UNWIND | UnwindAction::CLEANUP_PHASE,
|
||||||
exception.exception_class,
|
(*exception).exception_class,
|
||||||
exception,
|
exception,
|
||||||
&mut UnwindContext {
|
&mut UnwindContext {
|
||||||
frame: Some(&frame),
|
frame: Some(&frame),
|
||||||
ctx,
|
ctx,
|
||||||
signal,
|
signal,
|
||||||
},
|
},
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
match code {
|
match code {
|
||||||
UnwindReasonCode::CONTINUE_UNWIND => (),
|
UnwindReasonCode::CONTINUE_UNWIND => (),
|
||||||
@ -331,15 +343,15 @@ fn force_unwind_phase2(
|
|||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C-unwind" fn _Unwind_Resume(exception: &mut UnwindException) -> ! {
|
pub unsafe extern "C-unwind" fn _Unwind_Resume(exception: *mut UnwindException) -> ! {
|
||||||
with_context(|ctx| {
|
with_context(|ctx| {
|
||||||
let code = match exception.private_1 {
|
let code = match unsafe { (*exception).private_1 } {
|
||||||
None => {
|
None => {
|
||||||
let handler_cfa = exception.private_2;
|
let handler_cfa = unsafe { (*exception).private_2 };
|
||||||
raise_exception_phase2(exception, ctx, handler_cfa)
|
raise_exception_phase2(exception, ctx, handler_cfa)
|
||||||
}
|
}
|
||||||
Some(stop) => {
|
Some(stop) => {
|
||||||
let stop_arg = exception.private_2 as _;
|
let stop_arg = unsafe { (*exception).private_2 as _ };
|
||||||
force_unwind_phase2(exception, ctx, stop, stop_arg)
|
force_unwind_phase2(exception, ctx, stop, stop_arg)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -351,16 +363,16 @@ pub extern "C-unwind" fn _Unwind_Resume(exception: &mut UnwindException) -> ! {
|
|||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C-unwind" fn _Unwind_Resume_or_Rethrow(
|
pub unsafe extern "C-unwind" fn _Unwind_Resume_or_Rethrow(
|
||||||
exception: &mut UnwindException,
|
exception: *mut UnwindException,
|
||||||
) -> UnwindReasonCode {
|
) -> UnwindReasonCode {
|
||||||
let stop = match exception.private_1 {
|
let stop = match unsafe { (*exception).private_1 } {
|
||||||
None => return _Unwind_RaiseException(exception),
|
None => return unsafe { _Unwind_RaiseException(exception) },
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
};
|
};
|
||||||
|
|
||||||
with_context(|ctx| {
|
with_context(|ctx| {
|
||||||
let stop_arg = exception.private_2 as _;
|
let stop_arg = unsafe { (*exception).private_2 as _ };
|
||||||
let code = force_unwind_phase2(exception, ctx, stop, stop_arg);
|
let code = force_unwind_phase2(exception, ctx, stop, stop_arg);
|
||||||
assert!(code == UnwindReasonCode::INSTALL_CONTEXT);
|
assert!(code == UnwindReasonCode::INSTALL_CONTEXT);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user