X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdwarfwriter.c;h=2f216dda226e0456f03c6df7c38fda188a367ed3;hb=32455dbbe90d3f7826a2bae5a95360e050f04172;hp=2c589d46980a415bbaa29bcd566d2602e12e8d91;hpb=1ecb61405f8816c6ef3eb9d2105edd8eb2497ec8;p=mono.git diff --git a/mono/mini/dwarfwriter.c b/mono/mini/dwarfwriter.c index 2c589d46980..2f216dda226 100644 --- a/mono/mini/dwarfwriter.c +++ b/mono/mini/dwarfwriter.c @@ -52,6 +52,7 @@ struct _MonoDwarfWriter const char *temp_prefix; gboolean emit_line, appending, collect_line_info; GSList *line_info; + int cur_file_index; }; static void @@ -111,6 +112,7 @@ mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file, int il_file_st w->class_to_vtype_die = g_hash_table_new (NULL, NULL); w->class_to_pointer_die = g_hash_table_new (NULL, NULL); w->class_to_reference_die = g_hash_table_new (NULL, NULL); + w->cur_file_index = -1; return w; } @@ -435,6 +437,7 @@ emit_fde (MonoDwarfWriter *w, int fde_index, char *start_symbol, char *end_symbo #define ABBREV_PARAM_LOCLIST 15 #define ABBREV_INHERITANCE 16 #define ABBREV_STRUCT_TYPE_NOCHILDREN 17 +#define ABBREV_TRAMP_SUBPROGRAM 18 static int compile_unit_attr [] = { DW_AT_producer ,DW_FORM_string, @@ -448,12 +451,23 @@ static int compile_unit_attr [] = { static int subprogram_attr [] = { DW_AT_name , DW_FORM_string, +#ifndef TARGET_IOS DW_AT_description , DW_FORM_string, +#endif DW_AT_low_pc , DW_FORM_addr, DW_AT_high_pc , DW_FORM_addr, DW_AT_frame_base , DW_FORM_block1 }; +static int tramp_subprogram_attr [] = { + DW_AT_name , DW_FORM_string, +#ifndef TARGET_IOS + DW_AT_description , DW_FORM_string, +#endif + DW_AT_low_pc , DW_FORM_addr, + DW_AT_high_pc , DW_FORM_addr, +}; + static int param_attr [] = { DW_AT_name, DW_FORM_string, DW_AT_type, DW_FORM_ref4, @@ -723,20 +737,43 @@ emit_line_number_info_begin (MonoDwarfWriter *w) emit_label (w, ".Ldebug_line_end"); } +static char * +escape_path (char *name) +{ + if (strchr (name, '\\')) { + char *s = g_malloc (strlen (name) * 2); + int len, i, j; + + len = strlen (name); + j = 0; + for (i = 0; i < len; ++i) { + if (name [i] == '\\') { + s [j ++] = '\\'; + s [j ++] = '\\'; + } else { + s [j ++] = name [i]; + } + } + return s; + } + return name; +} + static void emit_all_line_number_info (MonoDwarfWriter *w) { int i; GHashTable *dir_to_index, *index_to_dir; GSList *l; + GSList *info_list; g_assert (w->collect_line_info); - add_line_number_file_name (w, "xdb.il", 0, 0); + add_line_number_file_name (w, "", 0, 0); /* Collect files */ - // FIXME: Revert list - for (l = w->line_info; l; l = l->next) { + info_list = g_slist_reverse (w->line_info); + for (l = info_list; l; l = l->next) { MethodLineNumberInfo *info = l->data; MonoDebugMethodInfo *minfo; char *source_file; @@ -810,7 +847,7 @@ emit_all_line_number_info (MonoDwarfWriter *w) for (i = 0; i < w->line_number_dir_index; ++i) { char *dir = g_hash_table_lookup (index_to_dir, GUINT_TO_POINTER (i + 1)); - emit_string (w, dir); + emit_string (w, escape_path (dir)); } /* End of Includes */ emit_byte (w, 0); @@ -831,7 +868,7 @@ emit_all_line_number_info (MonoDwarfWriter *w) if (basename) emit_string (w, basename); else - emit_string (w, name); + emit_string (w, escape_path (name)); emit_uleb128 (w, dir_index); emit_byte (w, 0); emit_byte (w, 0); @@ -843,11 +880,12 @@ emit_all_line_number_info (MonoDwarfWriter *w) emit_label (w, ".Ldebug_line_header_end"); /* Emit line number table */ - for (l = w->line_info; l; l = l->next) { + for (l = info_list; l; l = l->next) { MethodLineNumberInfo *info = l->data; emit_line_number_info (w, info->method, info->start_symbol, info->end_symbol, info->code, info->code_size, info->debug_info); } + g_slist_free (info_list); emit_byte (w, 0); emit_byte (w, 1); @@ -915,6 +953,8 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra reference_type_attr, G_N_ELEMENTS (reference_type_attr)); emit_dwarf_abbrev (w, ABBREV_INHERITANCE, DW_TAG_inheritance, FALSE, inheritance_attr, G_N_ELEMENTS (inheritance_attr)); + emit_dwarf_abbrev (w, ABBREV_TRAMP_SUBPROGRAM, DW_TAG_subprogram, FALSE, + tramp_subprogram_attr, G_N_ELEMENTS (tramp_subprogram_attr)); emit_byte (w, 0); emit_section_change (w, ".debug_info", 0); @@ -1561,6 +1601,7 @@ emit_advance_op (MonoDwarfWriter *w, int line_diff, int addr_diff) if (opcode != 0) { emit_byte (w, opcode); } else { + //printf ("large: %d %d %d\n", line_diff, addr_diff, max_special_addr_diff); emit_byte (w, DW_LNS_advance_line); emit_sleb128 (w, line_diff); emit_byte (w, DW_LNS_advance_pc); @@ -1594,7 +1635,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, MonoDebugMethodInfo *minfo; MonoDebugLineNumberEntry *ln_array; int *native_to_il_offset = NULL; - + if (!w->emit_line) { mono_metadata_free_mh (header); return; @@ -1638,6 +1679,8 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, prev_il_offset = -1; for (i = 0; i < code_size; ++i) { + int line_diff, addr_diff; + if (!minfo) continue; @@ -1664,57 +1707,60 @@ 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) { - int line_diff = (gint32)loc->row - (gint32)prev_line; - int addr_diff = i - prev_native_offset; - - if (first) { - emit_section_change (w, ".debug_line", LINE_SUBSECTION_DATA); - - emit_byte (w, 0); - emit_byte (w, sizeof (gpointer) + 1); - emit_byte (w, DW_LNE_set_address); - if (start_symbol) - emit_pointer_unaligned (w, start_symbol); - else - emit_pointer_value (w, code); + if (!(loc && loc->source_file)) + continue; - /* - * 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); - emit_sleb128 (w, (gint32)loc->row - (gint32)prev_line); - prev_line = loc->row; - } + 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_byte (w, 0); + emit_byte (w, sizeof (gpointer) + 1); + emit_byte (w, DW_LNE_set_address); + if (start_symbol) + 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); + prev_line = loc->row; + first = FALSE; + } - if (loc->row != prev_line) { - 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); - g_free (prev_file_name); - prev_file_name = g_strdup (loc->source_file); + if (loc->row != prev_line) { + 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); + g_free (prev_file_name); + prev_file_name = g_strdup (loc->source_file); + if (w->cur_file_index != file_index) { emit_byte (w, DW_LNS_set_file); emit_uleb128 (w, file_index); emit_byte (w, DW_LNS_copy); - } - //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); - - prev_line = loc->row; - prev_native_offset = i; + w->cur_file_index = file_index; + } } + //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); - first = FALSE; - - mono_debug_symfile_free_location (loc); + prev_line = loc->row; + prev_native_offset = i; } + + mono_debug_symfile_free_location (loc); } g_free (native_to_il_offset); @@ -1877,7 +1923,9 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod emit_uleb128 (w, ABBREV_SUBPROGRAM); name = mono_method_full_name (method, FALSE); emit_string (w, name); +#ifndef TARGET_IOS emit_string (w, name); +#endif g_free (name); if (start_symbol) { emit_pointer_unaligned (w, start_symbol); @@ -2045,14 +2093,10 @@ mono_dwarf_writer_emit_trampoline (MonoDwarfWriter *w, const char *tramp_name, c emit_section_change (w, ".debug_info", 0); /* Subprogram */ - emit_uleb128 (w, ABBREV_SUBPROGRAM); + emit_uleb128 (w, ABBREV_TRAMP_SUBPROGRAM); emit_string (w, tramp_name); emit_pointer_value (w, code); emit_pointer_value (w, code + code_size); - /* frame_base */ - emit_byte (w, 2); - emit_byte (w, DW_OP_breg6); - emit_byte (w, 16); /* Subprogram end */ emit_uleb128 (w, 0x0);