From 970e7793bfefd3d93034869ef8672affa02fff24 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 27 Aug 2020 19:11:48 +0200 Subject: [PATCH] Add __fastfail for Windows on arm/aarch64 --- library/panic_abort/src/lib.rs | 15 +++++++++++++-- library/std/src/sys/windows/mod.rs | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index ccc067a3c94..7eece6768e9 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -47,7 +47,7 @@ pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 { } __rust_abort(); } - } else if #[cfg(all(windows, any(target_arch = "x86", target_arch = "x86_64")))] { + } else if #[cfg(windows)] { // On Windows, use the processor-specific __fastfail mechanism. In Windows 8 // and later, this will terminate the process immediately without running any // in-process exception handlers. In earlier versions of Windows, this @@ -59,7 +59,18 @@ pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 { // // Note: this is the same implementation as in libstd's `abort_internal` unsafe fn abort() -> ! { - llvm_asm!("int $$0x29" :: "{ecx}"(7) ::: volatile); // 7 is FAST_FAIL_FATAL_APP_EXIT + const FAST_FAIL_FATAL_APP_EXIT: usize = 7; + cfg_if::cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + llvm_asm!("int $$0x29" :: "{ecx}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile); + } else if #[cfg(target_arch = "arm")] { + llvm_asm!(".inst 0xDEFB" :: "{r0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile); + } else if #[cfg(target_arch = "aarch64")] { + llvm_asm!(".inst 0xF003" :: "{x0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile); + } else { + core::intrinsics::abort(); + } + } core::intrinsics::unreachable(); } } else { diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index a0d5a7471d8..8fbd43ad5a5 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -306,10 +306,20 @@ pub fn dur2timeout(dur: Duration) -> c::DWORD { /// that function for more information on `__fastfail` #[allow(unreachable_code)] pub fn abort_internal() -> ! { - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + const FAST_FAIL_FATAL_APP_EXIT: usize = 7; unsafe { - llvm_asm!("int $$0x29" :: "{ecx}"(7) ::: volatile); // 7 is FAST_FAIL_FATAL_APP_EXIT - crate::intrinsics::unreachable(); + cfg_if::cfg_if! { + if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + llvm_asm!("int $$0x29" :: "{ecx}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile); + crate::intrinsics::unreachable(); + } else if #[cfg(target_arch = "arm")] { + llvm_asm!(".inst 0xDEFB" :: "{r0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile); + crate::intrinsics::unreachable(); + } else if #[cfg(target_arch = "aarch64")] { + llvm_asm!(".inst 0xF003" :: "{x0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile); + crate::intrinsics::unreachable(); + } + } } crate::intrinsics::abort(); }