X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions-x86.c;h=d3f09813c202f29cb035745f6decaa09f8302f80;hb=5b558abeeb255a3179d4ca6a85617e051c6abd38;hp=37ca8897d6a507badc4432708ca1f91a762d74aa;hpb=049c5cb8380011ae09fca32a7daef4cc99a8bcf9;p=mono.git diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index 37ca8897d6a..d3f09813c20 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -41,6 +41,10 @@ static MonoW32ExceptionHandler segv_handler; static LPTOP_LEVEL_EXCEPTION_FILTER old_handler; +#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) @@ -138,7 +142,7 @@ win32_handle_stack_overflow (EXCEPTION_POINTERS* ep, struct sigcontext *sctx) 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 (); @@ -304,8 +308,17 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) /* 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; } @@ -324,9 +337,10 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) guint8 *code; MonoJumpInfo *ji = NULL; GSList *unwind_ops = NULL; + guint kMaxCodeSize = NACL_SIZE (64, 128); /* call_filter (MonoContext *ctx, unsigned long eip) */ - start = code = mono_global_codeman_reserve (64); + start = code = mono_global_codeman_reserve (kMaxCodeSize); x86_push_reg (code, X86_EBP); x86_mov_reg_reg (code, X86_EBP, X86_ESP, 4); @@ -371,10 +385,19 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) 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) < 64); + g_assert ((code - start) < kMaxCodeSize); return start; } @@ -492,8 +515,9 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea int i, stack_size, stack_offset, arg_offsets [5], regs_offset; MonoJumpInfo *ji = NULL; GSList *unwind_ops = NULL; + guint kMaxCodeSize = NACL_SIZE (128, 256); - start = code = mono_global_codeman_reserve (128); + start = code = mono_global_codeman_reserve (kMaxCodeSize); stack_size = 128; @@ -542,11 +566,14 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea /* 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 } } @@ -599,12 +626,19 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea } x86_breakpoint (code); - g_assert ((code - start) < 128); + nacl_global_codeman_validate(&start, kMaxCodeSize, &code); - mono_save_trampoline_xdebug_info (name, start, code - start, unwind_ops); + g_assert ((code - start) < kMaxCodeSize); if (info) - *info = mono_tramp_info_create (name, start, code - start, ji, unwind_ops); + *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; } @@ -630,7 +664,7 @@ mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) gpointer mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline ("rethow_exception", TRUE, FALSE, FALSE, FALSE, FALSE, info, aot); + return get_throw_trampoline ("rethrow_exception", TRUE, FALSE, FALSE, FALSE, FALSE, info, aot); } /** @@ -654,6 +688,27 @@ mono_arch_exceptions_init (void) { 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; @@ -679,14 +734,15 @@ mono_arch_exceptions_init (void) } /* - * 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); @@ -725,7 +781,8 @@ mono_arch_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, 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]; @@ -788,6 +845,7 @@ mono_arch_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, if (!((guint32)((*lmf)->previous_lmf) & 1)) /* Top LMF entry */ return FALSE; + g_assert_not_reached (); /* Trampoline lmf frame */ frame->method = (*lmf)->method; } @@ -850,6 +908,18 @@ mono_arch_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, 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; @@ -875,11 +945,15 @@ mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) mctx->edi = ctx->SC_EDI; mctx->eip = ctx->SC_EIP; #endif +#endif /* if defined(__native_client__) */ } 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; @@ -905,18 +979,24 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) ctx->SC_EDI = mctx->edi; ctx->SC_EIP = mctx->eip; #endif +#endif /* __native_client__ */ } gpointer 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 ucontext_t *ctx = (ucontext_t*)sigctx; return (gpointer)UCONTEXT_REG_EIP (ctx); #else struct sigcontext *ctx = sigctx; return (gpointer)ctx->SC_EIP; -#endif +#endif +#endif /* __native_client__ */ } /* @@ -978,10 +1058,15 @@ mono_x86_get_signal_exception_trampoline (MonoTrampInfo **info, gboolean aot) g_assert ((code - start) < 128); - mono_save_trampoline_xdebug_info ("x86_signal_exception_trampoline", start, code - start, unwind_ops); - 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; } @@ -990,16 +1075,18 @@ gboolean mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) { #if defined(MONO_ARCH_USE_SIGACTION) + ucontext_t *ctx = (ucontext_t*)sigctx; + /* * Handling the exception in the signal handler is problematic, since the original * signal is disabled, and we could run arbitrary code though the debugger. So * resume into the normal stack and do most work there if possible. */ MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); - guint64 sp = UCONTEXT_REG_ESP (sigctx); + guint64 sp = UCONTEXT_REG_ESP (ctx); /* Pass the ctx parameter in TLS */ - mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); + mono_arch_sigctx_to_monoctx (ctx, &jit_tls->ex_ctx); /* * Can't pass the obj on the stack, since we are executing on the * same stack. Can't save it into MonoJitTlsData, since it needs GC tracking. @@ -1007,16 +1094,16 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) * pushes it. */ g_assert (!test_only); - UCONTEXT_REG_EAX (sigctx) = (gsize)obj; - UCONTEXT_REG_ECX (sigctx) = UCONTEXT_REG_EIP (sigctx); - UCONTEXT_REG_EDX (sigctx) = (gsize)handle_signal_exception; + UCONTEXT_REG_EAX (ctx) = (gsize)obj; + UCONTEXT_REG_ECX (ctx) = UCONTEXT_REG_EIP (ctx); + UCONTEXT_REG_EDX (ctx) = (gsize)handle_signal_exception; /* Allocate a stack frame, align it to 16 bytes which is needed on apple */ sp -= 16; sp &= ~15; - UCONTEXT_REG_ESP (sigctx) = sp; + UCONTEXT_REG_ESP (ctx) = sp; - UCONTEXT_REG_EIP (sigctx) = (gsize)signal_exception_trampoline; + UCONTEXT_REG_EIP (ctx) = (gsize)signal_exception_trampoline; return TRUE; #elif defined (TARGET_WIN32) @@ -1170,6 +1257,9 @@ mono_tasklets_arch_restore (void) static guint8* saved = NULL; guint8 *code, *start; +#ifdef __native_client_codegen__ + g_print("mono_tasklets_arch_restore needs to be aligned for Native Client\n"); +#endif if (saved) return (MonoContinuationRestore)saved; code = start = mono_global_codeman_reserve (48);