X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions-x86.c;h=2247b91a2abe39a3351df201a4a0ef77a815ee5c;hb=be532638;hp=982c34a5960a8117f7c3234deb458567d823ef67;hpb=53c76f5069b8e4fc017b8fe7fdc990e6f504e2ba;p=mono.git diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index 982c34a5960..2247b91a2ab 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -8,6 +8,13 @@ */ #include + +#if _WIN32_WINNT < 0x0501 +/* Required for Vectored Exception Handling. */ +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif /* _WIN32_WINNT < 0x0501 */ + #include #include #include @@ -39,14 +46,30 @@ static MonoW32ExceptionHandler fpe_handler; 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; +gpointer mono_win_vectored_exception_handle; +extern gboolean mono_win_chained_exception_needs_run; +extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*); #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) + +LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep) +{ +#ifndef MONO_CROSS_COMPILE + if (mono_old_win_toplevel_exception_filter) { + return (*mono_old_win_toplevel_exception_filter)(ep); + } +#endif + + mono_handle_native_sigsegv (SIGSEGV, NULL); + + return EXCEPTION_CONTINUE_SEARCH; +} /* * mono_win32_get_handle_stackoverflow (void): @@ -81,8 +104,7 @@ mono_win32_get_handle_stackoverflow (void) /* get stack overflow exception from domain object */ x86_mov_reg_membase (code, X86_EAX, X86_EAX, G_STRUCT_OFFSET (MonoDomain, stack_overflow_ex), 4); - /* call mono_arch_handle_exception (sctx, stack_overflow_exception_obj, FALSE) */ - x86_push_imm (code, 0); + /* call mono_arch_handle_exception (sctx, stack_overflow_exception_obj) */ x86_push_reg (code, X86_EAX); x86_push_reg (code, X86_EBX); x86_call_code (code, mono_arch_handle_exception); @@ -116,7 +138,7 @@ win32_handle_stack_overflow (EXCEPTION_POINTERS* ep, struct sigcontext *sctx) DWORD page_size; MonoDomain *domain = mono_domain_get (); MonoJitInfo rji; - MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); MonoLMF *lmf = jit_tls->lmf; MonoContext initial_ctx; MonoContext ctx; @@ -142,7 +164,7 @@ win32_handle_stack_overflow (EXCEPTION_POINTERS* ep, struct sigcontext *sctx) do { MonoContext new_ctx; - mono_arch_find_jit_info (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 (); @@ -169,13 +191,14 @@ win32_handle_stack_overflow (EXCEPTION_POINTERS* ep, struct sigcontext *sctx) * Unhandled Exception Filter * Top-level per-process exception handler. */ -LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep) +LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) { EXCEPTION_RECORD* er; CONTEXT* ctx; struct sigcontext* sctx; LONG res; + mono_win_chained_exception_needs_run = FALSE; res = EXCEPTION_CONTINUE_EXECUTION; er = ep->ExceptionRecord; @@ -215,18 +238,30 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep) break; } - /* 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; + if (mono_win_chained_exception_needs_run) { + /* Don't copy context back if we chained exception + * as the handler may have modfied the EXCEPTION_POINTERS + * directly. We don't pass sigcontext to chained handlers. + * Return continue search so the UnhandledExceptionFilter + * 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; + } - g_free (sctx); + /* TODO: Find right place to free this in stack overflow case */ + if (er->ExceptionCode != EXCEPTION_STACK_OVERFLOW) + g_free (sctx); return res; } @@ -237,12 +272,14 @@ void win32_seh_init() if (!restore_stack) restore_stack = mono_win32_get_handle_stackoverflow (); - old_handler = SetUnhandledExceptionFilter(seh_handler); + mono_old_win_toplevel_exception_filter = SetUnhandledExceptionFilter(seh_unhandled_exception_filter); + mono_win_vectored_exception_handle = AddVectoredExceptionHandler (1, seh_vectored_exception_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); + RemoveVectoredExceptionHandler (seh_unhandled_exception_filter); } void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler) @@ -308,8 +345,10 @@ 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); + *info = mono_tramp_info_create ("restore_context", start, code - start, ji, unwind_ops); else { GSList *l; @@ -335,11 +374,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) 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); @@ -387,8 +422,10 @@ 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); + *info = mono_tramp_info_create ("call_filter", start, code - start, ji, unwind_ops); else { GSList *l; @@ -457,7 +494,7 @@ mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, /* adjust eip so that it point into the call instruction */ ctx.eip -= 1; - mono_handle_exception (&ctx, exc, (gpointer)eip, FALSE); + mono_handle_exception (&ctx, exc); restore_context (&ctx); @@ -515,11 +552,8 @@ 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; -#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; @@ -625,14 +659,16 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea code = mono_arch_emit_load_aotconst (start, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, corlib ? "mono_x86_throw_corlib_exception" : "mono_x86_throw_exception"); x86_call_reg (code, X86_EAX); } else { - x86_call_code (code, resume_unwind ? (mono_x86_resume_unwind) : (corlib ? (gpointer)mono_x86_throw_corlib_exception : (gpointer)mono_x86_throw_exception)); + x86_call_code (code, resume_unwind ? (gpointer)(mono_x86_resume_unwind) : (corlib ? (gpointer)mono_x86_throw_corlib_exception : (gpointer)mono_x86_throw_exception)); } 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); + *info = mono_tramp_info_create (name, start, code - start, ji, unwind_ops); else { GSList *l; @@ -750,7 +786,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, memset (frame, 0, sizeof (StackFrameInfo)); frame->ji = ji; - frame->managed = FALSE; *new_ctx = *ctx; @@ -762,9 +797,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, 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 @@ -809,15 +841,11 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, /* Pop arguments off the stack */ /* * FIXME: LLVM doesn't push these, we can't use ji->from_llvm as it describes - * the caller. + * the callee. */ #ifndef ENABLE_LLVM - { - MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, mono_method_signature (ji->method)->param_count + 1); - - guint32 stack_to_pop = mono_arch_get_argument_info (mono_method_signature (ji->method), mono_method_signature (ji->method)->param_count, arg_info); - new_ctx->esp += stack_to_pop; - } + if (ji->has_arch_eh_info) + new_ctx->esp += mono_jit_info_get_arch_eh_info (ji)->stack_size; #endif return TRUE; @@ -871,14 +899,16 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, /* Pop arguments off the stack */ /* FIXME: Handle the delegate case too ((*lmf)->method == NULL) */ /* FIXME: Handle the IMT/vtable case too */ +#if 0 #ifndef ENABLE_LLVM if ((*lmf)->method) { MonoMethod *method = (*lmf)->method; MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, mono_method_signature (method)->param_count + 1); - guint32 stack_to_pop = mono_arch_get_argument_info (mono_method_signature (method), mono_method_signature (method)->param_count, arg_info); + guint32 stack_to_pop = mono_arch_get_argument_info (NULL, mono_method_signature (method), mono_method_signature (method)->param_count, arg_info); new_ctx->esp += stack_to_pop; } +#endif #endif } else @@ -894,94 +924,17 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, 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) @@ -1008,7 +961,7 @@ mono_arch_ip_from_context (void *sigctx) static void handle_signal_exception (gpointer obj) { - MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); MonoContext ctx; static void (*restore_context) (MonoContext *); @@ -1020,7 +973,7 @@ handle_signal_exception (gpointer obj) if (mono_debugger_handle_exception (&ctx, (MonoObject *)obj)) return; - mono_handle_exception (&ctx, obj, MONO_CONTEXT_GET_IP (&ctx), FALSE); + mono_handle_exception (&ctx, obj); restore_context (&ctx); } @@ -1060,7 +1013,7 @@ mono_x86_get_signal_exception_trampoline (MonoTrampInfo **info, gboolean aot) g_assert ((code - start) < 128); if (info) - *info = mono_tramp_info_create (g_strdup ("x86_signal_exception_trampoline"), start, code - start, ji, unwind_ops); + *info = mono_tramp_info_create ("x86_signal_exception_trampoline", start, code - start, ji, unwind_ops); else { GSList *l; @@ -1072,10 +1025,30 @@ mono_x86_get_signal_exception_trampoline (MonoTrampInfo **info, gboolean aot) return start; } + +void +mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data) +{ + /* + * 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. + * So put it into a register, and branch to a trampoline which + * pushes it. + */ + ctx->eax = (mgreg_t)user_data; + ctx->ecx = ctx->eip; + ctx->edx = (mgreg_t)async_cb; + + /*align the stack*/ + ctx->esp = (ctx->esp - 16) & ~15; + ctx->eip = (mgreg_t)signal_exception_trampoline; +} + gboolean -mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) +mono_arch_handle_exception (void *sigctx, gpointer obj) { #if defined(MONO_ARCH_USE_SIGACTION) + MonoContext mctx; ucontext_t *ctx = (ucontext_t*)sigctx; /* @@ -1083,54 +1056,26 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) * 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 (ctx); + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); /* Pass the ctx parameter in TLS */ 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. - * So put it into a register, and branch to a trampoline which - * pushes it. - */ - g_assert (!test_only); - 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 (ctx) = sp; - - UCONTEXT_REG_EIP (ctx) = (gsize)signal_exception_trampoline; + mctx = jit_tls->ex_ctx; + mono_setup_async_callback (&mctx, handle_signal_exception, obj); + mono_monoctx_to_sigctx (&mctx, sigctx); return TRUE; #elif defined (TARGET_WIN32) - MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); + MonoContext mctx; + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); struct sigcontext *ctx = (struct sigcontext *)sigctx; - guint64 sp = ctx->SC_ESP; mono_arch_sigctx_to_monoctx (sigctx, &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. - * So put it into a register, and branch to a trampoline which - * pushes it. - */ - g_assert (!test_only); - ctx->SC_EAX = (gsize)obj; - ctx->SC_ECX = ctx->SC_EIP; - ctx->SC_EDX = (gsize)handle_signal_exception; - - /* Allocate a stack frame, align it to 16 bytes which is needed on apple */ - sp -= 16; - sp &= ~15; - ctx->SC_ESP = sp; - - ctx->SC_EIP = (gsize)signal_exception_trampoline; + mctx = jit_tls->ex_ctx; + mono_setup_async_callback (&mctx, handle_signal_exception, obj); + mono_monoctx_to_sigctx (&mctx, sigctx); return TRUE; #else @@ -1141,7 +1086,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) return TRUE; - mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only); + mono_handle_exception (&mctx, obj); mono_arch_monoctx_to_sigctx (&mctx, sigctx); @@ -1152,7 +1097,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) static void restore_soft_guard_pages (void) { - MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); if (jit_tls->stack_ovf_guard_base) mono_mprotect (jit_tls->stack_ovf_guard_base, jit_tls->stack_ovf_guard_size, MONO_MMAP_NONE); } @@ -1176,13 +1121,13 @@ prepare_for_guard_pages (MonoContext *mctx) } static void -altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf) +altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf) { void (*restore_context) (MonoContext *); MonoContext mctx; restore_context = mono_get_restore_context (); - mono_arch_sigctx_to_monoctx (sigctx, &mctx); + mctx = *ctx; if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) { if (stack_ovf) @@ -1190,7 +1135,7 @@ altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf) restore_context (&mctx); } - mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, FALSE); + mono_handle_exception (&mctx, obj); if (stack_ovf) prepare_for_guard_pages (&mctx); restore_context (&mctx); @@ -1231,7 +1176,8 @@ mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean * ctx arg * return ip */ - frame_size = sizeof (ucontext_t) + sizeof (gpointer) * 4; + // FIXME: test_only is no more. + frame_size = sizeof (MonoContext) + sizeof (gpointer) * 4; frame_size += 15; frame_size &= ~15; sp = (gpointer)(UCONTEXT_REG_ESP (ctx) & ~15); @@ -1243,8 +1189,7 @@ mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean sp [0] = sp + 4; sp [1] = exc; sp [2] = (gpointer)stack_ovf; - /* may need to adjust pointers in the new struct copy, depending on the OS */ - memcpy (sp + 4, ctx, sizeof (ucontext_t)); + mono_sigctx_to_monoctx (sigctx, (MonoContext*)(sp + 4)); /* at the return form the signal handler execution starts in altstack_handle_and_restore() */ UCONTEXT_REG_EIP (ctx) = (unsigned long)altstack_handle_and_restore; UCONTEXT_REG_ESP (ctx) = (unsigned long)(sp - 1); @@ -1267,6 +1212,9 @@ mono_tasklets_arch_restore (void) /* the signature is: restore (MonoContinuation *cont, int state, MonoLMF **lmf_addr) */ /* put cont in edx */ x86_mov_reg_membase (code, X86_EDX, X86_ESP, 4, 4); + /* state in eax, so it's setup as the return value */ + x86_mov_reg_membase (code, X86_EAX, X86_ESP, 8, 4); + /* setup the copy of the stack */ x86_mov_reg_membase (code, X86_ECX, X86_EDX, G_STRUCT_OFFSET (MonoContinuation, stack_used_size), 4); x86_shift_reg_imm (code, X86_SHR, X86_ECX, 2); @@ -1287,8 +1235,6 @@ mono_tasklets_arch_restore (void) /*x86_mov_reg_membase (code, X86_ECX, X86_ESP, 12, 4); x86_mov_membase_reg (code, X86_ECX, 0, X86_EDX, 4);*/ - /* state in eax, so it's setup as the return value */ - x86_mov_reg_membase (code, X86_EAX, X86_ESP, 8, 4); x86_jump_membase (code, X86_EDX, G_STRUCT_OFFSET (MonoContinuation, return_ip)); g_assert ((code - start) <= 48); saved = start; @@ -1296,3 +1242,18 @@ mono_tasklets_arch_restore (void) } #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); +}