From 970e7793bfefd3d93034869ef8672affa02fff24 Mon Sep 17 00:00:00 2001
From: Ryan Levick <ryan.levick@gmail.com>
Date: Thu, 27 Aug 2020 19:11:48 +0200
Subject: [PATCH 1/4] 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 ccc067a3c943d..7eece6768e99a 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 a0d5a7471d8af..8fbd43ad5a58e 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();
 }

From 8bcc4d617869f190c9f7fc0c301e8328f719d85a Mon Sep 17 00:00:00 2001
From: Ryan Levick <ryan.levick@gmail.com>
Date: Fri, 28 Aug 2020 11:22:16 +0200
Subject: [PATCH 2/4] Switch to asm! macro and use brk instruction on ARM

---
 library/panic_abort/src/lib.rs     | 8 ++++----
 library/std/src/sys/windows/mod.rs | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index 7eece6768e99a..a09234e09ff9b 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -17,7 +17,7 @@
 #![feature(panic_runtime)]
 #![feature(staged_api)]
 #![feature(rustc_attrs)]
-#![feature(llvm_asm)]
+#![feature(asm)]
 
 use core::any::Any;
 
@@ -62,11 +62,11 @@ pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 {
                 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);
+                        asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
                     } else if #[cfg(target_arch = "arm")] {
-                        llvm_asm!(".inst 0xDEFB" :: "{r0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile);
+                        asm!("brk 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                     } else if #[cfg(target_arch = "aarch64")] {
-                        llvm_asm!(".inst 0xF003" :: "{x0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile);
+                        asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT);
                     } else {
                         core::intrinsics::abort();
                     }
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index 8fbd43ad5a58e..03ddc3e646180 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -310,13 +310,13 @@ pub fn abort_internal() -> ! {
     unsafe {
         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);
+                asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
                 crate::intrinsics::unreachable();
             } else if #[cfg(target_arch = "arm")] {
-                llvm_asm!(".inst 0xDEFB" :: "{r0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile);
+                asm!("brk 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                 crate::intrinsics::unreachable();
             } else if #[cfg(target_arch = "aarch64")] {
-                llvm_asm!(".inst 0xF003" :: "{x0}"(FAST_FAIL_FATAL_APP_EXIT) ::: volatile);
+                asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT);
                 crate::intrinsics::unreachable();
             }
         }

From 9e2228d2d07c77b8323a3f3e1bf82badddd7bfec Mon Sep 17 00:00:00 2001
From: Ryan Levick <ryan.levick@gmail.com>
Date: Fri, 28 Aug 2020 17:40:56 +0200
Subject: [PATCH 3/4] Back to opcode for 32 bit ARM __fastfail

---
 library/panic_abort/src/lib.rs     | 2 +-
 library/std/src/sys/windows/mod.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index a09234e09ff9b..a37bfa451732e 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -64,7 +64,7 @@ pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 {
                     if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
                         asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
                     } else if #[cfg(target_arch = "arm")] {
-                        asm!("brk 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
+                        asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                     } else if #[cfg(target_arch = "aarch64")] {
                         asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT);
                     } else {
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index 03ddc3e646180..d3b9a626a9e2e 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -313,7 +313,7 @@ pub fn abort_internal() -> ! {
                 asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
                 crate::intrinsics::unreachable();
             } else if #[cfg(target_arch = "arm")] {
-                asm!("brk 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
+                asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                 crate::intrinsics::unreachable();
             } else if #[cfg(target_arch = "aarch64")] {
                 asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT);

From d931e974029a3475bd6712ca8d3bc9cb9dfe558f Mon Sep 17 00:00:00 2001
From: Ryan Levick <ryan.levick@gmail.com>
Date: Sat, 29 Aug 2020 12:30:49 +0200
Subject: [PATCH 4/4] Explicitly look for 'thumb-mode' before using __fastfail
 on 'arm'

---
 library/panic_abort/src/lib.rs     | 2 +-
 library/std/src/sys/windows/mod.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index a37bfa451732e..31058a2b0969b 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -63,7 +63,7 @@ pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 {
                 cfg_if::cfg_if! {
                     if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
                         asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
-                    } else if #[cfg(target_arch = "arm")] {
+                    } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
                         asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                     } else if #[cfg(target_arch = "aarch64")] {
                         asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT);
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index d3b9a626a9e2e..8178e6806b9b3 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -312,7 +312,7 @@ pub fn abort_internal() -> ! {
             if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
                 asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT);
                 crate::intrinsics::unreachable();
-            } else if #[cfg(target_arch = "arm")] {
+            } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
                 asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT);
                 crate::intrinsics::unreachable();
             } else if #[cfg(target_arch = "aarch64")] {