X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions-mips.c;h=13aff78f9de3f0b47a2541b7d32e58a4059ecfdb;hb=c2d511e567dd2d535056dc79b745f88b4fb64afa;hp=54a524a6e3905a87fea76d6d88e23559a5967909;hpb=1fb42c0c8772816f8abae8ac3b08144cd78f5827;p=mono.git diff --git a/mono/mini/exceptions-mips.c b/mono/mini/exceptions-mips.c index 54a524a6e39..13aff78f9de 100644 --- a/mono/mini/exceptions-mips.c +++ b/mono/mini/exceptions-mips.c @@ -4,7 +4,12 @@ * Authors: * Mark Mason (mason@broadcom.com) * + * Based on exceptions-ppc.c by: + * Dietmar Maurer (dietmar@ximian.com) + * Paolo Molaro (lupus@ximian.com) + * * (C) 2006 Broadcom + * (C) 2001 Ximian, Inc. */ #include @@ -26,10 +31,6 @@ #define GENERIC_EXCEPTION_SIZE 256 -#ifdef CUSTOM_EXCEPTION_HANDLING -static gboolean arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only); -#endif - /* XXX */ #if 1 #define restore_regs_from_context(ctx_reg,ip_reg,tmp_reg) do { \ @@ -63,23 +64,21 @@ mono_arch_get_restore_context (void) guint8 *code; static guint8 start [128]; static int inited = 0; + guint32 iregs_to_restore; if (inited) return start; inited = 1; code = start; + iregs_to_restore = (MONO_ARCH_CALLEE_SAVED_REGS \ + | (1 << mips_sp) | (1 << mips_ra)); for (i = 0; i < MONO_SAVED_GREGS; ++i) { - if (MONO_ARCH_CALLEE_SAVED_REGS & (1 << i)) { - mips_lw (code, i, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[i])); + if (iregs_to_restore & (1 << i)) { + MIPS_LW (code, i, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[i])); } } - /* restore also the sp, fp and ra */ - mips_lw (code, mips_sp, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_sp])); - mips_lw (code, mips_fp, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_fp])); - mips_lw (code, mips_ra, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_ra])); - /* Get the address to return to */ mips_lw (code, mips_t9, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_pc)); @@ -115,13 +114,12 @@ mono_arch_get_call_filter (void) static int inited = 0; guint8 *code; int alloc_size; - int offset = 16; + int offset; if (inited) return start; inited = 1; - code = start; alloc_size = 64; @@ -131,26 +129,27 @@ mono_arch_get_call_filter (void) mips_sw (code, mips_ra, mips_sp, alloc_size + MIPS_RET_ADDR_OFFSET); /* Save global registers on stack (s0 - s7) */ - mips_sw (code, mips_s0, mips_sp, offset); offset += 4; - mips_sw (code, mips_s1, mips_sp, offset); offset += 4; - mips_sw (code, mips_s2, mips_sp, offset); offset += 4; - mips_sw (code, mips_s3, mips_sp, offset); offset += 4; - mips_sw (code, mips_s4, mips_sp, offset); offset += 4; - mips_sw (code, mips_s5, mips_sp, offset); offset += 4; - mips_sw (code, mips_s6, mips_sp, offset); offset += 4; - mips_sw (code, mips_s7, mips_sp, offset); offset += 4; - mips_sw (code, mips_fp, mips_sp, offset); offset += 4; - - /* Restore global registers (s0-s7) */ - mips_lw (code, mips_s0, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s0])); - mips_lw (code, mips_s1, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s1])); - mips_lw (code, mips_s2, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s2])); - mips_lw (code, mips_s3, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s3])); - mips_lw (code, mips_s4, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s4])); - mips_lw (code, mips_s5, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s5])); - mips_lw (code, mips_s6, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s6])); - mips_lw (code, mips_s7, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s7])); - mips_lw (code, mips_fp, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_fp])); + offset = 16; + MIPS_SW (code, mips_s0, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_s1, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_s2, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_s3, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_s4, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_s5, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_s6, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_s7, mips_sp, offset); offset += IREG_SIZE; + MIPS_SW (code, mips_fp, mips_sp, offset); offset += IREG_SIZE; + + /* Restore global registers from MonoContext, including the frame pointer */ + MIPS_LW (code, mips_s0, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s0])); + MIPS_LW (code, mips_s1, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s1])); + MIPS_LW (code, mips_s2, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s2])); + MIPS_LW (code, mips_s3, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s3])); + MIPS_LW (code, mips_s4, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s4])); + MIPS_LW (code, mips_s5, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s5])); + MIPS_LW (code, mips_s6, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s6])); + MIPS_LW (code, mips_s7, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_s7])); + MIPS_LW (code, mips_fp, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[mips_fp])); /* a1 is the handler to call */ mips_move (code, mips_t9, mips_a1); @@ -161,15 +160,15 @@ mono_arch_get_call_filter (void) /* restore all regs from the stack */ offset = 16; - mips_lw (code, mips_s0, mips_sp, offset); offset += 4; - mips_lw (code, mips_s1, mips_sp, offset); offset += 4; - mips_lw (code, mips_s2, mips_sp, offset); offset += 4; - mips_lw (code, mips_s3, mips_sp, offset); offset += 4; - mips_lw (code, mips_s4, mips_sp, offset); offset += 4; - mips_lw (code, mips_s5, mips_sp, offset); offset += 4; - mips_lw (code, mips_s6, mips_sp, offset); offset += 4; - mips_lw (code, mips_s7, mips_sp, offset); offset += 4; - mips_lw (code, mips_fp, mips_sp, offset); offset += 4; + MIPS_LW (code, mips_s0, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_s1, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_s2, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_s3, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_s4, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_s5, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_s6, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_s7, mips_sp, offset); offset += IREG_SIZE; + MIPS_LW (code, mips_fp, mips_sp, offset); offset += IREG_SIZE; /* epilog */ mips_lw (code, mips_ra, mips_sp, alloc_size + MIPS_RET_ADDR_OFFSET); @@ -188,9 +187,9 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean static void (*restore_context) (MonoContext *); MonoContext ctx; -#if 0 - printf("throw_exception: exc=%p eip=%x esp=%x rethrow=%d\n", - exc, (unsigned int) eip, (unsigned int) esp, rethrow); +#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) @@ -201,14 +200,10 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean setup_context (&ctx); - /*printf ("stack in throw: %p\n", esp);*/ + /*g_print ("stack in throw: %p\n", esp);*/ memcpy (&ctx.sc_regs, (void *)(esp + MIPS_STACK_PARAM_OFFSET), sizeof (gulong) * MONO_SAVED_GREGS); -#if 0 - memcpy (&ctx.sc_fpregs, fp_regs, sizeof (float) * MONO_SAVED_FREGS); -#else - memset (&ctx.sc_fpregs, 0, sizeof (float) * MONO_SAVED_FREGS); -#endif + 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)) { @@ -216,10 +211,11 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean if (!rethrow) mono_ex->stack_trace = NULL; } -#ifdef CUSTOM_EXCEPTION_HANDLING - arch_handle_exception (&ctx, exc, FALSE); -#else 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); @@ -236,14 +232,14 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean * */ static gpointer -mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gboolean rethrow) +mono_arch_get_throw_exception_generic (guint8 *start, int size, int corlib, gboolean rethrow) { guint8 *code; int alloc_size, pos, i; code = start; - //printf("mono_arch_get_throw_exception_generic: code=%p\n", code); + //g_print ("mono_arch_get_throw_exception_generic: code=%p\n", code); pos = 0; /* XXX - save all the FP regs on the stack ? */ @@ -262,18 +258,17 @@ mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gbo /* Save all the regs on the stack */ for (i = 0; i < MONO_MAX_IREGS; i++) { if (i != mips_sp) - mips_sw (code, i, mips_sp, i*sizeof(guint32) + MIPS_STACK_PARAM_OFFSET); + MIPS_SW (code, i, mips_sp, i*IREG_SIZE + MIPS_STACK_PARAM_OFFSET); else { mips_addiu (code, mips_at, mips_sp, alloc_size); - mips_sw (code, mips_at, mips_sp, i*sizeof(guint32) + MIPS_STACK_PARAM_OFFSET); + MIPS_SW (code, mips_at, mips_sp, i*IREG_SIZE + MIPS_STACK_PARAM_OFFSET); } } - if (by_name) { - mips_move (code, mips_a2, mips_a0); + if (corlib) { + mips_move (code, mips_a1, mips_a0); mips_load (code, mips_a0, mono_defaults.corlib); - mips_load (code, mips_a1, "System"); - mips_load (code, mips_t9, mono_exception_from_name); + mips_load (code, mips_t9, mono_exception_from_token); mips_jalr (code, mips_t9, mips_ra); mips_nop (code); mips_move (code, mips_a0, mips_v0); @@ -283,7 +278,7 @@ mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gbo /* exc is already in place in a0 */ /* pointer to ip */ - if (by_name) + if (corlib) mips_lw (code, mips_a1, mips_sp, alloc_size + MIPS_RET_ADDR_OFFSET); else mips_move (code, mips_a1, mips_ra); @@ -349,20 +344,29 @@ mono_arch_get_throw_exception (void) return start; } +gpointer +mono_arch_get_throw_exception_by_name (void) +{ + guint8 *start, *code; + int size = 64; + + /* Not used on MIPS */ + start = code = mono_global_codeman_reserve (size); + mips_break (code, 0xfd); + mono_arch_flush_icache (start, code - start); + return start; +} + /** - * arch_get_throw_exception_by_name: + * mono_arch_get_throw_corlib_exception: * * Returns a function pointer which can be used to raise * corlib exceptions. The returned function has the following - * signature: void (*func) (char *exc_name); - * For example to raise an arithmetic exception you can use: - * - * x86_push_imm (code, "ArithmeticException"); - * x86_call_code (code, arch_get_throw_exception_by_name ()); - * + * signature: void (*func) (guint32 ex_token, guint32 offset); + * On MIPS, the offset argument is missing. */ gpointer -mono_arch_get_throw_exception_by_name (void) +mono_arch_get_throw_corlib_exception (void) { static guint8 start [GENERIC_EXCEPTION_SIZE]; static int inited = 0; @@ -406,11 +410,11 @@ MonoJitInfo * mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, MonoContext *new_ctx, - char **trace, MonoLMF **lmf, - int *native_offset, gboolean *managed) + 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 */ @@ -419,23 +423,16 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, else ji = mono_jit_info_table_find (domain, ip); - if (trace) - *trace = NULL; - - if (native_offset) - *native_offset = -1; - if (managed) *managed = FALSE; + memcpy (new_ctx, ctx, sizeof (MonoContext)); + if (ji != NULL) { int i; gint32 address; int offset = 0; - *new_ctx = *ctx; - setup_context (new_ctx); - if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) { /* remove any unused lmf */ *lmf = (*lmf)->previous_lmf; @@ -443,69 +440,84 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, address = (char *)ip - (char *)ji->code_start; - if (native_offset) - *native_offset = address; - if (managed) if (!ji->method->wrapper_type) *managed = TRUE; - if (trace) { - *trace = mono_debug_print_stack_frame (ji->method, offset, domain); - } + /* My stack frame */ + fp = MONO_CONTEXT_GET_BP (ctx); + /* Compute the previous stack frame */ - sp = (guint32)(MONO_CONTEXT_GET_BP (ctx)) - (short)(*(guint32 *)(ji->code_start)); + sp = (guint32)(fp) - (short)(*(guint32 *)(ji->code_start)); /* Sanity check the frame */ if (!sp || (sp == 0xffffffff) - || (sp & 0x07) || (sp < 64*1024)) + || (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; - MONO_CONTEXT_SET_BP (new_ctx, sp); + } if (ji->method->save_lmf && 0) { - 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); + /* 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) { - /* keep updated with emit_prolog in mini-mips.c */ - offset = 0; - /* FIXME handle floating point args */ - for (i = 0; i < MONO_MAX_IREGS; i++) { - new_ctx->sc_regs [i] = 0; + 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++; } - new_ctx->sc_regs [mips_fp] = sp; - new_ctx->sc_regs [mips_sp] = sp; - new_ctx->sc_regs [mips_ra] = *(guint32 *)(sp-4); + 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); } /* we substract 8, so that the IP points into the call instruction */ MONO_CONTEXT_SET_IP (new_ctx, new_ctx->sc_regs[mips_ra] - 8); + /* Sanity check -- we should have made progress here */ + g_assert (new_ctx->sc_pc != ctx->sc_pc); return ji; } else if (*lmf) { - - *new_ctx = *ctx; - setup_context (new_ctx); - - if (!(*lmf)->method) + if (!(*lmf)->method) { +#ifdef DEBUG_EXCEPTIONS + g_print ("mono_arch_find_jit_info: bad lmf @ %p\n", (void *) *lmf); +#endif return (gpointer)-1; - - if (trace) { - char *fname = mono_method_full_name ((*lmf)->method, TRUE); - *trace = g_strdup_printf ("in (unmanaged) %s", fname); - g_free (fname); } - + g_assert (((*lmf)->magic == MIPS_LMF_MAGIC1) || ((*lmf)->magic == MIPS_LMF_MAGIC2)); + if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) { } else { - memset (res, 0, sizeof (MonoJitInfo)); + memset (res, 0, MONO_SIZEOF_JIT_INFO); res->method = (*lmf)->method; } - -#if 0 memcpy (&new_ctx->sc_regs, (*lmf)->iregs, sizeof (gulong) * MONO_SAVED_GREGS); memcpy (&new_ctx->sc_fpregs, (*lmf)->fregs, sizeof (float) * MONO_SAVED_FREGS); -#endif - MONO_CONTEXT_SET_BP (new_ctx, (*lmf)->ebp); MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip); + /* ensure that we've made progress */ + g_assert (new_ctx->sc_pc != ctx->sc_pc); *lmf = (*lmf)->previous_lmf; return ji ? ji : res; @@ -514,127 +526,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, return NULL; } -#ifdef CUSTOM_STACK_WALK - -void -mono_jit_walk_stack (MonoStackWalk func, gboolean do_il_offset, gpointer user_data) { - MonoDomain *domain = mono_domain_get (); - MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); - MonoLMF *lmf = jit_tls->lmf; - MonoJitInfo *ji, rji; - gint native_offset, il_offset; - gboolean managed; - MonoMipsStackFrame *sframe; - - MonoContext ctx, new_ctx; - - setup_context (&ctx); - setup_context (&new_ctx); - - MONO_INIT_CONTEXT_FROM_FUNC (&ctx, mono_jit_walk_stack); - MONO_INIT_CONTEXT_FROM_FUNC (&new_ctx, mono_jit_walk_stack); - - while (MONO_CONTEXT_GET_BP (&ctx) < jit_tls->end_of_stack) { - - ji = mono_find_jit_info (domain, jit_tls, &rji, NULL, &ctx, &new_ctx, NULL, &lmf, &native_offset, &managed); - g_assert (ji); - - if (ji == (gpointer)-1) - return; - - if (do_il_offset) { - MonoDebugSourceLocation *source; - - source = mono_debug_lookup_source_location (ji->method, native_offset, domain); - il_offset = source ? source->il_offset : -1; - mono_debug_free_source_location (source); - } else - il_offset = -1; - - if (func (ji->method, native_offset, il_offset, managed, user_data)) - return; - - ctx = new_ctx; - setup_context (&ctx); - } -} - - -MonoBoolean -ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info, - MonoReflectionMethod **method, - gint32 *iloffset, gint32 *native_offset, - MonoString **file, gint32 *line, gint32 *column) -{ - MonoDomain *domain = mono_domain_get (); - MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); - MonoLMF *lmf = jit_tls->lmf; - MonoJitInfo *ji, rji; - MonoContext ctx, new_ctx; - MonoMipsStackFrame *sframe; - MonoDebugSourceLocation *location; - -#if 0 -#ifdef __APPLE__ - __asm__ volatile("lwz %0,0(r1)" : "=r" (sframe)); -#else - __asm__ volatile("lwz %0,0(1)" : "=r" (sframe)); -#endif -#endif - MONO_CONTEXT_SET_BP (&ctx, sframe->sp); - sframe = (MonoMipsStackFrame*)sframe->sp; - MONO_CONTEXT_SET_IP (&ctx, sframe->ra); - /*MONO_CONTEXT_SET_IP (&ctx, ves_icall_get_frame_info); - MONO_CONTEXT_SET_BP (&ctx, __builtin_frame_address (0));*/ - - skip++; - - do { - ji = mono_find_jit_info (domain, jit_tls, &rji, NULL, &ctx, &new_ctx, NULL, &lmf, native_offset, NULL); - - ctx = new_ctx; - - if (!ji || ji == (gpointer)-1 || MONO_CONTEXT_GET_BP (&ctx) >= jit_tls->end_of_stack) - return FALSE; - - /* skip all wrappers ??*/ - if (ji->method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE || - ji->method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK || - ji->method->wrapper_type == MONO_WRAPPER_XDOMAIN_INVOKE || - ji->method->wrapper_type == MONO_WRAPPER_XDOMAIN_DISPATCH || - ji->method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE) - continue; - - skip--; - - } while (skip >= 0); - - *method = mono_method_get_object (domain, ji->method, NULL); - - location = mono_debug_lookup_source_location (ji->method, *native_offset, domain); - if (location) - *iloffset = location->il_offset; - else - *iloffset = 0; - - if (need_file_info) { - if (location) { - *file = mono_string_new (domain, location->source_file); - *line = location->row; - *column = location->column; - } else { - *file = NULL; - *line = *column = 0; - } - } - - mono_debug_free_source_location (location); - - return TRUE; -} - -#endif /* CUSTOM_STACK_WALK */ - void mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { @@ -664,8 +555,8 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) gpointer mono_arch_ip_from_context (void *sigctx) { - struct ucontext *uc = sigctx; - return (gpointer)(guint32)uc->uc_mcontext.pc; + struct sigcontext *ctx = (struct sigcontext *)sigctx; + return (gpointer)(guint32)ctx->sc_pc; } /* @@ -678,13 +569,15 @@ mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only) gboolean result; mono_arch_sigctx_to_monoctx (ctx, &mctx); -#ifdef CUSTOM_EXCEPTION_HANDLING - result = arch_handle_exception (&mctx, obj, test_only); -#else +#ifdef DEBUG_EXCEPTIONS + g_print ("mono_arch_handle_exception: pc=%p\n", (void *) mctx.sc_pc); +#endif mono_handle_exception (&mctx, obj, (gpointer)mctx.sc_pc, test_only); result = TRUE; -#endif +#ifdef DEBUG_EXCEPTIONS + g_print ("mono_arch_handle_exception: restore pc=%p\n", (void *)mctx.sc_pc); +#endif /* restore the context so that returning from the signal handler * will invoke the catch clause */ @@ -693,175 +586,6 @@ mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only) return result; } -#ifdef CUSTOM_EXCEPTION_HANDLING -/** - * arch_handle_exception: - * @ctx: saved processor state - * @obj: the exception object - * @test_only: only test if the exception is caught, but dont call handlers - * - * - */ -static gboolean -arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only) -{ - MonoDomain *domain = mono_domain_get (); - MonoJitInfo *ji, rji; - static int (*call_filter) (MonoContext *, gpointer, gpointer) = NULL; - MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id); - MonoLMF *lmf = jit_tls->lmf; - GList *trace_ips = NULL; - MonoException *mono_ex; - MonoArray *initial_trace_ips = NULL; - int frame_count = 0; - gboolean has_dynamic_methods = FALSE; - - g_assert (ctx != NULL); - if (!obj) { - MonoException *ex = mono_get_exception_null_reference (); - ex->message = mono_string_new (domain, - "Object reference not set to an instance of an object"); - obj = (MonoObject *)ex; - } - - if (mono_object_isinst (obj, mono_defaults.exception_class)) { - mono_ex = (MonoException*)obj; - initial_trace_ips = mono_ex->trace_ips; - } else { - mono_ex = NULL; - } - - - if (!call_filter) - call_filter = mono_arch_get_call_filter (); - - g_assert (jit_tls->end_of_stack); - g_assert (jit_tls->abort_func); - - if (!test_only) { - MonoContext ctx_cp = *ctx; - setup_context (&ctx_cp); - if (mono_jit_trace_calls != NULL) - g_print ("EXCEPTION handling: %s\n", mono_object_class (obj)->name); - if (!arch_handle_exception (&ctx_cp, obj, TRUE)) { - if (mono_break_on_exc) - G_BREAKPOINT (); - mono_unhandled_exception (obj); - } - } - - memset (&rji, 0, sizeof (rji)); - - while (1) { - MonoContext new_ctx; - - setup_context (&new_ctx); - ji = mono_arch_find_jit_info (domain, jit_tls, &rji, &rji, ctx, &new_ctx, - NULL, &lmf, NULL, NULL); - if (!ji) { - g_warning ("Exception inside function without unwind info"); - g_assert_not_reached (); - } - - if (ji != (gpointer)-1) { - frame_count ++; - - if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && mono_ex) { - /* - * Avoid overwriting the stack trace if the exception is - * rethrown. Also avoid giant stack traces during a stack - * overflow. - */ - if (!initial_trace_ips && (frame_count < 1000)) { - trace_ips = g_list_prepend (trace_ips, MONO_CONTEXT_GET_IP (ctx)); - - } - } - - if (ji->method->dynamic) - has_dynamic_methods = TRUE; - - if (ji->num_clauses) { - int i; - - g_assert (ji->clauses); - - for (i = 0; i < ji->num_clauses; i++) { - MonoJitExceptionInfo *ei = &ji->clauses [i]; - gboolean filtered = FALSE; - - if (ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && - MONO_CONTEXT_GET_IP (ctx) <= ei->try_end) { - /* catch block */ - - if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)) { - /* store the exception object int cfg->excvar */ - g_assert (ei->exvar_offset); - /* need to use the frame pointer (mips_fp): methods with clauses always have mips_fp */ - *((gpointer *)(void*)((char *)(ctx->sc_regs [mips_fp]) + ei->exvar_offset)) = obj; - } - - if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) - filtered = call_filter (ctx, ei->data.filter, mono_ex); - - if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE && - mono_object_isinst (obj, ei->data.catch_class)) || filtered) { - if (test_only) { - if (mono_ex && !initial_trace_ips) { - trace_ips = g_list_reverse (trace_ips); - mono_ex->trace_ips = glist_to_array (trace_ips, mono_defaults.int_class); - if (has_dynamic_methods) - /* These methods could go away anytime, so compute the stack trace now */ - mono_ex->stack_trace = ves_icall_System_Exception_get_trace (mono_ex); - } - g_list_free (trace_ips); - return TRUE; - } - if (mono_jit_trace_calls != NULL) - g_print ("EXCEPTION: catch found at clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE)); - /*printf ("stack for catch: %p\n", MONO_CONTEXT_GET_BP (ctx));*/ - MONO_CONTEXT_SET_IP (ctx, ei->handler_start); - jit_tls->lmf = lmf; - return 0; - } - if (!test_only && ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && - MONO_CONTEXT_GET_IP (ctx) < ei->try_end && - (ei->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) { - if (mono_jit_trace_calls != NULL) - g_print ("EXCEPTION: finally clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE)); - call_filter (ctx, ei->handler_start, NULL); - } - - } - } - } - } - - *ctx = new_ctx; - setup_context (ctx); - - if ((ji == (gpointer)-1) || MONO_CONTEXT_GET_BP (ctx) >= jit_tls->end_of_stack) { - if (!test_only) { - jit_tls->lmf = lmf; - jit_tls->abort_func (obj); - g_assert_not_reached (); - } else { - if (mono_ex && !initial_trace_ips) { - trace_ips = g_list_reverse (trace_ips); - mono_ex->trace_ips = glist_to_array (trace_ips, mono_defaults.int_class); - if (has_dynamic_methods) - /* These methods could go away anytime, so compute the stack trace now */ - mono_ex->stack_trace = ves_icall_System_Exception_get_trace (mono_ex); - } - g_list_free (trace_ips); - return FALSE; - } - } - } - - g_assert_not_reached (); -} -#endif /* CUSTOM_EXCEPTION_HANDLING */ gboolean mono_arch_has_unwind_info (gconstpointer addr)