about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-05-05 16:42:47 +0200
committerGitHub <noreply@github.com>2024-05-05 16:42:47 +0200
commit3b8eba97478d74d76e4a07168e7570370c916558 (patch)
tree3a076f53569282aa26e9f9881bd78c310ee29328
parent3953df53f88ac9783ba27c094425a1993d35248f (diff)
parentfa22863f1b13251014c5cae1532c96582749978f (diff)
downloadrust-3b8eba97478d74d76e4a07168e7570370c916558.tar.gz
rust-3b8eba97478d74d76e4a07168e7570370c916558.zip
Rollup merge of #124748 - madsmtm:fix-32bit-watchos-unwind, r=Mark-Simulacrum
Fix unwinding on 32-bit watchOS ARM (v2)

This PR is identical to https://github.com/rust-lang/rust/pull/124494, which was approved and merged but then removed from master by a force-push due to a [CI bug](https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra/topic/ci.20broken.3F).

r? Mark-Simulacrum

Original PR description:

---

Found while doing https://github.com/rust-lang/rust/pull/124491, I wanted to unify the code under `target_vendor = "apple"`, and found that [Clang actually specifies that watchOS ARM 32-bit does not use SjLj](https://github.com/llvm/llvm-project/blob/llvmorg-18.1.4/clang/lib/Driver/ToolChains/Darwin.cpp#L3107-L3119).

I don't have an Apple Watch from that generation at hand to test this myself (series 1 to 3), and I don't think it will be sufficient to test it in the simulator (as it's architecture-specific), so maybe someone else could do so?

N.B. The code is written in a way to support 32-bit iOS and tvOS ARM devices (which do use SjLj) for future compatibility even though we currently only have a target for 32-bit iOS ARM (if you think that's excessive, then I'll change it).

`@rustbot` label O-watchos
-rw-r--r--library/std/src/sys/personality/dwarf/eh.rs9
-rw-r--r--library/std/src/sys/personality/gcc.rs5
-rw-r--r--library/unwind/src/libunwind.rs24
3 files changed, 23 insertions, 15 deletions
diff --git a/library/std/src/sys/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs
index 3f3615ea3e0..ff88ef4e0e1 100644
--- a/library/std/src/sys/personality/dwarf/eh.rs
+++ b/library/std/src/sys/personality/dwarf/eh.rs
@@ -54,7 +54,14 @@ pub enum EHAction {
     Terminate,
 }
 
-pub const USING_SJLJ_EXCEPTIONS: bool = cfg!(all(target_os = "ios", target_arch = "arm"));
+/// 32-bit Apple ARM uses SjLj exceptions, except for watchOS.
+///
+/// I.e. iOS and tvOS, as those are the only Apple OSes that used 32-bit ARM
+/// devices.
+///
+/// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.4/clang/lib/Driver/ToolChains/Darwin.cpp#L3107-L3119>
+pub const USING_SJLJ_EXCEPTIONS: bool =
+    cfg!(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"));
 
 pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result<EHAction, ()> {
     if lsda.is_null() {
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index b0f744dd966..0dc53550ca9 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -92,11 +92,12 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
 // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
 
 cfg_if::cfg_if! {
-    if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "visionos"), not(target_os = "netbsd")))] {
+    if #[cfg(all(not(all(target_vendor = "apple", not(target_os = "watchos"))), target_arch = "arm", not(target_os = "netbsd")))] {
         // ARM EHABI personality routine.
         // https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
         //
-        // iOS uses the default routine instead since it uses SjLj unwinding.
+        // Apple 32-bit ARM (but not watchOS) uses the default routine instead
+        // since it uses SjLj unwinding.
         #[lang = "eh_personality"]
         unsafe extern "C" fn rust_eh_personality(
             state: uw::_Unwind_State,
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index e34e73a3516..e5e28f32e4d 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -33,10 +33,10 @@ pub const unwinder_private_data_size: usize = 2;
 #[cfg(all(target_arch = "x86_64", target_os = "windows"))]
 pub const unwinder_private_data_size: usize = 6;
 
-#[cfg(all(target_arch = "arm", not(any(target_os = "ios", target_os = "watchos"))))]
+#[cfg(all(target_arch = "arm", not(all(target_vendor = "apple", not(target_os = "watchos")))))]
 pub const unwinder_private_data_size: usize = 20;
 
-#[cfg(all(target_arch = "arm", any(target_os = "ios", target_os = "watchos")))]
+#[cfg(all(target_arch = "arm", all(target_vendor = "apple", not(target_os = "watchos"))))]
 pub const unwinder_private_data_size: usize = 5;
 
 #[cfg(all(target_arch = "aarch64", target_pointer_width = "64", not(target_os = "windows")))]
@@ -123,7 +123,7 @@ extern "C" {
 }
 
 cfg_if::cfg_if! {
-if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos", target_os = "netbsd", not(target_arch = "arm")))] {
+if #[cfg(any(all(target_vendor = "apple", not(target_os = "watchos")), target_os = "netbsd", not(target_arch = "arm")))] {
     // Not ARM EHABI
     #[repr(C)]
     #[derive(Copy, Clone, PartialEq)]
@@ -258,8 +258,15 @@ if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", targe
 } // cfg_if!
 
 cfg_if::cfg_if! {
-if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
-    // Not 32-bit iOS
+if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"))] {
+    // 32-bit ARM Apple (except for watchOS) uses SjLj and does not provide
+    // _Unwind_Backtrace()
+    extern "C-unwind" {
+        pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
+    }
+
+    pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException;
+} else {
     #[cfg_attr(
         all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),
         link(name = "unwind", kind = "static", modifiers = "-bundle")
@@ -276,13 +283,6 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
                                  trace_argument: *mut c_void)
                                  -> _Unwind_Reason_Code;
     }
-} else {
-    // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
-    extern "C-unwind" {
-        pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
-    }
-
-    pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException;
 }
 } // cfg_if!