Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Kumpera <kumpera@users.noreply.github.com>2017-02-23 01:20:17 +0300
committerGitHub <noreply@github.com>2017-02-23 01:20:17 +0300
commit0c07e908c50f946b26c07385036a1db553314ae7 (patch)
tree0fd690e165aa8d5de4674b5e34528283443255d4
parent2f2562bed82a36361a041074422cd0647f2eba49 (diff)
parentfe6d9dd2124ca33afde79169222dab83dc882efc (diff)
Merge pull request #4352 from evincarofautumn/fix-xmm-scanning-mac-4.2mono-4.2.0-branch
Backport Mac 64 SIMD fixes to 4.2
-rw-r--r--mono/metadata/sgen-os-mach.c11
-rw-r--r--mono/mini/mini-darwin.c11
-rw-r--r--mono/utils/mach-support-amd64.c36
-rw-r--r--mono/utils/mach-support-arm.c28
-rw-r--r--mono/utils/mach-support-unknown.c19
-rw-r--r--mono/utils/mach-support-x86.c61
-rw-r--r--mono/utils/mach-support.h10
-rw-r--r--mono/utils/mono-context.c40
-rw-r--r--mono/utils/mono-context.h160
-rw-r--r--mono/utils/mono-sigcontext.h21
-rw-r--r--mono/utils/mono-threads-mach.c19
11 files changed, 338 insertions, 78 deletions
diff --git a/mono/metadata/sgen-os-mach.c b/mono/metadata/sgen-os-mach.c
index eee4d837d3f..c57b06179c4 100644
--- a/mono/metadata/sgen-os-mach.c
+++ b/mono/metadata/sgen-os-mach.c
@@ -49,8 +49,8 @@ sgen_resume_thread (SgenThreadInfo *info)
gboolean
sgen_suspend_thread (SgenThreadInfo *info)
{
- mach_msg_type_number_t num_state;
- thread_state_t state;
+ mach_msg_type_number_t num_state, num_fpstate;
+ thread_state_t state, fpstate;
kern_return_t ret;
ucontext_t ctx;
mcontext_t mctx;
@@ -58,17 +58,20 @@ sgen_suspend_thread (SgenThreadInfo *info)
gpointer stack_start;
state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+ fpstate = (thread_state_t) alloca (mono_mach_arch_get_thread_fpstate_size ());
mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
ret = thread_suspend (info->client_info.info.native_handle);
if (ret != KERN_SUCCESS)
return FALSE;
- ret = mono_mach_arch_get_thread_state (info->client_info.info.native_handle, state, &num_state);
+ do {
+ ret = mono_mach_arch_get_thread_states (info->client_info.info.native_handle, state, &num_state, fpstate, &num_fpstate);
+ } while (ret == KERN_ABORTED);
if (ret != KERN_SUCCESS)
return FALSE;
- mono_mach_arch_thread_state_to_mcontext (state, mctx);
+ mono_mach_arch_thread_states_to_mcontext (state, fpstate, mctx);
ctx.uc_mcontext = mctx;
info->client_info.stopped_domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
diff --git a/mono/mini/mini-darwin.c b/mono/mini/mini-darwin.c
index 9c1e46ed829..f07fc5ea01c 100644
--- a/mono/mini/mini-darwin.c
+++ b/mono/mini/mini-darwin.c
@@ -298,8 +298,8 @@ gboolean
mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
{
kern_return_t ret;
- mach_msg_type_number_t num_state;
- thread_state_t state;
+ mach_msg_type_number_t num_state, num_fpstate;
+ thread_state_t state, fpstate;
ucontext_t ctx;
mcontext_t mctx;
MonoJitTlsData *jit_tls;
@@ -315,13 +315,16 @@ mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo
tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+ fpstate = (thread_state_t) alloca (mono_mach_arch_get_thread_fpstate_size ());
mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
- ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+ do {
+ ret = mono_mach_arch_get_thread_states (info->native_handle, state, &num_state, fpstate, &num_fpstate);
+ } while (ret == KERN_ABORTED);
if (ret != KERN_SUCCESS)
return FALSE;
- mono_mach_arch_thread_state_to_mcontext (state, mctx);
+ mono_mach_arch_thread_states_to_mcontext (state, fpstate, mctx);
ctx.uc_mcontext = mctx;
mono_sigctx_to_monoctx (&ctx, &tctx->ctx);
diff --git a/mono/utils/mach-support-amd64.c b/mono/utils/mach-support-amd64.c
index 7944e2c986b..42a66d541ce 100644
--- a/mono/utils/mach-support-amd64.c
+++ b/mono/utils/mach-support-amd64.c
@@ -56,21 +56,23 @@ mono_mach_arch_get_mcontext_size ()
}
void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
{
x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+ x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
-
ctx->__ss = *arch_state;
+ ctx->__fs = *arch_fpstate;
}
void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
{
x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+ x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
-
*arch_state = ctx->__ss;
+ *arch_fpstate = ctx->__fs;
}
int
@@ -79,23 +81,39 @@ mono_mach_arch_get_thread_state_size ()
return sizeof (x86_thread_state64_t);
}
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+ return sizeof (x86_float_state64_t);
+}
+
kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
{
- x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+ x86_thread_state64_t *arch_state = (x86_thread_state64_t *)state;
+ x86_float_state64_t *arch_fpstate = (x86_float_state64_t *)fpstate;
kern_return_t ret;
*count = x86_THREAD_STATE64_COUNT;
+ *fpcount = x86_FLOAT_STATE64_COUNT;
- ret = thread_get_state (thread, x86_THREAD_STATE64, (thread_state_t) arch_state, count);
+ ret = thread_get_state (thread, x86_THREAD_STATE64, (thread_state_t)arch_state, count);
+ if (ret != KERN_SUCCESS)
+ return ret;
+ ret = thread_get_state (thread, x86_FLOAT_STATE64, (thread_state_t)arch_fpstate, fpcount);
return ret;
}
kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
{
- return thread_set_state (thread, x86_THREAD_STATE64, state, count);
+ kern_return_t ret;
+ ret = thread_set_state (thread, x86_THREAD_STATE64, state, count);
+ if (ret != KERN_SUCCESS)
+ return ret;
+ ret = thread_set_state (thread, x86_FLOAT_STATE64, fpstate, fpcount);
+ return ret;
}
void *
diff --git a/mono/utils/mach-support-arm.c b/mono/utils/mach-support-arm.c
index cdf701cd8f4..9e04ddc508c 100644
--- a/mono/utils/mach-support-arm.c
+++ b/mono/utils/mach-support-arm.c
@@ -82,7 +82,7 @@ mono_mach_arch_get_mcontext_size ()
}
void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
{
#ifdef TARGET_ARM64
arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
@@ -98,7 +98,7 @@ mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
}
void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
{
#ifdef TARGET_ARM64
arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
@@ -113,6 +113,20 @@ mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
#endif
}
+void
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
+{
+ int i;
+ arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
+ for (i = 0; i < 13; ++i)
+ context->regs [i] = arch_state->__r [i];
+ context->regs [ARMREG_R13] = arch_state->__sp;
+ context->regs [ARMREG_R14] = arch_state->__lr;
+ context->regs [ARMREG_R15] = arch_state->__pc;
+ context->pc = arch_state->__pc;
+ context->cpsr = arch_state->__cpsr;
+}
+
int
mono_mach_arch_get_thread_state_size ()
{
@@ -123,8 +137,14 @@ mono_mach_arch_get_thread_state_size ()
#endif
}
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+ return sizeof (arm_neon_state_t);
+}
+
kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
{
#ifdef TARGET_ARM64
arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
@@ -145,7 +165,7 @@ mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mac
}
kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
{
#ifdef TARGET_ARM64
return thread_set_state (thread, ARM_UNIFIED_THREAD_STATE, state, count);
diff --git a/mono/utils/mach-support-unknown.c b/mono/utils/mach-support-unknown.c
index 9fece227216..88eb187da44 100644
--- a/mono/utils/mach-support-unknown.c
+++ b/mono/utils/mach-support-unknown.c
@@ -35,17 +35,22 @@ mono_mach_arch_get_mcontext_size ()
}
void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
{
g_assert_not_reached ();
}
void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
{
g_assert_not_reached ();
}
+void
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
+{
+ g_assert_not_reached ();
+}
int
mono_mach_arch_get_thread_state_size ()
@@ -53,14 +58,20 @@ mono_mach_arch_get_thread_state_size ()
g_assert_not_reached ();
}
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+ g_assert_not_reached ();
+}
+
kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
{
g_assert_not_reached ();
}
kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
{
g_assert_not_reached ();
}
diff --git a/mono/utils/mach-support-x86.c b/mono/utils/mach-support-x86.c
index 967aeb7abcf..7535b253a4b 100644
--- a/mono/utils/mach-support-x86.c
+++ b/mono/utils/mach-support-x86.c
@@ -16,6 +16,9 @@
#include "utils/mono-sigcontext.h"
#include "mach-support.h"
+// For reg numbers
+#include <mono/arch/amd64/amd64-codegen.h>
+
/* Known offsets used for TLS storage*/
/* All OSX versions up to 10.8 */
@@ -55,21 +58,47 @@ mono_mach_arch_get_mcontext_size ()
}
void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
{
x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+ x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context;
-
ctx->__ss = *arch_state;
+ ctx->__fs = *arch_fpstate;
}
void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
{
x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+ x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context;
-
*arch_state = ctx->__ss;
+ *arch_fpstate = ctx->__fs;
+}
+
+void
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
+{
+ x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+ x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) state;
+ context->eax = arch_state->__eax;
+ context->ebx = arch_state->__ebx;
+ context->ecx = arch_state->__ecx;
+ context->edx = arch_state->__edx;
+ context->ebp = arch_state->__ebp;
+ context->esp = arch_state->__esp;
+ context->esi = arch_state->__edi;
+ context->edi = arch_state->__esi;
+ context->eip = arch_state->__eip;
+ context->fregs [X86_XMM0] = arch_fpstate->__fpu_xmm0;
+ context->fregs [X86_XMM1] = arch_fpstate->__fpu_xmm1;
+ context->fregs [X86_XMM2] = arch_fpstate->__fpu_xmm2;
+ context->fregs [X86_XMM3] = arch_fpstate->__fpu_xmm3;
+ context->fregs [X86_XMM4] = arch_fpstate->__fpu_xmm4;
+ context->fregs [X86_XMM5] = arch_fpstate->__fpu_xmm5;
+ context->fregs [X86_XMM6] = arch_fpstate->__fpu_xmm6;
+ context->fregs [X86_XMM7] = arch_fpstate->__fpu_xmm7;
}
int
@@ -78,23 +107,39 @@ mono_mach_arch_get_thread_state_size ()
return sizeof (x86_thread_state32_t);
}
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+ return sizeof (x86_float_state32_t);
+}
+
kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
{
x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+ x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
kern_return_t ret;
*count = x86_THREAD_STATE32_COUNT;
+ *fpcount = x86_FLOAT_STATE32_COUNT;
- ret = thread_get_state (thread, x86_THREAD_STATE32, (thread_state_t) arch_state, count);
+ ret = thread_get_state (thread, x86_THREAD_STATE32, (thread_state_t)arch_state, count);
+ if (ret != KERN_SUCCESS)
+ return ret;
+ ret = thread_get_state (thread, x86_FLOAT_STATE32, (thread_state_t)arch_fpstate, fpcount);
return ret;
}
kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
{
- return thread_set_state (thread, x86_THREAD_STATE32, state, count);
+ kern_return_t ret;
+ ret = thread_set_state (thread, x86_THREAD_STATE32, state, count);
+ if (ret != KERN_SUCCESS)
+ return ret;
+ ret = thread_set_state (thread, x86_FLOAT_STATE32, fpstate, fpcount);
+ return ret;
}
void *
diff --git a/mono/utils/mach-support.h b/mono/utils/mach-support.h
index 940cf0356a0..4ce00952c0a 100644
--- a/mono/utils/mach-support.h
+++ b/mono/utils/mach-support.h
@@ -28,14 +28,16 @@ void *mono_mach_arch_get_sp (thread_state_t state);
void mono_mach_init (pthread_key_t key);
int mono_mach_arch_get_mcontext_size (void);
-void mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context);
-void mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state);
+void mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context);
+void mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate);
+/* FIXME: Should return size_t, not int. */
int mono_mach_arch_get_thread_state_size (void);
+int mono_mach_arch_get_thread_fpstate_size (void);
kern_return_t mono_mach_get_threads (thread_act_array_t *threads, guint32 *count);
kern_return_t mono_mach_free_threads (thread_act_array_t threads, guint32 count);
-kern_return_t mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count);
-kern_return_t mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count);
+kern_return_t mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount);
+kern_return_t mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount);
void *mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key);
void *mono_mach_get_tls_address_from_thread (pthread_t thread, pthread_key_t key);
diff --git a/mono/utils/mono-context.c b/mono/utils/mono-context.c
index a05c7bab76d..c3c173518a3 100644
--- a/mono/utils/mono-context.c
+++ b/mono/utils/mono-context.c
@@ -163,6 +163,26 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
mctx->gregs [AMD64_R14] = UCONTEXT_REG_R14 (ctx);
mctx->gregs [AMD64_R15] = UCONTEXT_REG_R15 (ctx);
mctx->gregs [AMD64_RIP] = UCONTEXT_REG_RIP (ctx);
+
+#ifdef UCONTEXT_REG_XMM
+ mctx->fregs [0] = UCONTEXT_REG_XMM0 (ctx);
+ mctx->fregs [1] = UCONTEXT_REG_XMM1 (ctx);
+ mctx->fregs [2] = UCONTEXT_REG_XMM2 (ctx);
+ mctx->fregs [3] = UCONTEXT_REG_XMM3 (ctx);
+ mctx->fregs [4] = UCONTEXT_REG_XMM4 (ctx);
+ mctx->fregs [5] = UCONTEXT_REG_XMM5 (ctx);
+ mctx->fregs [6] = UCONTEXT_REG_XMM6 (ctx);
+ mctx->fregs [7] = UCONTEXT_REG_XMM7 (ctx);
+ mctx->fregs [8] = UCONTEXT_REG_XMM8 (ctx);
+ mctx->fregs [9] = UCONTEXT_REG_XMM9 (ctx);
+ mctx->fregs [10] = UCONTEXT_REG_XMM10 (ctx);
+ mctx->fregs [11] = UCONTEXT_REG_XMM11 (ctx);
+ mctx->fregs [12] = UCONTEXT_REG_XMM12 (ctx);
+ mctx->fregs [13] = UCONTEXT_REG_XMM13 (ctx);
+ mctx->fregs [14] = UCONTEXT_REG_XMM14 (ctx);
+ mctx->fregs [15] = UCONTEXT_REG_XMM15 (ctx);
+#endif
+
#elif defined(HOST_WIN32)
CONTEXT *context = (CONTEXT*)sigctx;
@@ -233,6 +253,26 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
+
+#ifdef UCONTEXT_REG_XMM
+ UCONTEXT_REG_XMM0 (ctx) = mctx->fregs [0];
+ UCONTEXT_REG_XMM1 (ctx) = mctx->fregs [1];
+ UCONTEXT_REG_XMM2 (ctx) = mctx->fregs [2];
+ UCONTEXT_REG_XMM3 (ctx) = mctx->fregs [3];
+ UCONTEXT_REG_XMM4 (ctx) = mctx->fregs [4];
+ UCONTEXT_REG_XMM5 (ctx) = mctx->fregs [5];
+ UCONTEXT_REG_XMM6 (ctx) = mctx->fregs [6];
+ UCONTEXT_REG_XMM7 (ctx) = mctx->fregs [7];
+ UCONTEXT_REG_XMM8 (ctx) = mctx->fregs [8];
+ UCONTEXT_REG_XMM9 (ctx) = mctx->fregs [9];
+ UCONTEXT_REG_XMM10 (ctx) = mctx->fregs [10];
+ UCONTEXT_REG_XMM11 (ctx) = mctx->fregs [11];
+ UCONTEXT_REG_XMM12 (ctx) = mctx->fregs [12];
+ UCONTEXT_REG_XMM13 (ctx) = mctx->fregs [13];
+ UCONTEXT_REG_XMM14 (ctx) = mctx->fregs [14];
+ UCONTEXT_REG_XMM15 (ctx) = mctx->fregs [15];
+#endif
+
#elif defined(HOST_WIN32)
CONTEXT *context = (CONTEXT*)sigctx;
diff --git a/mono/utils/mono-context.h b/mono/utils/mono-context.h
index 55d75bda44d..188c0b3f7a3 100644
--- a/mono/utils/mono-context.h
+++ b/mono/utils/mono-context.h
@@ -21,6 +21,13 @@
#include <ucontext.h>
#endif
+#define MONO_CONTEXT_OFFSET(field, index, field_type) \
+ "i" (offsetof (MonoContext, field) + (index) * sizeof (field_type))
+
+#if defined(__APPLE__)
+typedef struct __darwin_xmm_reg MonoContextSimdReg;
+#endif
+
/*
* General notes about mono-context.
* Each arch defines a MonoContext struct with all GPR regs + IP/PC.
@@ -90,6 +97,8 @@ struct sigcontext {
# define SC_ESI esi
#endif
+#include <mono/arch/x86/x86-codegen.h>
+
typedef struct {
mgreg_t eax;
mgreg_t ebx;
@@ -100,6 +109,9 @@ typedef struct {
mgreg_t esi;
mgreg_t edi;
mgreg_t eip;
+#ifdef __APPLE__
+ MonoContextSimdReg fregs [X86_XMM_NREG];
+#endif
} MonoContext;
#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->eip = (mgreg_t)(ip); } while (0);
@@ -132,18 +144,26 @@ typedef struct {
#else
#define MONO_CONTEXT_GET_CURRENT(ctx) \
__asm__ __volatile__( \
- "movl $0x0, 0x00(%0)\n" \
- "mov %%ebx, 0x04(%0)\n" \
- "mov %%ecx, 0x08(%0)\n" \
- "mov %%edx, 0x0c(%0)\n" \
- "mov %%ebp, 0x10(%0)\n" \
- "mov %%esp, 0x14(%0)\n" \
- "mov %%esi, 0x18(%0)\n" \
- "mov %%edi, 0x1c(%0)\n" \
+ "movl $0x0, %c[eax](%0)\n" \
+ "mov %%ebx, %c[ebx](%0)\n" \
+ "mov %%ecx, %c[ecx](%0)\n" \
+ "mov %%edx, %c[edx](%0)\n" \
+ "mov %%ebp, %c[ebp](%0)\n" \
+ "mov %%esp, %c[esp](%0)\n" \
+ "mov %%esi, %c[esi](%0)\n" \
+ "mov %%edi, %c[edi](%0)\n" \
"call 1f\n" \
"1: pop 0x20(%0)\n" \
: \
- : "a" (&(ctx)) \
+ : "a" (&(ctx)), \
+ [eax] MONO_CONTEXT_OFFSET (eax, 0, mgreg_t), \
+ [ebx] MONO_CONTEXT_OFFSET (ebx, 0, mgreg_t), \
+ [ecx] MONO_CONTEXT_OFFSET (ecx, 0, mgreg_t), \
+ [edx] MONO_CONTEXT_OFFSET (edx, 0, mgreg_t), \
+ [ebp] MONO_CONTEXT_OFFSET (ebp, 0, mgreg_t), \
+ [esp] MONO_CONTEXT_OFFSET (esp, 0, mgreg_t), \
+ [esi] MONO_CONTEXT_OFFSET (esi, 0, mgreg_t), \
+ [edi] MONO_CONTEXT_OFFSET (edi, 0, mgreg_t) \
: "memory")
#endif
@@ -163,7 +183,11 @@ typedef struct {
typedef struct {
mgreg_t gregs [AMD64_NREG];
+#ifdef __APPLE__
+ MonoContextSimdReg fregs [AMD64_XMM_NREG];
+#else
double fregs [AMD64_XMM_NREG];
+#endif
} MonoContext;
#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->gregs [AMD64_RIP] = (mgreg_t)(ip); } while (0);
@@ -204,30 +228,100 @@ extern void mono_context_get_current (void *);
: "a" ((int64_t)&(ctx)) \
: "rdx", "memory")
#else
-#define MONO_CONTEXT_GET_CURRENT(ctx) \
- __asm__ __volatile__( \
- "movq $0x0, 0x00(%0)\n" \
- "movq %%rbx, 0x08(%0)\n" \
- "movq %%rcx, 0x10(%0)\n" \
- "movq %%rdx, 0x18(%0)\n" \
- "movq %%rbp, 0x20(%0)\n" \
- "movq %%rsp, 0x28(%0)\n" \
- "movq %%rsi, 0x30(%0)\n" \
- "movq %%rdi, 0x38(%0)\n" \
- "movq %%r8, 0x40(%0)\n" \
- "movq %%r9, 0x48(%0)\n" \
- "movq %%r10, 0x50(%0)\n" \
- "movq %%r11, 0x58(%0)\n" \
- "movq %%r12, 0x60(%0)\n" \
- "movq %%r13, 0x68(%0)\n" \
- "movq %%r14, 0x70(%0)\n" \
- "movq %%r15, 0x78(%0)\n" \
- /* "leaq (%%rip), %%rdx\n" is not understood by icc */ \
- ".byte 0x48, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00\n" \
- "movq %%rdx, 0x80(%0)\n" \
- : \
- : "a" (&(ctx)) \
- : "rdx", "memory")
+
+#define MONO_CONTEXT_GET_CURRENT_GREGS(ctx) \
+ do { \
+ __asm__ __volatile__( \
+ "movq $0x0, %c[rax](%0)\n" \
+ "movq %%rcx, %c[rcx](%0)\n" \
+ "movq %%rdx, %c[rdx](%0)\n" \
+ "movq %%rbx, %c[rbx](%0)\n" \
+ "movq %%rsp, %c[rsp](%0)\n" \
+ "movq %%rbp, %c[rbp](%0)\n" \
+ "movq %%rsi, %c[rsi](%0)\n" \
+ "movq %%rdi, %c[rdi](%0)\n" \
+ "movq %%r8, %c[r8](%0)\n" \
+ "movq %%r9, %c[r9](%0)\n" \
+ "movq %%r10, %c[r10](%0)\n" \
+ "movq %%r11, %c[r11](%0)\n" \
+ "movq %%r12, %c[r12](%0)\n" \
+ "movq %%r13, %c[r13](%0)\n" \
+ "movq %%r14, %c[r14](%0)\n" \
+ "movq %%r15, %c[r15](%0)\n" \
+ /* "leaq (%%rip), %%rdx\n" is not understood by icc */ \
+ ".byte 0x48, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00\n" \
+ "movq %%rdx, %c[rip](%0)\n" \
+ : \
+ : "a" (&(ctx)), \
+ [rax] MONO_CONTEXT_OFFSET (gregs, AMD64_RAX, mgreg_t), \
+ [rcx] MONO_CONTEXT_OFFSET (gregs, AMD64_RCX, mgreg_t), \
+ [rdx] MONO_CONTEXT_OFFSET (gregs, AMD64_RDX, mgreg_t), \
+ [rbx] MONO_CONTEXT_OFFSET (gregs, AMD64_RBX, mgreg_t), \
+ [rsp] MONO_CONTEXT_OFFSET (gregs, AMD64_RSP, mgreg_t), \
+ [rbp] MONO_CONTEXT_OFFSET (gregs, AMD64_RBP, mgreg_t), \
+ [rsi] MONO_CONTEXT_OFFSET (gregs, AMD64_RSI, mgreg_t), \
+ [rdi] MONO_CONTEXT_OFFSET (gregs, AMD64_RDI, mgreg_t), \
+ [r8] MONO_CONTEXT_OFFSET (gregs, AMD64_R8, mgreg_t), \
+ [r9] MONO_CONTEXT_OFFSET (gregs, AMD64_R9, mgreg_t), \
+ [r10] MONO_CONTEXT_OFFSET (gregs, AMD64_R10, mgreg_t), \
+ [r11] MONO_CONTEXT_OFFSET (gregs, AMD64_R11, mgreg_t), \
+ [r12] MONO_CONTEXT_OFFSET (gregs, AMD64_R12, mgreg_t), \
+ [r13] MONO_CONTEXT_OFFSET (gregs, AMD64_R13, mgreg_t), \
+ [r14] MONO_CONTEXT_OFFSET (gregs, AMD64_R14, mgreg_t), \
+ [r15] MONO_CONTEXT_OFFSET (gregs, AMD64_R15, mgreg_t), \
+ [rip] MONO_CONTEXT_OFFSET (gregs, AMD64_RIP, mgreg_t) \
+ : "rdx", "memory"); \
+ } while (0)
+
+#ifdef UCONTEXT_REG_XMM
+#define MONO_CONTEXT_GET_CURRENT_FREGS(ctx) \
+ do { \
+ __asm__ __volatile__ ( \
+ "movups %%xmm0, %c[xmm0](%0)\n" \
+ "movups %%xmm1, %c[xmm1](%0)\n" \
+ "movups %%xmm2, %c[xmm2](%0)\n" \
+ "movups %%xmm3, %c[xmm3](%0)\n" \
+ "movups %%xmm4, %c[xmm4](%0)\n" \
+ "movups %%xmm5, %c[xmm5](%0)\n" \
+ "movups %%xmm6, %c[xmm6](%0)\n" \
+ "movups %%xmm7, %c[xmm7](%0)\n" \
+ "movups %%xmm8, %c[xmm8](%0)\n" \
+ "movups %%xmm9, %c[xmm9](%0)\n" \
+ "movups %%xmm10, %c[xmm10](%0)\n" \
+ "movups %%xmm11, %c[xmm11](%0)\n" \
+ "movups %%xmm12, %c[xmm12](%0)\n" \
+ "movups %%xmm12, %c[xmm12](%0)\n" \
+ "movups %%xmm14, %c[xmm14](%0)\n" \
+ "movups %%xmm15, %c[xmm15](%0)\n" \
+ : \
+ : "a" (&(ctx)), \
+ [xmm0] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM0, MonoContextSimdReg), \
+ [xmm1] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM1, MonoContextSimdReg), \
+ [xmm2] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM2, MonoContextSimdReg), \
+ [xmm3] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM3, MonoContextSimdReg), \
+ [xmm4] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM4, MonoContextSimdReg), \
+ [xmm5] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM5, MonoContextSimdReg), \
+ [xmm6] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM6, MonoContextSimdReg), \
+ [xmm7] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM7, MonoContextSimdReg), \
+ [xmm8] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM8, MonoContextSimdReg), \
+ [xmm9] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM9, MonoContextSimdReg), \
+ [xmm10] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM10, MonoContextSimdReg), \
+ [xmm11] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM11, MonoContextSimdReg), \
+ [xmm12] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM12, MonoContextSimdReg), \
+ [xmm13] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM13, MonoContextSimdReg), \
+ [xmm14] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM14, MonoContextSimdReg), \
+ [xmm15] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM15, MonoContextSimdReg)); \
+ } while (0)
+#else
+#define MONO_CONTEXT_GET_CURRENT_FREGS(ctx)
+#endif
+
+#define MONO_CONTEXT_GET_CURRENT(ctx) \
+ do { \
+ MONO_CONTEXT_GET_CURRENT_GREGS(ctx); \
+ MONO_CONTEXT_GET_CURRENT_FREGS(ctx); \
+ } while (0)
+
#endif
#define MONO_ARCH_HAS_MONO_CONTEXT 1
diff --git a/mono/utils/mono-sigcontext.h b/mono/utils/mono-sigcontext.h
index de4f6c45b75..6d47813802b 100644
--- a/mono/utils/mono-sigcontext.h
+++ b/mono/utils/mono-sigcontext.h
@@ -173,6 +173,23 @@ typedef struct ucontext {
#define UCONTEXT_REG_R13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r13)
#define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r14)
#define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r15)
+ #define UCONTEXT_REG_XMM
+ #define UCONTEXT_REG_XMM0(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm0)
+ #define UCONTEXT_REG_XMM1(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm1)
+ #define UCONTEXT_REG_XMM2(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm2)
+ #define UCONTEXT_REG_XMM3(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm3)
+ #define UCONTEXT_REG_XMM4(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm4)
+ #define UCONTEXT_REG_XMM5(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm5)
+ #define UCONTEXT_REG_XMM6(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm6)
+ #define UCONTEXT_REG_XMM7(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm7)
+ #define UCONTEXT_REG_XMM8(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm8)
+ #define UCONTEXT_REG_XMM9(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm9)
+ #define UCONTEXT_REG_XMM10(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm10)
+ #define UCONTEXT_REG_XMM11(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm11)
+ #define UCONTEXT_REG_XMM12(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm12)
+ #define UCONTEXT_REG_XMM13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm13)
+ #define UCONTEXT_REG_XMM14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm14)
+ #define UCONTEXT_REG_XMM15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm15)
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#define UCONTEXT_REG_RAX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rax)
#define UCONTEXT_REG_RBX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rbx)
@@ -224,8 +241,8 @@ typedef struct ucontext {
#define UCONTEXT_REG_R13(ctx) (((ucontext_t*)(ctx))->sc_r13)
#define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->sc_r14)
#define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->sc_r15)
-#else
-#define UCONTEXT_GREGS(ctx) ((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext.gregs))
+#elif !defined(HOST_WIN32)
+ #define UCONTEXT_GREGS(ctx) ((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext.gregs))
#endif
#ifdef UCONTEXT_GREGS
diff --git a/mono/utils/mono-threads-mach.c b/mono/utils/mono-threads-mach.c
index fc884e7a055..66af94c24b1 100644
--- a/mono/utils/mono-threads-mach.c
+++ b/mono/utils/mono-threads-mach.c
@@ -116,8 +116,8 @@ mono_threads_core_begin_async_resume (MonoThreadInfo *info)
if (info->async_target) {
MonoContext tmp = info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX].ctx;
- mach_msg_type_number_t num_state;
- thread_state_t state;
+ mach_msg_type_number_t num_state, num_fpstate;
+ thread_state_t state, fpstate;
ucontext_t uctx;
mcontext_t mctx;
@@ -126,13 +126,17 @@ mono_threads_core_begin_async_resume (MonoThreadInfo *info)
info->async_target = (void (*)(void *)) info->user_data;
state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+ fpstate = (thread_state_t) alloca (mono_mach_arch_get_thread_fpstate_size ());
mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
- ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+ do {
+ ret = mono_mach_arch_get_thread_states (info->native_handle, state, &num_state, fpstate, &num_fpstate);
+ } while (ret == KERN_ABORTED);
+
if (ret != KERN_SUCCESS)
return FALSE;
- mono_mach_arch_thread_state_to_mcontext (state, mctx);
+ mono_mach_arch_thread_states_to_mcontext (state, fpstate, mctx);
#ifdef TARGET_ARM64
g_assert_not_reached ();
#else
@@ -140,9 +144,12 @@ mono_threads_core_begin_async_resume (MonoThreadInfo *info)
#endif
mono_monoctx_to_sigctx (&tmp, &uctx);
- mono_mach_arch_mcontext_to_thread_state (mctx, state);
+ mono_mach_arch_mcontext_to_thread_states (mctx, state, fpstate);
+
+ do {
+ ret = mono_mach_arch_set_thread_states (info->native_handle, state, num_state, fpstate, num_fpstate);
+ } while (ret == KERN_ABORTED);
- ret = mono_mach_arch_set_thread_state (info->native_handle, state, num_state);
if (ret != KERN_SUCCESS)
return FALSE;
}