2010-05-30 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / dwarfwriter.c
index c83c4b5f28da3f777f424d946971c34e6f93a3ab..1541629d4d12047459c7ade7ef7c1fd09a24905f 100644 (file)
@@ -1068,6 +1068,9 @@ emit_type (MonoDwarfWriter *w, MonoType *t)
                                tdie = ".LDIE_I4";
                        }
                        break;
+               case MONO_TYPE_PTR:
+                       tdie = ".LDIE_I";
+                       break;
                default:
                        tdie = ".LDIE_I4";
                        break;
@@ -1255,6 +1258,7 @@ disasm_ins (MonoMethod *method, const guchar *ip, const guint8 **endip)
        token_handler_ip = NULL;
 
        *endip = ip;
+       mono_metadata_free_mh (header);
        return dis;
 }
 
@@ -1333,11 +1337,13 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
        char *prev_file_name = NULL;
        MonoMethodHeader *header = mono_method_get_header (method);
        MonoDebugMethodInfo *minfo;
-       GArray *ln_array;
+       MonoDebugLineNumberEntry *ln_array;
        int *native_to_il_offset = NULL;
 
-       if (!w->emit_line)
+       if (!w->emit_line) {
+               mono_metadata_free_mh (header);
                return;
+       }
 
        minfo = mono_debug_lookup_method (method);
 
@@ -1345,37 +1351,33 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
 
        g_assert (code_size);
 
-#ifdef _EGLIB_MAJOR
-       /* g_array is not implemented in eglib */
-       return;
-#else
-       ln_array = g_array_sized_new (FALSE, FALSE, sizeof (MonoDebugLineNumberEntry), 
-                                                                 debug_info->num_line_numbers);
-       g_array_append_vals (ln_array, debug_info->line_numbers, debug_info->num_line_numbers);
-       g_array_sort (ln_array, (GCompareFunc)compare_lne);
+       ln_array = g_new0 (MonoDebugLineNumberEntry, debug_info->num_line_numbers);
+       memcpy (ln_array, debug_info->line_numbers, debug_info->num_line_numbers * sizeof (MonoDebugLineNumberEntry));
+
+       qsort (ln_array, debug_info->num_line_numbers, sizeof (MonoDebugLineNumberEntry), (gpointer)compare_lne);
+
        native_to_il_offset = g_new0 (int, code_size + 1);
 
        for (i = 0; i < debug_info->num_line_numbers; ++i) {
                int j;
-               MonoDebugLineNumberEntry lne = g_array_index (ln_array, MonoDebugLineNumberEntry, i);
+               MonoDebugLineNumberEntry *lne = &ln_array [i];
 
                if (i == 0) {
-                       for (j = 0; j < lne.native_offset; ++j)
+                       for (j = 0; j < lne->native_offset; ++j)
                                native_to_il_offset [j] = -1;
                }
 
                if (i < debug_info->num_line_numbers - 1) {
-                       MonoDebugLineNumberEntry lne_next = g_array_index (ln_array, MonoDebugLineNumberEntry, i + 1);
+                       MonoDebugLineNumberEntry *lne_next = &ln_array [i + 1];
 
-                       for (j = lne.native_offset; j < lne_next.native_offset; ++j)
-                               native_to_il_offset [j] = lne.il_offset;
+                       for (j = lne->native_offset; j < lne_next->native_offset; ++j)
+                               native_to_il_offset [j] = lne->il_offset;
                } else {
-                       for (j = lne.native_offset; j < code_size; ++j)
-                               native_to_il_offset [j] = lne.il_offset;
+                       for (j = lne->native_offset; j < code_size; ++j)
+                               native_to_il_offset [j] = lne->il_offset;
                }
        }
-       g_array_free (ln_array, TRUE);
-#endif
+       g_free (ln_array);
 
        prev_line = 1;
        prev_il_offset = -1;
@@ -1408,7 +1410,10 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
 
                loc = mono_debug_symfile_lookup_location (minfo, il_offset);
 
-               if (loc) {
+               // Added the loc->source_file check as otherwise we can
+               // crash, see the sample in bug 553191 that makes this code
+               // crash when we call strcmp on loc->source_file below
+               if (loc && loc->source_file) {
                        int line_diff = (gint32)loc->row - (gint32)prev_line;
                        int addr_diff = i - prev_native_offset;
 
@@ -1454,10 +1459,12 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
                        }
 
                        first = FALSE;
-                       g_free (loc);
+
+                       mono_debug_symfile_free_location (loc);
                }
        }
 
+       g_free (native_to_il_offset);
        g_free (prev_file_name);
 
        if (!first) {
@@ -1549,6 +1556,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
                fflush (w->il_file);
                g_free (il_to_line);
        }
+       mono_metadata_free_mh (header);
 }
 
 static MonoMethodVar*
@@ -1576,7 +1584,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
        char *name;
        MonoMethodSignature *sig;
        MonoMethodHeader *header;
-       char **names, **tdies, **local_tdies;
+       char **names;
        char **local_names;
        int *local_indexes;
        int i, num_locals;
@@ -1589,7 +1597,6 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
        header = mono_method_get_header (method);
 
        /* Parameter types */
-       tdies = g_new0 (char *, sig->param_count + sig->hasthis);
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
                MonoType *t;
 
@@ -1606,7 +1613,6 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
        }
 
        /* Local types */
-       local_tdies = g_new0 (char *, header->num_locals);
        for (i = 0; i < header->num_locals; ++i) {
                emit_type (w, header->locals [i]);
        }
@@ -1755,6 +1761,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
                emit_line_number_info (w, method, start_symbol, end_symbol, code, code_size, debug_info);
 
        emit_line (w);
+       mono_metadata_free_mh (header);
 }
 
 void