From 29bed26036f5b74d4779423ec2313ba8280ec4a0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 21 Dec 2020 13:35:45 +0100 Subject: [PATCH 1/3] slightly more typed interface to panic implementation --- library/panic_abort/src/lib.rs | 4 +++- library/panic_unwind/src/lib.rs | 3 +-- library/std/src/panicking.rs | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index a8ebb4b3219..eb2277d8baa 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -14,11 +14,13 @@ #![feature(core_intrinsics)] #![feature(nll)] #![feature(panic_runtime)] +#![feature(std_internals)] #![feature(staged_api)] #![feature(rustc_attrs)] #![feature(asm)] use core::any::Any; +use core::panic::BoxMeUp; #[rustc_std_internal_symbol] #[allow(improper_ctypes_definitions)] @@ -28,7 +30,7 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen // "Leak" the payload and shim to the relevant abort on the platform in question. #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 { +pub unsafe extern "C" fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 { abort(); cfg_if::cfg_if! { diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 0b74a844fec..1ac050be3e4 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -104,8 +104,7 @@ pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any // implementation. #[rustc_std_internal_symbol] #[unwind(allowed)] -pub unsafe extern "C" fn __rust_start_panic(payload: usize) -> u32 { - let payload = payload as *mut &mut dyn BoxMeUp; +pub unsafe extern "C" fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32 { let payload = (*payload).take_box(); imp::panic(Box::from_raw(payload)) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 8ba3feccb6b..31c215a52a2 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -48,7 +48,7 @@ extern "C" { /// It cannot be `Box` because the other end of this call does not depend /// on liballoc, and thus cannot use `Box`. #[unwind(allowed)] - fn __rust_start_panic(payload: usize) -> u32; + fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32; } /// This function is called by the panic runtime if FFI code catches a Rust @@ -637,7 +637,7 @@ pub fn rust_panic_without_hook(payload: Box) -> ! { fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! { let code = unsafe { let obj = &mut msg as *mut &mut dyn BoxMeUp; - __rust_start_panic(obj as usize) + __rust_start_panic(obj) }; rtabort!("failed to initiate panic, error {}", code) } From 7524eb2704b025a6b36bcc280ce2a81bdb782699 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 22 Dec 2020 12:49:59 +0100 Subject: [PATCH 2/3] update a seemingly outdated comment --- library/std/src/panicking.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 31c215a52a2..7f4b739cbf8 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -44,9 +44,8 @@ use realstd::io::set_output_capture; extern "C" { fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static); - /// `payload` is actually a `*mut &mut dyn BoxMeUp` but that would cause FFI warnings. - /// It cannot be `Box` because the other end of this call does not depend - /// on liballoc, and thus cannot use `Box`. + /// `payload` is actually a `Box`, but we pass this by-reference because the other + /// end of this call does not depend on liballoc, and thus cannot use `Box`. #[unwind(allowed)] fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32; } From 1600f7d693c5fba1b279f8d96ec714c897e21799 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 25 Dec 2020 23:37:27 +0100 Subject: [PATCH 3/3] fix another comment, and make __rust_start_panic code a bit more semantically clear --- library/panic_unwind/src/lib.rs | 4 ++-- library/std/src/panicking.rs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 1ac050be3e4..9ce9c477ec0 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -105,7 +105,7 @@ pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any #[rustc_std_internal_symbol] #[unwind(allowed)] pub unsafe extern "C" fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32 { - let payload = (*payload).take_box(); + let payload = Box::from_raw((*payload).take_box()); - imp::panic(Box::from_raw(payload)) + imp::panic(payload) } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 7f4b739cbf8..6cd572cbe87 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -44,8 +44,9 @@ use realstd::io::set_output_capture; extern "C" { fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static); - /// `payload` is actually a `Box`, but we pass this by-reference because the other - /// end of this call does not depend on liballoc, and thus cannot use `Box`. + /// `payload` is passed through another layer of raw pointers as `&mut dyn Trait` is not + /// FFI-safe. `BoxMeUp` lazily performs allocation only when needed (this avoids allocations + /// when using the "abort" panic runtime). #[unwind(allowed)] fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32; }