void mono_trace_enter_method (MonoMethod *method, char *ebp) { int i, j; MonoClass *klass; MonoObject *o; MonoJitArgumentInfo *arg_info; MonoMethodSignature *sig; char *fname; MonoGenericSharingContext *gsctx = NULL; if (!trace_spec.enabled) return; while (output_lock != 0 || InterlockedCompareExchange (&output_lock, 1, 0) != 0) mono_thread_info_yield (); fname = mono_method_full_name (method, TRUE); indent (1); printf ("ENTER: %s(", fname); g_free (fname); if (!ebp) { printf (") ip: %p\n", RETURN_ADDRESS_N (1)); goto unlock; } sig = mono_method_signature (method); arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1)); if (method->is_inflated) { /* FIXME: Might be better to pass the ji itself */ MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (), NULL); if (ji) { gsctx = mono_jit_info_get_generic_sharing_context (ji); if (gsctx && gsctx->is_gsharedvt) { /* Needs a ctx to get precise method */ printf (") <gsharedvt>\n"); goto unlock; } } } mono_arch_get_argument_info (sig, sig->param_count, arg_info); if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)) { g_assert (!mono_method_signature (method)->ret->byref); printf ("VALUERET:%p, ", *((gpointer *)(ebp + 8))); } if (mono_method_signature (method)->hasthis) { gpointer *this = (gpointer *)(ebp + arg_info [0].offset); if (method->klass->valuetype) { printf ("value:%p, ", *arg_in_stack_slot(this, gpointer *)); } else {
void mono_trace_enter_method (MonoMethod *method, char *ebp) { int i, j; MonoClass *class; MonoObject *o; MonoJitArgumentInfo *arg_info; MonoMethodSignature *sig; char *fname; if (!trace_spec.enabled) return; fname = mono_method_full_name (method, TRUE); indent (1); printf ("ENTER: %s(", fname); g_free (fname); if (!ebp) { printf (") ip: %p\n", __builtin_return_address (1)); return; } sig = mono_method_signature (method); arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1)); mono_arch_get_argument_info (sig, sig->param_count, arg_info); if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)) { g_assert (!mono_method_signature (method)->ret->byref); printf ("VALUERET:%p, ", *((gpointer *)(ebp + 8))); } if (mono_method_signature (method)->hasthis) { gpointer *this = (gpointer *)(ebp + arg_info [0].offset); if (method->klass->valuetype) { printf ("value:%p, ", *arg_in_stack_slot(this, gpointer *)); } else {
/* * mono_arch_find_jit_info: * * See exceptions-amd64.c for docs. */ gboolean mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *ji, MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf, mgreg_t **save_locations, StackFrameInfo *frame) { gpointer ip = MONO_CONTEXT_GET_IP (ctx); memset (frame, 0, sizeof (StackFrameInfo)); frame->ji = ji; *new_ctx = *ctx; if (ji != NULL) { gssize regs [MONO_MAX_IREGS + 1]; guint8 *cfa; guint32 unwind_info_len; guint8 *unwind_info; frame->type = FRAME_TYPE_MANAGED; if (ji->from_aot) unwind_info = mono_aot_get_unwind_info (ji, &unwind_info_len); else unwind_info = mono_get_cached_unwind_info (ji->used_regs, &unwind_info_len); regs [X86_EAX] = new_ctx->eax; regs [X86_EBX] = new_ctx->ebx; regs [X86_ECX] = new_ctx->ecx; regs [X86_EDX] = new_ctx->edx; regs [X86_ESP] = new_ctx->esp; regs [X86_EBP] = new_ctx->ebp; regs [X86_ESI] = new_ctx->esi; regs [X86_EDI] = new_ctx->edi; regs [X86_NREG] = new_ctx->eip; mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, (guint8*)ji->code_start + ji->code_size, ip, regs, MONO_MAX_IREGS + 1, save_locations, MONO_MAX_IREGS, &cfa); new_ctx->eax = regs [X86_EAX]; new_ctx->ebx = regs [X86_EBX]; new_ctx->ecx = regs [X86_ECX]; new_ctx->edx = regs [X86_EDX]; new_ctx->esp = regs [X86_ESP]; new_ctx->ebp = regs [X86_EBP]; new_ctx->esi = regs [X86_ESI]; new_ctx->edi = regs [X86_EDI]; new_ctx->eip = regs [X86_NREG]; /* The CFA becomes the new SP value */ new_ctx->esp = (gssize)cfa; /* Adjust IP */ new_ctx->eip --; if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) { /* remove any unused lmf */ *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); } /* Pop arguments off the stack */ /* * FIXME: LLVM doesn't push these, we can't use ji->from_llvm as it describes * the callee. */ #ifndef ENABLE_LLVM if (ji->has_arch_eh_info) new_ctx->esp += mono_jit_info_get_arch_eh_info (ji)->stack_size; #endif return TRUE; } else if (*lmf) { if (((guint64)(*lmf)->previous_lmf) & 2) { /* * This LMF entry is created by the soft debug code to mark transitions to * managed code done during invokes. */ MonoLMFExt *ext = (MonoLMFExt*)(*lmf); g_assert (ext->debugger_invoke); memcpy (new_ctx, &ext->ctx, sizeof (MonoContext)); *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); frame->type = FRAME_TYPE_DEBUGGER_INVOKE; return TRUE; } if ((ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL))) { } else { if (!((guint32)((*lmf)->previous_lmf) & 1)) /* Top LMF entry */ return FALSE; g_assert_not_reached (); /* Trampoline lmf frame */ frame->method = (*lmf)->method; } new_ctx->esi = (*lmf)->esi; new_ctx->edi = (*lmf)->edi; new_ctx->ebx = (*lmf)->ebx; new_ctx->ebp = (*lmf)->ebp; new_ctx->eip = (*lmf)->eip; /* Adjust IP */ new_ctx->eip --; frame->ji = ji; frame->type = FRAME_TYPE_MANAGED_TO_NATIVE; /* Check if we are in a trampoline LMF frame */ if ((guint32)((*lmf)->previous_lmf) & 1) { /* lmf->esp is set by the trampoline code */ new_ctx->esp = (*lmf)->esp; /* Pop arguments off the stack */ /* FIXME: Handle the delegate case too ((*lmf)->method == NULL) */ /* FIXME: Handle the IMT/vtable case too */ #if 0 #ifndef ENABLE_LLVM if ((*lmf)->method) { MonoMethod *method = (*lmf)->method; MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, mono_method_signature (method)->param_count + 1); guint32 stack_to_pop = mono_arch_get_argument_info (NULL, mono_method_signature (method), mono_method_signature (method)->param_count, arg_info); new_ctx->esp += stack_to_pop; } #endif #endif } else /* 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->esp = (unsigned long)&((*lmf)->eip); *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); return TRUE; } return FALSE; }