diff options
| author | Valerii Hiora <valerii.hiora@gmail.com> | 2014-05-05 10:07:49 +0300 |
|---|---|---|
| committer | Valerii Hiora <valerii.hiora@gmail.com> | 2014-06-12 21:15:14 +0300 |
| commit | a49b765f9a5b5926e338da30fcaae59ff1ae5c02 (patch) | |
| tree | 489f1930d52ae1e9050e840940b3bcb1daedb615 /src/librustrt | |
| parent | 0c10c686824bf37084af87af84f338bcd2a7551a (diff) | |
| download | rust-a49b765f9a5b5926e338da30fcaae59ff1ae5c02.tar.gz rust-a49b765f9a5b5926e338da30fcaae59ff1ae5c02.zip | |
Basic iOS support
Diffstat (limited to 'src/librustrt')
| -rw-r--r-- | src/librustrt/args.rs | 1 | ||||
| -rw-r--r-- | src/librustrt/lib.rs | 2 | ||||
| -rw-r--r-- | src/librustrt/libunwind.rs | 25 | ||||
| -rw-r--r-- | src/librustrt/local_ptr.rs | 5 | ||||
| -rw-r--r-- | src/librustrt/mutex.rs | 5 | ||||
| -rw-r--r-- | src/librustrt/stack.rs | 12 | ||||
| -rw-r--r-- | src/librustrt/thread.rs | 2 | ||||
| -rw-r--r-- | src/librustrt/thread_local_storage.rs | 3 | ||||
| -rw-r--r-- | src/librustrt/unwind.rs | 64 |
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) } } } |
