libunwind_panic: adjust miri panic hack

This commit is contained in:
Ralf Jung 2019-11-27 20:39:53 +01:00
parent 8f1bbd69e1
commit 02b66a1901
4 changed files with 18 additions and 59 deletions

View File

@ -1348,9 +1348,11 @@ extern "rust-intrinsic" {
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
/// Internal hook used by Miri to implement unwinding.
/// Compiles to a NOP during non-Miri codegen.
///
/// Perma-unstable: do not use
#[cfg(not(bootstrap))]
pub fn miri_start_panic(data: *mut (dyn crate::any::Any + crate::marker::Send)) -> !;
pub fn miri_start_panic(data: *mut (dyn crate::any::Any + crate::marker::Send)) -> ();
}
// Some functions are defined here because they accidentally got made

View File

@ -36,10 +36,7 @@ use core::raw;
use core::panic::BoxMeUp;
cfg_if::cfg_if! {
if #[cfg(miri)] {
#[path = "miri.rs"]
mod imp;
} else if #[cfg(target_os = "emscripten")] {
if #[cfg(target_os = "emscripten")] {
#[path = "emcc.rs"]
mod imp;
} else if #[cfg(target_arch = "wasm32")] {
@ -94,5 +91,14 @@ pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
#[unwind(allowed)]
pub unsafe extern "C" fn __rust_start_panic(payload: usize) -> u32 {
let payload = payload as *mut &mut dyn BoxMeUp;
imp::panic(Box::from_raw((*payload).take_box()))
let payload = (*payload).take_box();
// Miri panic support: cfg'd out of normal builds just to be sure.
// When going through normal codegen, `miri_start_panic` is a NOP, so the
// Miri-enabled sysroot still supports normal unwinding. But when executed in
// Miri, this line initiates unwinding.
#[cfg(miri)]
core::intrinsics::miri_start_panic(payload);
imp::panic(Box::from_raw(payload))
}

View File

@ -1,42 +0,0 @@
#![allow(nonstandard_style)]
use core::any::Any;
use alloc::boxed::Box;
pub fn payload() -> *mut u8 {
core::ptr::null_mut()
}
pub unsafe fn panic(data: Box<dyn Any + Send>) -> ! {
core::intrinsics::miri_start_panic(Box::into_raw(data))
}
pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
Box::from_raw(ptr)
}
// This is required by the compiler to exist (e.g., it's a lang item),
// but is never used by Miri. Therefore, we just use a stub here
#[lang = "eh_personality"]
#[cfg(not(test))]
fn rust_eh_personality() {
unsafe { core::intrinsics::abort() }
}
// The rest is required on *some* targets to exist (specifically, MSVC targets that use SEH).
// We just add it on all targets. Copied from `seh.rs`.
#[repr(C)]
pub struct _TypeDescriptor {
pub pVFTable: *const u8,
pub spare: *mut u8,
pub name: [u8; 11],
}
const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
#[cfg_attr(not(test), lang = "eh_catch_typeinfo")]
static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
pVFTable: core::ptr::null(),
spare: core::ptr::null_mut(),
name: TYPE_NAME,
};

View File

@ -528,18 +528,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => FnAbi::new(&bx, sig, &extra_args)
};
// This should never be reachable at runtime:
// We should only emit a call to this intrinsic in #[cfg(miri)] mode,
// which means that we will never actually use the generate object files
// (we will just be interpreting the MIR)
//
// Note that we still need to be able to codegen *something* for this intrisnic:
// Miri currently uses Xargo to build a special libstd. As a side effect,
// we generate normal object files for libstd - while these are never used,
// we still need to be able to build them.
// For normal codegen, this Miri-specific intrinsic is just a NOP.
if intrinsic == Some("miri_start_panic") {
bx.abort();
bx.unreachable();
let target = destination.as_ref().unwrap().1;
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
helper.funclet_br(self, &mut bx, target);
return;
}