X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions-ia64.c;h=85c7792be30fae4b8258fc864f744cab998efead;hb=ce992c6c6fd36ae236298c819e324bab81129642;hp=326520187d26db10bed250e15c0eb5937fae9fb0;hpb=8cd1f5e0973ffe4c2180becc8c510acfb9342b30;p=mono.git diff --git a/mono/mini/exceptions-ia64.c b/mono/mini/exceptions-ia64.c index 326520187d2..85c7792be30 100644 --- a/mono/mini/exceptions-ia64.c +++ b/mono/mini/exceptions-ia64.c @@ -37,12 +37,10 @@ #define ALIGN_TO(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) -#define NOT_IMPLEMENTED g_assert_not_reached () - #define GP_SCRATCH_REG 31 #define GP_SCRATCH_REG2 30 -static void +G_GNUC_UNUSED static void print_ctx (MonoContext *ctx) { char name[256]; @@ -92,8 +90,12 @@ restore_context (MonoContext *ctx) * Returns a pointer to a method which restores a previously saved sigcontext. */ gpointer -mono_arch_get_restore_context (void) +mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) { + g_assert (!aot); + if (info) + *info = NULL; + return restore_context; } @@ -101,8 +103,8 @@ static gpointer get_real_call_filter (void) { static gpointer filter; + static gboolean inited = FALSE; guint8 *start; - gboolean inited = FALSE; Ia64CodegenState code; int in0, local0, out0, nout; unw_dyn_info_t *di; @@ -116,17 +118,18 @@ get_real_call_filter (void) /* int call_filter (guint64 fp, guint64 ip) */ /* - * We have to create a register+stack frame similar to the frame which contains - * the filter. + * We have to create a register+stack frame similar to the frame which + * contains the filter. * - setting fp * - setting up a register stack frame - * These cannot be set up in this function, because the fp register is a stacked - * register which is different in each method. Also, the register stack frame is - * different in each method. So we pass the FP value in a a non-stacked - * register and the code generated by the OP_START_HANDLER opcode will copy it - * to the appropriate register after setting up the register stack frame. + * These cannot be set up in this function, because the fp register is a + * stacked register which is different in each method. Also, the register + * stack frame is different in each method. So we pass the FP value in a a + * non-stacked register and the code generated by the OP_START_HANDLER + * opcode will copy it to the appropriate register after setting up the + * register stack frame. * The stacked registers are not need to be set since variables used in - * handler registers are never allocated to registers. + * handler regions are never allocated to registers. */ in0 = 32; @@ -152,25 +155,13 @@ get_real_call_filter (void) /* Target ip */ ia64_mov_to_br (code, IA64_B6, in0 + 1); - /* Return address */ - ia64_mov_from_ip (code, GP_SCRATCH_REG); - ia64_adds_imm (code, GP_SCRATCH_REG, 3 * 16, GP_SCRATCH_REG); - /* Call the filter */ ia64_br_call_reg (code, IA64_B0, IA64_B6); /* R8 contains the result of the filter */ - /* R9 contains the saved apr_pfs value */ /* FIXME: Add unwind info for this */ - /* The filter returns using br_cond_reg, so have to do another return */ - ia64_mov_to_ar_i (code, IA64_PFS, IA64_R9); - ia64_mov_from_ip (code, GP_SCRATCH_REG); - ia64_adds_imm (code, GP_SCRATCH_REG, 4 * 16, GP_SCRATCH_REG); - ia64_mov_to_br (code, IA64_B0, GP_SCRATCH_REG); - ia64_br_ret_reg (code, IA64_B0); - ia64_begin_bundle (code); r_body = mono_ia64_create_unwind_region (&code); @@ -229,8 +220,12 @@ call_filter (MonoContext *ctx, gpointer ip) * @exc object in this case). */ gpointer -mono_arch_get_call_filter (void) +mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) { + g_assert (!aot); + if (info) + *info = NULL; + /* Initialize the real filter non-lazily */ get_real_call_filter (); @@ -269,7 +264,7 @@ throw_exception (MonoObject *exc, guint64 rethrow) res = unw_get_reg (&ctx.cursor, UNW_IA64_SP, &sp); g_assert (res == 0); - ji = mono_jit_info_table_find (mono_domain_get (), (gpointer)ip); + ji = mini_jit_info_table_find (mono_domain_get (), (gpointer)ip, NULL); //printf ("UN: %s %lx %lx\n", ji ? ji->method->name : "", ip, sp); @@ -287,8 +282,9 @@ throw_exception (MonoObject *exc, guint64 rethrow) } g_assert (res >= 0); } + ctx.precise_ip = FALSE; - mono_handle_exception (&ctx, exc, (gpointer)(ip), FALSE); + mono_handle_exception (&ctx, exc); restore_context (&ctx); g_assert_not_reached (); @@ -366,56 +362,24 @@ get_throw_trampoline (gboolean rethrow) * signature: void (*func) (MonoException *exc); * */ -gpointer -mono_arch_get_throw_exception (void) +gpointer +mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { - static guint8* start; - static gboolean inited = FALSE; - - if (inited) - return start; + g_assert (!aot); + if (info) + *info = NULL; - start = get_throw_trampoline (FALSE); - - inited = TRUE; - - return start; + return get_throw_trampoline (FALSE); } -gpointer -mono_arch_get_rethrow_exception (void) +gpointer +mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { - static guint8* start; - static gboolean inited = FALSE; - - if (inited) - return start; - - start = get_throw_trampoline (TRUE); + g_assert (!aot); + if (info) + *info = NULL; - inited = TRUE; - - return start; -} - -gpointer -mono_arch_get_throw_exception_by_name (void) -{ - guint8* start; - Ia64CodegenState code; - - start = mono_global_codeman_reserve (64); - - /* Not used on ia64 */ - ia64_codegen_init (code, start); - ia64_break_i (code, 1001); - ia64_codegen_close (code); - - g_assert ((code.buf - start) <= 256); - - mono_arch_flush_icache (start, code.buf - start); - - return start; + return get_throw_trampoline (TRUE); } /** @@ -423,24 +387,29 @@ mono_arch_get_throw_exception_by_name (void) * * 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); + * signature: void (*func) (guint32 ex_token_index, guint32 offset); * Here, 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. */ -gpointer -mono_arch_get_throw_corlib_exception (void) +gpointer +mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { - static guint8* start; + static guint8* res; static gboolean inited = FALSE; + guint8 *start; gpointer ptr; int i, in0, local0, out0, nout; Ia64CodegenState code; unw_dyn_info_t *di; unw_dyn_region_info_t *r_pro; + g_assert (!aot); + if (info) + *info = NULL; + if (inited) - return start; + return res; start = mono_global_codeman_reserve (1024); @@ -466,6 +435,8 @@ mono_arch_get_throw_corlib_exception (void) /* Call exception_from_token */ ia64_movl (code, out0 + 0, mono_defaults.exception_class->image); ia64_mov (code, out0 + 1, in0 + 0); + ia64_movl (code, GP_SCRATCH_REG, MONO_TOKEN_TYPE_DEF); + ia64_add (code, out0 + 1, in0 + 0, GP_SCRATCH_REG); ptr = mono_exception_from_token; ia64_movl (code, GP_SCRATCH_REG, ptr); ia64_ld8_inc_imm (code, GP_SCRATCH_REG2, GP_SCRATCH_REG, 8); @@ -510,71 +481,71 @@ mono_arch_get_throw_corlib_exception (void) mono_arch_flush_icache (start, code.buf - start); - return ia64_create_ftnptr (start); + res = ia64_create_ftnptr (start); + inited = TRUE; + + return res; } -/* mono_arch_find_jit_info: +/* + * mono_arch_find_jit_info: * - * This function is used to gather information from @ctx. It return 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, char **trace, MonoLMF **lmf, int *native_offset, - 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; int err; unw_word_t ip; - *new_ctx = *ctx; - - while (TRUE) { - err = unw_get_reg (&new_ctx->cursor, UNW_IA64_IP, &ip); - g_assert (err == 0); - - /* Avoid costly table lookup during stack overflow */ - if (prev_ji && ((guint8*)ip > (guint8*)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, (gpointer)ip); + memset (frame, 0, sizeof (StackFrameInfo)); + frame->ji = ji; - if (managed) - *managed = FALSE; - - /* - { - char name[256]; - unw_word_t off; + *new_ctx = *ctx; + new_ctx->precise_ip = FALSE; - unw_get_proc_name (&new_ctx->cursor, name, 256, &off); - printf ("F: %s\n", name); - } - */ + if (!ji) { + while (TRUE) { + err = unw_get_reg (&new_ctx->cursor, UNW_IA64_IP, &ip); + g_assert (err == 0); - if (ji != NULL) { - if (managed) - if (!ji->method->wrapper_type) - *managed = TRUE; + ji = mini_jit_info_table_find (domain, (gpointer)ip, NULL); - break; + /* + { + char name[256]; + unw_word_t off; + + unw_get_proc_name (&new_ctx->cursor, name, 256, &off); + printf ("F: %s\n", name); + } + */ + + if (ji) + break; + + /* This is an unmanaged frame, so just unwind through it */ + /* FIXME: This returns -3 for the __clone2 frame in libc */ + err = unw_step (&new_ctx->cursor); + if (err < 0) + break; + + if (err == 0) + break; } - - /* This is an unmanaged frame, so just unwind through it */ - /* FIXME: This returns -3 for the __clone2 frame in libc */ - err = unw_step (&new_ctx->cursor); - if (err < 0) - break; - - if (err == 0) - break; } if (ji) { + frame->type = FRAME_TYPE_MANAGED; + frame->ji = ji; + //print_ctx (new_ctx); err = unw_step (&new_ctx->cursor); @@ -582,10 +553,10 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf //print_ctx (new_ctx); - return ji; + return TRUE; } else - return (gpointer)(gssize)-1; + return FALSE; } /** @@ -595,7 +566,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf * @obj: the exception object */ gboolean -mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) +mono_arch_handle_exception (void *sigctx, gpointer obj) { /* libunwind takes care of this */ unw_context_t unw_ctx; @@ -617,7 +588,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) res = unw_get_reg (&ctx.cursor, UNW_IA64_IP, &ip); g_assert (res == 0); - ji = mono_jit_info_table_find (mono_domain_get (), (gpointer)ip); + ji = mini_jit_info_table_find (mono_domain_get (), (gpointer)ip, NULL); if (ji) break; @@ -625,8 +596,9 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) res = unw_step (&ctx.cursor); g_assert (res >= 0); } + ctx.precise_ip = TRUE; - mono_handle_exception (&ctx, obj, (gpointer)ip, test_only); + mono_handle_exception (&ctx, obj); restore_context (&ctx); @@ -636,16 +608,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) gpointer mono_arch_ip_from_context (void *sigctx) { - /* On IA64, these two are equal */ - unw_context_t *ctx = (unw_context_t*)sigctx; - unw_cursor_t cursor; - int res; - unw_word_t w; - - res = unw_init_local (&cursor, ctx); - g_assert (res == 0); - res = unw_get_reg (&cursor, UNW_IA64_IP, &w); - g_assert (res == 0); + ucontext_t *ctx = (ucontext_t*)sigctx; - return (gpointer)w; + return (gpointer)ctx->uc_mcontext.sc_ip; }