2009-01-29 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Thu, 29 Jan 2009 22:14:03 +0000 (22:14 -0000)
committerZoltan Varga <vargaz@gmail.com>
Thu, 29 Jan 2009 22:14:03 +0000 (22:14 -0000)
* exceptions-arm.c: Fix warnings.

* tramp-arm.c aot-compiler.c unwind.h unwind.c: Implement xdebug support for
ARM.

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

mono/mini/ChangeLog
mono/mini/aot-compiler.c
mono/mini/exceptions-arm.c
mono/mini/tramp-arm.c
mono/mini/unwind.c
mono/mini/unwind.h

index 7f3d488b67122be441395c93e3839abaf9b63fb8..45193dfd745aa416e04ac6957b6a1ec4dc531d70 100644 (file)
@@ -1,5 +1,10 @@
 2009-01-29  Zoltan Varga  <vargaz@gmail.com>
 
+       * exceptions-arm.c: Fix warnings.
+
+       * tramp-arm.c aot-compiler.c unwind.h unwind.c: Implement xdebug support for
+       ARM.
+
        * mini-x86.c: Fix --enable-minimal=jit build.
 
        * mini.c: Really fix --enable-minimal=jit build.
index 6d6c7bbdab0c9a9168e66b5bbf5f064297dbe48e..70ebe947190e99d107a199cb331fee71d3217f63 100644 (file)
@@ -1518,7 +1518,7 @@ asm_writer_emit_section_change (MonoAotCompile *acfg, const char *section_name,
                fprintf (acfg->fp, "%s\n", ".data");
        else
                fprintf (acfg->fp, "%s\n", section_name);
-#elif defined(sparc) || defined(__arm__)
+#elif defined(sparc)
        /* For solaris as, GNU as should accept the same */
        fprintf (acfg->fp, ".section \"%s\"\n", section_name);
 #else
@@ -3437,6 +3437,7 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg)
        guint8 *p, *buf, *debug_info;
        MonoJitInfo *jinfo = cfg->jit_info;
        guint32 flags;
+       gboolean use_unwind_ops = FALSE;
 
        method = cfg->orig_method;
        code = cfg->native_code;
@@ -3452,12 +3453,16 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg)
        buf_size = header->num_clauses * 256 + debug_info_size + 256;
        p = buf = g_malloc (buf_size);
 
-       flags = (jinfo->has_generic_jit_info ? 1 : 0) | ((cfg->unwind_ops != NULL) ? 2 : 0);
+#if defined(__x86_64__)
+       use_unwind_ops = cfg->unwind_ops != NULL;
+#endif
+
+       flags = (jinfo->has_generic_jit_info ? 1 : 0) | (use_unwind_ops ? 2 : 0);
 
        encode_value (jinfo->code_size, p, &p);
        encode_value (flags, p, &p);
 
