X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmach-support-x86.c;h=76d2b06beef149fdee73ddc7c1977bc6c2f40d42;hb=2e34a838d380715565ada6d447a06d03d6874136;hp=d3c967d2ed8019a957721ecf2b2595eaea00ee05;hpb=189c5058808d70e85d57907f6683fe5ef00e0f31;p=mono.git diff --git a/mono/utils/mach-support-x86.c b/mono/utils/mach-support-x86.c index d3c967d2ed8..76d2b06beef 100644 --- a/mono/utils/mach-support-x86.c +++ b/mono/utils/mach-support-x86.c @@ -16,6 +16,14 @@ #include "utils/mono-sigcontext.h" #include "mach-support.h" +/* Known offsets used for TLS storage*/ + +/* All OSX versions up to 10.8 */ +#define TLS_VECTOR_OFFSET_CATS 0x48 +#define TLS_VECTOR_OFFSET_10_9 0xb0 + +static int tls_vector_offset; + void * mono_mach_arch_get_ip (thread_state_t state) { @@ -39,7 +47,7 @@ mono_mach_arch_get_mcontext_size () } void -mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t context) +mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context) { x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state; struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context; @@ -48,7 +56,7 @@ mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t contex } void -mono_mach_arch_mcontext_to_thread_state (mcontext_t context, thread_state_t state) +mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state) { x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state; struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context; @@ -85,11 +93,11 @@ void * mono_mach_get_tls_address_from_thread (pthread_t thread, pthread_key_t key) { /* OSX stores TLS values in a hidden array inside the pthread_t structure - * They are keyed off a giant array offset 0x48 into the pointer. This value + * They are keyed off a giant array from a known offset into the pointer. This value * is baked into their pthread_getspecific implementation */ intptr_t *p = (intptr_t *) thread; - intptr_t **tsd = (intptr_t **) ((char*)p + 0x48); + intptr_t **tsd = (intptr_t **) ((char*)p + tls_vector_offset); return (void *) &tsd [key]; } @@ -100,5 +108,29 @@ mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key) return *(void**)mono_mach_get_tls_address_from_thread (thread, key); } +void +mono_mach_init (pthread_key_t key) +{ + void *old_value = pthread_getspecific (key); + void *canary = (void*)0xDEADBEEFu; + + pthread_key_create (&key, NULL); + g_assert (old_value != canary); + + pthread_setspecific (key, canary); + + /*First we probe for cats*/ + tls_vector_offset = TLS_VECTOR_OFFSET_CATS; + if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary) + goto ok; + + tls_vector_offset = TLS_VECTOR_OFFSET_10_9; + if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary) + goto ok; + + g_error ("could not discover the mach TLS offset"); +ok: + pthread_setspecific (key, old_value); +} #endif