Merge pull request #1742 from alexrp/symbol-renaming
[mono.git] / mono / mini / dwarfwriter.c
index 9f68a62683e94c6033c25e4995891bf282e2fb5d..2a6a56964b2cba43f60c74bc3cb37b705ee9a3a9 100644 (file)
@@ -30,6 +30,9 @@
 
 #include <mono/utils/freebsd-dwarf.h>
 
+#define DW_AT_MIPS_linkage_name 0x2007
+#define DW_LNE_set_prologue_end 0x0a
+
 typedef struct {
        MonoMethod *method;
        char *start_symbol, *end_symbol;
@@ -91,12 +94,12 @@ mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file, int il_file_st
        w->appending = appending;
 
        if (appending)
-               g_assert (img_writer_subsections_supported (w->w));
+               g_assert (mono_img_writer_subsections_supported (w->w));
 
        w->emit_line = TRUE;
 
        if (appending) {
-               if (!img_writer_subsections_supported (w->w))
+               if (!mono_img_writer_subsections_supported (w->w))
                        /* Can't emit line number info without subsections */
                        w->emit_line = FALSE;
        } else {
@@ -109,8 +112,8 @@ mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file, int il_file_st
                w->collect_line_info = FALSE;
        }
 
-       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);
@@ -138,97 +141,85 @@ 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); 
-}
-
-static inline void
-emit_zero_bytes (MonoDwarfWriter *w, int num) 
-{ 
-       img_writer_emit_zero_bytes (w->w, num); 
+       mono_img_writer_emit_symbol_diff (w->w, end, start, offset); 
 }
 
 static inline void
 emit_byte (MonoDwarfWriter *w, guint8 val) 
 { 
-       img_writer_emit_byte (w->w, val); 
+       mono_img_writer_emit_byte (w->w, val); 
 }
 
 static G_GNUC_UNUSED void
@@ -455,6 +446,9 @@ static int compile_unit_attr [] = {
 
 static int subprogram_attr [] = {
        DW_AT_name         , DW_FORM_string,
+       DW_AT_MIPS_linkage_name, DW_FORM_string,
+       DW_AT_decl_file    , DW_FORM_udata,
+       DW_AT_decl_line    , DW_FORM_udata,
 #ifndef TARGET_IOS
        DW_AT_description  , DW_FORM_string,
 #endif
@@ -847,7 +841,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
 }
@@ -907,7 +901,7 @@ 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) {
+       if (mono_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 */
@@ -1059,7 +1053,6 @@ 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)
@@ -1071,7 +1064,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:
@@ -1376,6 +1369,7 @@ static const guint8 *token_handler_ip;
 static char*
 token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
 {
+       MonoError error;
        char *res, *desc;
        MonoMethod *cmethod;
        MonoClass *klass;
@@ -1389,10 +1383,12 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
        case CEE_ISINST:
        case CEE_CASTCLASS:
        case CEE_LDELEMA:
-               if (method->wrapper_type)
+               if (method->wrapper_type) {
                        klass = data;
-               else
-                       klass = mono_class_get_full (method->klass->image, token, NULL);
+               } else {
+                       klass = mono_class_get_checked (method->klass->image, token, &error);
+                       g_assert (mono_error_ok (&error)); /* FIXME error handling */
+               }
                res = g_strdup_printf ("<%s>", klass->name);
                break;
        case CEE_NEWOBJ:
@@ -1419,10 +1415,12 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
        case CEE_LDSFLD:
        case CEE_STFLD:
        case CEE_STSFLD:
-               if (method->wrapper_type)
+               if (method->wrapper_type) {
                        field = data;
-               else
-                       field = mono_field_from_token (method->klass->image, token, &klass, NULL);
+               } else {
+                       field = mono_field_from_token_checked (method->klass->image, token, &klass, NULL,  &error);
+                       g_assert (mono_error_ok (&error)); /* FIXME error handling */
+               }
                desc = mono_field_full_name (field);
                res = g_strdup_printf ("<%s>", desc);
                g_free (desc);
@@ -1661,14 +1659,6 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
                                emit_pointer_unaligned (w, start_symbol);
                        else
                                emit_pointer_value (w, code);
-
-                       /* 
-                        * The prolog+initlocals region does not have a line number, this
-                        * makes them belong to the first line of the method.
-                        */
-                       emit_byte (w, DW_LNS_advance_line);
-                       //printf ("FIRST: %d %d %d\n", prev_line, loc->row, il_offset);
-                       emit_sleb128 (w, (gint32)loc->row - (gint32)prev_line);
                        first = FALSE;
                }
 
@@ -1692,7 +1682,10 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
                        }
                }
 
-               if (loc->row != prev_line && !first) {
+               if (loc->row != prev_line) {
+                       if (prev_native_offset == 0)
+                               emit_byte (w, DW_LNE_set_prologue_end);
+
                        //printf ("X: %p(+0x%x) %d %s:%d(+%d)\n", code + i, addr_diff, loc->il_offset, loc->source_file, loc->row, line_diff);
                        emit_advance_op (w, line_diff, addr_diff);
 
@@ -1819,13 +1812,16 @@ find_vmv (MonoCompile *cfg, MonoInst *ins)
 }
 
 void
-mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod *method, char *start_symbol, char *end_symbol, guint8 *code, guint32 code_size, MonoInst **args, MonoInst **locals, GSList *unwind_info, MonoDebugMethodJitInfo *debug_info)
+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)
 {
        char *name;
        MonoMethodSignature *sig;
        MonoMethodHeader *header;
        char **names;
        MonoDebugLocalsInfo *locals_info;
+       MonoDebugMethodInfo *minfo;
+       MonoDebugSourceLocation *loc = NULL;
        int i;
        guint8 buf [128];
        guint8 *p;
@@ -1857,13 +1853,32 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
                emit_type (w, header->locals [i]);
        }
 
+       minfo = mono_debug_lookup_method (method);
+       if (minfo)
+               loc = mono_debug_symfile_lookup_location (minfo, 0);
+
        /* Subprogram */
        names = g_new0 (char *, sig->param_count);
        mono_method_get_param_names (method, (const char **) names);
 
        emit_uleb128 (w, ABBREV_SUBPROGRAM);
+       /* DW_AT_name */
        name = mono_method_full_name (method, FALSE);
        emit_string (w, name);
+       /* DW_AT_MIPS_linkage_name */
+       if (linkage_name)
+               emit_string (w, linkage_name);
+       else
+               emit_string (w, "");
+       /* DW_AT_decl_file/DW_AT_decl_line */
+       if (loc) {
+               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);
+       } else {
+               emit_uleb128 (w, 0);
+               emit_uleb128 (w, 0);
+       }
 #ifndef TARGET_IOS
        emit_string (w, name);
 #endif