-       if (cfg->unwind_ops) {
+       if (use_unwind_ops) {
                guint32 encoded_len;
                guint8 *encoded;
 
@@ -5356,7 +5361,7 @@ emit_dwarf_abbrev (MonoAotCompile *acfg, int code, int tag, gboolean has_child,
 static void
 emit_cie (MonoAotCompile *acfg)
 {
-#if defined(__x86_64__)
+#if defined(__x86_64__) || defined(__arm__)
        emit_section_change (acfg, ".debug_frame", 0);
 
        emit_alignment (acfg, 8);
@@ -5370,6 +5375,9 @@ emit_cie (MonoAotCompile *acfg)
 #ifdef __x86_64__
        emit_sleb128 (acfg, -8); /* data alignment factor */
        emit_uleb128 (acfg, AMD64_RIP);
+#elif defined(__arm__)
+       emit_sleb128 (acfg, -4); /* data alignment factor */
+       emit_uleb128 (acfg, mono_hw_reg_to_dwarf_reg (ARMREG_LR));
 #else
        g_assert_not_reached ();
 #endif
@@ -5380,6 +5388,7 @@ emit_cie (MonoAotCompile *acfg)
        emit_uleb128 (acfg, 8); /* offset=8 */
        emit_byte (acfg, DW_CFA_offset | AMD64_RIP);
        emit_uleb128 (acfg, 1); /* offset=-8 */
+#elif defined(__arm__)
 #else
        g_assert_not_reached ();
 #endif
@@ -5400,12 +5409,21 @@ static void
 emit_fde (MonoAotCompile *acfg, int fde_index, char *start_symbol, char *end_symbol,
                  guint8 *code, guint32 code_size, GSList *unwind_ops, gboolean use_cie)
 {
-#if defined(__x86_64__)
+#if defined(__x86_64__) || defined(__arm__)
        char symbol [128];
        GSList *l;
        guint8 *uw_info;
        guint32 uw_info_len;
 
+#ifdef __arm__
+       if (!unwind_ops)
+               /* 
+                * The debugger can unwind without unwind info, but gets confused by empty
+                * info.
+                */
+               return;
+#endif
+
        emit_section_change (acfg, ".debug_frame", 0);
 
        sprintf (symbol, ".Lfde%d_end", fde_index);
@@ -5414,12 +5432,14 @@ emit_fde (MonoAotCompile *acfg, int fde_index, char *start_symbol, char *end_sym
        if (start_symbol) {
                emit_pointer (acfg, start_symbol); /* initial_location */
                emit_symbol_diff (acfg, end_symbol, start_symbol, 0); /* address_range */
-               emit_int32 (acfg, 0);
        } else {
                emit_pointer_value (acfg, code);
                emit_int32 (acfg, code_size);
-               emit_int32 (acfg, 0);
        }
+#if SIZEOF_VOID_P == 8
+       /* Upper 32 bits of code size */
+       emit_int32 (acfg, 0);
+#endif
 
        l = unwind_ops;
 #ifdef __x86_64__
@@ -5924,6 +5944,8 @@ emit_method_dwarf_info (MonoAotCompile *acfg, MonoMethod *method, char *start_sy
        /* Subprogram end */
        emit_uleb128 (acfg, 0x0);
 
+       emit_line (acfg);
+
        /* Emit unwind info */
        emit_fde (acfg, acfg->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, TRUE);
        acfg->fde_index ++;
index 0b1d7ca4b8b062a07f7395d3d3e596f66e4e809c..400587188dcc101c15e03bb469dbb81203297e79 100644 (file)
@@ -219,7 +219,7 @@ mono_arm_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp,
 void
 mono_arm_throw_exception_by_token (guint32 type_token, unsigned long eip, unsigned long esp, gulong *int_regs, gdouble *fp_regs)
 {
-       mono_arm_throw_exception (mono_exception_from_token (mono_defaults.corlib, type_token), eip, esp, int_regs, fp_regs);
+       mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, type_token), eip, esp, int_regs, fp_regs);
 }
 
 /**
@@ -266,7 +266,7 @@ mono_arch_get_throw_exception_generic (int size, int by_token, gboolean rethrow,
                code += 4;
                ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_PC, ARMREG_IP);
        } else {
-               code = mono_arm_emit_load_imm (code, ARMREG_IP, GPOINTER_TO_UINT (by_token ? mono_arm_throw_exception_by_token : mono_arm_throw_exception));
+               code = mono_arm_emit_load_imm (code, ARMREG_IP, GPOINTER_TO_UINT (by_token ? (gpointer)mono_arm_throw_exception_by_token : (gpointer)mono_arm_throw_exception));
        }
        ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
        ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_IP);
index 79eac50dcb388678d8cb3e00867e971d92c5ddbb..65f76b8518d6628fe3b81486d8ffcf2153003520 100644 (file)
@@ -164,6 +164,8 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
        guint8 *buf, *code = NULL;
        guint8 *load_get_lmf_addr, *load_trampoline;
        gpointer *constants;
+       GSList *unwind_ops = NULL, *l;
+       int cfa_offset;
 
        *ji = NULL;
 
@@ -178,6 +180,16 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
         * saved as sp + LR_OFFSET by the push in the specific trampoline
         */
 #define LR_OFFSET (sizeof (gpointer) * 13)
+
+       // FIXME: Finish the unwind info, the current info allows us to unwind
+       // when the trampoline is not in the epilog
+
+       // CFA = SP + (num registers pushed) * 4
+       cfa_offset = 14 * sizeof (gpointer);
+       mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, cfa_offset);
+       // PC saved at sp+LR_OFFSET
+       mono_add_unwind_op_offset (unwind_ops, code, buf, ARMREG_LR, -4);
+
        ARM_MOV_REG_REG (code, ARMREG_V1, ARMREG_SP);
        if (aot && tramp_type != MONO_TRAMPOLINE_GENERIC_CLASS_INIT) {
                /* 
@@ -217,6 +229,8 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
         * the iregs array is already allocated on the stack by push.
         */
        ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, sizeof (MonoLMF) - sizeof (guint) * 14);
+       cfa_offset += sizeof (MonoLMF) - sizeof (guint) * 14;
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
        ARM_ADD_REG_IMM8 (code, ARMREG_R1, ARMREG_SP, STACK - sizeof (MonoLMF));
        /* r0 is the result from mono_get_lmf_addr () */
        ARM_STR_IMM (code, ARMREG_R0, ARMREG_R1, G_STRUCT_OFFSET (MonoLMF, lmf_addr));
@@ -357,6 +371,12 @@ mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *c
                nullified_class_init_trampoline = mono_arch_get_nullified_class_init_trampoline (&code_len);
        }
 
+       mono_save_trampoline_xdebug_info ("<generic_trampoline>", buf, *code_size, unwind_ops);
+
+       for (l = unwind_ops; l; l = l->next)
+               g_free (l->data);
+       g_slist_free (unwind_ops);
+
        return buf;
 }
 
@@ -547,7 +567,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_s
                /* Jump to the actual trampoline */
                ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0); /* temp reg */
                ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R1);
