コード例 #1
0
ファイル: exceptions-amd64.c プロジェクト: TheMetalMage/mono
/* 
 * The first few arguments are dummy, to force the other arguments to be passed on
 * the stack, this avoids overwriting the argument registers in the throw trampoline.
 */
void
mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4,
							guint64 dummy5, guint64 dummy6,
							MonoContext *mctx, MonoObject *exc, gboolean rethrow)
{
	MonoContext ctx;

	/* mctx is on the caller's stack */
	memcpy (&ctx, mctx, sizeof (MonoContext));

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow) {
			mono_ex->stack_trace = NULL;
			mono_ex->trace_ips = NULL;
		}
	}

	/* adjust eip so that it point into the call instruction */
	ctx.gregs [AMD64_RIP] --;

	mono_handle_exception (&ctx, exc);
	mono_restore_context (&ctx);
	g_assert_not_reached ();
}
コード例 #2
0
void
mono_arm_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gulong *int_regs, gdouble *fp_regs)
{
	static void (*restore_context) (MonoContext *);
	MonoContext ctx;
	gboolean rethrow = eip & 1;

	if (!restore_context)
		restore_context = mono_get_restore_context ();

	eip &= ~1; /* clear the optional rethrow bit */
	/* adjust eip so that it point into the call instruction */
	eip -= 4;

	/*printf ("stack in throw: %p\n", esp);*/
	MONO_CONTEXT_SET_BP (&ctx, int_regs [ARMREG_FP - 4]);
	MONO_CONTEXT_SET_SP (&ctx, esp);
	MONO_CONTEXT_SET_IP (&ctx, eip);
	memcpy (((guint8*)&ctx.regs) + (4 * 4), int_regs, sizeof (gulong) * 8);
	/* memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_SAVED_FREGS); */

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow)
			mono_ex->stack_trace = NULL;
	}
	mono_handle_exception (&ctx, exc, (gpointer)(eip + 4), FALSE);
	restore_context (&ctx);
	g_assert_not_reached ();
}
コード例 #3
0
ファイル: exceptions-amd64.c プロジェクト: TheMetalMage/mono
/**
 * mono_arch_handle_exception:
 *
 * @ctx: saved processor state
 * @obj: the exception object
 */
gboolean
mono_arch_handle_exception (void *sigctx, gpointer obj)
{
#if defined(MONO_ARCH_USE_SIGACTION)
	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 = (MonoJitTlsData *)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;
#else
	MonoContext mctx;

	mono_sigctx_to_monoctx (sigctx, &mctx);

	mono_handle_exception (&mctx, obj);

	mono_monoctx_to_sigctx (&mctx, sigctx);

	return TRUE;
#endif
}
コード例 #4
0
ファイル: exceptions-sparc.c プロジェクト: Adamcbrz/mono
gboolean
mono_arch_handle_exception (void *sigctx, gpointer obj)
{
	MonoContext mctx;
	ucontext_t *ctx = (ucontext_t*)sigctx;
	gpointer *window;

	/*
	 * Access to the machine state using the ucontext_t parameter is somewhat
	 * under documented under solaris. The code below seems to work under
	 * Solaris 9.
	 */
	g_assert (!ctx->uc_mcontext.gwins);

	mctx.ip = ctx->uc_mcontext.gregs [REG_PC];
	mctx.sp = ctx->uc_mcontext.gregs [REG_SP];
	window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
	mctx.fp = window [sparc_fp - 16];

	mono_handle_exception (&mctx, obj);
	
	/* We can't use restore_context to return from a signal handler */
	ctx->uc_mcontext.gregs [REG_PC] = mctx.ip;
	ctx->uc_mcontext.gregs [REG_nPC] = mctx.ip + 4;
	ctx->uc_mcontext.gregs [REG_SP] = mctx.sp;
	window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
	window [sparc_fp - 16] = mctx.fp;

	return TRUE;
}
コード例 #5
0
ファイル: exceptions-sparc.c プロジェクト: Adamcbrz/mono
static void
throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow)
{
	MonoContext ctx;
	static void (*restore_context) (MonoContext *);
	gpointer *window;
	
	if (!restore_context)
		restore_context = mono_get_restore_context ();

	window = MONO_SPARC_WINDOW_ADDR (sp);
	ctx.sp = (gpointer*)sp;
	ctx.ip = ip;
	ctx.fp = (gpointer*)(MONO_SPARC_WINDOW_ADDR (sp) [sparc_i6 - 16]);

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow)
			mono_ex->stack_trace = NULL;
	}
	mono_handle_exception (&ctx, exc);
	restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #6
