Skip to content

Commit c738b82

Browse files
committed
Fix unwinding on 32-bit watchOS ARM
The code is written in a way to support 32-bit iOS and tvOS ARM devices, for future compatibility even though we currently only have a target for 32-bit iOS ARM.
1 parent 28d5ede commit c738b82

File tree

3 files changed

+23
-15
lines changed

3 files changed

+23
-15
lines changed

Diff for: std/src/sys/personality/dwarf/eh.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,14 @@ pub enum EHAction {
5454
Terminate,
5555
}
5656

57-
pub const USING_SJLJ_EXCEPTIONS: bool = cfg!(all(target_os = "ios", target_arch = "arm"));
57+
/// 32-bit Apple ARM uses SjLj exceptions, except for watchOS.
58+
///
59+
/// I.e. iOS and tvOS, as those are the only Apple OSes that used 32-bit ARM
60+
/// devices.
61+
///
62+
/// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.4/clang/lib/Driver/ToolChains/Darwin.cpp#L3107-L3119>
63+
pub const USING_SJLJ_EXCEPTIONS: bool =
64+
cfg!(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"));
5865

5966
pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result<EHAction, ()> {
6067
if lsda.is_null() {

Diff for: std/src/sys/personality/gcc.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,12 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
9292
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
9393

9494
cfg_if::cfg_if! {
95-
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")))] {
95+
if #[cfg(all(not(all(target_vendor = "apple", not(target_os = "watchos"))), target_arch = "arm", not(target_os = "netbsd")))] {
9696
// ARM EHABI personality routine.
9797
// https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
9898
//
99-
// iOS uses the default routine instead since it uses SjLj unwinding.
99+
// Apple 32-bit ARM (but not watchOS) uses the default routine instead
100+
// since it uses SjLj unwinding.
100101
#[lang = "eh_personality"]
101102
unsafe extern "C" fn rust_eh_personality(
102103
state: uw::_Unwind_State,

Diff for: unwind/src/libunwind.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ pub const unwinder_private_data_size: usize = 2;
3333
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
3434
pub const unwinder_private_data_size: usize = 6;
3535

36-
#[cfg(all(target_arch = "arm", not(any(target_os = "ios", target_os = "watchos"))))]
36+
#[cfg(all(target_arch = "arm", not(all(target_vendor = "apple", not(target_os = "watchos")))))]
3737
pub const unwinder_private_data_size: usize = 20;
3838

39-
#[cfg(all(target_arch = "arm", any(target_os = "ios", target_os = "watchos")))]
39+
#[cfg(all(target_arch = "arm", all(target_vendor = "apple", not(target_os = "watchos"))))]
4040
pub const unwinder_private_data_size: usize = 5;
4141

4242
#[cfg(all(target_arch = "aarch64", target_pointer_width = "64", not(target_os = "windows")))]
@@ -123,7 +123,7 @@ extern "C" {
123123
}
124124

125125
cfg_if::cfg_if! {
126-
if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos", target_os = "netbsd", not(target_arch = "arm")))] {
126+
if #[cfg(any(all(target_vendor = "apple", not(target_os = "watchos")), target_os = "netbsd", not(target_arch = "arm")))] {
127127
// Not ARM EHABI
128128
#[repr(C)]
129129
#[derive(Copy, Clone, PartialEq)]
@@ -258,8 +258,15 @@ if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", targe
258258
} // cfg_if!
259259

260260
cfg_if::cfg_if! {
261-
if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
262-
// Not 32-bit iOS
261+
if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = "arm"))] {
262+
// 32-bit ARM Apple (except for watchOS) uses SjLj and does not provide
263+
// _Unwind_Backtrace()
264+
extern "C-unwind" {
265+
pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
266+
}
267+
268+
pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException;
269+
} else {
263270
#[cfg_attr(
264271
all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),
265272
link(name = "unwind", kind = "static", modifiers = "-bundle")
@@ -276,13 +283,6 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
276283
trace_argument: *mut c_void)
277284
-> _Unwind_Reason_Code;
278285
}
279-
} else {
280-
// 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
281-
extern "C-unwind" {
282-
pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
283-
}
284-
285-
pub use _Unwind_SjLj_RaiseException as _Unwind_RaiseException;
286286
}
287287
} // cfg_if!
288288

0 commit comments

Comments
 (0)