Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / dwarfwriter.c
index c9c3b120000d38480d243672922254dc0f66d6cf..9f2c405b68360afdf129e789ed284a382f25fe3a 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * dwarfwriter.c: Creation of DWARF debug information
+/**
+ * \file
+ * Creation of DWARF debug information
  *
  * Author:
  *   Zoltan Varga (vargaz@gmail.com)
@@ -8,6 +9,7 @@
  */
 
 #include "config.h"
+#include <mono/utils/mono-compiler.h>
 
 #if !defined(DISABLE_AOT) && !defined(DISABLE_JIT)
 #include "dwarfwriter.h"
@@ -20,8 +22,7 @@
 #endif
 
 #include <mono/metadata/mono-endian.h>
-#include <mono/metadata/debug-mono-symfile.h>
-#include <mono/utils/mono-compiler.h>
+#include <mono/metadata/debug-internals.h>
 
 #ifndef HOST_WIN32
 #include <mono/utils/freebsd-elf32.h>
@@ -52,7 +53,7 @@ struct _MonoDwarfWriter
        GSList *cie_program;
        FILE *fp;
        const char *temp_prefix;
-       gboolean emit_line, appending, collect_line_info;
+       gboolean emit_line;
        GSList *line_info;
        int cur_file_index;
 };
@@ -69,51 +70,20 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
  *   Create a DWARF writer object. WRITER is the underlying image writer this 
  * writer will emit to. IL_FILE is the file where IL code will be dumped to for
  * methods which have no line number info. It can be NULL.
- * If APPENDING is TRUE, the output file will be in assembleable state after each
- * call to the _emit_ functions. This is used for XDEBUG. If APPENDING is FALSE,
- * a separate mono_dwarf_writer_close () call is needed to finish the emission of
- * debug information.
  */
 MonoDwarfWriter*
-mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file, int il_file_start_line, gboolean appending, gboolean emit_line_numbers)
+mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file, int il_file_start_line, gboolean emit_line_numbers)
 {
        MonoDwarfWriter *w = g_new0 (MonoDwarfWriter, 1);
-       
-       /*
-        * The appending flag is needed because we use subsections to order things in 
-        * the debug info, and:
-        * - apple's assembler doesn't support them
-        * - the binary writer has problems with subsections+alignment
-        * So instead of subsections, we use the _close () function in AOT mode,
-        * which writes out things in order.
-        */
 
        w->w = writer;
        w->il_file = il_file;
        w->il_file_line_index = il_file_start_line;
-       w->appending = appending;
-
-       if (appending)
-               g_assert (img_writer_subsections_supported (w->w));
-
-       w->emit_line = TRUE;
-
-       if (appending) {
-               if (!img_writer_subsections_supported (w->w))
-                       /* Can't emit line number info without subsections */
-                       w->emit_line = FALSE;
-       } else {
-               /* Collect line number info and emit it at once */
-               w->collect_line_info = TRUE;
-       }
 
-       if (!emit_line_numbers) {
-               w->emit_line = FALSE;
-               w->collect_line_info = FALSE;
-       }
+       w->emit_line = emit_line_numbers;
 
-       w->fp = img_writer_get_fp (w->w);
-       w->temp_prefix = img_writer_get_temp_label_prefix (w->w);
+       w->fp = mono_img_writer_get_fp (w->w);
+       w->temp_prefix = mono_img_writer_get_temp_label_prefix (w->w);
 
        w->class_to_die = g_hash_table_new (NULL, NULL);
        w->class_to_vtype_die = g_hash_table_new (NULL, NULL);
@@ -141,97 +111,118 @@ mono_dwarf_writer_get_il_file_line_index (MonoDwarfWriter *w)
 static inline void
 emit_section_change (MonoDwarfWriter *w, const char *section_name, int subsection_index)
 {
-       img_writer_emit_section_change (w->w, section_name, subsection_index);
+       mono_img_writer_emit_section_change (w->w, section_name, subsection_index);
 }
 
 static inline void
 emit_push_section (MonoDwarfWriter *w, const char *section_name, int subsection)
 {
-       img_writer_emit_push_section (w->w, section_name, subsection);
+       mono_img_writer_emit_push_section (w->w, section_name, subsection);
 }
 
 static inline void
 emit_pop_section (MonoDwarfWriter *w)
 {
-       img_writer_emit_pop_section (w->w);
-}
-
-static inline void
-emit_local_symbol (MonoDwarfWriter *w, const char *name, const char *end_label, gboolean func) 
-{ 
-       img_writer_emit_local_symbol (w->w, name, end_label, func); 
+       mono_img_writer_emit_pop_section (w->w);
 }
 
 static inline void
 emit_label (MonoDwarfWriter *w, const char *name) 
 { 
-       img_writer_emit_label (w->w, name); 
+       mono_img_writer_emit_label (w->w, name); 
 }
 
 static inline void
 emit_bytes (MonoDwarfWriter *w, const guint8* buf, int size) 
 { 
-       img_writer_emit_bytes (w->w, buf, size); 
+       mono_img_writer_emit_bytes (w->w, buf, size); 
 }
 
 static inline void
 emit_string (MonoDwarfWriter *w, const char *value) 
 { 
-       img_writer_emit_string (w->w, value); 
+       mono_img_writer_emit_string (w->w, value); 
 }
 
 static inline void
 emit_line (MonoDwarfWriter *w) 
 { 
-       img_writer_emit_line (w->w); 
+       mono_img_writer_emit_line (w->w); 
 }
 
 static inline void
 emit_alignment (MonoDwarfWriter *w, int size) 
 { 
-       img_writer_emit_alignment (w->w, size); 
+       mono_img_writer_emit_alignment (w->w, size); 
 }
 
 static inline void
 emit_pointer_unaligned (MonoDwarfWriter *w, const char *target) 
 { 
-       img_writer_emit_pointer_unaligned (w->w, target); 
+       mono_img_writer_emit_pointer_unaligned (w->w, target); 
 }
 
 static inline void
 emit_pointer (MonoDwarfWriter *w, const char *target) 
 { 
-       img_writer_emit_pointer (w->w, target); 
+       mono_img_writer_emit_pointer (w->w, target); 
 }
 
 static inline void
 emit_int16 (MonoDwarfWriter *w, int value) 
 { 
-       img_writer_emit_int16 (w->w, value); 
+       mono_img_writer_emit_int16 (w->w, value); 
 }
 
 static inline void
 emit_int32 (MonoDwarfWriter *w, int value) 
 { 
-       img_writer_emit_int32 (w->w, value); 
+       mono_img_writer_emit_int32 (w->w, value); 
 }
 
 static inline void
 emit_symbol_diff (MonoDwarfWriter *w, const char *end, const char* start, int offset) 
 { 
-       img_writer_emit_symbol_diff (w->w, end, start, offset); 
+       mono_img_writer_emit_symbol_diff (w->w, end, start, offset); 
 }
 
 static inline void
-emit_zero_bytes (MonoDwarfWriter *w, int num
+emit_byte (MonoDwarfWriter *w, guint8 val
 { 
-       img_writer_emit_zero_bytes (w->w, num); 
+       mono_img_writer_emit_byte (w->w, val); 
 }
 
-static inline void
-emit_byte (MonoDwarfWriter *w, guint8 val) 
-{ 
-       img_writer_emit_byte (w->w, val); 
+static void
+emit_escaped_string (MonoDwarfWriter *w, char *value)
+{
+       int i, len;
+
+       len = strlen (value);
+       for (i = 0; i < len; ++i) {
+               char c = value [i];
+               if (!(isalnum (c))) {
+                       switch (c) {
+                       case '_':
+                       case '-':
+                       case ':':
+                       case '.':
+                       case ',':
+                       case '/':
+                       case '<':
+                       case '>':
+                       case '`':
+                       case '(':
+                       case ')':
+                       case '[':
+                       case ']':
+                               break;
+                       default:
+                               value [i] = '_';
+                               break;
+                       }
+               }
+       }
+       mono_img_writer_emit_string (w->w, value);
 }
 
 static G_GNUC_UNUSED void
@@ -418,7 +409,7 @@ emit_fde (MonoDwarfWriter *w, int fde_index, char *start_symbol, char *end_symbo
        }
 
        /* Convert the list of MonoUnwindOps to the format used by DWARF */     
-       uw_info = mono_unwind_ops_encode (l, &uw_info_len);
+       uw_info = mono_unwind_ops_encode_full (l, &uw_info_len, FALSE);
        emit_bytes (w, uw_info, uw_info_len);
        g_free (uw_info);
 
@@ -581,71 +572,6 @@ static DwarfBasicType basic_types [] = {
 #define LINE_BASE -5
 #define LINE_RANGE 14
 
-/* Subsections of the .debug_line section */
-#define LINE_SUBSECTION_HEADER 1
-#define LINE_SUBSECTION_INCLUDES 2
-#define LINE_SUBSECTION_FILES 3
-#define LINE_SUBSECTION_DATA 4
-#define LINE_SUBSECTION_END 5
-
-static int
-emit_line_number_file_name (MonoDwarfWriter *w, const char *name,
-                                                       gint64 last_mod_time, gint64 file_size)
-{
-       int index;
-       int dir_index;
-       char *basename = NULL;
-
-       if (!w->file_to_index)
-               w->file_to_index = g_hash_table_new (g_str_hash, g_str_equal);
-
-       index = GPOINTER_TO_UINT (g_hash_table_lookup (w->file_to_index, name));
-       if (index > 0)
-               return index;
-
-       if (g_path_is_absolute (name)) {
-               char *dir = g_path_get_dirname (name);
-
-               if (!w->dir_to_index)
-                       w->dir_to_index = g_hash_table_new (g_str_hash, g_str_equal);
-
-               dir_index = GPOINTER_TO_UINT (g_hash_table_lookup (w->dir_to_index, dir));
-               if (dir_index == 0) {
-                       emit_section_change (w, ".debug_line", LINE_SUBSECTION_INCLUDES);
-                       emit_string (w, dir);
-
-                       dir_index = ++ w->line_number_dir_index;
-                       g_hash_table_insert (w->dir_to_index, g_strdup (dir), GUINT_TO_POINTER (dir_index));
-               }
-
-               g_free (dir);
-
-               basename = g_path_get_basename (name);
-       } else {
-               dir_index = 0;
-       }
-
-       emit_section_change (w, ".debug_line", LINE_SUBSECTION_FILES);
-
-       if (basename)
-               emit_string (w, basename);
-       else
-               emit_string (w, name);
-       emit_uleb128 (w, dir_index);
-       emit_byte (w, 0);
-       emit_byte (w, 0);
-
-       emit_section_change (w, ".debug_line", LINE_SUBSECTION_DATA);
-
-       if (basename)
-               g_free (basename);
-
-       index = ++ w->line_number_file_index;
-       g_hash_table_insert (w->file_to_index, g_strdup (name), GUINT_TO_POINTER (index));
-
-       return index;
-}
-
 static int
 get_line_number_file_name (MonoDwarfWriter *w, const char *name)
 {
@@ -689,7 +615,7 @@ mono_dwarf_escape_path (const char *name)
                int len, i, j;
 
                len = strlen (name);
-               s = g_malloc0 ((len + 1) * 2);
+               s = (char *)g_malloc0 ((len + 1) * 2);
                j = 0;
                for (i = 0; i < len; ++i) {
                        if (name [i] == '\\') {
@@ -712,16 +638,13 @@ emit_all_line_number_info (MonoDwarfWriter *w)
        GSList *l;
        GSList *info_list;
 
-       g_assert (w->collect_line_info);
-
        add_line_number_file_name (w, "<unknown>", 0, 0);
 
        /* Collect files */
        info_list = g_slist_reverse (w->line_info);
        for (l = info_list; l; l = l->next) {
-               MethodLineNumberInfo *info = l->data;
+               MethodLineNumberInfo *info = (MethodLineNumberInfo *)l->data;
                MonoDebugMethodInfo *minfo;
-               char *source_file;
                GPtrArray *source_file_list;
 
                // FIXME: Free stuff
@@ -729,9 +652,9 @@ emit_all_line_number_info (MonoDwarfWriter *w)
                if (!minfo)
                        continue;
 
-               mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+               mono_debug_get_seq_points (minfo, NULL, &source_file_list, NULL, NULL, NULL);
                for (i = 0; i < source_file_list->len; ++i) {
-                       MonoDebugSourceInfo *sinfo = g_ptr_array_index (source_file_list, i);
+                       MonoDebugSourceInfo *sinfo = (MonoDebugSourceInfo *)g_ptr_array_index (source_file_list, i);
                        add_line_number_file_name (w, sinfo->source_file, 0, 0);
                }
        }               
@@ -740,7 +663,7 @@ emit_all_line_number_info (MonoDwarfWriter *w)
        dir_to_index = g_hash_table_new (g_str_hash, g_str_equal);
        index_to_dir = g_hash_table_new (NULL, NULL);
        for (i = 0; i < w->line_number_file_index; ++i) {
-               char *name = g_hash_table_lookup (w->index_to_file, GUINT_TO_POINTER (i + 1));
+               char *name = (char *)g_hash_table_lookup (w->index_to_file, GUINT_TO_POINTER (i + 1));
                char *copy;
                int dir_index = 0;
 
@@ -790,7 +713,7 @@ emit_all_line_number_info (MonoDwarfWriter *w)
        /* Includes */
        emit_section_change (w, ".debug_line", 0);
        for (i = 0; i < w->line_number_dir_index; ++i) {
-               char *dir = g_hash_table_lookup (index_to_dir, GUINT_TO_POINTER (i + 1));
+               char *dir = (char *)g_hash_table_lookup (index_to_dir, GUINT_TO_POINTER (i + 1));
 
                emit_string (w, mono_dwarf_escape_path (dir));
        }
@@ -799,7 +722,7 @@ emit_all_line_number_info (MonoDwarfWriter *w)
 
        /* Files */
        for (i = 0; i < w->line_number_file_index; ++i) {
-               char *name = g_hash_table_lookup (w->index_to_file, GUINT_TO_POINTER (i + 1));
+               char *name = (char *)g_hash_table_lookup (w->index_to_file, GUINT_TO_POINTER (i + 1));
                char *basename = NULL, *dir;
                int dir_index = 0;
 
@@ -826,10 +749,12 @@ emit_all_line_number_info (MonoDwarfWriter *w)
 
        /* Emit line number table */
        for (l = info_list; l; l = l->next) {
-               MethodLineNumberInfo *info = l->data;
+               MethodLineNumberInfo *info = (MethodLineNumberInfo *)l->data;
                MonoDebugMethodJitInfo *dmji;
 
-               dmji = mono_debug_find_method (info->method, mono_domain_get ());;
+               dmji = mono_debug_find_method (info->method, mono_domain_get ());
+               if (!dmji)
+                       continue;
                emit_line_number_info (w, info->method, info->start_symbol, info->end_symbol, info->code, info->code_size, dmji);
                mono_debug_free_method_jit_info (dmji);
        }
@@ -853,7 +778,7 @@ emit_debug_info_end (MonoDwarfWriter *w)
 {
        /* This doesn't seem to work/required with recent iphone sdk versions */
 #if 0
-       if (!img_writer_subsections_supported (w->w))
+       if (!mono_img_writer_subsections_supported (w->w))
                fprintf (w->fp, "\n.set %sdebug_info_end,.\n", w->temp_prefix);
 #endif
 }
@@ -864,6 +789,12 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, const char *cu_name, GSLis
        char *s, *build_info;
        int i;
 
+       if (!w->emit_line) {
+               emit_section_change (w, ".debug_line", 0);
+               emit_label (w, ".Ldebug_line_section_start");
+               emit_label (w, ".Ldebug_line_start");
+       }
+
        w->cie_program = base_unwind_program;
 
        emit_section_change (w, ".debug_abbrev", 0);
@@ -913,14 +844,6 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, const char *cu_name, GSLis
        emit_int32 (w, 0); /* .debug_abbrev offset */
        emit_byte (w, sizeof (gpointer)); /* address size */
 
-       if (img_writer_subsections_supported (w->w) && w->appending) {
-               /* Emit this into a separate section so it gets placed at the end */
-               emit_section_change (w, ".debug_info", 1);
-               emit_byte (w, 0); /* close COMPILE_UNIT */
-               emit_label (w, ".Ldebug_info_end");
-               emit_section_change (w, ".debug_info", 0);
-       }
-
        /* Compilation unit */
        emit_uleb128 (w, ABBREV_COMPILE_UNIT);
        build_info = mono_get_runtime_build_info ();
@@ -934,10 +857,7 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, const char *cu_name, GSLis
        emit_pointer_value (w, 0);
        emit_pointer_value (w, 0);
        /* offset into .debug_line section */
-       if (w->emit_line)
-               emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0);
-       else
-               emit_pointer_value (w, 0);
+       emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0);
 
        /* Base types */
        for (i = 0; i < G_N_ELEMENTS (basic_types); ++i) {
@@ -965,13 +885,11 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, const char *cu_name, GSLis
 void
 mono_dwarf_writer_close (MonoDwarfWriter *w)
 {
-       if (!w->appending) {
-               emit_section_change (w, ".debug_info", 0);
-               emit_byte (w, 0); /* close COMPILE_UNIT */
-               emit_label (w, ".Ldebug_info_end");
-       }
+       emit_section_change (w, ".debug_info", 0);
+       emit_byte (w, 0); /* close COMPILE_UNIT */
+       emit_label (w, ".Ldebug_info_end");
 
-       if (w->collect_line_info)
+       if (w->emit_line)
                emit_all_line_number_info (w);
 }
 
@@ -988,7 +906,7 @@ get_class_die (MonoDwarfWriter *w, MonoClass *klass, gboolean vtype)
        else
                cache = w->class_to_die;
 
-       return g_hash_table_lookup (cache, klass);
+       return (const char *)g_hash_table_lookup (cache, klass);
 }
 
 /* Returns the local symbol pointing to the emitted debug info */
@@ -1009,7 +927,7 @@ emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass, gboolean vtype)
        else
                cache = w->class_to_die;
 
-       die = g_hash_table_lookup (cache, klass);
+       die = (char *)g_hash_table_lookup (cache, klass);
        if (die)
                return die;
 
@@ -1065,10 +983,9 @@ emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass, gboolean vtype)
                iter = NULL;
                while ((field = mono_class_get_fields (klass, &iter))) {
                        const char *p;
-                       int len;
                        MonoTypeEnum def_type;
 
-                       if (strcmp ("value__", mono_field_get_name (field)) == 0)
+                       if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
                                continue;
                        if (mono_field_is_deleted (field))
                                continue;
@@ -1077,7 +994,7 @@ emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass, gboolean vtype)
                        emit_string (w, mono_field_get_name (field));
 
                        p = mono_class_get_field_default_value (field, &def_type);
-                       len = mono_metadata_decode_blob_size (p, &p);
+                       /* len = */ mono_metadata_decode_blob_size (p, &p);
                        switch (mono_class_enum_basetype (klass)->type) {
                        case MONO_TYPE_U1:
                        case MONO_TYPE_I1:
@@ -1217,7 +1134,7 @@ get_type_die (MonoDwarfWriter *w, MonoType *t)
 
        if (t->byref) {
                if (t->type == MONO_TYPE_VALUETYPE) {
-                       tdie = g_hash_table_lookup (w->class_to_pointer_die, klass);
+                       tdie = (const char *)g_hash_table_lookup (w->class_to_pointer_die, klass);
                }
                else {
                        tdie = get_class_die (w, klass, FALSE);
@@ -1234,7 +1151,7 @@ get_type_die (MonoDwarfWriter *w, MonoType *t)
        } else {
                switch (t->type) {
                case MONO_TYPE_CLASS:
-                       tdie = g_hash_table_lookup (w->class_to_reference_die, klass);
+                       tdie = (const char *)g_hash_table_lookup (w->class_to_reference_die, klass);
                        //tdie = ".LDIE_OBJECT";
                        break;
                case MONO_TYPE_ARRAY:
@@ -1248,7 +1165,7 @@ get_type_die (MonoDwarfWriter *w, MonoType *t)
                        break;
                case MONO_TYPE_GENERICINST:
                        if (!MONO_TYPE_ISSTRUCT (t)) {
-                               tdie = g_hash_table_lookup (w->class_to_reference_die, klass);
+                               tdie = (const char *)g_hash_table_lookup (w->class_to_reference_die, klass);
                        } else {
                                tdie = ".LDIE_I4";
                        }
@@ -1397,7 +1314,7 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
        case CEE_CASTCLASS:
        case CEE_LDELEMA:
                if (method->wrapper_type) {
-                       klass = data;
+                       klass = (MonoClass *)data;
                } else {
                        klass = mono_class_get_checked (method->klass->image, token, &error);
                        g_assert (mono_error_ok (&error)); /* FIXME error handling */
@@ -1407,17 +1324,21 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
        case CEE_NEWOBJ:
        case CEE_CALL:
        case CEE_CALLVIRT:
-               if (method->wrapper_type)
-                       cmethod = data;
-               else
-                       cmethod = mono_get_method_full (method->klass->image, token, NULL, NULL);
+               if (method->wrapper_type) {
+                       cmethod = (MonoMethod *)data;
+               } else {
+                       MonoError error;
+                       cmethod = mono_get_method_checked (method->klass->image, token, NULL, NULL, &error);
+                       if (!cmethod)
+                               g_error ("Could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+               }
                desc = mono_method_full_name (cmethod, TRUE);
                res = g_strdup_printf ("<%s>", desc);
                g_free (desc);
                break;
        case CEE_CALLI:
                if (method->wrapper_type) {
-                       desc = mono_signature_get_desc (data, FALSE);
+                       desc = mono_signature_get_desc ((MonoMethodSignature *)data, FALSE);
                        res = g_strdup_printf ("<%s>", desc);
                        g_free (desc);
                } else {
@@ -1429,7 +1350,7 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
        case CEE_STFLD:
        case CEE_STSFLD:
                if (method->wrapper_type) {
-                       field = data;
+                       field = (MonoClassField *)data;
                } else {
                        field = mono_field_from_token_checked (method->klass->image, token, &klass, NULL,  &error);
                        g_assert (mono_error_ok (&error)); /* FIXME error handling */
@@ -1456,9 +1377,11 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
 static char*
 disasm_ins (MonoMethod *method, const guchar *ip, const guint8 **endip)
 {
+       MonoError error;
        char *dis;
        MonoDisHelper dh;
-       MonoMethodHeader *header = mono_method_get_header (method);
+       MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
+       mono_error_assert_ok (&error); /* FIXME don't swallow the error */
 
        memset (&dh, 0, sizeof (dh));
        dh.newline = "";
@@ -1573,17 +1496,20 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
                                           guint8 *code, guint32 code_size,
                                           MonoDebugMethodJitInfo *debug_info)
 {
+       MonoError error;
        guint32 prev_line = 0;
        guint32 prev_native_offset = 0;
        int i, file_index, il_offset, prev_il_offset;
        gboolean first = TRUE;
        MonoDebugSourceLocation *loc;
        char *prev_file_name = NULL;
-       MonoMethodHeader *header = mono_method_get_header (method);
+       MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
        MonoDebugMethodInfo *minfo;
        MonoDebugLineNumberEntry *ln_array;
        int *native_to_il_offset = NULL;
        
+       mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
        if (!w->emit_line) {
                mono_metadata_free_mh (header);
                return;
@@ -1598,7 +1524,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
        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);
+       qsort (ln_array, debug_info->num_line_numbers, sizeof (MonoDebugLineNumberEntry), (int (*)(const void *, const void *))compare_lne);
 
        native_to_il_offset = g_new0 (int, code_size + 1);
 
@@ -1655,15 +1581,19 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
 
                prev_il_offset = il_offset;
 
-               loc = mono_debug_symfile_lookup_location (minfo, il_offset);
-               if (!(loc && loc->source_file))
+               loc = mono_debug_method_lookup_location (minfo, il_offset);
+               if (!loc)
                        continue;
+               if (!loc->source_file) {
+                       mono_debug_free_source_location (loc);
+                       continue;
+               }
 
                line_diff = (gint32)loc->row - (gint32)prev_line;
                addr_diff = i - prev_native_offset;
 
                if (first) {    
-                       emit_section_change (w, ".debug_line", LINE_SUBSECTION_DATA);
+                       emit_section_change (w, ".debug_line", 0);
 
                        emit_byte (w, 0);
                        emit_byte (w, sizeof (gpointer) + 1);
@@ -1679,10 +1609,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
                        if (!prev_file_name || strcmp (loc->source_file, prev_file_name) != 0) {
                                /* Add an entry to the file table */
                                /* FIXME: Avoid duplicates */
-                               if (w->collect_line_info)
-                                       file_index = get_line_number_file_name (w, loc->source_file) + 1;
-                               else
-                                       file_index = emit_line_number_file_name (w, loc->source_file, 0, 0);
+                               file_index = get_line_number_file_name (w, loc->source_file) + 1;
                                g_free (prev_file_name);
                                prev_file_name = g_strdup (loc->source_file);
 
@@ -1706,7 +1633,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
                        prev_native_offset = i;
                }
 
-               mono_debug_symfile_free_location (loc);
+               mono_debug_free_source_location (loc);
                first = FALSE;
        }
 
@@ -1740,7 +1667,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
 
                il_to_line = g_new0 (int, header->code_size);
 
-               emit_section_change (w, ".debug_line", LINE_SUBSECTION_DATA);
+               emit_section_change (w, ".debug_line", 0);
                emit_byte (w, 0);
                emit_byte (w, sizeof (gpointer) + 1);
                emit_byte (w, DW_LNE_set_address);
@@ -1828,6 +1755,7 @@ void
 mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod *method, char *start_symbol, char *end_symbol, char *linkage_name,
                                                           guint8 *code, guint32 code_size, MonoInst **args, MonoInst **locals, GSList *unwind_info, MonoDebugMethodJitInfo *debug_info)
 {
+       MonoError error;
        char *name;
        MonoMethodSignature *sig;
        MonoMethodHeader *header;
@@ -1842,7 +1770,8 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
        emit_section_change (w, ".debug_info", 0);
 
        sig = mono_method_signature (method);
-       header = mono_method_get_header (method);
+       header = mono_method_get_header_checked (method, &error);
+       mono_error_assert_ok (&error); /* FIXME don't swallow the error */
 
        /* Parameter types */
        for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
@@ -1868,7 +1797,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
 
        minfo = mono_debug_lookup_method (method);
        if (minfo)
-               loc = mono_debug_symfile_lookup_location (minfo, 0);
+               loc = mono_debug_method_lookup_location (minfo, 0);
 
        /* Subprogram */
        names = g_new0 (char *, sig->param_count);
@@ -1877,7 +1806,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
        emit_uleb128 (w, ABBREV_SUBPROGRAM);
        /* DW_AT_name */
        name = mono_method_full_name (method, FALSE);
-       emit_string (w, name);
+       emit_escaped_string (w, name);
        /* DW_AT_MIPS_linkage_name */
        if (linkage_name)
                emit_string (w, linkage_name);
@@ -1888,6 +1817,9 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
                int file_index = add_line_number_file_name (w, loc->source_file, 0, 0);
                emit_uleb128 (w, file_index + 1);
                emit_uleb128 (w, loc->row);
+
+               mono_debug_free_source_location (loc);
+               loc = NULL;
        } else {
                emit_uleb128 (w, 0);
                emit_uleb128 (w, 0);
@@ -2017,7 +1949,7 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
        }
 
        if (locals_info)
-               mono_debug_symfile_free_locals (locals_info);
+               mono_debug_free_locals (locals_info);
 
        /* Subprogram end */
        emit_uleb128 (w, 0x0);
@@ -2032,23 +1964,18 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
                w->fde_index ++;
        }
 
-       /* Emit line number info */
+       /* Save the information needed to emit the line number info later at once */
        /* != could happen when using --regression */
        if (debug_info && (debug_info->code_start == code)) {
-               if (w->collect_line_info) {
-                       MethodLineNumberInfo *info;
-
-                       /* Save the information needed to emit the line number info later at once */
-                       info = g_new0 (MethodLineNumberInfo, 1);
-                       info->method = method;
-                       info->start_symbol = g_strdup (start_symbol);
-                       info->end_symbol = g_strdup (end_symbol);
-                       info->code = code;
-                       info->code_size = code_size;
-                       w->line_info = g_slist_prepend (w->line_info, info);
-               } else {
-                       emit_line_number_info (w, method, start_symbol, end_symbol, code, code_size, debug_info);
-               }
+               MethodLineNumberInfo *info;
+
+               info = g_new0 (MethodLineNumberInfo, 1);
+               info->method = method;
+               info->start_symbol = g_strdup (start_symbol);
+               info->end_symbol = g_strdup (end_symbol);
+               info->code = code;
+               info->code_size = code_size;
+               w->line_info = g_slist_prepend (w->line_info, info);
        }
 
        emit_line (w);
@@ -2075,4 +2002,9 @@ mono_dwarf_writer_emit_trampoline (MonoDwarfWriter *w, const char *tramp_name, c
        emit_fde (w, w->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, FALSE);
        w->fde_index ++;
 }
+
+#else /* !defined(DISABLE_AOT) && !defined(DISABLE_JIT) */
+
+MONO_EMPTY_SOURCE_FILE (dwarfwriter);
+
 #endif /* End of: !defined(DISABLE_AOT) && !defined(DISABLE_JIT) */