0
ファイル: exceptions-sparc.c プロジェクト: Adamcbrz/mono
gboolean
mono_arch_handle_exception (void *sigctx, gpointer obj)
{
       MonoContext mctx;
       struct sigcontext *sc = sigctx;
       gpointer *window;

#ifdef SPARCV9
       mctx.ip = (gpointer) sc->sigc_regs.tpc;
       mctx.sp = (gpointer) sc->sigc_regs.u_regs[14];
#else
       mctx.ip = (gpointer) sc->si_regs.pc;
       mctx.sp = (gpointer) sc->si_regs.u_regs[14];
#endif

       window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
       mctx.fp = window [sparc_fp - 16];

       mono_handle_exception (&mctx, obj);

#ifdef SPARCV9
       sc->sigc_regs.tpc = (unsigned long) mctx.ip;
       sc->sigc_regs.tnpc = (unsigned long) (mctx.ip + 4);
       sc->sigc_regs.u_regs[14] = (unsigned long) mctx.sp;
#else
       sc->si_regs.pc = (unsigned long) mctx.ip;
       sc->si_regs.npc = (unsigned long) (mctx.ip + 4);
       sc->si_regs.u_regs[14] = (unsigned long) mctx.sp;
#endif

       window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
       window [sparc_fp - 16] = mctx.fp;

       return TRUE;
}
コード例 #7
0
ファイル: exceptions-amd64.c プロジェクト: shahid-pk/mono
/* 
 * The first few arguments are dummy, to force the other arguments to be passed on
 * the stack, this avoids overwriting the argument registers in the throw trampoline.
 */
void
mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4,
							guint64 dummy5, guint64 dummy6,
							mgreg_t *regs, mgreg_t rip,
							MonoObject *exc, gboolean rethrow)
{
	MonoContext ctx;

	ctx.rsp = regs [AMD64_RSP];
	ctx.rip = rip;
	ctx.rbx = regs [AMD64_RBX];
	ctx.rbp = regs [AMD64_RBP];
	ctx.r12 = regs [AMD64_R12];
	ctx.r13 = regs [AMD64_R13];
	ctx.r14 = regs [AMD64_R14];
	ctx.r15 = regs [AMD64_R15];
	ctx.rdi = regs [AMD64_RDI];
	ctx.rsi = regs [AMD64_RSI];
	ctx.rax = regs [AMD64_RAX];
	ctx.rcx = regs [AMD64_RCX];
	ctx.rdx = regs [AMD64_RDX];

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow)
			mono_ex->stack_trace = NULL;
	}

	/* adjust eip so that it point into the call instruction */
	ctx.rip -= 1;

	mono_handle_exception (&ctx, exc);
	mono_restore_context (&ctx);
	g_assert_not_reached ();
}
コード例 #8
0
ファイル: exceptions-arm.c プロジェクト: aakashapoorv/mono
void
mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs)
{
	MonoContext ctx;
	gboolean rethrow = pc & 1;

	pc &= ~1; /* clear the optional rethrow bit */
	/* adjust eip so that it point into the call instruction */
	pc -= 4;

	/*printf ("stack in throw: %p\n", esp);*/
	MONO_CONTEXT_SET_BP (&ctx, int_regs [ARMREG_FP - 4]);
	MONO_CONTEXT_SET_SP (&ctx, sp);
	MONO_CONTEXT_SET_IP (&ctx, pc);
	memcpy (((guint8*)&ctx.regs) + (ARMREG_R4 * sizeof (mgreg_t)), int_regs, 8 * sizeof (mgreg_t));
	memcpy (&ctx.fregs, fp_regs, sizeof (double) * 16);

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow)
			mono_ex->stack_trace = NULL;
	}
	mono_handle_exception (&ctx, exc);
	mono_restore_context (&ctx);
	g_assert_not_reached ();
}
コード例 #9
0
ファイル: exceptions-ppc.c プロジェクト: medo64/mono
void
mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, mgreg_t *int_regs, gdouble *fp_regs, gboolean rethrow)
{
	MonoError error;
	MonoContext ctx;

	/* adjust eip so that it point into the call instruction */
	eip -= 4;

	setup_context (&ctx);

	/*printf ("stack in throw: %p\n", esp);*/
	MONO_CONTEXT_SET_BP (&ctx, esp);
	MONO_CONTEXT_SET_IP (&ctx, eip);
	memcpy (&ctx.regs, int_regs, sizeof (mgreg_t) * MONO_MAX_IREGS);
	memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_MAX_FREGS);

	if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow) {
			mono_ex->stack_trace = NULL;
			mono_ex->trace_ips = NULL;
		}
	}
	mono_error_assert_ok (&error);
	mono_handle_exception (&ctx, exc);
	mono_restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #10
