2009-11-19 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Thu, 19 Nov 2009 15:18:32 +0000 (15:18 -0000)
committerZoltan Varga <vargaz@gmail.com>
Thu, 19 Nov 2009 15:18:32 +0000 (15:18 -0000)
* unwind.c: Fix support for ppc.

* exceptions-ppc.c (mono_arch_find_jit_info): Change this to use dwarf frame
unwind info. Change to the mono_arch_find_jit_info_ext () interface.

svn path=/trunk/mono/; revision=146545

mono/mini/ChangeLog
mono/mini/exceptions-ppc.c
mono/mini/mini-ppc.h
mono/mini/unwind.c

index 26f45a70ba1c57cb90f6dcb8f8589412e9d4d116..5e7f3297a6ee9dcc9bfe043b10048fb4627494a4 100644 (file)
@@ -1,3 +1,10 @@
+2009-11-19  Zoltan Varga  <vargaz@gmail.com>
+
+       * unwind.c: Fix support for ppc.
+
+       * exceptions-ppc.c (mono_arch_find_jit_info): Change this to use dwarf frame
+       unwind info. Change to the mono_arch_find_jit_info_ext () interface.
+
 2009-11-19  Zoltan Varga  <vargaz@gmail.com>
 
        * mini-ppc.c (mono_arch_emit_prolog): Fix a copy-paste error to fix the ppc64
index 0ca9161103a227c338fe5bfab806f0d9c8841da7..6e9202be32bf387d2bfefc272931d43029c5bdfd 100644 (file)
@@ -527,49 +527,43 @@ mono_arch_get_throw_corlib_exception_full (guint32 *code_size, MonoJumpInfo **ji
        return mono_arch_get_throw_exception_generic (size, code_size, ji, TRUE, FALSE, aot);
 }
 
-/* mono_arch_find_jit_info:
+/*
+ * mono_arch_find_jit_info_ext:
  *
- * 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.
+ * See exceptions-amd64.c for docs.
  */
-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_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, 
+                                                        MonoJitInfo *ji, MonoContext *ctx, 
+                                                        MonoContext *new_ctx, MonoLMF **lmf, 
+                                                        StackFrameInfo *frame)
 {
-       MonoJitInfo *ji;
        gpointer ip = MONO_CONTEXT_GET_IP (ctx);
        MonoPPCStackFrame *sframe;
 
-       /* 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 = mini_jit_info_table_find (domain, ip, NULL);
+       memset (frame, 0, sizeof (StackFrameInfo));
+       frame->ji = ji;
+       frame->managed = FALSE;
 
-       if (managed)
-               *managed = FALSE;
+       *new_ctx = *ctx;
+       setup_context (new_ctx);
 
        if (ji != NULL) {
-               gint32 address;
-               int offset, i;
+               int i;
+               gssize regs [ppc_lr + 1];
+               guint8 *cfa;
+               guint32 unwind_info_len;
+               guint8 *unwind_info;
 
-               *new_ctx = *ctx;
-               setup_context (new_ctx);
+               frame->type = FRAME_TYPE_MANAGED;
 
-               if (*lmf && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->ebp)) {
-                       /* remove any unused lmf */
-                       *lmf = (*lmf)->previous_lmf;
-               }
-
-               address = (char *)ip - (char *)ji->code_start;
+               if (!ji->method->wrapper_type || ji->method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)
+                       frame->managed = TRUE;
 
-               if (managed)
-                       if (!ji->method->wrapper_type)
-                               *managed = TRUE;
+               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);
 
                sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_SP (ctx);
                MONO_CONTEXT_SET_BP (new_ctx, sframe->sp);
@@ -578,41 +572,43 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                        guint8 *lmf_addr = (guint8*)sframe->sp - sizeof (MonoLMF);
                        memcpy (&new_ctx->fregs, lmf_addr + G_STRUCT_OFFSET (MonoLMF, fregs), sizeof (double) * MONO_SAVED_FREGS);
                        memcpy (&new_ctx->regs, lmf_addr + G_STRUCT_OFFSET (MonoLMF, iregs), sizeof (mgreg_t) * MONO_SAVED_GREGS);
