Пример #1
0
void
mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data)
{
    mgreg_t sp = (mgreg_t)MONO_CONTEXT_GET_SP (ctx);

    // FIXME:
    g_assert (!user_data);

    /* Allocate a stack frame */
    sp -= 32;
    MONO_CONTEXT_SET_SP (ctx, sp);

    mono_arch_setup_resume_sighandler_ctx (ctx, async_cb);
}
Пример #2
0
void
mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data)
{
	mgreg_t sp = (mgreg_t)MONO_CONTEXT_GET_SP (ctx);

	// FIXME:
	g_assert (!user_data);

	/* Allocate a stack frame */
	sp -= 16;
	MONO_CONTEXT_SET_SP (ctx, sp);
	MONO_CONTEXT_SET_IP (ctx, async_cb);

	// FIXME: thumb/arm
}
Пример #3
0
void
mono_arm_resume_unwind (guint32 dummy1, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs)
{
	MonoContext ctx;

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

	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));

	mono_resume_unwind (&ctx);
}
Пример #4
0
static void
mono_arm_resume_unwind (guint32 dummy1, unsigned long eip, unsigned long esp, gulong *int_regs, gdouble *fp_regs)
{
	MonoContext ctx;

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

	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);

	mono_resume_unwind (&ctx);
}
Пример #5
0
/* mono_arch_find_jit_info:
 *
 * This function is used to gather information from @ctx. It returns the 
 * MonoJitInfo of the corresponding function, unwinds one stack frame and
 * stores the resulting context into @new_ctx. It also stores a string 
 * describing the stack location into @trace (if not NULL), and modifies
 * the @lmf if necessary. @native_offset return the IP offset from the 
 * start of the function or -1 if that info is not available.
 */
MonoJitInfo *
mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
			 MonoJitInfo *res, MonoJitInfo *prev_ji,
			 MonoContext *ctx, MonoContext *new_ctx,
			 MonoLMF **lmf, gboolean *managed)
{
	MonoJitInfo *ji;
	gpointer ip = MONO_CONTEXT_GET_IP (ctx);
	gpointer fp = MONO_CONTEXT_GET_BP (ctx);
	guint32 sp;

	/* Avoid costly table lookup during stack overflow */
	if (prev_ji && (ip > prev_ji->code_start && ((guint8*)ip < ((guint8*)prev_ji->code_start) + prev_ji->code_size)))
		ji = prev_ji;
	else
		ji = mini_jit_info_table_find (domain, ip, NULL);

	if (managed)
		*managed = FALSE;

	memcpy (new_ctx, ctx, sizeof (MonoContext));

	if (ji != NULL) {
		int i;
		gint32 address;
		int offset = 0;

		if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
			/* remove any unused lmf */
			*lmf = (*lmf)->previous_lmf;
		}

		address = (char *)ip - (char *)ji->code_start;

		if (managed)
			if (!ji->method->wrapper_type)
				*managed = TRUE;

		/* My stack frame */
		fp = MONO_CONTEXT_GET_BP (ctx);

		/* Compute the previous stack frame */
		sp = (guint32)(fp) - (short)(*(guint32 *)(ji->code_start));

		/* Sanity check the frame */
		if (!sp || (sp == 0xffffffff)
		    || (sp & 0x07) || (sp < 64*1024)) {
#ifdef DEBUG_EXCEPTIONS
			g_print ("mono_arch_find_jit_info: bad stack sp=%p\n", (void *) sp);
#endif
			return (gpointer)-1;
		}

		if (ji->method->save_lmf && 0) {
			/* only enable this when prologue stops emitting
			 * normal save of s-regs when save_lmf is true.
			 * Will have to sync with prologue code at that point.
			 */
			memcpy (&new_ctx->sc_fpregs,
				(char*)sp - sizeof (float) * MONO_SAVED_FREGS,
				sizeof (float) * MONO_SAVED_FREGS);
			memcpy (&new_ctx->sc_regs,
				(char*)sp - sizeof (float) * MONO_SAVED_FREGS - sizeof (gulong) * MONO_SAVED_GREGS,
				sizeof (gulong) * MONO_SAVED_GREGS);
		} else if (ji->used_regs) {
			guint32 *insn;
			guint32 mask = ji->used_regs;

			/* these all happen before adjustment of fp */
			/* Look for sw ??, ????(sp) */
			insn = ((guint32 *)ji->code_start) + 1;
			while (!*insn || ((*insn & 0xffe00000) == 0xafa00000) || ((*insn & 0xffe00000) == 0xffa00000)) {
				int reg = (*insn >> 16) & 0x1f;
				guint32 addr = (((guint32)fp) + (short)(*insn & 0x0000ffff));

				mask &= ~(1 << reg);
				if ((*insn & 0xffe00000) == 0xafa00000)
					new_ctx->sc_regs [reg] = *(guint32 *)addr;
				else
					new_ctx->sc_regs [reg] = *(guint64 *)addr;
				insn++;
			}
			MONO_CONTEXT_SET_SP (new_ctx, sp);
			MONO_CONTEXT_SET_BP (new_ctx, sp);
			/* assert that we found all registers we were supposed to */
			g_assert (!mask);
		}