Fix mono_amd64_emit_tls_get on darwin. Fixes sgen and #673813
authorGeoff Norton <grompf@sublimeintervention.com>
Mon, 21 Feb 2011 17:49:05 +0000 (12:49 -0500)
committerGeoff Norton <grompf@sublimeintervention.com>
Mon, 21 Feb 2011 17:49:05 +0000 (12:49 -0500)
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h

index 10f9f0ff31377da9b0bffc55b74fd1ed1e1bb43a..06bb66fa4f06564e0729f2d81d41b434d2fa68d7 100644 (file)
@@ -3588,6 +3588,43 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
 
 #endif /* DISABLE_JIT */
 
+gboolean
+mono_amd64_have_tls_get (void)
+{
+#ifdef __APPLE__
+       static gboolean have_tls_get = FALSE;
+       static gboolean inited = FALSE;
+
+       if (inited)
+               return have_tls_get;
+
+       guint8 *ins = (guint8*)pthread_getspecific;
+
+       /*
+        * We're looking for these two instructions:
+        *
+        * mov    %gs:0x60(,%rdi,8),%rax
+        * retq
+        */
+       have_tls_get = ins [0] == 0x65 &&
+                      ins [1] == 0x48 &&
+                      ins [2] == 0x8b &&
+                      ins [3] == 0x04 &&
+                      ins [4] == 0xfd &&
+                      ins [5] == 0x60 &&
+                      ins [6] == 0x00 &&
+                      ins [7] == 0x00 &&
+                      ins [8] == 0x00 &&
+                      ins [9] == 0xc3;
+
+       inited = TRUE;
+
+       return have_tls_get;
+#else
+       return TRUE;
+#endif
+}
+
 /*
  * mono_amd64_emit_tls_get:
  * @code: buffer to store code to
@@ -3607,6 +3644,9 @@ mono_amd64_emit_tls_get (guint8* code, int dreg, int tls_offset)
        g_assert (tls_offset < 64);
        x86_prefix (code, X86_GS_PREFIX);
        amd64_mov_reg_mem (code, dreg, (tls_offset * 8) + 0x1480, 8);
+#elif defined(__APPLE__)
+       x86_prefix (code, X86_GS_PREFIX);
+       amd64_mov_reg_mem (code, dreg, 0x60 + tls_offset * 8, 8);
 #else
        if (optimize_for_xen) {
                x86_prefix (code, X86_FS_PREFIX);
@@ -7033,7 +7073,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                        amd64_mov_reg_membase (code, X86_ECX, X86_ECX, G_STRUCT_OFFSET (MonoJitTlsData, restore_stack_prot), 8);
                        x86_alu_reg_imm (code, X86_CMP, X86_ECX, 0);
                        patch = code;
-                       x86_branch8 (code, X86_CC_Z, 0, FALSE);
+                       x86_branch8 (code, X86_CC_Z, 0, FALSE);
                        /* note that the call trampoline will preserve eax/edx */
                        x86_call_reg (code, X86_ECX);
                        x86_patch (patch, code);
index effe00bcbb0b34d053f1c3eee26f3adad44bd87d..01285149edbfa0e7c2e2958e7927af611e81aa1a 100644 (file)
@@ -351,7 +351,7 @@ typedef struct {
 #define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
 #define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES_2 1
 #define MONO_ARCH_HAVE_IMT 1
-#define MONO_ARCH_HAVE_TLS_GET 1
+#define MONO_ARCH_HAVE_TLS_GET (mono_amd64_have_tls_get ())
 #define MONO_ARCH_IMT_REG AMD64_R10
 #define MONO_ARCH_IMT_SCRATCH_REG AMD64_R11
 #define MONO_ARCH_VTABLE_REG MONO_AMD64_ARG_REG1
@@ -443,6 +443,9 @@ mono_amd64_get_original_ip (void) MONO_INTERNAL;
 guint8*
 mono_amd64_emit_tls_get (guint8* code, int dreg, int tls_offset) MONO_INTERNAL;
 
+gboolean
+mono_amd64_have_tls_get (void) MONO_INTERNAL;
+
 GSList*
 mono_amd64_get_exception_trampolines (gboolean aot) MONO_INTERNAL;