-               } else if (ji->used_regs) {
-                       /* keep updated with emit_prolog in mini-ppc.c */
-                       offset = 0;
-                       /* FIXME handle floating point args 
-                       for (i = 31; i >= 14; --i) {
-                               if (ji->used_fregs & (1 << i)) {
-                                       offset += sizeof (double);
-                                       new_ctx->fregs [i - 14] = *(gulong*)((char*)sframe->sp - offset);
-                               }
-                       }*/
-                       for (i = 31; i >= 13; --i) {
-                               if (ji->used_regs & (1 << i)) {
-                                       offset += sizeof (mgreg_t);
-                                       new_ctx->regs [i - 13] = *(mgreg_t*)((char*)sframe->sp - offset);
-                               }
-                       }
+                       /* the calling IP is in the parent frame */
+                       sframe = (MonoPPCStackFrame*)sframe->sp;
+                       /* we substract 4, so that the IP points into the call instruction */
+                       MONO_CONTEXT_SET_IP (new_ctx, sframe->lr - 4);
+               } else {
+                       regs [ppc_lr] = ctx->sc_ir;
+                       regs [ppc_sp] = ctx->sc_sp;
+                       for (i = 0; i < MONO_SAVED_GREGS; ++i)
+                               regs [ppc_r13 + i] = ctx->regs [i];
+
+                       mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, 
+                                                          (guint8*)ji->code_start + ji->code_size,
+                                                          ip, regs, MONO_MAX_IREGS + 1, &cfa);
+
+                       /* we substract 4, so that the IP points into the call instruction */
+                       MONO_CONTEXT_SET_IP (new_ctx, regs [ppc_lr] - 4);
+                       MONO_CONTEXT_SET_BP (new_ctx, cfa);
+
+                       for (i = 0; i < MONO_SAVED_GREGS; ++i)
+                               new_ctx->regs [i] = regs [ppc_r13 + i];
+               }
+
+               if (*lmf && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->ebp)) {
+                       /* remove any unused lmf */
+                       *lmf = (*lmf)->previous_lmf;
                }
-               /* the calling IP is in the parent frame */
-               sframe = (MonoPPCStackFrame*)sframe->sp;
-               /* we substract 4, so that the IP points into the call instruction */
-               MONO_CONTEXT_SET_IP (new_ctx, sframe->lr - 4);
 
-               return ji;
+               return TRUE;
        } else if (*lmf) {
                
-               *new_ctx = *ctx;
-               setup_context (new_ctx);
-
                if ((ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL))) {
                } else {
                        if (!(*lmf)->method)
-                               return (gpointer)-1;
+                               return FALSE;
 
-                       memset (res, 0, MONO_SIZEOF_JIT_INFO);
-                       res->method = (*lmf)->method;
+                       /* Trampoline lmf frame */
+                       frame->method = (*lmf)->method;
                }
 
                /*sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_SP (ctx);
@@ -623,14 +619,17 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                memcpy (&new_ctx->regs, (*lmf)->iregs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
                memcpy (&new_ctx->fregs, (*lmf)->fregs, sizeof (double) * MONO_SAVED_FREGS);
 
+               frame->ji = ji;
+               frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
+
                /* FIXME: what about trampoline LMF frames?  see exceptions-x86.c */
 
                *lmf = (*lmf)->previous_lmf;
 
-               return ji ? ji : res;
+               return TRUE;
        }
 
