2009-12-07 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / exceptions-amd64.c
index 126b0aaa7a95e94a8987127edcb5089b436643df..73c8bf8c83c79a890a3f619bdea4b71489d44f24 100644 (file)
@@ -33,7 +33,7 @@
 
 #define ALIGN_TO(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
 
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
 static MonoW32ExceptionHandler fpe_handler;
 static MonoW32ExceptionHandler ill_handler;
 static MonoW32ExceptionHandler segv_handler;
@@ -41,7 +41,7 @@ static MonoW32ExceptionHandler segv_handler;
 static LPTOP_LEVEL_EXCEPTION_FILTER old_handler;
 
 #define W32_SEH_HANDLE_EX(_ex) \
-       if (_ex##_handler) _ex##_handler((int)sctx)
+       if (_ex##_handler) _ex##_handler(0, er, sctx)
 
 /*
  * Unhandled Exception Filter
@@ -144,7 +144,7 @@ void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler)
        }
 }
 
-#endif /* PLATFORM_WIN32 */
+#endif /* TARGET_WIN32 */
 
 /*
  * mono_arch_get_restore_context:
@@ -252,7 +252,7 @@ mono_arch_get_call_filter_full (guint32 *code_size, MonoJumpInfo **ji, gboolean
        amd64_mov_reg_membase (code, AMD64_R13, AMD64_ARG_REG1, G_STRUCT_OFFSET (MonoContext, r13), 8);
        amd64_mov_reg_membase (code, AMD64_R14, AMD64_ARG_REG1, G_STRUCT_OFFSET (MonoContext, r14), 8);
        amd64_mov_reg_membase (code, AMD64_R15, AMD64_ARG_REG1, G_STRUCT_OFFSET (MonoContext, r15), 8);
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
        amd64_mov_reg_membase (code, AMD64_RDI, AMD64_ARG_REG1,  G_STRUCT_OFFSET (MonoContext, rdi), 8);
        amd64_mov_reg_membase (code, AMD64_RSI, AMD64_ARG_REG1,  G_STRUCT_OFFSET (MonoContext, rsi), 8);
 #endif
@@ -386,7 +386,7 @@ get_throw_trampoline (gboolean rethrow, guint32 *code_size, MonoJumpInfo **ji, g
        /* Exception */
        amd64_push_reg (code, AMD64_ARG_REG1);
 
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
        /* align stack */
        amd64_push_imm (code, 0);
        amd64_push_imm (code, 0);
@@ -489,11 +489,11 @@ mono_arch_get_throw_corlib_exception_full (guint32 *code_size, MonoJumpInfo **ji
                amd64_mov_reg_imm (code, AMD64_ARG_REG1, mono_defaults.exception_class->image);
                amd64_mov_reg_imm (code, AMD64_R11, mono_exception_from_token);
        }
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
        amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 32);
 #endif
        amd64_call_reg (code, AMD64_R11);
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
        amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 32);
 #endif
 
@@ -528,30 +528,27 @@ mono_arch_get_throw_corlib_exception_full (guint32 *code_size, MonoJumpInfo **ji
        return start;
 }
 
-/* mono_arch_find_jit_info:
+/*
+ * mono_arch_find_jit_info_ext:
  *
- * This function is used to gather information from @ctx. It return the 
- * MonoJitInfo of the corresponding function, unwinds one stack frame and
- * stores the resulting context into @new_ctx. It also stores a string 
- * describing the stack location into @trace (if not NULL), and modifies
- * the @lmf if necessary. @native_offset return the IP offset from the 
- * start of the function or -1 if that info is not available.
+ * This function is used to gather information from @ctx, and store it in @frame_info.
+ * It unwinds one stack frame, and stores the resulting context into @new_ctx. @lmf
+ * is modified if needed.
+ * Returns TRUE on success, FALSE otherwise.
+ * This function is a version of mono_arch_find_jit_info () where all the results are
+ * returned in a StackFrameInfo structure.
  */
