static MonoW32ExceptionHandler ill_handler;
static MonoW32ExceptionHandler segv_handler;
-static LPTOP_LEVEL_EXCEPTION_FILTER old_handler;
+LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter;
+guint64 mono_win_chained_exception_filter_result;
+gboolean mono_win_chained_exception_filter_didrun;
+
+#ifndef PROCESS_CALLBACK_FILTER_ENABLED
+# define PROCESS_CALLBACK_FILTER_ENABLED 1
+#endif
#define W32_SEH_HANDLE_EX(_ex) \
- if (_ex##_handler) _ex##_handler(0, er, sctx)
+ if (_ex##_handler) _ex##_handler(0, ep, sctx)
/*
* mono_win32_get_handle_stackoverflow (void):
do {
MonoContext new_ctx;
- mono_arch_find_jit_info_ext (domain, jit_tls, &rji, &ctx, &new_ctx, &lmf, &frame);
+ mono_arch_find_jit_info (domain, jit_tls, &rji, &ctx, &new_ctx, &lmf, NULL, &frame);
if (!frame.ji) {
g_warning ("Exception inside function without unwind info");
g_assert_not_reached ();
struct sigcontext* sctx;
LONG res;
+ mono_win_chained_exception_filter_didrun = FALSE;
res = EXCEPTION_CONTINUE_EXECUTION;
er = ep->ExceptionRecord;
g_free (sctx);
+ if (mono_win_chained_exception_filter_didrun)
+ res = mono_win_chained_exception_filter_result;
+
return res;
}
if (!restore_stack)
restore_stack = mono_win32_get_handle_stackoverflow ();
- old_handler = SetUnhandledExceptionFilter(seh_handler);
+ mono_old_win_toplevel_exception_filter = SetUnhandledExceptionFilter(seh_handler);
}
void win32_seh_cleanup()
{
- if (old_handler) SetUnhandledExceptionFilter(old_handler);
+ if (mono_old_win_toplevel_exception_filter) SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter);
}
void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler)
/* jump to the saved IP */
x86_ret (code);
+ nacl_global_codeman_validate(&start, 128, &code);
+
if (info)
*info = mono_tramp_info_create (g_strdup_printf ("restore_context"), start, code - start, ji, unwind_ops);
+ else {
+ GSList *l;
+
+ for (l = unwind_ops; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (unwind_ops);
+ }
return start;
}
guint8 *code;
MonoJumpInfo *ji = NULL;
GSList *unwind_ops = NULL;
-#ifdef __native_client_codegen__
- guint kMaxCodeSize = 128;
-#else
- guint kMaxCodeSize = 64;
-#endif /* __native_client_codegen__ */
+ guint kMaxCodeSize = NACL_SIZE (64, 128);
/* call_filter (MonoContext *ctx, unsigned long eip) */
start = code = mono_global_codeman_reserve (kMaxCodeSize);
x86_leave (code);
x86_ret (code);
+ nacl_global_codeman_validate(&start, kMaxCodeSize, &code);
+
if (info)
*info = mono_tramp_info_create (g_strdup_printf ("call_filter"), start, code - start, ji, unwind_ops);
+ else {
+ GSList *l;
+
+ for (l = unwind_ops; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (unwind_ops);
+ }
g_assert ((code - start) < kMaxCodeSize);
return start;
int i, stack_size, stack_offset, arg_offsets [5], regs_offset;
MonoJumpInfo *ji = NULL;
GSList *unwind_ops = NULL;
-#ifdef __native_client_codegen__
- guint kMaxCodeSize = 256;
-#else
- guint kMaxCodeSize = 128;
-#endif
+ guint kMaxCodeSize = NACL_SIZE (128, 256);
+
start = code = mono_global_codeman_reserve (kMaxCodeSize);
stack_size = 128;
/* We don't generate stack alignment code on osx to save space */
#endif
} else {
- /* One argument */
+ /* One argument + stack alignment */
stack_offset = stack_size + 4 + 4;
#ifdef __APPLE__
/* Pop the alignment added by OP_THROW too */
stack_offset += MONO_ARCH_FRAME_ALIGNMENT - 4;
+#else
+ if (mono_do_x86_stack_align)
+ stack_offset += MONO_ARCH_FRAME_ALIGNMENT - 4;
#endif
}
}
}
x86_breakpoint (code);
+ nacl_global_codeman_validate(&start, kMaxCodeSize, &code);
+
g_assert ((code - start) < kMaxCodeSize);
if (info)
*info = mono_tramp_info_create (g_strdup (name), start, code - start, ji, unwind_ops);
+ else {
+ GSList *l;
+
+ for (l = unwind_ops; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (unwind_ops);
+ }
return start;
}
{
guint8 *tramp;
+/*
+ * If we're running WoW64, we need to set the usermode exception policy
+ * for SEHs to behave. This requires hotfix http://support.microsoft.com/kb/976038
+ * or (eventually) Windows 7 SP1.
+ */
+#ifdef HOST_WIN32
+ DWORD flags;
+ FARPROC getter;
+ FARPROC setter;
+ HMODULE kernel32 = LoadLibraryW (L"kernel32.dll");
+
+ if (kernel32) {
+ getter = GetProcAddress (kernel32, "GetProcessUserModeExceptionPolicy");
+ setter = GetProcAddress (kernel32, "SetProcessUserModeExceptionPolicy");
+ if (getter && setter) {
+ if (getter (&flags))
+ setter (flags & ~PROCESS_CALLBACK_FILTER_ENABLED);
+ }
+ }
+#endif
+
if (mono_aot_only) {
signal_exception_trampoline = mono_aot_get_trampoline ("x86_signal_exception_trampoline");
return;
}
/*
- * mono_arch_find_jit_info_ext:
+ * mono_arch_find_jit_info:
*
* See exceptions-amd64.c for docs.
*/
gboolean
-mono_arch_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
+mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
MonoJitInfo *ji, MonoContext *ctx,
- MonoContext *new_ctx, MonoLMF **lmf,
+ MonoContext *new_ctx, MonoLMF **lmf,
+ mgreg_t **save_locations,
StackFrameInfo *frame)
{
gpointer ip = MONO_CONTEXT_GET_IP (ctx);
memset (frame, 0, sizeof (StackFrameInfo));
frame->ji = ji;
- frame->managed = FALSE;
*new_ctx = *ctx;
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);
else
mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start,
(guint8*)ji->code_start + ji->code_size,
- ip, regs, MONO_MAX_IREGS + 1, &cfa);
+ ip, regs, MONO_MAX_IREGS + 1,
+ save_locations, MONO_MAX_IREGS, &cfa);
new_ctx->eax = regs [X86_EAX];
new_ctx->ebx = regs [X86_EBX];
if (!((guint32)((*lmf)->previous_lmf) & 1))
/* Top LMF entry */
return FALSE;
+ g_assert_not_reached ();
/* Trampoline lmf frame */
frame->method = (*lmf)->method;
}
return FALSE;
}
-#ifdef __sun
-#define REG_EAX EAX
-#define REG_EBX EBX
-#define REG_ECX ECX
-#define REG_EDX EDX
-#define REG_EBP EBP
-#define REG_ESP ESP
-#define REG_ESI ESI
-#define REG_EDI EDI
-#define REG_EIP EIP
-#endif
-
void
mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
{
-#if defined (__native_client__)
- printf("WARNING: mono_arch_sigctx_to_monoctx() called!\n");
- mctx->eax = 0xDEADBEEF;
- mctx->ebx = 0xDEADBEEF;
- mctx->ecx = 0xDEADBEEF;
- mctx->edx = 0xDEADBEEF;
- mctx->ebp = 0xDEADBEEF;
- mctx->esp = 0xDEADBEEF;
- mctx->esi = 0xDEADBEEF;
- mctx->edi = 0xDEADBEEF;
- mctx->eip = 0xDEADBEEF;
-#else
-#ifdef MONO_ARCH_USE_SIGACTION
- ucontext_t *ctx = (ucontext_t*)sigctx;
-
- mctx->eax = UCONTEXT_REG_EAX (ctx);
- mctx->ebx = UCONTEXT_REG_EBX (ctx);
- mctx->ecx = UCONTEXT_REG_ECX (ctx);
- mctx->edx = UCONTEXT_REG_EDX (ctx);
- mctx->ebp = UCONTEXT_REG_EBP (ctx);
- mctx->esp = UCONTEXT_REG_ESP (ctx);
- mctx->esi = UCONTEXT_REG_ESI (ctx);
- mctx->edi = UCONTEXT_REG_EDI (ctx);
- mctx->eip = UCONTEXT_REG_EIP (ctx);
-#else
- struct sigcontext *ctx = (struct sigcontext *)sigctx;
-
- mctx->eax = ctx->SC_EAX;
- mctx->ebx = ctx->SC_EBX;
- mctx->ecx = ctx->SC_ECX;
- mctx->edx = ctx->SC_EDX;
- mctx->ebp = ctx->SC_EBP;
- mctx->esp = ctx->SC_ESP;
- mctx->esi = ctx->SC_ESI;
- mctx->edi = ctx->SC_EDI;
- mctx->eip = ctx->SC_EIP;
-#endif
-#endif /* if defined(__native_client__) */
+ mono_sigctx_to_monoctx (sigctx, mctx);
}
void
mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
{
-#if defined(__native_client__)
- printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
-#else
-#ifdef MONO_ARCH_USE_SIGACTION
- ucontext_t *ctx = (ucontext_t*)sigctx;
-
- UCONTEXT_REG_EAX (ctx) = mctx->eax;
- UCONTEXT_REG_EBX (ctx) = mctx->ebx;
- UCONTEXT_REG_ECX (ctx) = mctx->ecx;
- UCONTEXT_REG_EDX (ctx) = mctx->edx;
- UCONTEXT_REG_EBP (ctx) = mctx->ebp;
- UCONTEXT_REG_ESP (ctx) = mctx->esp;
- UCONTEXT_REG_ESI (ctx) = mctx->esi;
- UCONTEXT_REG_EDI (ctx) = mctx->edi;
- UCONTEXT_REG_EIP (ctx) = mctx->eip;
-#else
- struct sigcontext *ctx = (struct sigcontext *)sigctx;
-
- ctx->SC_EAX = mctx->eax;
- ctx->SC_EBX = mctx->ebx;
- ctx->SC_ECX = mctx->ecx;
- ctx->SC_EDX = mctx->edx;
- ctx->SC_EBP = mctx->ebp;
- ctx->SC_ESP = mctx->esp;
- ctx->SC_ESI = mctx->esi;
- ctx->SC_EDI = mctx->edi;
- ctx->SC_EIP = mctx->eip;
-#endif
-#endif /* __native_client__ */
-}
+ mono_monoctx_to_sigctx (mctx, sigctx);
+}
gpointer
mono_arch_ip_from_context (void *sigctx)
if (info)
*info = mono_tramp_info_create (g_strdup ("x86_signal_exception_trampoline"), start, code - start, ji, unwind_ops);
+ else {
+ GSList *l;
+
+ for (l = unwind_ops; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (unwind_ops);
+ }
return start;
}
}
#endif
+/*
+ * mono_arch_setup_resume_sighandler_ctx:
+ *
+ * Setup CTX so execution continues at FUNC.
+ */
+void
+mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func)
+{
+ int align = (((gint32)MONO_CONTEXT_GET_SP (ctx)) % MONO_ARCH_FRAME_ALIGNMENT + 4);
+
+ if (align != 0)
+ MONO_CONTEXT_SET_SP (ctx, (gsize)MONO_CONTEXT_GET_SP (ctx) - align);
+
+ MONO_CONTEXT_SET_IP (ctx, func);
+}