Example #1
0
void
mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
{
	os_ucontext *uc = sigctx;

	UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
	UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
	memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
	memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
}
Example #2
0
void
mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
{
	os_ucontext *uc = sigctx;

	mctx->sc_ir = UCONTEXT_REG_NIP(uc);
	mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);

	memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 0), sizeof (mgreg_t) * MONO_MAX_IREGS);
	memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 0), sizeof (double) * MONO_MAX_FREGS);
}
Example #3
0
void
mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
{
	os_ucontext *uc = sigctx;

	memcpy (&UCONTEXT_REG_Rn(uc, 0), &mctx->regs, sizeof (mgreg_t) * MONO_MAX_IREGS);
	memcpy (&UCONTEXT_REG_FPRn(uc, 0), &mctx->fregs, sizeof (double) * MONO_MAX_FREGS);

	/* The valid values for pc and sp are stored here and not in regs array */
	UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
	UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
}
Example #4
0
void
mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
{
#ifdef MONO_CROSS_COMPILE
	g_assert_not_reached ();
#else
	os_ucontext *uc = ctx;

	UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
	UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
	memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
	memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
#endif
}
Example #5
0
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
}
Example #6
0
static void
setup_ucontext_return (void *uc, gpointer func)
{
#if !defined(MONO_CROSS_COMPILE)
	UCONTEXT_REG_LNK(uc) = UCONTEXT_REG_NIP(uc);
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
	{
		MonoPPCFunctionDescriptor *handler_ftnptr = (MonoPPCFunctionDescriptor*)func;

		UCONTEXT_REG_NIP(uc) = (gulong)handler_ftnptr->code;
		UCONTEXT_REG_Rn(uc, 2) = (gulong)handler_ftnptr->toc;
	}
#else
	UCONTEXT_REG_NIP(uc) = (unsigned long)func;
#if _CALL_ELF == 2
	/* ELF v2 ABI calling convention requires to put the target address into
	* r12 if we use the global entry point of a function. */
	UCONTEXT_REG_Rn(uc, 12) = (unsigned long) func;
#endif
#endif
#endif
}
Example #7
0
void
mono_ppc_set_func_into_sigctx (void *sigctx, void *func)
{
#ifdef MONO_CROSS_COMPILE
	g_assert_not_reached ();
#elif defined(PPC_USES_FUNCTION_DESCRIPTOR)
	/* Have to set both the ip and the TOC reg */
	os_ucontext *uc = sigctx;

	UCONTEXT_REG_NIP(uc) = ((gsize*)func) [0];
	UCONTEXT_REG_Rn (uc, 2) = ((gsize*)func)[1];
#else
	g_assert_not_reached ();
#endif
}
Example #8
0
static void
setup_ucontext_return (void *uc, gpointer func)
{
#if !defined(MONO_CROSS_COMPILE)
	UCONTEXT_REG_LNK(uc) = UCONTEXT_REG_NIP(uc);
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
	{
		MonoPPCFunctionDescriptor *handler_ftnptr = (MonoPPCFunctionDescriptor*)func;

		UCONTEXT_REG_NIP(uc) = (gulong)handler_ftnptr->code;
		UCONTEXT_REG_Rn(uc, 2) = (gulong)handler_ftnptr->toc;
	}
#else
	UCONTEXT_REG_NIP(uc) = (unsigned long)func;
#endif
#endif
}
Example #9
0
void
mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *siginfo, gpointer fault_addr, gboolean stack_ovf)
{
#ifdef MONO_CROSS_COMPILE
	g_assert_not_reached ();
#else
#ifdef MONO_ARCH_USE_SIGACTION
	os_ucontext *uc = (ucontext_t*)sigctx;
	os_ucontext *uc_copy;
	MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (sigctx), NULL);
	gpointer *sp;
	int frame_size;

	if (stack_ovf) {
		const char *method;
		/* we don't do much now, but we can warn the user with a useful message */
		fprintf (stderr, "Stack overflow: IP: %p, SP: %p\n", mono_arch_ip_from_context (sigctx), (gpointer)UCONTEXT_REG_Rn(uc, 1));
		if (ji && !ji->is_trampoline && jinfo_get_method (ji))
			method = mono_method_full_name (jinfo_get_method (ji), TRUE);
		else
			method = "Unmanaged";
		fprintf (stderr, "At %s\n", method);
		abort ();
	}
	if (!ji)
		mono_handle_native_crash ("SIGSEGV", sigctx, siginfo);
	/* setup a call frame on the real stack so that control is returned there
	 * and exception handling can continue.
	 * The frame looks like:
	 *   ucontext struct
	 *   ...
	 * 224 is the size of the red zone
	 */
	frame_size = sizeof (ucontext_t) + sizeof (gpointer) * 16 + 224;
	frame_size += 15;
	frame_size &= ~15;
	sp = (gpointer)(UCONTEXT_REG_Rn(uc, 1) & ~15);
	sp = (gpointer)((char*)sp - frame_size);
	/* may need to adjust pointers in the new struct copy, depending on the OS */
	uc_copy = (ucontext_t*)(sp + 16);
	memcpy (uc_copy, uc, sizeof (os_ucontext));
#if defined(__linux__) && !defined(__mono_ppc64__)
	uc_copy->uc_mcontext.uc_regs = (gpointer)((char*)uc_copy + ((char*)uc->uc_mcontext.uc_regs - (char*)uc));
#endif
	g_assert (mono_arch_ip_from_context (uc) == mono_arch_ip_from_context (uc_copy));
	/* at the return form the signal handler execution starts in altstack_handle_and_restore() */
	UCONTEXT_REG_LNK(uc) = UCONTEXT_REG_NIP(uc);
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
	{
		MonoPPCFunctionDescriptor *handler_ftnptr = (MonoPPCFunctionDescriptor*)altstack_handle_and_restore;

		UCONTEXT_REG_NIP(uc) = (gulong)handler_ftnptr->code;
		UCONTEXT_REG_Rn(uc, 2) = (gulong)handler_ftnptr->toc;
	}
#else
	UCONTEXT_REG_NIP(uc) = (unsigned long)altstack_handle_and_restore;
#if _CALL_ELF == 2
	/* ELF v2 ABI calling convention requires to put the target address into
	* r12 if we use the global entry point of a function. */
	UCONTEXT_REG_Rn(uc, 12) = (unsigned long) altstack_handle_and_restore;
#endif
#endif
	UCONTEXT_REG_Rn(uc, 1) = (unsigned long)sp;
	UCONTEXT_REG_Rn(uc, PPC_FIRST_ARG_REG) = (unsigned long)(sp + 16);
	UCONTEXT_REG_Rn(uc, PPC_FIRST_ARG_REG + 1) = 0;
	UCONTEXT_REG_Rn(uc, PPC_FIRST_ARG_REG + 2) = 0;
#endif

#endif /* !MONO_CROSS_COMPILE */
}