-MonoJitInfo *
-mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, 
-                        MonoContext *new_ctx, MonoLMF **lmf, gboolean *managed)
+gboolean
+mono_arch_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, 
+                                                        MonoJitInfo *ji, MonoContext *ctx, 
+                                                        MonoContext *new_ctx, MonoLMF **lmf, 
+                                                        StackFrameInfo *frame)
 {
-       MonoJitInfo *ji;
        gpointer ip = MONO_CONTEXT_GET_IP (ctx);
 
-       /* Avoid costly table lookup during stack overflow */
-       if (prev_ji && (ip > prev_ji->code_start && ((guint8*)ip < ((guint8*)prev_ji->code_start) + prev_ji->code_size)))
-               ji = prev_ji;
-       else
-               ji = mini_jit_info_table_find (domain, ip, NULL);
-
-       if (managed)
-               *managed = FALSE;
+       memset (frame, 0, sizeof (StackFrameInfo));
+       frame->ji = ji;
+       frame->managed = FALSE;
 
        *new_ctx = *ctx;
 
@@ -561,9 +558,10 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                guint32 unwind_info_len;
                guint8 *unwind_info;
 
-               if (managed)
-                       if (!ji->method->wrapper_type)
-                               *managed = TRUE;
+               frame->type = FRAME_TYPE_MANAGED;
+
+               if (!ji->method->wrapper_type || ji->method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)
+                       frame->managed = TRUE;
 
                if (ji->from_aot)
                        unwind_info = mono_aot_get_unwind_info (ji, &unwind_info_len);
@@ -610,7 +608,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
 
                if (*lmf && ((*lmf) != jit_tls->first_lmf) && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->rsp)) {
                        /* remove any unused lmf */
-                       *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~1);
+                       *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~3);
                }
 
 #ifndef MONO_AMD64_NO_PUSHES
@@ -623,16 +621,34 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                }
 #endif
 
-               return ji;
+               return TRUE;
        } else if (*lmf) {
                guint64 rip;
 
+               if (((guint64)(*lmf)->previous_lmf) & 2) {
+                       /* 
+                        * This LMF entry is created by the soft debug code to mark transitions to
+                        * managed code done during invokes.
+                        */
+                       MonoLMFExt *ext = (MonoLMFExt*)(*lmf);
+
+                       g_assert (ext->debugger_invoke);
+
+                       memcpy (new_ctx, &ext->ctx, sizeof (MonoContext));
+
+                       *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~3);
+
+                       frame->type = FRAME_TYPE_DEBUGGER_INVOKE;
+
+                       return TRUE;
+               }
+
                if (((guint64)(*lmf)->previous_lmf) & 1) {
                        /* This LMF has the rip field set */
                        rip = (*lmf)->rip;
                } else if ((*lmf)->rsp == 0) {
                        /* Top LMF entry */
-                       return (gpointer)-1;
+                       return FALSE;
                } else {
                        /* 
                         * The rsp field is set just before the call which transitioned to native 
@@ -644,9 +660,12 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                ji = mini_jit_info_table_find (domain, (gpointer)rip, NULL);
                if (!ji) {
                        // FIXME: This can happen with multiple appdomains (bug #444383)
-                       return (gpointer)-1;
+                       return FALSE;
                }
 
+               frame->ji = ji;
+               frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
+
                new_ctx->rip = rip;
                new_ctx->rbp = (*lmf)->rbp;
                new_ctx->rsp = (*lmf)->rsp;
@@ -656,17 +675,17 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                new_ctx->r13 = (*lmf)->r13;
                new_ctx->r14 = (*lmf)->r14;
                new_ctx->r15 = (*lmf)->r15;
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
                new_ctx->rdi = (*lmf)->rdi;
                new_ctx->rsi = (*lmf)->rsi;
 #endif
 
-               *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~1);
+               *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~3);
 
-               return ji ? ji : res;
+               return TRUE;
        }
 
-       return NULL;
+       return FALSE;
 }
 
 /**
@@ -1050,7 +1069,7 @@ mono_arch_exceptions_init (void)
        }
 }
 
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
 
 /*
  * The mono_arch_unwindinfo* methods are used to build and add
@@ -1329,7 +1348,7 @@ mono_tasklets_arch_restore (void)
        amd64_mov_reg_membase (code, AMD64_R13, AMD64_RCX, G_STRUCT_OFFSET (MonoLMF, r13), 8);
        amd64_mov_reg_membase (code, AMD64_R14, AMD64_RCX, G_STRUCT_OFFSET (MonoLMF, r14), 8);
        amd64_mov_reg_membase (code, AMD64_R15, AMD64_RCX, G_STRUCT_OFFSET (MonoLMF, r15), 8);
-#ifdef PLATFORM_WIN32
+#ifdef TARGET_WIN32
        amd64_mov_reg_membase (code, AMD64_RDI, AMD64_RCX, G_STRUCT_OFFSET (MonoLMF, rdi), 8);
        amd64_mov_reg_membase (code, AMD64_RSI, AMD64_RCX, G_STRUCT_OFFSET (MonoLMF, rsi), 8);
 #endif