0
ファイル: exceptions-ia64.c プロジェクト: red-gate/mono
static void
throw_exception (MonoObject *exc, guint64 rethrow)
{
	unw_context_t unw_ctx;
	MonoContext ctx;
	MonoJitInfo *ji;
	unw_word_t ip, sp;
	int res;

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow) {
			mono_ex->stack_trace = NULL;
			mono_ex->trace_ips = NULL;
		}
	}

	res = unw_getcontext (&unw_ctx);
	g_assert (res == 0);
	res = unw_init_local (&ctx.cursor, &unw_ctx);
	g_assert (res == 0);

	/* 
	 * Unwind until the first managed frame. This is needed since 
	 * mono_handle_exception expects the variables in the original context to
	 * correspond to the method returned by mono_find_jit_info.
	 */
	while (TRUE) {
		res = unw_get_reg (&ctx.cursor, UNW_IA64_IP, &ip);
		g_assert (res == 0);

		res = unw_get_reg (&ctx.cursor, UNW_IA64_SP, &sp);
		g_assert (res == 0);

		ji = mini_jit_info_table_find (mono_domain_get (), (gpointer)ip, NULL);

		//printf ("UN: %s %lx %lx\n", ji ? jinfo_get_method (ji)->name : "", ip, sp);

		if (ji)
			break;

		res = unw_step (&ctx.cursor);

		if (res == 0) {
			/*
			 * This means an unhandled exception during the compilation of a
			 * topmost method like Main
			 */
			break;
		}
		g_assert (res >= 0);
	}
	ctx.precise_ip = FALSE;

	mono_handle_exception (&ctx, exc);
	restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #11
0
ファイル: exceptions-x86.c プロジェクト: efcastrillon/mono
/*
 * mono_x86_throw_exception:
 *
 *   C function called from the throw trampolines.
 */
void
mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, 
						  mgreg_t eip, gboolean rethrow)
{
	static void (*restore_context) (MonoContext *);
	MonoContext ctx;

	if (!restore_context)
		restore_context = mono_get_restore_context ();

	ctx.esp = regs [X86_ESP];
	ctx.eip = eip;
	ctx.ebp = regs [X86_EBP];
	ctx.edi = regs [X86_EDI];
	ctx.esi = regs [X86_ESI];
	ctx.ebx = regs [X86_EBX];
	ctx.edx = regs [X86_EDX];
	ctx.ecx = regs [X86_ECX];
	ctx.eax = regs [X86_EAX];

#ifdef __APPLE__
	/* The OSX ABI specifies 16 byte alignment at call sites */
	g_assert ((ctx.esp % MONO_ARCH_FRAME_ALIGNMENT) == 0);
#endif

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow)
			mono_ex->stack_trace = NULL;
	}

	if (mono_debug_using_mono_debugger ()) {
		guint8 buf [16], *code;

		mono_breakpoint_clean_code (NULL, (gpointer)eip, 8, buf, sizeof (buf));
		code = buf + 8;

		if (buf [3] == 0xe8) {
			MonoContext ctx_cp = ctx;
			ctx_cp.eip = eip - 5;

			if (mono_debugger_handle_exception (&ctx_cp, exc)) {
				restore_context (&ctx_cp);
				g_assert_not_reached ();
			}
		}
	}

	/* adjust eip so that it point into the call instruction */
	ctx.eip -= 1;

	mono_handle_exception (&ctx, exc);

	restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #12
