about summary refs log tree commit diff
path: root/src/librustrt
diff options
context:
space:
mode:
authorValerii Hiora <valerii.hiora@gmail.com>2014-05-05 10:07:49 +0300
committerValerii Hiora <valerii.hiora@gmail.com>2014-06-12 21:15:14 +0300
commita49b765f9a5b5926e338da30fcaae59ff1ae5c02 (patch)
tree489f1930d52ae1e9050e840940b3bcb1daedb615 /src/librustrt
parent0c10c686824bf37084af87af84f338bcd2a7551a (diff)
downloadrust-a49b765f9a5b5926e338da30fcaae59ff1ae5c02.tar.gz
rust-a49b765f9a5b5926e338da30fcaae59ff1ae5c02.zip
Basic iOS support
Diffstat (limited to 'src/librustrt')
-rw-r--r--src/librustrt/args.rs1
-rw-r--r--src/librustrt/lib.rs2
-rw-r--r--src/librustrt/libunwind.rs25
-rw-r--r--src/librustrt/local_ptr.rs5
-rw-r--r--src/librustrt/mutex.rs5
-rw-r--r--src/librustrt/stack.rs12
-rw-r--r--src/librustrt/thread.rs2
-rw-r--r--src/librustrt/thread_local_storage.rs3
-rw-r--r--src/librustrt/unwind.rs64
9 files changed, 105 insertions, 14 deletions
diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs
index 0789bf7f906..d6d4b18051b 100644
--- a/src/librustrt/args.rs
+++ b/src/librustrt/args.rs
@@ -145,6 +145,7 @@ mod imp {
 }
 
 #[cfg(target_os = "macos")]
