[runtime] Use the windows CONTEXT<->MonoContext conversion code to mono-context.c...
authorZoltan Varga <vargaz@gmail.com>
Thu, 18 Sep 2014 02:37:18 +0000 (22:37 -0400)
committerZoltan Varga <vargaz@gmail.com>
Thu, 18 Sep 2014 02:37:18 +0000 (22:37 -0400)
mono/mini/exceptions-amd64.c
mono/mini/exceptions-x86.c
mono/mini/mini-windows.c
mono/mini/mini.h
mono/utils/mono-context.c
mono/utils/mono-context.h
mono/utils/mono-threads-windows.c

index 12b4ef31dde102e27377b1ed2d0f4f65f740112e..592969a5256e9f538531bc822d46d975140a3f88 100644 (file)
@@ -45,7 +45,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter;
 void *mono_win_vectored_exception_handle;
 
 #define W32_SEH_HANDLE_EX(_ex) \
-       if (_ex##_handler) _ex##_handler(0, ep, sctx)
+       if (_ex##_handler) _ex##_handler(0, ep, ctx)
 
 static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
 {
@@ -68,7 +68,6 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
 {
        EXCEPTION_RECORD* er;
        CONTEXT* ctx;
-       MonoContext* sctx;
        LONG res;
        MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
 
@@ -81,22 +80,6 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
 
        er = ep->ExceptionRecord;
        ctx = ep->ContextRecord;
-       sctx = g_malloc(sizeof(MonoContext));
-
-       /* Copy Win32 context to UNIX style context */
-       sctx->rax = ctx->Rax;
-       sctx->rbx = ctx->Rbx;
-       sctx->rcx = ctx->Rcx;
-       sctx->rdx = ctx->Rdx;
-       sctx->rbp = ctx->Rbp;
-       sctx->rsp = ctx->Rsp;
-       sctx->rsi = ctx->Rsi;
-       sctx->rdi = ctx->Rdi;
-       sctx->rip = ctx->Rip;
-       sctx->r12 = ctx->R12;
-       sctx->r13 = ctx->R13;
-       sctx->r14 = ctx->R14;
-       sctx->r15 = ctx->R15;
 
        switch (er->ExceptionCode) {
        case EXCEPTION_ACCESS_VIOLATION:
@@ -126,30 +109,8 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
                * can correctly chain the exception.
                */
                res = EXCEPTION_CONTINUE_SEARCH;
-       } else {
-               /* Copy context back */
-               /* Nonvolatile */
-               ctx->Rsp = sctx->rsp;
-               ctx->Rdi = sctx->rdi;
-               ctx->Rsi = sctx->rsi;
-               ctx->Rbx = sctx->rbx;
-               ctx->Rbp = sctx->rbp;
-               ctx->R12 = sctx->r12;
-               ctx->R13 = sctx->r13;
-               ctx->R14 = sctx->r14;
-               ctx->R15 = sctx->r15;
-               ctx->Rip = sctx->rip;
-
-               /* Volatile But should not matter?*/
-               ctx->Rax = sctx->rax;
-               ctx->Rcx = sctx->rcx;
-               ctx->Rdx = sctx->rdx;
        }
 
-       /* TODO: Find right place to free this in stack overflow case */
-       if (er->ExceptionCode != EXCEPTION_STACK_OVERFLOW)
-               g_free (sctx);
-
        return res;
 }
 
@@ -841,6 +802,8 @@ mono_arch_ip_from_context (void *sigctx)
        ucontext_t *ctx = (ucontext_t*)sigctx;
 
        return (gpointer)UCONTEXT_REG_RIP (ctx);
+#elif defined(HOST_WIN32)
+       return ((CONTEXT*)sigctx)->Rip;
 #else
        MonoContext *ctx = sigctx;
        return (gpointer)ctx->rip;
index d335d7ea5c6c3fa92c97b57f891722683410c673..9c46d34bd201247f0fda88982cdb46bc067fa3a2 100644 (file)
@@ -49,7 +49,7 @@ extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*);
 #endif
 
 #define W32_SEH_HANDLE_EX(_ex) \
-       if (_ex##_handler) _ex##_handler(0, ep, sctx)
+       if (_ex##_handler) _ex##_handler(0, ep, ctx)
 
 LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
 {
@@ -189,7 +189,6 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
 {
        EXCEPTION_RECORD* er;
        CONTEXT* ctx;
-       struct sigcontext* sctx;
        LONG res;
        MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
 
@@ -202,18 +201,6 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
 
        er = ep->ExceptionRecord;
        ctx = ep->ContextRecord;
-       sctx = g_malloc(sizeof(struct sigcontext));
-
-       /* Copy Win32 context to UNIX style context */
-       sctx->eax = ctx->Eax;
-       sctx->ebx = ctx->Ebx;
-       sctx->ecx = ctx->Ecx;
-       sctx->edx = ctx->Edx;
-       sctx->ebp = ctx->Ebp;
-       sctx->esp = ctx->Esp;
-       sctx->esi = ctx->Esi;
-       sctx->edi = ctx->Edi;
-       sctx->eip = ctx->Eip;
 
        switch (er->ExceptionCode) {
        case EXCEPTION_STACK_OVERFLOW:
@@ -246,23 +233,8 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
                * can correctly chain the exception.
                */
                res = EXCEPTION_CONTINUE_SEARCH;
-       } else {
-               /* Copy context back */
-               ctx->Eax = sctx->eax;
-               ctx->Ebx = sctx->ebx;
-               ctx->Ecx = sctx->ecx;
-               ctx->Edx = sctx->edx;
-               ctx->Ebp = sctx->ebp;
-               ctx->Esp = sctx->esp;
-               ctx->Esi = sctx->esi;
-               ctx->Edi = sctx->edi;
-               ctx->Eip = sctx->eip;
        }
 
-       /* TODO: Find right place to free this in stack overflow case */
-       if (er->ExceptionCode != EXCEPTION_STACK_OVERFLOW)
-               g_free (sctx);
-
        return res;
 }
 
@@ -952,15 +924,15 @@ mono_arch_ip_from_context (void *sigctx)
 #if defined(__native_client__)
        printf("WARNING: mono_arch_ip_from_context() called!\n");
        return (NULL);
-#else
-#ifdef MONO_ARCH_USE_SIGACTION
+#elif defined(MONO_ARCH_USE_SIGACTION)
        ucontext_t *ctx = (ucontext_t*)sigctx;
        return (gpointer)UCONTEXT_REG_EIP (ctx);
+#elif defined(HOST_WIN32)
+       return ((CONTEXT*)sigctx)->Eip;
 #else
        struct sigcontext *ctx = sigctx;
        return (gpointer)ctx->SC_EIP;
 #endif
-#endif /* __native_client__ */
 }
 
 /*
index 125b4e4e7dce6e341b1fe30d9135f4d2321aa062..614f7af6fedda0bcbd7e92055750731c6407eef9 100644 (file)
@@ -170,34 +170,7 @@ mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo
        ctx = &tctx->ctx;
 
        memset (ctx, 0, sizeof (MonoContext));
-#ifdef TARGET_AMD64
-       ctx->rip = context.Rip;
-       ctx->rax = context.Rax;
-       ctx->rcx = context.Rcx;
-       ctx->rdx = context.Rdx;
-       ctx->rbx = context.Rbx;
-       ctx->rsp = context.Rsp;
-       ctx->rbp = context.Rbp;
-       ctx->rsi = context.Rsi;
-       ctx->rdi = context.Rdi;
-       ctx->r8 = context.R8;
-       ctx->r9 = context.R9;
-       ctx->r10 = context.R10;
-       ctx->r11 = context.R11;
-       ctx->r12 = context.R12;
-       ctx->r13 = context.R13;
-       ctx->r14 = context.R14;
-       ctx->r15 = context.R15;
-#else
-       ctx->edi = context.Edi;
-       ctx->esi = context.Esi;
-       ctx->ebx = context.Ebx;
-       ctx->edx = context.Edx;
-       ctx->ecx = context.Ecx;
-       ctx->eax = context.Eax;
-       ctx->ebp = context.Ebp;
-       ctx->esp = context.Esp;
-#endif
+       mono_sigctx_to_monoctx (&context, ctx);
 
        /* mono_set_jit_tls () sets this */
        jit_tls = mono_thread_info_tls_get (info, TLS_KEY_JIT_TLS);
index 4bb5ad1d7d4641a6e6a275e2d41567e5550cb4d7..31f7ee138e00b1da9d1acc726812ef4eda333515 100644 (file)
@@ -2822,6 +2822,7 @@ void mono_cross_helpers_run (void) MONO_INTERNAL;
 
 #ifndef GET_CONTEXT
 #ifdef HOST_WIN32
+/* seh_vectored_exception_handler () passes in a CONTEXT* */
 #define GET_CONTEXT \
     void *ctx = context;
 #else
index bc0286485fc008a9d5d7cdf3ba8e2dde36e92a80..02fa8c8701c34f1eac0eb9eb2905f3fc9e733f59 100644 (file)
 
 #include <mono/utils/mono-context.h>
 
+#ifdef HOST_WIN32
+#include <windows.h>
+#endif
+
 #ifdef __sun
 #define REG_EAX EAX
 #define REG_EBX EBX
@@ -53,6 +57,17 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
        mctx->esi = UCONTEXT_REG_ESI (ctx);
        mctx->edi = UCONTEXT_REG_EDI (ctx);
        mctx->eip = UCONTEXT_REG_EIP (ctx);
+#elif defined(HOST_WIN32)
+       CONTEXT *context = (CONTEXT*)sigctx;
+
+       mctx->edi = context->Edi;
+       mctx->esi = context->Esi;
+       mctx->ebx = context->Ebx;
+       mctx->edx = context->Edx;
+       mctx->ecx = context->Ecx;
+       mctx->eax = context->Eax;
+       mctx->ebp = context->Ebp;
+       mctx->esp = context->Esp;
 #else  
        struct sigcontext *ctx = (struct sigcontext *)sigctx;
 
@@ -85,6 +100,18 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
        UCONTEXT_REG_ESI (ctx) = mctx->esi;
        UCONTEXT_REG_EDI (ctx) = mctx->edi;
        UCONTEXT_REG_EIP (ctx) = mctx->eip;
+#elif defined(HOST_WIN32)
+       CONTEXT *context = (CONTEXT*)sigctx;
+
+       context->Eip = mctx->eip;
+       context->Edi = mctx->edi;
+       context->Esi = mctx->esi;
+       context->Ebx = mctx->ebx;
+       context->Edx = mctx->edx;
+       context->Ecx = mctx->ecx;
+       context->Eax = mctx->eax;
+       context->Ebp = mctx->ebp;
+       context->Esp = mctx->esp;
 #else
        struct sigcontext *ctx = (struct sigcontext *)sigctx;
 
@@ -104,6 +131,10 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
 
 #include <mono/utils/mono-context.h>
 
+#ifdef HOST_WIN32
+#include <windows.h>
+#endif
+
 void
 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 {
@@ -131,6 +162,26 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
        mctx->r14 = UCONTEXT_REG_R14 (ctx);
        mctx->r15 = UCONTEXT_REG_R15 (ctx);
        mctx->rip = UCONTEXT_REG_RIP (ctx);
+#elif defined(HOST_WIN32)
+       CONTEXT *context = (CONTEXT*)sigctx;
+
+       mctx->rip = context->Rip;
+       mctx->rax = context->Rax;
+       mctx->rcx = context->Rcx;
+       mctx->rdx = context->Rdx;
+       mctx->rbx = context->Rbx;
+       mctx->rsp = context->Rsp;
+       mctx->rbp = context->Rbp;
+       mctx->rsi = context->Rsi;
+       mctx->rdi = context->Rdi;
+       mctx->r8 = context->R8;
+       mctx->r9 = context->R9;
+       mctx->r10 = context->R10;
+       mctx->r11 = context->R11;
+       mctx->r12 = context->R12;
+       mctx->r13 = context->R13;
+       mctx->r14 = context->R14;
+       mctx->r15 = context->R15;
 #else
        MonoContext *ctx = (MonoContext *)sigctx;
 
@@ -181,6 +232,26 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
        UCONTEXT_REG_R14 (ctx) = mctx->r14;
        UCONTEXT_REG_R15 (ctx) = mctx->r15;
        UCONTEXT_REG_RIP (ctx) = mctx->rip;
+#elif defined(HOST_WIN32)
+       CONTEXT *context = (CONTEXT*)sigctx;
+
+       context->Rip = mctx->rip;
+       context->Rax = mctx->rax;
+       context->Rcx = mctx->rcx;
+       context->Rdx = mctx->rdx;
+       context->Rbx = mctx->rbx;
+       context->Rsp = mctx->rsp;
+       context->Rbp = mctx->rbp;
+       context->Rsi = mctx->rsi;
+       context->Rdi = mctx->rdi;
+       context->R8 = mctx->r8;
+       context->R9 = mctx->r9;
+       context->R10 = mctx->r10;
+       context->R11 = mctx->r11;
+       context->R12 = mctx->r12;
+       context->R13 = mctx->r13;
+       context->R14 = mctx->r14;
+       context->R15 = mctx->r15;
 #else
        MonoContext *ctx = (MonoContext *)sigctx;
 
index 1a38146b3244320be55bb930e1468c081d1e40c3..251e58111d1ec96c883f7d42f3045bb901a65f40 100755 (executable)
@@ -544,7 +544,18 @@ typedef struct ucontext MonoContext;
 
 #endif
 
+/*
+ * The naming is misleading, the SIGCTX argument should be the platform's context
+ * structure (ucontext_c on posix, CONTEXT on windows).
+ */
 void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) MONO_INTERNAL;
+
+/*
+ * This will not completely initialize SIGCTX since MonoContext contains less
+ * information that the system context. The caller should obtain a SIGCTX from
+ * the system, and use this function to override the parts of it which are
+ * also in MonoContext.
+ */
 void mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) MONO_INTERNAL;
 
 #endif /* __MONO_MONO_CONTEXT_H__ */
index c9ba893f4100bdafefeaf5c5937cfc61b7c3a4e7..892a8f5dc5c6c65a81bbeb7f4291aa39e5c0c982 100755 (executable)
@@ -113,38 +113,9 @@ mono_threads_core_resume (MonoThreadInfo *info)
                g_assert (context.ContextFlags & CONTEXT_INTEGER);
                g_assert (context.ContextFlags & CONTEXT_CONTROL);
 
-               // FIXME: This should be in mini-windows.c
-               context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
-#ifdef TARGET_AMD64
-               context.Rip = ctx.rip;
-               context.Rax = ctx.rax;
-               context.Rcx = ctx.rcx;
-               context.Rdx = ctx.rdx;
-               context.Rbx = ctx.rbx;
-               context.Rsp = ctx.rsp;
-               context.Rbp = ctx.rbp;
-               context.Rsi = ctx.rsi;
-               context.Rdi = ctx.rdi;
-               context.R8 = ctx.r8;
-               context.R9 = ctx.r9;
-               context.R10 = ctx.r10;
-               context.R11 = ctx.r11;
-               context.R12 = ctx.r12;
-               context.R13 = ctx.r13;
-               context.R14 = ctx.r14;
-               context.R15 = ctx.r15;
-#else
-               context.Eip = ctx.eip;
-               context.Edi = ctx.edi;
-               context.Esi = ctx.esi;
-               context.Ebx = ctx.ebx;
-               context.Edx = ctx.edx;
-               context.Ecx = ctx.ecx;
-               context.Eax = ctx.eax;
-               context.Ebp = ctx.ebp;
-               context.Esp = ctx.esp;
-#endif
+               mono_monoctx_to_sigctx (&ctx, &context);
 
+               context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
                res = SetThreadContext (handle, &context);
                g_assert (res);
        }