X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fmini%2Fexceptions-s390x.c;h=c3714f94ee0d37bc67485bd437ffd9e65ca95e32;hb=5b7a67e75ce1faf5137bc5d6cae0021a6d079a79;hp=38c4a5b987a41747ecbe637cb7c217b1372029c6;hpb=99b5aad5ee74b270b33e3779cf14cf18d847db50;p=mono.git diff --git a/mono/mini/exceptions-s390x.c b/mono/mini/exceptions-s390x.c index 38c4a5b987a..c3714f94ee0 100644 --- a/mono/mini/exceptions-s390x.c +++ b/mono/mini/exceptions-s390x.c @@ -33,8 +33,6 @@ #define S390_THROWSTACK_ACCREGS (S390_THROWSTACK_FLTREGS+(16*sizeof(gdouble))) #define S390_THROWSTACK_SIZE (S390_THROWSTACK_ACCREGS+(16*sizeof(gint32))) -#define S390_REG_SAVE_R13 (S390_REG_SAVE_OFFSET+(7*sizeof(gulong))) - #define SZ_THROW 384 #define setup_context(ctx) @@ -68,8 +66,11 @@ /* P r o t o t y p e s */ /*------------------------------------------------------------------*/ -gboolean mono_arch_handle_exception (void *ctx, - gpointer obj); +static void throw_exception (MonoObject *, unsigned long, unsigned long, + gulong *, gdouble *, gint32 *, guint, gboolean); +static gpointer mono_arch_get_throw_exception_generic (int, MonoTrampInfo **, + int, gboolean, gboolean); +static void handle_signal_exception (gpointer); /*========================= End of Prototypes ======================*/ @@ -212,6 +213,9 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) g_assert ((code - start) < SZ_THROW); + mono_arch_flush_icache(start, code - start); + mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); + if (info) *info = mono_tramp_info_create ("call_filter", start, code - start, ji, @@ -258,8 +262,10 @@ throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp, if (mono_object_isinst (exc, mono_defaults.exception_class)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) + if (!rethrow) { mono_ex->stack_trace = NULL; + mono_ex->trace_ips = NULL; + } } // mono_arch_handle_exception (&ctx, exc, FALSE); mono_handle_exception (&ctx, exc); @@ -359,10 +365,13 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, s390_break (code); g_assert ((code - start) < size); + mono_arch_flush_icache (start, code - start); + mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); + if (info) *info = mono_tramp_info_create (corlib ? "throw_corlib_exception" - : (rethrow ? "rethrow_exception" - : "throw_exception"), + : (rethrow ? "rethrow_exception" + : "throw_exception"), start, code - start, ji, unwind_ops); return start; @@ -412,7 +421,7 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) if (info) *info = NULL; - return (mono_arch_get_throw_exception_generic (SZ_THROW, info, FALSE, FALSE, aot)); + return (mono_arch_get_throw_exception_generic (SZ_THROW, info, FALSE, TRUE, aot)); } /*========================= End of Function ========================*/ @@ -442,21 +451,20 @@ mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) /*------------------------------------------------------------------*/ /* */ -/* Name - mono_arch_find_jit_info */ +/* Name - mono_arch_unwind_frame */ /* */ /* Function - See exceptions-amd64.c for docs. */ /* */ /*------------------------------------------------------------------*/ gboolean -mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, +mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *ji, MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf, mgreg_t **save_locations, StackFrameInfo *frame) { gpointer ip = (gpointer) MONO_CONTEXT_GET_IP (ctx); - MonoS390StackFrame *sframe; memset (frame, 0, sizeof (StackFrameInfo)); frame->ji = ji; @@ -474,27 +482,17 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len); - if (*lmf && ((*lmf) != jit_tls->first_lmf) && - (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->ebp)) { - /* remove any unused lmf */ - *lmf = (*lmf)->previous_lmf; - } - address = (char *)ip - (char *)ji->code_start; memcpy(®s, &ctx->uc_mcontext.gregs, sizeof(regs)); mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, - (guint8 *) ji->code_start + ji->code_size, - ip, regs, 16, save_locations, - MONO_MAX_IREGS, &cfa); + (guint8 *) ji->code_start + ji->code_size, + ip, NULL, regs, 16, save_locations, + MONO_MAX_IREGS, &cfa); memcpy (&new_ctx->uc_mcontext.gregs, ®s, sizeof(regs)); MONO_CONTEXT_SET_IP(new_ctx, regs[14] - 2); MONO_CONTEXT_SET_BP(new_ctx, cfa); - if (*lmf && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->ebp)) { - /* remove any unused lmf */ - *lmf = (*lmf)->previous_lmf; - } return TRUE; } else if (*lmf) { @@ -525,52 +523,85 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, /*------------------------------------------------------------------*/ /* */ -/* Name - mono_arch_handle_exception */ +/* Name - handle_signal_exception */ /* */ /* Function - Handle an exception raised by the JIT code. */ /* */ -/* Parameters - ctx - Saved processor state */ -/* obj - The exception object */ +/* Parameters - obj - The exception object */ /* */ /*------------------------------------------------------------------*/ -gboolean -mono_arch_handle_exception (void *uc, gpointer obj) +static void +handle_signal_exception (gpointer obj) { - return mono_handle_exception (uc, obj); + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + MonoContext ctx; + + memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext)); + mono_handle_exception (&ctx, obj); + mono_restore_context (&ctx); } /*========================= End of Function ========================*/ /*------------------------------------------------------------------*/ /* */ -/* Name - mono_arch_sigctx_to_monoctx. */ +/* Name - mono_arch_handle_exception */ /* */ -/* Function - Called from the signal handler to convert signal */ -/* context to MonoContext. */ +/* Function - Handle an exception raised by the JIT code. */ +/* */ +/* Parameters - ctx - Saved processor state */ +/* obj - The exception object */ /* */ /*------------------------------------------------------------------*/ -void -mono_arch_sigctx_to_monoctx (void *ctx, MonoContext *mctx) +gboolean +mono_arch_handle_exception (void *sigctx, gpointer obj) { - mono_sigctx_to_monoctx(ctx, mctx); + MonoContext mctx; + + /* + * 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 = mono_native_tls_get_value (mono_jit_tls_id); + + /* Pass the ctx parameter in TLS */ + mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); + + mctx = jit_tls->ex_ctx; + mono_arch_setup_async_callback (&mctx, handle_signal_exception, obj); + mono_monoctx_to_sigctx (&mctx, sigctx); + + return TRUE; } /*========================= End of Function ========================*/ /*------------------------------------------------------------------*/ /* */ -/* Name - mono_arch_monoctx_to_sigctx. */ +/* Name - mono_arch_setup_async_callback */ /* */ -/* Function - Convert MonoContext structure to signal context. */ +/* Function - Establish the async callback. */ +/* */ +/* Parameters - ctx - Context */ +/* async_cb - Callback routine address */ +/* user_data - Data to be passed to callback */ /* */ /*------------------------------------------------------------------*/ void -mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx) +mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data) { - mono_monoctx_to_sigctx(mctx, ctx); + uintptr_t sp = (uintptr_t) MONO_CONTEXT_GET_SP(ctx); + + ctx->uc_mcontext.gregs[2] = (unsigned long) user_data; + + sp -= S390_MINIMAL_STACK_SIZE; + *(unsigned long *)sp = MONO_CONTEXT_GET_SP(ctx); + MONO_CONTEXT_SET_BP(ctx, sp); + MONO_CONTEXT_SET_IP(ctx, (unsigned long) async_cb); } /*========================= End of Function ========================*/