about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMads Marquart <mads@marquart.dk>2024-09-07 17:57:47 +0200
committerMads Marquart <mads@marquart.dk>2024-09-08 09:12:31 +0200
commitf98ca32b0a594b1ee59e22e1927198ed03eb0ce7 (patch)
tree4e9b34dcae6acbc8cf7af6c284418f7fa928d8aa
parent9afe7136958edaa403f0b0eb00f0353c125b7352 (diff)
downloadrust-f98ca32b0a594b1ee59e22e1927198ed03eb0ce7.tar.gz
rust-f98ca32b0a594b1ee59e22e1927198ed03eb0ce7.zip
Fix linking error when compiling for 32-bit watchOS
In https://github.com/rust-lang/rust/pull/124748, I mistakenly conflated
"not SjLj" to mean "ARM EHABI", which isn't true, watchOS armv7k
(specifically only that architecture) uses a third unwinding method
called "DWARF CFI".
-rw-r--r--library/std/src/sys/personality/dwarf/eh.rs6
-rw-r--r--library/std/src/sys/personality/gcc.rs13
-rw-r--r--library/unwind/src/libunwind.rs13
3 files changed, 18 insertions, 14 deletions
diff --git a/library/std/src/sys/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs
index c37c3e442ae..778d8686f02 100644
--- a/library/std/src/sys/personality/dwarf/eh.rs
+++ b/library/std/src/sys/personality/dwarf/eh.rs
@@ -54,10 +54,10 @@ pub enum EHAction {
     Terminate,
 }
 
-/// 32-bit Apple ARM uses SjLj exceptions, except for watchOS.
+/// 32-bit ARM Darwin platforms uses SjLj exceptions.
 ///
-/// I.e. iOS and tvOS, as those are the only Apple OSes that used 32-bit ARM
-/// devices.
+/// The exception is watchOS armv7k (specifically that subarchitecture), which
+/// instead uses DWARF Call Frame Information (CFI) unwinding.
 ///
 /// <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 =
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index f6b1844e153..ad596ecff65 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -95,14 +95,15 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
 
 cfg_if::cfg_if! {
     if #[cfg(all(
-            target_arch = "arm",
-            not(all(target_vendor = "apple", not(target_os = "watchos"))),
-            not(target_os = "netbsd"),
-        ))] {
+        target_arch = "arm",
+        not(target_vendor = "apple"),
+        not(target_os = "netbsd"),
+    ))] {
         /// personality fn called by [ARM EHABI][armeabi-eh]
         ///
-        /// Apple 32-bit ARM (but not watchOS) uses the default routine instead
-        /// since it uses "setjmp-longjmp" unwinding.
+        /// 32-bit ARM on iOS/tvOS/watchOS does not use ARM EHABI, it uses
+        /// either "setjmp-longjmp" unwinding or DWARF CFI unwinding, which is
+        /// handled by the default routine.
         ///
         /// [armeabi-eh]: https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
         #[lang = "eh_personality"]
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index e5e28f32e4d..1d856ce1879 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(all(target_vendor = "apple", not(target_os = "watchos")))))]
+#[cfg(all(target_arch = "arm", not(target_vendor = "apple")))]
 pub const unwinder_private_data_size: usize = 20;
 
-#[cfg(all(target_arch = "arm", all(target_vendor = "apple", not(target_os = "watchos"))))]
+#[cfg(all(target_arch = "arm", target_vendor = "apple"))]
 pub const unwinder_private_data_size: usize = 5;
 
 #[cfg(all(target_arch = "aarch64", target_pointer_width = "64", not(target_os = "windows")))]
@@ -123,8 +123,11 @@ extern "C" {
 }
 
 cfg_if::cfg_if! {
-if #[cfg(any(all(target_vendor = "apple", not(target_os = "watchos")), target_os = "netbsd", not(target_arch = "arm")))] {
+if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "arm")))] {
     // Not ARM EHABI
+    //
+    // 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or
+    // "setjmp-longjmp" / SjLj unwinding.
     #[repr(C)]
     #[derive(Copy, Clone, PartialEq)]
     pub enum _Unwind_Action {
@@ -259,8 +262,8 @@ if #[cfg(any(all(target_vendor = "apple", not(target_os = "watchos")), target_os
 
 cfg_if::cfg_if! {
 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()
+    // 32-bit ARM Apple (except for watchOS armv7k specifically) uses SjLj and
+    // does not provide _Unwind_Backtrace()
     extern "C-unwind" {
         pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
     }