0
ファイル: exceptions-ppc.c プロジェクト: medo64/mono
static void
altstack_handle_and_restore (void *sigctx, gpointer obj)
{
	MonoContext mctx;

	mono_sigctx_to_monoctx (sigctx, &mctx);
	mono_handle_exception (&mctx, obj);
	mono_restore_context (&mctx);
}
コード例 #13
0
/* 
 * The first few arguments are dummy, to force the other arguments to be passed on
 * the stack, this avoids overwriting the argument registers in the throw trampoline.
 */
void
mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4,
							guint64 dummy5, guint64 dummy6,
							mgreg_t *regs, mgreg_t rip,
							MonoObject *exc, gboolean rethrow)
{
	static void (*restore_context) (MonoContext *);
	MonoContext ctx;

	if (!restore_context)
		restore_context = mono_get_restore_context ();

	ctx.rsp = regs [AMD64_RSP];
	ctx.rip = rip;
	ctx.rbx = regs [AMD64_RBX];
	ctx.rbp = regs [AMD64_RBP];
	ctx.r12 = regs [AMD64_R12];
	ctx.r13 = regs [AMD64_R13];
	ctx.r14 = regs [AMD64_R14];
	ctx.r15 = regs [AMD64_R15];
	ctx.rdi = regs [AMD64_RDI];
	ctx.rsi = regs [AMD64_RSI];
	ctx.rax = regs [AMD64_RAX];
	ctx.rcx = regs [AMD64_RCX];
	ctx.rdx = regs [AMD64_RDX];

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow)
			mono_ex->stack_trace = NULL;
	}

	if (mono_debug_using_mono_debugger ()) {
		guint8 buf [16];

		mono_breakpoint_clean_code (NULL, (gpointer)rip, 8, buf, sizeof (buf));

		if (buf [3] == 0xe8) {
			MonoContext ctx_cp = ctx;
			ctx_cp.rip = rip - 5;

			if (mono_debugger_handle_exception (&ctx_cp, exc)) {
				restore_context (&ctx_cp);
				g_assert_not_reached ();
			}
		}
	}

	/* adjust eip so that it point into the call instruction */
	ctx.rip -= 1;

	mono_handle_exception (&ctx, exc);
	restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #14
0
static void
altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf)
{
	MonoContext mctx;

	mctx = *ctx;

	mono_handle_exception (&mctx, obj);
	if (stack_ovf)
		prepare_for_guard_pages (&mctx);
	mono_restore_context (&mctx);
}
コード例 #15
0
ファイル: exceptions-arm.c プロジェクト: aakashapoorv/mono
/*
 * handle_exception:
 *
 *   Called by resuming from a signal handler.
 */
static void
handle_signal_exception (gpointer 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);
}
コード例 #16
0
ファイル: exceptions-x86.c プロジェクト: Sciumo/mono
gboolean
mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
{
#if defined(MONO_ARCH_USE_SIGACTION)
	MonoContext mctx;
	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 = 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);

	g_assert (!test_only);
	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)
	MonoContext mctx;
	MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
	struct sigcontext *ctx = (struct sigcontext *)sigctx;

	mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);

	g_assert (!test_only);
	mctx = jit_tls->ex_ctx;
	mono_setup_async_callback (&mctx, handle_signal_exception, obj);
	mono_monoctx_to_sigctx (&mctx, sigctx);

	return TRUE;
#else
	MonoContext mctx;

	mono_arch_sigctx_to_monoctx (sigctx, &mctx);

	if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj))
		return TRUE;

	mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only);

	mono_arch_monoctx_to_sigctx (&mctx, sigctx);

	return TRUE;
#endif
}
コード例 #17
0
ファイル: exceptions-arm.c プロジェクト: aakashapoorv/mono
/*
 * This is the function called from the signal handler
 */