-       return NULL;
+       return FALSE;
 }
 
 /*
index f6046df7f6be12cefe4e4b21f1adc04d73334b01..acb62051864f0f110091d8a5cba70b452243e758 100644 (file)
@@ -193,6 +193,8 @@ typedef struct MonoCompileArch {
 
 #define MONO_ARCH_HAVE_STATIC_RGCTX_TRAMPOLINE 1
 #define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
+#define MONO_ARCH_HAVE_XP_UNWIND 1
+#define MONO_ARCH_HAVE_FIND_JIT_INFO_EXT 1
 
 #define MONO_ARCH_GSHARED_SUPPORTED 1
 
index 47294a0deeac3c4ae47cd004479cbf043b0e28f0..981a254511529de6fb93536b248306c015d1eef3 100644 (file)
@@ -104,11 +104,14 @@ init_reg_map (void)
        int i;
 
        g_assert (NUM_REGS > 0);
-       g_assert (sizeof (map_hw_reg_to_dwarf_reg) / sizeof (int) == NUM_REGS);
-       for (i = 0; i < NUM_REGS; ++i) {
+       for (i = 0; i < sizeof (map_hw_reg_to_dwarf_reg) / sizeof (int); ++i) {
                map_dwarf_reg_to_hw_reg [mono_hw_reg_to_dwarf_reg (i)] = i;
        }
 
+#ifdef TARGET_POWERPC
+       map_dwarf_reg_to_hw_reg [DWARF_PC_REG] = ppc_lr;
+#endif
+
        mono_memory_barrier ();
        dwarf_reg_to_hw_reg_inited = TRUE;
 }
@@ -322,13 +325,13 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
                                   int nregs, guint8 **out_cfa) 
 {
        Loc locations [NUM_REGS];
-       int i, pos, reg, cfa_reg, cfa_offset, offset;
+       int i, pos, reg, cfa_reg, cfa_offset;
        guint8 *p;
        guint8 *cfa_val;
 
        g_assert (nregs <= NUM_REGS);
 
-       for (i = 0; i < nregs; ++i)
+       for (i = 0; i < NUM_REGS; ++i)
                locations [i].loc_type = LOC_SAME;
 
        p = unwind_info;
@@ -345,7 +348,7 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
                        p ++;
                        break;
                case DW_CFA_offset:
-                       reg = mono_dwarf_reg_to_hw_reg (*p & 0x3f);
+                       reg = *p & 0x3f;
                        p ++;
                        locations [reg].loc_type = LOC_OFFSET;
                        locations [reg].offset = decode_uleb128 (p, &p) * DWARF_DATA_ALIGN;
@@ -355,18 +358,19 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
                        p ++;
                        switch (ext_op) {
                        case DW_CFA_def_cfa:
-                               cfa_reg = mono_dwarf_reg_to_hw_reg (decode_uleb128 (p, &p));
+                               cfa_reg = decode_uleb128 (p, &p);
                                cfa_offset = decode_uleb128 (p, &p);
                                break;
                        case DW_CFA_def_cfa_offset:
                                cfa_offset = decode_uleb128 (p, &p);
                                break;
                        case DW_CFA_def_cfa_register:
-                               cfa_reg = mono_dwarf_reg_to_hw_reg (decode_uleb128 (p, &p));
+                               cfa_reg = decode_uleb128 (p, &p);
                                break;
                        case DW_CFA_offset_extended_sf:
-                               reg = mono_dwarf_reg_to_hw_reg (decode_uleb128 (p, &p));
-                               offset = decode_sleb128 (p, &p) * DWARF_DATA_ALIGN;
+                               reg = decode_uleb128 (p, &p);
+                               locations [reg].loc_type = LOC_OFFSET;
+                               locations [reg].offset = decode_sleb128 (p, &p) * DWARF_DATA_ALIGN;
                                break;
                        case DW_CFA_advance_loc4:
                                pos += *(guint32*)p;
@@ -382,10 +386,10 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
                }
        }
 
-       cfa_val = (guint8*)regs [cfa_reg] + cfa_offset;
-       for (i = 0; i < nregs; ++i) {
+       cfa_val = (guint8*)regs [mono_dwarf_reg_to_hw_reg (cfa_reg)] + cfa_offset;
+       for (i = 0; i < NUM_REGS; ++i) {
                if (locations [i].loc_type == LOC_OFFSET)
-                       regs [i] = *(gssize*)(cfa_val + locations [i].offset);
+                       regs [mono_dwarf_reg_to_hw_reg (i)] = *(gssize*)(cfa_val + locations [i].offset);
        }
 
        *out_cfa = cfa_val;