+#[cfg(target_os = "ios")]
 #[cfg(target_os = "win32")]
 mod imp {
     use core::prelude::*;
diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs
index 76cbeef443e..e17a43322ba 100644
--- a/src/librustrt/lib.rs
+++ b/src/librustrt/lib.rs
@@ -164,7 +164,7 @@ pub unsafe fn cleanup() {
 pub mod shouldnt_be_public {
     #[cfg(not(test))]
     pub use super::local_ptr::native::maybe_tls_key;
-    #[cfg(not(windows), not(target_os = "android"))]
+    #[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
     pub use super::local_ptr::compiled::RT_TLS_PTR;
 }
 
diff --git a/src/librustrt/libunwind.rs b/src/librustrt/libunwind.rs
index 846ec248805..50c2aba2b5c 100644
--- a/src/librustrt/libunwind.rs
+++ b/src/librustrt/libunwind.rs
@@ -17,6 +17,7 @@
 use libc;
 
 #[cfg(not(target_arch = "arm"))]
+#[cfg(target_os = "ios")]
 #[repr(C)]
 pub enum _Unwind_Action {
     _UA_SEARCH_PHASE = 1,
@@ -61,9 +62,12 @@ pub static unwinder_private_data_size: int = 5;
 #[cfg(target_arch = "x86_64")]
 pub static unwinder_private_data_size: int = 2;
 
-#[cfg(target_arch = "arm")]
+#[cfg(target_arch = "arm", not(target_os = "ios"))]
 pub static unwinder_private_data_size: int = 20;
 
+#[cfg(target_arch = "arm", target_os = "ios")]
+pub static unwinder_private_data_size: int = 5;
+
 #[cfg(target_arch = "mips")]
 pub static unwinder_private_data_size: int = 2;
 
@@ -89,8 +93,27 @@ extern {}
 #[link(name = "gcc")]
 extern {}
 
+
 extern "C" {
+    // iOS on armv7 uses SjLj exceptions and requires to link
+    // agains corresponding routine (..._SjLj_...)
+    // So here we just skip linking for iOS
+    #[cfg(not(target_os = "ios", target_arch = "arm"))]
     pub fn _Unwind_RaiseException(exception: *_Unwind_Exception)
                 -> _Unwind_Reason_Code;
     pub fn _Unwind_DeleteException(exception: *_Unwind_Exception);
 }
+
+// ... and now we just providing access to SjLj counterspart
+// through a standard name to hide those details from others
+// (see also comment above regarding _Unwind_RaiseException)
+#[cfg(target_os = "ios", target_arch = "arm")]
+#[inline(always)]
+pub unsafe fn _Unwind_RaiseException(exc: *_Unwind_Exception)
+                                     -> _Unwind_Reason_Code {
+    extern "C" {
+        fn _Unwind_SjLj_RaiseException(e: *_Unwind_Exception)
+                                       -> _Unwind_Reason_Code; }
+
+    _Unwind_SjLj_RaiseException(exc)
+}
diff --git a/src/librustrt/local_ptr.rs b/src/librustrt/local_ptr.rs
index 91e3409892e..b6858be32b7 100644
--- a/src/librustrt/local_ptr.rs
+++ b/src/librustrt/local_ptr.rs
@@ -24,10 +24,11 @@ use alloc::owned::Box;
 
 #[cfg(windows)]               // mingw-w32 doesn't like thread_local things
 #[cfg(target_os = "android")] // see #10686
+#[cfg(target_os = "ios")]
 pub use self::native::{init, cleanup, put, take, try_take, unsafe_take, exists,
                        unsafe_borrow, try_unsafe_borrow};
 
-#[cfg(not(windows), not(target_os = "android"))]
+#[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
 pub use self::compiled::{init, cleanup, put, take, try_take, unsafe_take, exists,
                          unsafe_borrow, try_unsafe_borrow};
 
@@ -81,7 +82,7 @@ pub unsafe fn borrow<T>() -> Borrowed<T> {
 /// implemented using LLVM's thread_local attribute which isn't necessarily
 /// working on all platforms. This implementation is faster, however, so we use
 /// it wherever possible.
-#[cfg(not(windows), not(target_os = "android"))]
+#[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
 pub mod compiled {
     use core::prelude::*;
 
diff --git a/src/librustrt/mutex.rs b/src/librustrt/mutex.rs
index eec19e9d5db..26359ff7f6e 100644
--- a/src/librustrt/mutex.rs
+++ b/src/librustrt/mutex.rs
@@ -283,6 +283,7 @@ mod imp {
     }
 
     #[cfg(target_os = "macos")]
+    #[cfg(target_os = "ios")]
     mod os {
         use libc;
 
@@ -294,6 +295,10 @@ mod imp {
         static __PTHREAD_MUTEX_SIZE__: uint = 40;
         #[cfg(target_arch = "x86")]
         static __PTHREAD_COND_SIZE__: uint = 24;
+        #[cfg(target_arch = "arm")]
+        static __PTHREAD_MUTEX_SIZE__: uint = 40;
+        #[cfg(target_arch = "arm")]
+        static __PTHREAD_COND_SIZE__: uint = 24;
 
         static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
         static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
diff --git a/src/librustrt/stack.rs b/src/librustrt/stack.rs
index aac773f6f85..e6fa845bedc 100644
--- a/src/librustrt/stack.rs
+++ b/src/librustrt/stack.rs
@@ -173,7 +173,8 @@ pub unsafe fn record_sp_limit(limit: uint) {
     return target_record_sp_limit(limit);
 
     // x86-64
-    #[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
+    #[cfg(target_arch = "x86_64", target_os = "macos")]
+    #[cfg(target_arch = "x86_64", target_os = "ios")] #[inline(always)]
     unsafe fn target_record_sp_limit(limit: uint) {
         asm!("movq $$0x60+90*8, %rsi
               movq $0, %gs:(%rsi)" :: "r"(limit) : "rsi" : "volatile")
@@ -195,7 +196,8 @@ pub unsafe fn record_sp_limit(limit: uint) {
     }
 
     // x86
-    #[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
+    #[cfg(target_arch = "x86", target_os = "macos")]
+    #[cfg(target_arch = "x86", target_os = "ios")] #[inline(always)]
     unsafe fn target_record_sp_limit(limit: uint) {
         asm!("movl $$0x48+90*4, %eax
               movl $0, %gs:(%eax)" :: "r"(limit) : "eax" : "volatile")
@@ -243,7 +245,8 @@ pub unsafe fn get_sp_limit() -> uint {
     return target_get_sp_limit();
 
     // x86-64
-    #[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
+    #[cfg(target_arch = "x86_64", target_os = "macos")]
+    #[cfg(target_arch = "x86_64", target_os = "ios")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
         let limit;
         asm!("movq $$0x60+90*8, %rsi
@@ -270,7 +273,8 @@ pub unsafe fn get_sp_limit() -> uint {
     }
 
     // x86
-    #[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
+    #[cfg(target_arch = "x86", target_os = "macos")]
+    #[cfg(target_arch = "x86", target_os = "ios")] #[inline(always)]
     unsafe fn target_get_sp_limit() -> uint {
         let limit;
         asm!("movl $$0x48+90*4, %eax
diff --git a/src/librustrt/thread.rs b/src/librustrt/thread.rs
index 4ef2cec19db..3dcd1c4a6f0 100644
--- a/src/librustrt/thread.rs
+++ b/src/librustrt/thread.rs
@@ -276,7 +276,6 @@ mod imp {
     }
 
     pub unsafe fn yield_now() { assert_eq!(sched_yield(), 0); }
-
     // glibc >= 2.15 has a __pthread_get_minstack() function that returns
     // PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
     // storage.  We need that information to avoid blowing up when a small stack
@@ -345,4 +344,3 @@ mod tests {
         assert_eq!(42, Thread::start_stack(1, proc () 42).join());
     }
 }
-
diff --git a/src/librustrt/thread_local_storage.rs b/src/librustrt/thread_local_storage.rs
index 2cdeb21fb83..4a7be39e6b8 100644
--- a/src/librustrt/thread_local_storage.rs
+++ b/src/librustrt/thread_local_storage.rs
@@ -37,13 +37,14 @@ pub unsafe fn destroy(key: Key) {
     assert!(pthread_key_delete(key) == 0);
 }
 
-#[cfg(target_os="macos")]
+#[cfg(target_os = "macos")]
 #[allow(non_camel_case_types)] // foreign type
 type pthread_key_t = ::libc::c_ulong;
 
 #[cfg(target_os="linux")]
 #[cfg(target_os="freebsd")]
 #[cfg(target_os="android")]
+#[cfg(target_os = "ios")]
 #[allow(non_camel_case_types)] // foreign type
 type pthread_key_t = ::libc::c_uint;
 
diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs
index f7475db1552..e60c50f0adb 100644
--- a/src/librustrt/unwind.rs
+++ b/src/librustrt/unwind.rs
@@ -285,16 +285,74 @@ pub mod eabi {
         }
         else { // cleanup phase
             unsafe {
-                 __gcc_personality_v0(version, actions, exception_class, ue_header,
+                __gcc_personality_v0(version, actions, exception_class, ue_header,
+                                     context)
+            }
+        }
+    }
+}
+
+// iOS on armv7 is using SjLj exceptions and therefore requires to use
+// a specialized personality routine: __gcc_personality_sj0
+
+#[cfg(target_os = "ios", target_arch = "arm", not(test))]
+#[doc(hidden)]
+#[allow(visible_private_types)]
+pub mod eabi {
+    use uw = libunwind;
+    use libc::c_int;
+
+    extern "C" {
+        #[cfg(target_os = "ios", target_arch = "arm")]
+        fn __gcc_personality_sj0(version: c_int,
+                                actions: uw::_Unwind_Action,
+                                exception_class: uw::_Unwind_Exception_Class,
+                                ue_header: *uw::_Unwind_Exception,
+                                context: *uw::_Unwind_Context)
+            -> uw::_Unwind_Reason_Code;
+    }
+
+    #[lang="eh_personality"]
+    #[no_mangle] // so we can reference it by name from middle/trans/base.rs
+    pub extern "C" fn rust_eh_personality(
+        version: c_int,
+        actions: uw::_Unwind_Action,
+        exception_class: uw::_Unwind_Exception_Class,
+        ue_header: *uw::_Unwind_Exception,
+        context: *uw::_Unwind_Context
+    ) -> uw::_Unwind_Reason_Code
+    {
+        unsafe {
+            __gcc_personality_sj0(version, actions, exception_class, ue_header,
+                                  context)
+        }
+    }
+
+    #[no_mangle] // referenced from rust_try.ll
+    pub extern "C" fn rust_eh_personality_catch(
+        version: c_int,
+        actions: uw::_Unwind_Action,
+        exception_class: uw::_Unwind_Exception_Class,
+        ue_header: *uw::_Unwind_Exception,
+        context: *uw::_Unwind_Context
+    ) -> uw::_Unwind_Reason_Code
+    {
+        if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
+            uw::_URC_HANDLER_FOUND // catch!
+        }
+        else { // cleanup phase
+            unsafe {
+                __gcc_personality_sj0(version, actions, exception_class, ue_header,
                                       context)
             }
         }
     }
 }
 
+
 // ARM EHABI uses a slightly different personality routine signature,
 // but otherwise works the same.
-#[cfg(target_arch = "arm", not(test))]
+#[cfg(target_arch = "arm", not(test), not(target_os = "ios"))]
 #[allow(visible_private_types)]
 pub mod eabi {
     use uw = libunwind;
@@ -332,7 +390,7 @@ pub mod eabi {
         }
         else { // cleanup phase
             unsafe {
-                 __gcc_personality_v0(state, ue_header, context)
+                __gcc_personality_v0(state, ue_header, context)
             }
         }
     }