FILE *il_file;
int il_file_line_index, loclist_index;
GSList *cie_program;
+ FILE *fp;
+ const char *temp_prefix;
+ gboolean emit_line;
};
/*
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;
}
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
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);
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);
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) {
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 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;
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 */
+ g_assert (code_size);
+
#ifndef _EGLIB_MAJOR
ln_array = g_array_sized_new (FALSE, FALSE, sizeof (MonoDebugLineNumberEntry),
debug_info->num_line_numbers);
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
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;
emit_line (w);
+ emit_debug_info_end (w);
+
/* Emit unwind info */
if (unwind_info) {
emit_fde (w, w->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, TRUE);
}
/* Emit line number info */
- if (code && debug_info)
- /* != could happen when using --regression */
- if (debug_info->code_start == code)
- 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);
}
/* 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 ++;