gboolean
mono_arch_handle_exception (void *ctx, gpointer obj)
{
#if defined(MONO_CROSS_COMPILE) || !defined(MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX)
	g_assert_not_reached ();
#elif defined(MONO_ARCH_USE_SIGACTION)
	arm_ucontext *sigctx = ctx;
	/*
	 * 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);
	guint64 sp = UCONTEXT_REG_SP (sigctx);

	/* Pass the ctx parameter in TLS */
	mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
	/* The others in registers */
	UCONTEXT_REG_R0 (sigctx) = (gsize)obj;

	/* Allocate a stack frame */
	sp -= 16;
	UCONTEXT_REG_SP (sigctx) = sp;

	UCONTEXT_REG_PC (sigctx) = (gsize)get_handle_signal_exception_addr ();
#ifdef UCONTEXT_REG_CPSR
	if ((gsize)UCONTEXT_REG_PC (sigctx) & 1)
		/* Transition to thumb */
		UCONTEXT_REG_CPSR (sigctx) |= (1 << 5);
	else
		/* Transition to ARM */
		UCONTEXT_REG_CPSR (sigctx) &= ~(1 << 5);
#endif

	return TRUE;
#else
	MonoContext mctx;
	gboolean result;

	mono_arch_sigctx_to_monoctx (ctx, &mctx);

	result = mono_handle_exception (&mctx, obj);
	/* restore the context so that returning from the signal handler will invoke
	 * the catch clause 
	 */
	mono_arch_monoctx_to_sigctx (&mctx, ctx);
	return result;
#endif
}
コード例 #18
0
ファイル: exceptions-x86.c プロジェクト: mhutch/mono
static void
altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf)
{
	MonoContext mctx;

	mctx = *ctx;

	mono_handle_exception (&mctx, obj);
	if (stack_ovf) {
		MonoJitTlsData *jit_tls = (MonoJitTlsData *) mono_tls_get_jit_tls ();
		jit_tls->stack_ovf_pending = 1;
		prepare_for_guard_pages (&mctx);
	}
	mono_restore_context (&mctx);
}
コード例 #19
0
ファイル: exceptions-x86.c プロジェクト: AveProjVstm/MonoVstm
gboolean
mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
{
	MonoContext mctx;

	mono_arch_sigctx_to_monoctx (sigctx, &mctx);

	if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj))
		return TRUE;

	mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only);

	mono_arch_monoctx_to_sigctx (&mctx, sigctx);

	return TRUE;
}
コード例 #20
0
static void
altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, gboolean stack_ovf)
{
	MonoContext mctx;
	MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), MONO_CONTEXT_GET_IP (ctx), NULL);

	if (!ji)
		mono_handle_native_sigsegv (SIGSEGV, NULL, NULL);

	mctx = *ctx;

	mono_handle_exception (&mctx, obj);
	if (stack_ovf)
		prepare_for_guard_pages (&mctx);
	mono_restore_context (&mctx);
}
コード例 #21
0
/*
 * handle_exception:
 *
 *   Called by resuming from a signal handler.
 */
static void
handle_signal_exception (gpointer obj, gboolean test_only)
{
	MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
	MonoContext ctx;
	static void (*restore_context) (MonoContext *);

	if (!restore_context)
		restore_context = mono_get_restore_context ();

	memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));

	mono_handle_exception (&ctx, obj, MONO_CONTEXT_GET_IP (&ctx), test_only);

	restore_context (&ctx);
}
コード例 #22
0
ファイル: exceptions-ppc.c プロジェクト: medo64/mono
gboolean
mono_arch_handle_exception (void *ctx, gpointer obj)
{
#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_REG_Rn)
	/*
	 * 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 ();
	mgreg_t sp;
	void *sigctx = ctx;
	int frame_size;
	void *uc = sigctx;

	/* Pass the ctx parameter in TLS */
	mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
	/* The others in registers */
	UCONTEXT_REG_Rn (sigctx, PPC_FIRST_ARG_REG) = (gsize)obj;

	/* Allocate a stack frame below the red zone */
	/* Similar to mono_arch_handle_altstack_exception () */
	frame_size = 224;
	frame_size += 15;
	frame_size &= ~15;
	sp = (mgreg_t)(UCONTEXT_REG_Rn(uc, 1) & ~15);
	sp = (mgreg_t)(sp - frame_size);
	UCONTEXT_REG_Rn(uc, 1) = (mgreg_t)sp;
	setup_ucontext_return (uc, handle_signal_exception);

	return TRUE;
#else
	MonoContext mctx;
	gboolean result;

	mono_sigctx_to_monoctx (ctx, &mctx);

	result = mono_handle_exception (&mctx, obj);
	/* restore the context so that returning from the signal handler will invoke
	 * the catch clause 
	 */
	mono_monoctx_to_sigctx (&mctx, ctx);
	return result;
#endif
}
コード例 #23
0
ファイル: exceptions-x86.c プロジェクト: efcastrillon/mono
/*
 * handle_exception:
 *
 *   Called by resuming from a signal handler.
 */
