X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmach-support-amd64.c;h=1802ff79f5364d8301566717bc2da54b5bcad12d;hb=b8893efbccd64f92c81082e42b8e480b74881927;hp=19040885da612aaf9908a3dedec6831aab1b491e;hpb=89d5527369717465b43e3145cbecdca3a8601ec4;p=mono.git diff --git a/mono/utils/mach-support-amd64.c b/mono/utils/mach-support-amd64.c index 19040885da6..1802ff79f53 100644 --- a/mono/utils/mach-support-amd64.c +++ b/mono/utils/mach-support-amd64.c @@ -18,11 +18,21 @@ #include "utils/mono-sigcontext.h" #include "mach-support.h" +//For reg numbers +#include + /* 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 +#define TLS_VECTOR_OFFSET_10_11 0x100 + +/* This is 2 slots less than the known low */ +#define TLS_PROBE_LOW_WATERMARK 0x50 +/* This is 28 slots above the know high, which is more than the known high-low*/ +#define TLS_PROBE_HIGH_WATERMARK 0x200 + static int tls_vector_offset; @@ -66,6 +76,28 @@ mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state) *arch_state = ctx->__ss; } +void +mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context) +{ + x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state; + context->gregs [AMD64_RAX] = arch_state->__rax; + context->gregs [AMD64_RBX] = arch_state->__rbx; + context->gregs [AMD64_RCX] = arch_state->__rcx; + context->gregs [AMD64_RDX] = arch_state->__rdx; + context->gregs [AMD64_RDI] = arch_state->__rdi; + context->gregs [AMD64_RBP] = arch_state->__rbp; + context->gregs [AMD64_RSP] = arch_state->__rsp; + context->gregs [AMD64_R8] = arch_state->__r8; + context->gregs [AMD64_R9] = arch_state->__r9; + context->gregs [AMD64_R10] = arch_state->__r10; + context->gregs [AMD64_R11] = arch_state->__r11; + context->gregs [AMD64_R12] = arch_state->__r12; + context->gregs [AMD64_R13] = arch_state->__r13; + context->gregs [AMD64_R14] = arch_state->__r14; + context->gregs [AMD64_R15] = arch_state->__r15; + context->gregs [AMD64_RIP] = arch_state->__rip; +} + int mono_mach_arch_get_thread_state_size () { @@ -100,6 +132,7 @@ mono_mach_get_tls_address_from_thread (pthread_t thread, pthread_key_t key) */ intptr_t *p = (intptr_t *)thread; intptr_t **tsd = (intptr_t **) ((char*)p + tls_vector_offset); + g_assert (tls_vector_offset != -1); return (void *) &tsd [key]; } @@ -113,6 +146,7 @@ mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key) void mono_mach_init (pthread_key_t key) { + int i; void *old_value = pthread_getspecific (key); void *canary = (void*)0xDEADBEEFu; @@ -130,7 +164,21 @@ mono_mach_init (pthread_key_t key) if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary) goto ok; - g_error ("could not discover the mach TLS offset"); + tls_vector_offset = TLS_VECTOR_OFFSET_10_11; + if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary) + goto ok; + + /*Fallback to scanning a large range of offsets*/ + for (i = TLS_PROBE_LOW_WATERMARK; i <= TLS_PROBE_HIGH_WATERMARK; i += 4) { + tls_vector_offset = i; + if (mono_mach_arch_get_tls_value_from_thread (pthread_self (), key) == canary) { + g_warning ("Found new TLS offset at %d", i); + goto ok; + } + } + + tls_vector_offset = -1; + g_warning ("could not discover the mach TLS offset"); ok: pthread_setspecific (key, old_value); }