-               *(guint32*)code = tramp;
+               *(gpointer*)code = tramp;
                code += 4;
        }
 
@@ -601,7 +621,7 @@ mono_arch_create_generic_class_init_trampoline (void)
        /* Jump to the actual trampoline */
        ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0); /* temp reg */
        ARM_MOV_REG_REG (code, ARMREG_PC, ARMREG_R1);
-       *(guint32*)code = tramp;
+       *(gpointer*)code = tramp;
        code += 4;
 
        mono_arch_flush_icache (buf, code - buf);
index 4f19777586e97fc2d7bd009740634aa935ab5f8b..29e22bdd6ce801755cad3a55ce612d4d0203363f 100644 (file)
@@ -38,9 +38,16 @@ static int cached_info_size;
 #ifdef __x86_64__
 static int map_hw_reg_to_dwarf_reg [] = { 0, 2, 1, 3, 7, 6, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
 #define NUM_REGS AMD64_NREG
+#define DWARF_DATA_ALIGN - 8
+#elif defined(__arm__)
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf
+static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+#define NUM_REGS 16
+#define DWARF_DATA_ALIGN - 4
 #else
 static int map_hw_reg_to_dwarf_reg [0];
 #define NUM_REGS 0
+#define DWARF_DATA_ALIGN 0
 #endif
 
 static gboolean dwarf_reg_to_hw_reg_inited;
@@ -55,12 +62,12 @@ static int map_dwarf_reg_to_hw_reg [NUM_REGS];
 int
 mono_hw_reg_to_dwarf_reg (int reg)
 {
-#ifdef __x86_64__
-       return map_hw_reg_to_dwarf_reg [reg];
-#else
-       g_assert_not_reached ();
-       return -1;
-#endif
+       if (NUM_REGS == 0) {
+               g_assert_not_reached ();
+               return -1;
+       } else {
+               return map_hw_reg_to_dwarf_reg [reg];
+       }
 }
 
 static void
@@ -173,7 +180,7 @@ mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
                        break;
                case DW_CFA_offset:
                        *p ++ = DW_CFA_offset | reg;
-                       encode_uleb128 (op->val / - 8, p, &p);
+                       encode_uleb128 (op->val / DWARF_DATA_ALIGN, p, &p);
                        break;
                default:
                        g_assert_not_reached ();
index b06a1eca409f6e9b2e2e9faee2483fef2bade2d5..47204f113910e056f0438bf05305fd47eb34339e 100644 (file)
@@ -82,7 +82,7 @@ typedef struct {
 /* Similar macros usable when a cfg is not available, like for trampolines */
 #define mono_add_unwind_op_def_cfa(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa, (reg), (offset))); } while (0)
 #define mono_add_unwind_op_def_cfa_reg(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa_register, (reg), (0))); } while (0)
-#define mono_add_unwind_op_def_cfa_offset(op_list,code,buf,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa, 0, (offset))); } while (0)
+#define mono_add_unwind_op_def_cfa_offset(op_list,code,buf,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa_offset, 0, (offset))); } while (0)
 #define mono_add_unwind_op_same_value(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_same_value, (reg), 0)); } while (0)
 #define mono_add_unwind_op_offset(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_offset, (reg), (offset))); } while (0)