X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdwarfwriter.c;h=94f1459c5ed4b67692954051e1912c20456d93be;hb=3dd824a7c5306569fbbe08e0f3e54f36619822d6;hp=a64acddc84b74ef6a387ea7b9f3280d74f45acd4;hpb=32a75cabc31b1b38295dbd2942f7cd310d9d19e7;p=mono.git diff --git a/mono/mini/dwarfwriter.c b/mono/mini/dwarfwriter.c index a64acddc84b..94f1459c5ed 100644 --- a/mono/mini/dwarfwriter.c +++ b/mono/mini/dwarfwriter.c @@ -8,6 +8,8 @@ */ #include "config.h" + +#if !defined(DISABLE_AOT) && !defined(DISABLE_JIT) #include "dwarfwriter.h" #include @@ -31,12 +33,16 @@ struct _MonoDwarfWriter { MonoImageWriter *w; - GHashTable *class_to_die; + GHashTable *class_to_die, *class_to_vtype_die, *class_to_pointer_die; + GHashTable *class_to_reference_die; int fde_index, tdie_index, line_number_file_index, line_number_dir_index; GHashTable *file_to_index, *dir_to_index; FILE *il_file; int il_file_line_index, loclist_index; GSList *cie_program; + FILE *fp; + const char *temp_prefix; + gboolean emit_line; }; /* @@ -54,6 +60,9 @@ mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file) w->w = writer; w->il_file = il_file; + w->fp = img_writer_get_fp (w->w); + w->temp_prefix = img_writer_get_temp_label_prefix (w->w); + return w; } @@ -362,6 +371,10 @@ emit_fde (MonoDwarfWriter *w, int fde_index, char *start_symbol, char *end_symbo #define ABBREV_NAMESPACE 10 #define ABBREV_VARIABLE 11 #define ABBREV_VARIABLE_LOCLIST 12 +#define ABBREV_POINTER_TYPE 13 +#define ABBREV_REFERENCE_TYPE 14 +#define ABBREV_PARAM_LOCLIST 15 +#define ABBREV_INHERITANCE 16 static int compile_unit_attr [] = { DW_AT_producer ,DW_FORM_string, @@ -386,6 +399,12 @@ static int param_attr [] = { DW_AT_location, DW_FORM_block1 }; +static int param_loclist_attr [] = { + DW_AT_name, DW_FORM_string, + DW_AT_type, DW_FORM_ref4, + DW_AT_location, DW_FORM_data4 +}; + static int base_type_attr [] = { DW_AT_byte_size, DW_FORM_data1, DW_AT_encoding, DW_FORM_data1, @@ -408,6 +427,14 @@ static int typedef_attr [] = { DW_AT_type, DW_FORM_ref4 }; +static int pointer_type_attr [] = { + DW_AT_type, DW_FORM_ref4, +}; + +static int reference_type_attr [] = { + DW_AT_type, DW_FORM_ref4, +}; + static int enum_type_attr [] = { DW_AT_name, DW_FORM_string, DW_AT_byte_size, DW_FORM_udata, @@ -434,6 +461,11 @@ static int variable_loclist_attr [] = { DW_AT_type, DW_FORM_ref4, DW_AT_location, DW_FORM_data4 }; + +static int inheritance_attr [] = { + DW_AT_type, DW_FORM_ref4, + DW_AT_data_member_location, DW_FORM_block1 +}; typedef struct DwarfBasicType { const char *die_name, *name; @@ -535,14 +567,6 @@ emit_line_number_file_name (MonoDwarfWriter *w, const char *name, static void emit_line_number_info_begin (MonoDwarfWriter *w) { - if (!w->il_file) { - /* FIXME: This doesn't seem to work with !xdebug */ - emit_section_change (w, ".debug_line", 0); - emit_label (w, ".Ldebug_line_start"); - emit_label (w, ".Ldebug_line_section_start"); - return; - } - /* Line number info header */ /* * GAS seems to emit its own data to the end of the first subsection, so we use @@ -603,12 +627,31 @@ emit_line_number_info_begin (MonoDwarfWriter *w) emit_label (w, ".Ldebug_line_end"); } +/* + * Some assemblers like apple's do not support subsections, so we can't place + * .Ldebug_info_end at the end of the section using subsections. Instead, we + * define it every time something gets added to the .debug_info section. + * The apple assember seems to use the last definition. + */ +static void +emit_debug_info_end (MonoDwarfWriter *w) +{ + if (!img_writer_subsections_supported (w->w)) + fprintf (w->fp, "\n.set %sdebug_info_end,.\n", w->temp_prefix); +} + void mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_program) { char *s, *build_info; int i; + if (!img_writer_subsections_supported (w->w)) + /* Can't emit line number info without subsections */ + w->emit_line = FALSE; + else + w->emit_line = TRUE; + w->cie_program = base_unwind_program; emit_section_change (w, ".debug_abbrev", 0); @@ -618,6 +661,8 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra subprogram_attr, G_N_ELEMENTS (subprogram_attr)); emit_dwarf_abbrev (w, ABBREV_PARAM, DW_TAG_formal_parameter, FALSE, param_attr, G_N_ELEMENTS (param_attr)); + emit_dwarf_abbrev (w, ABBREV_PARAM_LOCLIST, DW_TAG_formal_parameter, FALSE, + param_loclist_attr, G_N_ELEMENTS (param_loclist_attr)); emit_dwarf_abbrev (w, ABBREV_BASE_TYPE, DW_TAG_base_type, FALSE, base_type_attr, G_N_ELEMENTS (base_type_attr)); emit_dwarf_abbrev (w, ABBREV_STRUCT_TYPE, DW_TAG_class_type, TRUE, @@ -636,6 +681,12 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra variable_attr, G_N_ELEMENTS (variable_attr)); emit_dwarf_abbrev (w, ABBREV_VARIABLE_LOCLIST, DW_TAG_variable, FALSE, variable_loclist_attr, G_N_ELEMENTS (variable_loclist_attr)); + emit_dwarf_abbrev (w, ABBREV_POINTER_TYPE, DW_TAG_pointer_type, FALSE, + pointer_type_attr, G_N_ELEMENTS (pointer_type_attr)); + emit_dwarf_abbrev (w, ABBREV_REFERENCE_TYPE, DW_TAG_reference_type, FALSE, + 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_byte (w, 0); emit_section_change (w, ".debug_info", 0); @@ -645,11 +696,13 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra emit_int32 (w, 0); /* .debug_abbrev offset */ emit_byte (w, sizeof (gpointer)); /* address size */ - /* Emit this into a separate section so it gets placed at the end */ - emit_section_change (w, ".debug_info", 1); - emit_int32 (w, 0); /* close everything */ - emit_label (w, ".Ldebug_info_end"); - emit_section_change (w, ".debug_info", 0); + if (img_writer_subsections_supported (w->w)) { + /* Emit this into a separate section so it gets placed at the end */ + emit_section_change (w, ".debug_info", 1); + emit_int32 (w, 0); /* close everything */ + emit_label (w, ".Ldebug_info_end"); + emit_section_change (w, ".debug_info", 0); + } /* Compilation unit */ emit_uleb128 (w, ABBREV_COMPILE_UNIT); @@ -664,7 +717,10 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra emit_pointer_value (w, 0); emit_pointer_value (w, 0); /* offset into .debug_line section */ - emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0); + if (w->emit_line) + emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0); + else + emit_int32 (w, 0); /* Base types */ for (i = 0; i < G_N_ELEMENTS (basic_types); ++i) { @@ -675,37 +731,54 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra emit_string (w, basic_types [i].name); } + emit_debug_info_end (w); + /* debug_loc section */ emit_section_change (w, ".debug_loc", 0); emit_label (w, ".Ldebug_loc_start"); /* debug_line section */ - emit_line_number_info_begin (w); + if (w->emit_line) + emit_line_number_info_begin (w); emit_cie (w); } +static const char* emit_type (MonoDwarfWriter *w, MonoType *t); + /* Returns the local symbol pointing to the emitted debug info */ static char* -emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass) +emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass, gboolean vtype) { - char *die; - char *full_name; + char *die, *pointer_die, *reference_die; + char *full_name, *p; gpointer iter; MonoClassField *field; const char *fdie; int k; gboolean emit_namespace = FALSE; + GHashTable *cache; // FIXME: Appdomains if (!w->class_to_die) w->class_to_die = g_hash_table_new (NULL, NULL); + if (!w->class_to_vtype_die) + w->class_to_vtype_die = g_hash_table_new (NULL, NULL); + if (!w->class_to_pointer_die) + w->class_to_pointer_die = g_hash_table_new (NULL, NULL); + if (!w->class_to_reference_die) + w->class_to_reference_die = g_hash_table_new (NULL, NULL); + + if (vtype) + cache = w->class_to_vtype_die; + else + cache = w->class_to_die; - die = g_hash_table_lookup (w->class_to_die, klass); + die = g_hash_table_lookup (cache, klass); if (die) return die; - if (!((klass->byval_arg.type == MONO_TYPE_CLASS) || klass->enumtype)) + if (!((klass->byval_arg.type == MONO_TYPE_CLASS) || (klass->byval_arg.type == MONO_TYPE_OBJECT) || klass->byval_arg.type == MONO_TYPE_GENERICINST || klass->enumtype || (klass->byval_arg.type == MONO_TYPE_VALUETYPE && vtype))) return NULL; /* @@ -721,13 +794,28 @@ emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass) } full_name = g_strdup_printf ("%s%s%s", klass->name_space, klass->name_space ? "." : "", klass->name); + /* + * gdb doesn't support namespaces for non-C++ dwarf objects, so use _ + * to separate components. + */ + for (p = full_name; *p; p ++) + if (*p == '.') + *p = '_'; die = g_strdup_printf (".LTDIE_%d", w->tdie_index); - emit_label (w, die); + pointer_die = g_strdup_printf (".LTDIE_%d_POINTER", w->tdie_index); + reference_die = g_strdup_printf (".LTDIE_%d_REFERENCE", w->tdie_index); + w->tdie_index ++; + + g_hash_table_insert (w->class_to_pointer_die, klass, pointer_die); + g_hash_table_insert (w->class_to_reference_die, klass, reference_die); + g_hash_table_insert (cache, klass, die); if (klass->enumtype) { int size = mono_class_value_size (mono_class_from_mono_type (mono_class_enum_basetype (klass)), NULL); + emit_label (w, die); + emit_uleb128 (w, ABBREV_ENUM_TYPE); emit_string (w, full_name); emit_uleb128 (w, size); @@ -786,32 +874,59 @@ emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass) } } } else { + guint8 buf [128]; + guint8 *p; + char *parent_die; + + if (klass->parent) + parent_die = emit_class_dwarf_info (w, klass->parent, FALSE); + else + parent_die = NULL; + + /* Emit field types */ + iter = NULL; + while ((field = mono_class_get_fields (klass, &iter))) { + if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) + continue; + + emit_type (w, field->type); + } + + emit_label (w, die); + emit_uleb128 (w, ABBREV_STRUCT_TYPE); emit_string (w, full_name); emit_uleb128 (w, klass->instance_size); + if (parent_die) { + emit_uleb128 (w, ABBREV_INHERITANCE); + emit_symbol_diff (w, parent_die, ".Ldebug_info_start", 0); + + p = buf; + *p ++= DW_OP_plus_uconst; + encode_uleb128 (0, p, &p); + emit_byte (w, p - buf); + emit_bytes (w, buf, p - buf); + } + /* Emit fields */ iter = NULL; while ((field = mono_class_get_fields (klass, &iter))) { - guint8 buf [128]; - guint8 *p; - if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) continue; - for (k = 0; k < G_N_ELEMENTS (basic_types); ++k) - if (basic_types [k].type == field->type->type) - break; - if (k < G_N_ELEMENTS (basic_types) && field->type->type != MONO_TYPE_SZARRAY && field->type->type != MONO_TYPE_CLASS) { - fdie = basic_types [k].die_name; - + fdie = emit_type (w, field->type); + if (fdie) { emit_uleb128 (w, ABBREV_DATA_MEMBER); emit_string (w, field->name); emit_symbol_diff (w, fdie, ".Ldebug_info_start", 0); /* location */ p = buf; *p ++= DW_OP_plus_uconst; - encode_uleb128 (field->offset, p, &p); + if (klass->valuetype && vtype) + encode_uleb128 (field->offset - sizeof (MonoObject), p, &p); + else + encode_uleb128 (field->offset, p, &p); emit_byte (w, p - buf); emit_bytes (w, buf, p - buf); @@ -827,26 +942,48 @@ emit_class_dwarf_info (MonoDwarfWriter *w, MonoClass *klass) emit_string (w, full_name); emit_symbol_diff (w, die, ".Ldebug_info_start", 0); - g_free (full_name); - w->tdie_index ++; + /* Add a pointer type */ + emit_label (w, pointer_die); + + emit_uleb128 (w, ABBREV_POINTER_TYPE); + emit_symbol_diff (w, die, ".Ldebug_info_start", 0); + /* Add a reference type */ + emit_label (w, reference_die); + + emit_uleb128 (w, ABBREV_REFERENCE_TYPE); + emit_symbol_diff (w, die, ".Ldebug_info_start", 0); + + g_free (full_name); if (emit_namespace) { /* Namespace end */ emit_uleb128 (w, 0x0); } - g_hash_table_insert (w->class_to_die, klass, die); return die; } -static void -emit_var_type (MonoDwarfWriter *w, MonoType *t) +static const char* +emit_type (MonoDwarfWriter *w, MonoType *t) { MonoClass *klass = mono_class_from_mono_type (t); int j; const char *tdie; + if (t->byref) { + if (t->type == MONO_TYPE_VALUETYPE) { + tdie = emit_class_dwarf_info (w, klass, TRUE); + if (tdie) + return g_hash_table_lookup (w->class_to_pointer_die, klass); + } + else { + tdie = emit_class_dwarf_info (w, klass, FALSE); + /* Should return a pointer type to a reference */ + } + // FIXME: + t = &mono_defaults.int_class->byval_arg; + } for (j = 0; j < G_N_ELEMENTS (basic_types); ++j) if (basic_types [j].type == t->type) break; @@ -855,23 +992,43 @@ emit_var_type (MonoDwarfWriter *w, MonoType *t) else { switch (t->type) { case MONO_TYPE_CLASS: + emit_class_dwarf_info (w, klass, FALSE); + tdie = g_hash_table_lookup (w->class_to_reference_die, klass); + //tdie = ".LDIE_OBJECT"; + break; case MONO_TYPE_ARRAY: tdie = ".LDIE_OBJECT"; break; case MONO_TYPE_VALUETYPE: if (klass->enumtype) - tdie = emit_class_dwarf_info (w, klass); + tdie = emit_class_dwarf_info (w, klass, FALSE); else tdie = ".LDIE_I4"; break; + case MONO_TYPE_GENERICINST: + if (!MONO_TYPE_ISSTRUCT (t)) { + emit_class_dwarf_info (w, klass, FALSE); + tdie = g_hash_table_lookup (w->class_to_reference_die, klass); + } else { + tdie = ".LDIE_I4"; + } + break; default: tdie = ".LDIE_I4"; break; } } - if (t->byref) - // FIXME: - tdie = ".LDIE_I4"; + + return tdie; +} + +static void +emit_var_type (MonoDwarfWriter *w, MonoType *t) +{ + const char *tdie; + + tdie = emit_type (w, t); + emit_symbol_diff (w, tdie, ".Ldebug_info_start", 0); } @@ -932,6 +1089,7 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token) char *res, *desc; MonoMethod *cmethod; MonoClass *klass; + MonoClassField *field; gpointer data = NULL; if (method->wrapper_type) @@ -939,6 +1097,7 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token) switch (*token_handler_ip) { case CEE_ISINST: + case CEE_CASTCLASS: case CEE_LDELEMA: if (method->wrapper_type) klass = data; @@ -966,6 +1125,18 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token) res = g_strdup_printf ("<0x%08x>", token); } break; + case CEE_LDFLD: + case CEE_LDSFLD: + case CEE_STFLD: + case CEE_STSFLD: + if (method->wrapper_type) + field = data; + else + field = mono_field_from_token (method->klass->image, token, &klass, NULL); + desc = mono_field_full_name (field); + res = g_strdup_printf ("<%s>", desc); + g_free (desc); + break; default: res = g_strdup_printf ("<0x%08x>", token); break; @@ -1094,8 +1265,10 @@ compare_lne (MonoDebugLineNumberEntry *a, MonoDebugLineNumberEntry *b) } static void -emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, guint8 *code, - guint32 code_size, MonoDebugMethodJitInfo *debug_info) +emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, + char *start_symbol, char *end_symbol, + guint8 *code, guint32 code_size, + MonoDebugMethodJitInfo *debug_info) { guint32 prev_line = 0; guint32 prev_native_offset = 0; @@ -1108,15 +1281,16 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, guint8 *code, GArray *ln_array; int *native_to_il_offset = NULL; - if (!code) - // FIXME: The set_address op below only works with xdebug + if (!w->emit_line) return; minfo = mono_debug_lookup_method (method); /* Compute the native->IL offset mapping */ -#ifndef EGLIB_MAJOR + g_assert (code_size); + +#ifndef _EGLIB_MAJOR 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); @@ -1186,7 +1360,10 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, guint8 *code, emit_byte (w, 0); emit_byte (w, sizeof (gpointer) + 1); emit_byte (w, DW_LNE_set_address); - emit_pointer_value (w, code); + 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 @@ -1233,7 +1410,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, guint8 *code, emit_byte (w, 0); emit_byte (w, 1); emit_byte (w, DW_LNE_end_sequence); - } else if (code) { + } else if (!start_symbol) { /* No debug info, XDEBUG mode */ char *name, *dis; const guint8 *ip = header->code; @@ -1283,10 +1460,16 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, guint8 *code, continue; line = il_to_line [lne->il_offset]; if (!line) { - /* To help debugging */ + /* + * This seems to happen randomly, it looks like il_offset points + * into the middle of an instruction. + */ + continue; + /* printf ("%s\n", mono_method_full_name (method, TRUE)); printf ("%d %d\n", lne->il_offset, header->code_size); g_assert (line); + */ } if (line - prev_line != 0) { @@ -1310,6 +1493,25 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, guint8 *code, } } +static MonoMethodVar* +find_vmv (MonoCompile *cfg, MonoInst *ins) +{ + int j; + + if (cfg->varinfo) { + for (j = 0; j < cfg->num_varinfo; ++j) { + if (cfg->varinfo [j] == ins) + break; + } + + if (j < cfg->num_varinfo) { + return MONO_VARINFO (cfg, j); + } + } + + return NULL; +} + 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) { @@ -1334,18 +1536,21 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod MonoType *t; if (i == 0 && sig->hasthis) { - t = &method->klass->this_arg; + if (method->klass->valuetype) + t = &method->klass->this_arg; + else + t = &method->klass->byval_arg; } else { t = sig->params [i - sig->hasthis]; } - emit_class_dwarf_info (w, mono_class_from_mono_type (t)); + emit_type (w, t); } /* Local types */ local_tdies = g_new0 (char *, header->num_locals); for (i = 0; i < header->num_locals; ++i) { - emit_class_dwarf_info (w, mono_class_from_mono_type (header->locals [i])); + emit_type (w, header->locals [i]); } /* Subprogram */ @@ -1374,16 +1579,25 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod MonoType *t; const char *pname; char pname_buf [128]; + MonoMethodVar *vmv = NULL; + gboolean need_loclist = FALSE; + + vmv = find_vmv (cfg, arg); + if (code && vmv && (vmv->live_range_start || vmv->live_range_end)) + need_loclist = TRUE; if (i == 0 && sig->hasthis) { - t = &mono_defaults.object_class->byval_arg; + if (method->klass->valuetype) + t = &method->klass->this_arg; + else + t = &method->klass->byval_arg; pname = "this"; } else { t = sig->params [i - sig->hasthis]; pname = names [i - sig->hasthis]; } - - emit_uleb128 (w, ABBREV_PARAM); + + emit_uleb128 (w, need_loclist ? ABBREV_PARAM_LOCLIST : ABBREV_PARAM); /* name */ if (pname[0] == '\0') { sprintf (pname_buf, "param%d", i - sig->hasthis); @@ -1398,8 +1612,16 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod p = buf; encode_var_location (w, arg, p, &p); - emit_byte (w, p - buf); - emit_bytes (w, buf, p - buf); + if (need_loclist) { + vmv->live_range_start = 0; + if (vmv->live_range_end == 0) + /* FIXME: Uses made in calls are not recorded */ + vmv->live_range_end = code_size; + emit_loclist (w, arg, code + vmv->live_range_start, code + vmv->live_range_end, buf, p - buf); + } else { + emit_byte (w, p - buf); + emit_bytes (w, buf, p - buf); + } } g_free (names); @@ -1414,25 +1636,15 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod gboolean need_loclist = FALSE; /* ins->dreg no longer contains the original vreg */ - if (cfg->varinfo) { - for (j = 0; j < cfg->num_varinfo; ++j) { - if (cfg->varinfo [j] == ins) - break; - } - - if (code && j < cfg->num_varinfo) { - vmv = MONO_VARINFO (cfg, j); - if (vmv->live_range_start) { - /* This variable has a precise live range */ - need_loclist = TRUE; - } + vmv = find_vmv (cfg, ins); + if (code && vmv) { + if (vmv->live_range_start) { + /* This variable has a precise live range */ + need_loclist = TRUE; } } - if (need_loclist) - emit_uleb128 (w, ABBREV_VARIABLE_LOCLIST); - else - emit_uleb128 (w, ABBREV_VARIABLE); + emit_uleb128 (w, need_loclist ? ABBREV_VARIABLE_LOCLIST : ABBREV_VARIABLE); /* name */ for (j = 0; j < num_locals; ++j) if (local_indexes [j] == i) @@ -1471,13 +1683,18 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod emit_line (w); + emit_debug_info_end (w); + /* Emit unwind info */ - emit_fde (w, w->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, TRUE); - w->fde_index ++; + if (unwind_info) { + emit_fde (w, w->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, TRUE); + w->fde_index ++; + } /* Emit line number info */ - if (code && debug_info) - emit_line_number_info (w, method, code, code_size, debug_info); + /* != could happen when using --regression */ + if (debug_info && (debug_info->code_start == code)) + emit_line_number_info (w, method, start_symbol, end_symbol, code, code_size, debug_info); emit_line (w); } @@ -1500,7 +1717,10 @@ mono_dwarf_writer_emit_trampoline (MonoDwarfWriter *w, const char *tramp_name, c /* Subprogram end */ emit_uleb128 (w, 0x0); + emit_debug_info_end (w); + /* Emit unwind info */ emit_fde (w, w->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, FALSE); w->fde_index ++; } +#endif /* End of: !defined(DISABLE_AOT) && !defined(DISABLE_JIT) */