static void
handle_signal_exception (gpointer obj)
{
	MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
	MonoContext ctx;
	static void (*restore_context) (MonoContext *);

	if (!restore_context)
		restore_context = mono_get_restore_context ();

	memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));

	if (mono_debugger_handle_exception (&ctx, (MonoObject *)obj))
		return;

	mono_handle_exception (&ctx, obj);

	restore_context (&ctx);
}
コード例 #24
0
ファイル: exceptions-mips.c プロジェクト: LogosBible/mono
static void
throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean rethrow, gboolean preserve_ips)
{
	ERROR_DECL (error);
	MonoContext ctx;

#ifdef DEBUG_EXCEPTIONS
	g_print ("throw_exception: exc=%p eip=%p esp=%p rethrow=%d\n",
		 exc, (void *)eip, (void *) esp, rethrow);
#endif

	/* adjust eip so that it point into the call instruction */
	eip -= 8;

	memset (&ctx, 0, sizeof (MonoContext));

	/*g_print  ("stack in throw: %p\n", esp);*/
	memcpy (&ctx.sc_regs, (void *)(esp + MIPS_STACK_PARAM_OFFSET),
		sizeof (gulong) * MONO_SAVED_GREGS);
	memset (&ctx.sc_fpregs, 0, sizeof (mips_freg) * MONO_SAVED_FREGS);
	MONO_CONTEXT_SET_IP (&ctx, eip);

	if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow) {
			mono_ex->stack_trace = NULL;
			mono_ex->trace_ips = NULL;
		} if (preserve_ips) {
			mono_ex->caught_in_unmanaged = TRUE;
		}
	}
	mono_error_assert_ok (error);
	mono_handle_exception (&ctx, exc);
#ifdef DEBUG_EXCEPTIONS
	g_print ("throw_exception: restore to pc=%p sp=%p fp=%p ctx=%p\n",
		 (void *) ctx.sc_pc, (void *) ctx.sc_regs[mips_sp],
		 (void *) ctx.sc_regs[mips_fp], &ctx);
#endif
	mono_restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #25
0
/*
 * This is the function called from the signal handler
 */
gboolean
mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only)
{
#if defined(MONO_CROSS_COMPILE)
	g_assert_not_reached ();
#elif defined(MONO_ARCH_USE_SIGACTION)
	arm_ucontext *sigctx = ctx;
	/*
	 * 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_SP (sigctx);

	/* Pass the ctx parameter in TLS */
	mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
	/* The others in registers */
	UCONTEXT_REG_R0 (sigctx) = (gsize)obj;
	UCONTEXT_REG_R1 (sigctx) = test_only;

	/* Allocate a stack frame */
	sp -= 16;
	UCONTEXT_REG_SP (sigctx) = sp;

	UCONTEXT_REG_PC (sigctx) = (gsize)handle_signal_exception;

	return TRUE;
#else
	MonoContext mctx;
	gboolean result;

	mono_arch_sigctx_to_monoctx (ctx, &mctx);

	result = mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only);
	/* restore the context so that returning from the signal handler will invoke
	 * the catch clause 
	 */
	mono_arch_monoctx_to_sigctx (&mctx, ctx);
	return result;
