diff options
author | Rodrigo Kumpera <kumpera@gmail.com> | 2013-06-14 01:14:29 +0400 |
---|---|---|
committer | Rodrigo Kumpera <kumpera@gmail.com> | 2013-06-14 02:49:56 +0400 |
commit | 19bb19f699be9f0ba1c65b2173a72e0ec0cfbc00 (patch) | |
tree | 8bc145784c8b5be8ffe0c9b2050a77ef616c50ef | |
parent | 1fd343ac44155a5955624931402d88da87117ca2 (diff) |
Add TLS offset probing to mach-amd64 in the same way it's done on x86.
-rw-r--r-- | mono/utils/mach-support-amd64.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/mono/utils/mach-support-amd64.c b/mono/utils/mach-support-amd64.c index 06b2cf14174..19040885da6 100644 --- a/mono/utils/mach-support-amd64.c +++ b/mono/utils/mach-support-amd64.c @@ -3,8 +3,10 @@ * * Authors: * Geoff Norton (gnorton@novell.com) + * Rodrigo Kumpera (kumpera@gmail.com) * * (C) 2010 Novell, Inc. + * (C) 2013 Xamarin, Inc. */ #include <config.h> @@ -16,6 +18,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 0x60 +#define TLS_VECTOR_OFFSET_10_9 0xe0 + +static int tls_vector_offset; + void * mono_mach_arch_get_ip (thread_state_t state) { @@ -85,11 +95,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 0x60 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 + 0x60); + intptr_t **tsd = (intptr_t **) ((char*)p + tls_vector_offset); return (void *) &tsd [key]; } @@ -103,6 +113,26 @@ mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 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 |