-/*------------------------------------------------------------------*/
-/* */
-/* Name - exceptions-s390.c */
-/* */
-/* Function - Exception support for S/390. */
-/* */
-/* Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/* */
-/* Date - January, 2004 */
-/* */
-/* Derivation - From exceptions-x86 & exceptions-ppc */
-/* Paolo Molaro (lupus@ximian.com) */
-/* Dietmar Maurer (dietmar@ximian.com) */
-/* */
-/* Copyright - 2001 Ximian, Inc. */
-/* */
-/*------------------------------------------------------------------*/
+/**
+ * \file
+ *
+ * Function - Exception support for S/390.
+ *
+ * Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
+ *
+ * Date - January, 2004
+ *
+ * Derivation - From exceptions-x86 & exceptions-ppc
+ * Paolo Molaro (lupus@ximian.com)
+ * Dietmar Maurer (dietmar@ximian.com)
+ *
+ * Copyright - 2001 Ximian, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ *
+ */
/*------------------------------------------------------------------*/
/* D e f i n e s */
#include "mini.h"
#include "mini-s390x.h"
+#include "support-s390x.h"
/*========================= End of Includes ========================*/
/* 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 ======================*/
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);
+ MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
if (info)
*info = mono_tramp_info_create ("call_filter",
gulong *int_regs, gdouble *fp_regs, gint32 *acc_regs,
guint fpc, gboolean rethrow)
{
+ MonoError error;
MonoContext ctx;
int iReg;
MONO_CONTEXT_SET_BP (&ctx, sp);
MONO_CONTEXT_SET_IP (&ctx, ip);
- if (mono_object_isinst (exc, mono_defaults.exception_class)) {
+ if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
MonoException *mono_ex = (MonoException*)exc;
- if (!rethrow)
+ if (!rethrow) {
mono_ex->stack_trace = NULL;
+ mono_ex->trace_ips = NULL;
+ }
}
+ mono_error_assert_ok (&error);
// mono_arch_handle_exception (&ctx, exc, FALSE);
mono_handle_exception (&ctx, exc);
mono_restore_context(&ctx);
s390_stg (code, s390_r14, 0, STK_BASE, 0);
s390_lgr (code, s390_r3, s390_r2);
if (corlib) {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 10);
- s390_llong(code, mono_defaults.exception_class->image);
- s390_llong(code, mono_exception_from_token);
- s390_lg (code, s390_r2, 0, s390_r13, 4);
- s390_lg (code, s390_r1, 0, s390_r13, 12);
+ S390_SET (code, s390_r1, (guint8 *)mono_exception_from_token);
+ S390_SET (code, s390_r2, (guint8 *)mono_defaults.exception_class->image);
s390_basr (code, s390_r14, s390_r1);
}
s390_la (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_ACCREGS);
s390_stg (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_ACCPRM);
s390_stfpc(code, STK_BASE, S390_THROWSTACK_FPCPRM+4);
+ S390_SET (code, s390_r1, (guint8 *)throw_exception);
s390_lghi (code, s390_r7, rethrow);
s390_stg (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_RETHROW);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_llong(code, throw_exception);
- s390_lg (code, s390_r1, 0, s390_r13, 4);
s390_basr (code, s390_r14, s390_r1);
/* we should never reach this breakpoint */
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);
+ MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
if (info)
*info = mono_tramp_info_create (corlib ? "throw_corlib_exception"
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 ========================*/
/*------------------------------------------------------------------*/
/* */
-/* 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;
guint8 *unwind_info;
mgreg_t regs[16];
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
/*========================= End of Function ========================*/
+/*------------------------------------------------------------------*/
+/* */
+/* Name - handle_signal_exception */
+/* */
+/* Function - Handle an exception raised by the JIT code. */
+/* */
+/* Parameters - obj - The exception object */
+/* */
+/*------------------------------------------------------------------*/
+
+static void
+handle_signal_exception (gpointer obj)
+{
+ MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
+ 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_handle_exception */
/*------------------------------------------------------------------*/
gboolean
-mono_arch_handle_exception (void *uc, gpointer obj)
+mono_arch_handle_exception (void *sigctx, gpointer obj)
{
- return mono_handle_exception (uc, obj);
+ 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_tls_get_jit_tls ();
+
+ /* 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_setup_async_callback */
+/* */
+/* Function - Establish the async callback. */
+/* */
+/* Parameters - ctx - Context */
+/* async_cb - Callback routine address */
+/* user_data - Data to be passed to callback */
+/* */
+/*------------------------------------------------------------------*/
+
+void
+mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data)
+{
+ 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 ========================*/