#endif
}
コード例 #26
0
static void
altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf)
{
	void (*restore_context) (MonoContext *);
	MonoContext mctx;

	restore_context = mono_get_restore_context ();
	mono_arch_sigctx_to_monoctx (sigctx, &mctx);

	if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) {
		if (stack_ovf)
			prepare_for_guard_pages (&mctx);
		restore_context (&mctx);
	}

	mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, FALSE);
	if (stack_ovf)
		prepare_for_guard_pages (&mctx);
	restore_context (&mctx);
}
コード例 #27
0
ファイル: exceptions-x86.c プロジェクト: efcastrillon/mono
static void
altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf)
{
	void (*restore_context) (MonoContext *);
	MonoContext mctx;

	restore_context = mono_get_restore_context ();
	mctx = *ctx;

	if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) {
		if (stack_ovf)
			prepare_for_guard_pages (&mctx);
		restore_context (&mctx);
	}

	mono_handle_exception (&mctx, obj);
	if (stack_ovf)
		prepare_for_guard_pages (&mctx);
	restore_context (&mctx);
}
コード例 #28
0
ファイル: exceptions-mips.c プロジェクト: moander/mono
static void
throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean rethrow)
{
	static void (*restore_context) (MonoContext *);
	MonoContext ctx;

#ifdef DEBUG_EXCEPTIONS
	g_print ("throw_exception: exc=%p eip=%p esp=%p rethrow=%d\n",
		 exc, (void *)eip, (void *) esp, rethrow);
#endif

	if (!restore_context)
		restore_context = mono_get_restore_context ();

	/* adjust eip so that it point into the call instruction */
	eip -= 8;

	setup_context (&ctx);

	/*g_print  ("stack in throw: %p\n", esp);*/
	memcpy (&ctx.sc_regs, (void *)(esp + MIPS_STACK_PARAM_OFFSET),
		sizeof (gulong) * MONO_SAVED_GREGS);
	memset (&ctx.sc_fpregs, 0, sizeof (mips_freg) * MONO_SAVED_FREGS);
	MONO_CONTEXT_SET_IP (&ctx, eip);

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow)
			mono_ex->stack_trace = NULL;
	}
	mono_handle_exception (&ctx, exc, (void *)eip, FALSE);
#ifdef DEBUG_EXCEPTIONS
	g_print ("throw_exception: restore to pc=%p sp=%p fp=%p ctx=%p\n",
		 (void *) ctx.sc_pc, (void *) ctx.sc_regs[mips_sp],
		 (void *) ctx.sc_regs[mips_fp], &ctx);
#endif
	restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #29
0
/*
 * mono_x86_throw_exception:
 *
 *   C function called from the throw trampolines.
 */
void
mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, 
						  mgreg_t eip, gboolean rethrow)
{
	MonoError error;
	MonoContext ctx;

	ctx.esp = regs [X86_ESP];
	ctx.eip = eip;
	ctx.ebp = regs [X86_EBP];
	ctx.edi = regs [X86_EDI];
	ctx.esi = regs [X86_ESI];
	ctx.ebx = regs [X86_EBX];
	ctx.edx = regs [X86_EDX];
	ctx.ecx = regs [X86_ECX];
	ctx.eax = regs [X86_EAX];

#ifdef __APPLE__
	/* The OSX ABI specifies 16 byte alignment at call sites */
	g_assert ((ctx.esp % MONO_ARCH_FRAME_ALIGNMENT) == 0);
#endif

	if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow) {
			mono_ex->stack_trace = NULL;
			mono_ex->trace_ips = NULL;
		}
	}
	mono_error_assert_ok (&error);

	/* adjust eip so that it point into the call instruction */
	ctx.eip -= 1;

	mono_handle_exception (&ctx, exc);

	mono_restore_context (&ctx);

	g_assert_not_reached ();
}
コード例 #30
0
ファイル: exceptions-arm64.c プロジェクト: mono/mono
/*
 * mono_arm_throw_exception:
 *
 *   This function is called by the exception trampolines.
 * FP_REGS points to the 8 callee saved fp regs.
 */
void
mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow)
{
    MonoError error;
    MonoContext ctx;
    MonoObject *exc = NULL;
    guint32 ex_token_index, ex_token;

    if (!corlib)
        exc = arg;
    else {
        ex_token_index = (guint64)arg;
        ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index;
        exc = (MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token);
    }

    /* Adjust pc so it points into the call instruction */
    pc -= 4;

    /* Initialize a ctx based on the arguments */
    memset (&ctx, 0, sizeof (MonoContext));
    memcpy (&(ctx.regs [0]), int_regs, sizeof (mgreg_t) * 32);
    memcpy (&(ctx.fregs [ARMREG_D8]), fp_regs, sizeof (double) * 8);
    ctx.has_fregs = 1;
    ctx.pc = pc;

    if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
        MonoException *mono_ex = (MonoException*)exc;
        if (!rethrow) {
            mono_ex->stack_trace = NULL;
            mono_ex->trace_ips = NULL;
        }
    }
    mono_error_assert_ok (&error);

    mono_handle_exception (&ctx, exc);

    mono_restore_context (&ctx);
}