From: Ralf Jung Date: Sat, 14 Mar 2020 10:23:39 +0000 (+0100) Subject: adjust Miri interaction with panic runtime X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=9c5d8e9b520c12044c818dd3d48f02bcea075ec3;p=rust.git adjust Miri interaction with panic runtime --- diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index c2f13047e54..d722406b82b 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1892,10 +1892,12 @@ pub fn ptr_offset_from(ptr: *const T, base: *const T) -> isize; /// Internal hook used by Miri to implement unwinding. - /// Compiles to a NOP during non-Miri codegen. + /// ICEs when encountered during non-Miri codegen. /// - /// Perma-unstable: do not use - pub fn miri_start_panic(data: *mut (dyn crate::any::Any + crate::marker::Send)) -> (); + /// The `payload` ptr here will be exactly the one `do_catch` gets passed by `try`. + /// + /// Perma-unstable: do not use. + pub fn miri_start_panic(payload: *mut u8) -> !; } // Some functions are defined here because they accidentally got made diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index d6c33666938..c213b19d062 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -31,6 +31,9 @@ #![panic_runtime] #![feature(panic_runtime)] +// `real_imp` is unused with Miri, so silence warnings. +#![cfg_attr(miri, allow(dead_code))] + use alloc::boxed::Box; use core::any::Any; use core::panic::BoxMeUp; @@ -38,25 +41,38 @@ cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { #[path = "emcc.rs"] - mod imp; + mod real_imp; } else if #[cfg(target_arch = "wasm32")] { #[path = "dummy.rs"] - mod imp; + mod real_imp; } else if #[cfg(target_os = "hermit")] { #[path = "hermit.rs"] - mod imp; + mod real_imp; } else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] { #[path = "dummy.rs"] - mod imp; + mod real_imp; } else if #[cfg(target_env = "msvc")] { #[path = "seh.rs"] - mod imp; + mod real_imp; } else { // Rust runtime's startup objects depend on these symbols, so make them public. #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] - pub use imp::eh_frame_registry::*; + pub use real_imp::eh_frame_registry::*; #[path = "gcc.rs"] + mod real_imp; + } +} + +cfg_if::cfg_if! { + if #[cfg(miri)] { + // Use the Miri runtime. + // We still need to also load the normal runtime above, as rustc expects certain lang + // items from there to be defined. + #[path = "miri.rs"] mod imp; + } else { + // Use the real runtime. + use real_imp as imp; } } @@ -81,12 +97,5 @@ let payload = payload as *mut &mut dyn BoxMeUp; 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)) } diff --git a/src/libpanic_unwind/miri.rs b/src/libpanic_unwind/miri.rs new file mode 100644 index 00000000000..5f44b98566f --- /dev/null +++ b/src/libpanic_unwind/miri.rs @@ -0,0 +1,20 @@ +//! Unwinding panics for Miri. +use core::any::Any; +use alloc::boxed::Box; + +// The type of the payload that the Miri engine propagates through unwinding for us. +// Must be pointer-sized. +type Payload = Box>; + +pub unsafe fn panic(payload: Box) -> u32 { + // The payload we pass to `miri_start_panic` will be exactly the argument we get + // in `cleanup` below. So we just box it up once, to get something pointer-sized. + let payload_box: Payload = Box::new(payload); + core::intrinsics::miri_start_panic(Box::into_raw(payload_box) as *mut u8) +} + +pub unsafe fn cleanup(payload_box: *mut u8) -> Box { + // Recover the underlying `Box`. + let payload_box: Payload = Box::from_raw(payload_box as *mut _); + *payload_box +}