X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions-mips.c;h=710125dcfd14d48f2ff00f39f0c73b251c323833;hb=5600f484aa032bddfe71c1d85a80a33a32ae4a92;hp=c99243f96914b5570abcf023a259c8f714b04fbc;hpb=50426d9016807ef62c243d3366e3cb4a9fdb4ac0;p=mono.git diff --git a/mono/mini/exceptions-mips.c b/mono/mini/exceptions-mips.c index c99243f9691..710125dcfd1 100644 --- a/mono/mini/exceptions-mips.c +++ b/mono/mini/exceptions-mips.c @@ -58,7 +58,7 @@ * The first argument in a0 is the pointer to the MonoContext. */ gpointer -mono_arch_get_restore_context (void) +mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) { int i; guint8 *code; @@ -66,6 +66,10 @@ mono_arch_get_restore_context (void) static int inited = 0; guint32 iregs_to_restore; + g_assert (!aot); + if (info) + *info = NULL; + if (inited) return start; inited = 1; @@ -108,7 +112,7 @@ mono_arch_get_restore_context (void) * handler (void) */ gpointer -mono_arch_get_call_filter (void) +mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) { static guint8 start [320]; static int inited = 0; @@ -116,6 +120,10 @@ mono_arch_get_call_filter (void) int alloc_size; int offset; + g_assert (!aot); + if (info) + *info = NULL; + if (inited) return start; @@ -193,7 +201,7 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean #endif if (!restore_context) - restore_context = mono_arch_get_restore_context (); + restore_context = mono_get_restore_context (); /* adjust eip so that it point into the call instruction */ eip -= 8; @@ -232,7 +240,7 @@ 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; @@ -265,11 +273,10 @@ mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gbo } } - 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); @@ -279,7 +286,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); @@ -308,11 +315,15 @@ mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gbo * */ gpointer -mono_arch_get_rethrow_exception (void) +mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { static guint8 start [GENERIC_EXCEPTION_SIZE]; static int inited = 0; + g_assert (!aot); + if (info) + *info = NULL; + if (inited) return start; mono_arch_get_throw_exception_generic (start, sizeof (start), FALSE, TRUE); @@ -332,12 +343,16 @@ mono_arch_get_rethrow_exception (void) * x86_call_code (code, arch_get_throw_exception ()); * */ -gpointer -mono_arch_get_throw_exception (void) +gpointer +mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { static guint8 start [GENERIC_EXCEPTION_SIZE]; static int inited = 0; + g_assert (!aot); + if (info) + *info = NULL; + if (inited) return start; mono_arch_get_throw_exception_generic (start, sizeof (start), FALSE, FALSE); @@ -345,101 +360,81 @@ 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) +gpointer +mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { static guint8 start [GENERIC_EXCEPTION_SIZE]; static int inited = 0; + g_assert (!aot); + if (info) + *info = NULL; + if (inited) return start; mono_arch_get_throw_exception_generic (start, sizeof (start), TRUE, FALSE); inited = 1; return start; -} - -static MonoArray * -glist_to_array (GList *list, MonoClass *eclass) -{ - MonoDomain *domain = mono_domain_get (); - MonoArray *res; - int len, i; - - if (!list) - return NULL; - - len = g_list_length (list); - res = mono_array_new (domain, eclass, len); - - for (i = 0; list; list = list->next, i++) - mono_array_set (res, gpointer, i, list->data); - - return res; } -/* mono_arch_find_jit_info: +/* + * 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. + * This function is used to gather information from @ctx, and store it in @frame_info. + * It unwinds one stack frame, and stores the resulting context into @new_ctx. @lmf + * is modified if needed. + * Returns TRUE on success, FALSE otherwise. */ -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) +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) { - 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 = mono_jit_info_table_find (domain, ip); - - if (managed) - *managed = FALSE; + memset (frame, 0, sizeof (StackFrameInfo)); + frame->ji = ji; - memcpy (new_ctx, ctx, sizeof (MonoContext)); + *new_ctx = *ctx; if (ji != NULL) { - int i; gint32 address; - int offset = 0; + gpointer ip = MONO_CONTEXT_GET_IP (ctx); + gpointer fp = MONO_CONTEXT_GET_BP (ctx); + guint32 sp; - if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) { + frame->type = FRAME_TYPE_MANAGED; + + if (*lmf && (fp >= (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 */ + /* Compute the previous stack frame, assuming method + * starts with addiu sp, sp, . */ sp = (guint32)(fp) - (short)(*(guint32 *)(ji->code_start)); /* Sanity check the frame */ @@ -448,7 +443,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, #ifdef DEBUG_EXCEPTIONS g_print ("mono_arch_find_jit_info: bad stack sp=%p\n", (void *) sp); #endif - return (gpointer)-1; + return FALSE; } if (ji->method->save_lmf && 0) { @@ -489,22 +484,26 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, 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; + g_assert (MONO_CONTEXT_GET_BP (new_ctx) != MONO_CONTEXT_GET_BP (ctx)); + return TRUE; } else if (*lmf) { if (!(*lmf)->method) { #ifdef DEBUG_EXCEPTIONS g_print ("mono_arch_find_jit_info: bad lmf @ %p\n", (void *) *lmf); #endif - return (gpointer)-1; + return FALSE; } 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)); - res->method = (*lmf)->method; + ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL); + if (!ji) { + // FIXME: This can happen with multiple appdomains (bug #444383) + return FALSE; } + + frame->ji = ji; + frame->type = FRAME_TYPE_MANAGED_TO_NATIVE; + memcpy (&new_ctx->sc_regs, (*lmf)->iregs, sizeof (gulong) * MONO_SAVED_GREGS); memcpy (&new_ctx->sc_fpregs, (*lmf)->fregs, sizeof (float) * MONO_SAVED_FREGS); MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip); @@ -512,10 +511,10 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, g_assert (new_ctx->sc_pc != ctx->sc_pc); *lmf = (*lmf)->previous_lmf; - return ji ? ji : res; + return TRUE; } - return NULL; + return FALSE; } void @@ -577,11 +576,3 @@ mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only) return result; } - - -gboolean -mono_arch_has_unwind_info (gconstpointer addr) -{ - return FALSE; -} -