X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions-amd64.c;h=22c0f5f0250a36996144a69589acf4ac3f79d493;hb=6644c191b8292d9a07227f182be9ce689c1848e2;hp=947aaacf09ab6f570376784cdccc5c88f16398e9;hpb=51161d85dce41ec3be0a3b03c7d4184c5eb7da5c;p=mono.git diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index 947aaacf09a..22c0f5f0250 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -264,12 +264,23 @@ throw_exception (MonoObject *exc, guint64 rip, guint64 rsp, ctx.r14 = r14; ctx.r15 = r15; - if (mono_debugger_throw_exception ((gpointer)(rip - 8), (gpointer)rsp, exc)) { + if (!rethrow && mono_debugger_throw_exception ((gpointer)(rip - 8), (gpointer)rsp, exc)) { /* * The debugger wants us to stop on the `throw' instruction. * By the time we get here, it already inserted a breakpoint on * eip - 8 (which is the address of the `mov %r15,%rdi ; callq throw'). */ + + /* FIXME FIXME + * + * In case of a rethrow, the JIT is emitting code like this: + * + * mov 0xffffffffffffffd0(%rbp),%rax' + * mov %rax,%rdi + * callq throw + * + * Here, restore_context() wouldn't restore the %rax register correctly. + */ ctx.rip = rip - 8; ctx.rsp = rsp + 8; restore_context (&ctx); @@ -470,6 +481,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf if (ji != NULL) { int offset; + gboolean omit_fp = (ji->used_regs & (1 << 31)) > 0; *new_ctx = *ctx; @@ -487,8 +499,10 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf * We only need to do this if the exception was raised in managed * code, since otherwise the lmf was already popped of the stack. */ - if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) { + if (*lmf && ((*lmf) != jit_tls->first_lmf) && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->rsp)) { + new_ctx->rbp = (*lmf)->ebp; new_ctx->rbx = (*lmf)->rbx; + new_ctx->rsp = (*lmf)->rsp; new_ctx->r12 = (*lmf)->r12; new_ctx->r13 = (*lmf)->r13; new_ctx->r14 = (*lmf)->r14; @@ -496,12 +510,21 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf } } else { - offset = -1; + offset = omit_fp ? 0 : -1; /* restore caller saved registers */ for (i = 0; i < AMD64_NREG; i ++) if (AMD64_IS_CALLEE_SAVED_REG (i) && (ji->used_regs & (1 << i))) { - guint64 reg = *((guint64 *)ctx->SC_EBP + offset); - offset --; + guint64 reg; + + if (omit_fp) { + reg = *((guint64*)ctx->rsp + offset); + offset ++; + } + else { + reg = *((guint64 *)ctx->SC_EBP + offset); + offset --; + } + switch (i) { case AMD64_RBX: new_ctx->rbx = reg; @@ -518,22 +541,34 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf case AMD64_R15: new_ctx->r15 = reg; break; + case AMD64_RBP: + new_ctx->rbp = reg; + break; default: g_assert_not_reached (); } } } - if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) { + if (*lmf && ((*lmf) != jit_tls->first_lmf) && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->rsp)) { /* remove any unused lmf */ *lmf = (*lmf)->previous_lmf; } - /* Pop EBP and the return address */ - new_ctx->SC_ESP = ctx->SC_EBP + (2 * sizeof (gpointer)); - /* we substract 1, so that the IP points into the call instruction */ - new_ctx->SC_EIP = *((guint64 *)ctx->SC_EBP + 1) - 1; - new_ctx->SC_EBP = *((guint64 *)ctx->SC_EBP); + if (omit_fp) { + /* Pop frame */ + new_ctx->rsp += (ji->used_regs >> 16) & (0x7fff); + new_ctx->SC_EIP = *((guint64 *)new_ctx->rsp) - 1; + /* Pop return address */ + new_ctx->rsp += 8; + } + else { + /* Pop EBP and the return address */ + new_ctx->SC_ESP = ctx->SC_EBP + (2 * sizeof (gpointer)); + /* we substract 1, so that the IP points into the call instruction */ + new_ctx->SC_EIP = *((guint64 *)ctx->SC_EBP + 1) - 1; + new_ctx->SC_EBP = *((guint64 *)ctx->SC_EBP); + } /* Pop arguments off the stack */ { @@ -559,6 +594,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf new_ctx->SC_RIP = (*lmf)->rip; new_ctx->SC_RBP = (*lmf)->ebp; + new_ctx->SC_ESP = (*lmf)->rsp; new_ctx->SC_RBX = (*lmf)->rbx; new_ctx->SC_R12 = (*lmf)->r12; @@ -566,10 +602,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf new_ctx->SC_R14 = (*lmf)->r14; new_ctx->SC_R15 = (*lmf)->r15; - /* the lmf is always stored on the stack, so the following - * expression points to a stack location which can be used as ESP */ - new_ctx->SC_ESP = ALIGN_TO ((guint64)&((*lmf)->rip), 16); - *lmf = (*lmf)->previous_lmf; return ji ? ji : res;