X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions-arm.c;h=de769c87fff8d41d8af7e149f6173e65d1568f8a;hb=d295ab661864a5dee77a97d298bf2dde09c94de1;hp=b478a713bc5e108ea30e7d59ed5e4a2f8c24a9c0;hpb=b16bcb6332458610a13bb749b277f042ade32de2;p=mono.git diff --git a/mono/mini/exceptions-arm.c b/mono/mini/exceptions-arm.c index b478a713bc5..de769c87fff 100644 --- a/mono/mini/exceptions-arm.c +++ b/mono/mini/exceptions-arm.c @@ -1,5 +1,6 @@ -/* - * exceptions-arm.c: exception support for ARM +/** + * \file + * exception support for ARM * * Authors: * Dietmar Maurer (dietmar@ximian.com) @@ -14,9 +15,9 @@ #include #ifndef MONO_CROSS_COMPILE -#ifdef HAVE_ASM_SIGCONTEXT_H +#ifdef HOST_ANDROID #include -#endif /* def HAVE_ASM_SIGCONTEXT_H */ +#endif /* def HOST_ANDROID */ #endif #ifdef HAVE_UCONTEXT_H @@ -111,6 +112,8 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) ARM_MOV_REG_REG (code, ARMREG_IP, ARMREG_SP); ARM_PUSH (code, MONO_ARM_REGSAVE_MASK); + ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8); + /* restore all the regs from ctx (in r0), but not sp, the stack pointer */ ctx_reg = ARMREG_R0; ARM_LDR_IMM (code, ARMREG_IP, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, pc)); @@ -121,6 +124,8 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC); ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R1); + ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8); + /* epilog */ ARM_POP_NWB (code, 0xff0 | ((1 << ARMREG_SP) | (1 << ARMREG_PC))); @@ -137,6 +142,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) void mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs) { + MonoError error; MonoContext ctx; gboolean rethrow = sp & 1; @@ -152,25 +158,27 @@ mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_ memcpy (((guint8*)&ctx.regs) + (ARMREG_R4 * sizeof (mgreg_t)), int_regs, 8 * sizeof (mgreg_t)); memcpy (&ctx.fregs, fp_regs, sizeof (double) * 16); - if (mono_object_isinst (exc, mono_defaults.exception_class)) { + if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) { MonoException *mono_ex = (MonoException*)exc; if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } } + mono_error_assert_ok (&error); mono_handle_exception (&ctx, exc); mono_restore_context (&ctx); g_assert_not_reached (); } void -mono_arm_throw_exception_by_token (guint32 type_token, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs) +mono_arm_throw_exception_by_token (guint32 ex_token_index, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs) { + guint32 ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index; /* Clear thumb bit */ pc &= ~1; - mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, type_token), pc, sp, int_regs, fp_regs); + mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token), pc, sp, int_regs, fp_regs); } void @@ -245,9 +253,15 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm /* exc is already in place in r0 */ if (corlib) { /* The caller ip is already in R1 */ - if (llvm) - /* Negate the ip adjustment done in mono_arm_throw_exception */ - ARM_ADD_REG_IMM8 (code, ARMREG_R1, ARMREG_R1, 4); + if (llvm) { + /* + * The address passed by llvm might point to before the call, + * thus outside the eh range recorded by llvm. Use the return + * address instead. + * FIXME: Do this on more platforms. + */ + ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR); /* caller ip */ + } } else { ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR); /* caller ip */ } @@ -323,11 +337,10 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) /** * mono_arch_get_throw_corlib_exception: - * - * Returns a function pointer which can be used to raise + * \returns a function pointer which can be used to raise * corlib exceptions. The returned function has the following * signature: void (*func) (guint32 ex_token, guint32 offset); - * Here, offset is the offset which needs to be substracted from the caller IP + * Here, \c offset is the offset which needs to be substracted from the caller IP * to get the IP of the throw. Passing the offset has the advantage that it * needs no relocations in the caller. * On ARM, the ip is passed instead of an offset. @@ -452,20 +465,24 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, } else if (*lmf) { if (((gsize)(*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)); + if (ext->debugger_invoke) { + /* + * This LMF entry is created by the soft debug code to mark transitions to + * managed code done during invokes. + */ + frame->type = FRAME_TYPE_DEBUGGER_INVOKE; + memcpy (new_ctx, &ext->ctx, sizeof (MonoContext)); + } else if (ext->interp_exit) { + frame->type = FRAME_TYPE_INTERP_TO_MANAGED; + frame->interp_exit_data = ext->interp_exit_data; + } else { + g_assert_not_reached (); + } *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); - frame->type = FRAME_TYPE_DEBUGGER_INVOKE; - return TRUE; } @@ -514,7 +531,7 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, static void handle_signal_exception (gpointer obj) { - MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + MonoJitTlsData *jit_tls = mono_tls_get_jit_tls (); MonoContext ctx; memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext)); @@ -549,7 +566,7 @@ mono_arch_handle_exception (void *ctx, gpointer obj) * signal is disabled, and we could run arbitrary code though the debugger. So * resume into the normal stack and do most work there if possible. */ - MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + MonoJitTlsData *jit_tls = mono_tls_get_jit_tls (); guint64 sp = UCONTEXT_REG_SP (sigctx); /* Pass the ctx parameter in TLS */ @@ -592,8 +609,6 @@ mono_arch_ip_from_context (void *sigctx) { #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); -#elif defined(__native_client__) - g_assert_not_reached (); #else arm_ucontext *my_uc = sigctx; return (void*) UCONTEXT_REG_PC (my_uc);