Merge pull request #1504 from madrang/SafeHandle.SetInvalidRelease
[mono.git] / mono / mini / exceptions-amd64.c
index 592969a5256e9f538531bc822d46d975140a3f88..5df8f2f1805006be4409e4ffa652e744e8272200 100644 (file)
 #include <config.h>
 
 #include <glib.h>
-#include <signal.h>
 #include <string.h>
 
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
 #ifdef HAVE_UCONTEXT_H
 #include <ucontext.h>
 #endif
@@ -55,7 +57,7 @@ static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
        }
 #endif
 
-       mono_handle_native_sigsegv (SIGSEGV, NULL);
+       mono_handle_native_sigsegv (SIGSEGV, NULL, NULL);
 
        return EXCEPTION_CONTINUE_SEARCH;
 }
@@ -552,7 +554,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                guint8 *cfa;
                guint32 unwind_info_len;
                guint8 *unwind_info;
-               guint8 *epilog;
+               guint8 *epilog = NULL;
 
                frame->type = FRAME_TYPE_MANAGED;
 
@@ -565,7 +567,9 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                printf ("%s %p %p\n", ji->d.method->name, ji->code_start, ip);
                mono_print_unwind_info (unwind_info, unwind_info_len);
                */
-               epilog = (guint8*)ji->code_start + ji->code_size - mono_jinfo_get_epilog_size (ji);
+               /* LLVM compiled code doesn't have this info */
+               if (ji->has_arch_eh_info)
+                       epilog = (guint8*)ji->code_start + ji->code_size - mono_jinfo_get_epilog_size (ji);
  
                regs [AMD64_RAX] = new_ctx->rax;
                regs [AMD64_RBX] = new_ctx->rbx;
@@ -583,7 +587,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, 
                                                   (guint8*)ji->code_start + ji->code_size,
-                                                  ip, &epilog, regs, MONO_MAX_IREGS + 1,
+                                                  ip, epilog ? &epilog : NULL, regs, MONO_MAX_IREGS + 1,
                                                   save_locations, MONO_MAX_IREGS, &cfa);
 
                new_ctx->rax = regs [AMD64_RAX];
@@ -606,12 +610,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                /* Adjust IP */
                new_ctx->rip --;
 
-#ifndef MONO_AMD64_NO_PUSHES
-               /* Pop arguments off the stack */
-               if (ji->has_arch_eh_info)
-                       new_ctx->rsp += mono_jit_info_get_arch_eh_info (ji)->stack_size;
-#endif
-
                return TRUE;
        } else if (*lmf) {
                guint64 rip;
@@ -763,7 +761,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
        MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
 
        /* Pass the ctx parameter in TLS */
-       mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+       mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
 
        mctx = jit_tls->ex_ctx;
        mono_arch_setup_async_callback (&mctx, handle_signal_exception, obj);
@@ -773,28 +771,16 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
 #else
        MonoContext mctx;
 
-       mono_arch_sigctx_to_monoctx (sigctx, &mctx);
+       mono_sigctx_to_monoctx (sigctx, &mctx);
 
        mono_handle_exception (&mctx, obj);
 
-       mono_arch_monoctx_to_sigctx (&mctx, sigctx);
+       mono_monoctx_to_sigctx (&mctx, sigctx);
 
        return TRUE;
 #endif
 }
 
-void
-mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
-{
-       mono_sigctx_to_monoctx (sigctx, mctx);
-}
-
-void
-mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
-{
-       mono_monoctx_to_sigctx (mctx, sigctx);
-}
-
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
@@ -850,7 +836,7 @@ altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf)
 }
 
 void
-mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean stack_ovf)
+mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *siginfo, gpointer fault_addr, gboolean stack_ovf)
 {
 #if defined(MONO_ARCH_USE_SIGACTION)
        MonoException *exc = NULL;
@@ -862,7 +848,7 @@ mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean
        if (stack_ovf)
                exc = mono_domain_get ()->stack_overflow_ex;
        if (!ji)
-               mono_handle_native_sigsegv (SIGSEGV, sigctx);
+               mono_handle_native_sigsegv (SIGSEGV, sigctx, siginfo);
 
        /* setup a call frame on the real stack so that control is returned there
         * and exception handling can continue.
@@ -1025,10 +1011,17 @@ static gpointer throw_pending_exception;
  * exception.
  */
 void
-mono_arch_notify_pending_exc (void)
+mono_arch_notify_pending_exc (MonoThreadInfo *info)
 {
        MonoLMF *lmf = mono_get_lmf ();
 
+       if (!info) {
+               lmf = mono_get_lmf ();
+       } else {
+               g_assert (info->suspend_state.valid);
+               lmf = info->suspend_state.unwind_data [MONO_UNWIND_DATA_LMF];
+       }
+
        if (!lmf)
                /* Not yet started */
                return;