#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;
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
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,
};
return index;
}
-static void
-emit_line_number_info_begin (MonoDwarfWriter *w)
-{
- /* Line number info header */
- /*
- * GAS seems to emit its own data to the end of the first subsection, so we use
- * subsections 1, 2 etc:
- * 1 - contains the header
- * 2 - contains the file names
- * 3 - contains the end of the header + the data
- * 4 - the end symbol
- */
- emit_section_change (w, ".debug_line", 0);
- emit_label (w, ".Ldebug_line_section_start");
- emit_section_change (w, ".debug_line", LINE_SUBSECTION_HEADER);
- emit_label (w, ".Ldebug_line_start");
- emit_symbol_diff (w, ".Ldebug_line_end", ".", -4); /* length */
- emit_int16 (w, 0x2); /* version */
- emit_symbol_diff (w, ".Ldebug_line_header_end", ".", -4); /* header_length */
- emit_byte (w, 1); /* minimum_instruction_length */
- emit_byte (w, 1); /* default_is_stmt */
- emit_byte (w, LINE_BASE); /* line_base */
- emit_byte (w, LINE_RANGE); /* line_range */
- emit_byte (w, OPCODE_BASE); /* opcode_base */
- emit_byte (w, 0); /* standard_opcode_lengths */
- emit_byte (w, 1);
- emit_byte (w, 1);
- emit_byte (w, 1);
- emit_byte (w, 1);
- emit_byte (w, 0);
- emit_byte (w, 0);
- emit_byte (w, 0);
- emit_byte (w, 1);
- emit_byte (w, 0);
- emit_byte (w, 0);
- emit_byte (w, 1);
-
- /* Includes */
- emit_section_change (w, ".debug_line", LINE_SUBSECTION_INCLUDES);
-
- /* End of Includes */
- emit_section_change (w, ".debug_line", LINE_SUBSECTION_FILES);
- emit_byte (w, 0);
-
- /* Files */
- emit_line_number_file_name (w, "xdb.il", 0, 0);
-
- /* End of Files */
- emit_section_change (w, ".debug_line", LINE_SUBSECTION_DATA);
- emit_byte (w, 0);
-
- emit_label (w, ".Ldebug_line_header_end");
-
- /* Emit this into a separate subsection so it gets placed at the end */
- emit_section_change (w, ".debug_line", LINE_SUBSECTION_END);
-
- emit_byte (w, 0);
- emit_byte (w, 1);
- emit_byte (w, DW_LNE_end_sequence);
-
- emit_label (w, ".Ldebug_line_end");
-}
-
char *
mono_dwarf_escape_path (const char *name)
{
if (!minfo)
continue;
- mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL);
+ mono_debug_symfile_get_line_numbers_full (minfo, &source_file, &source_file_list, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
for (i = 0; i < source_file_list->len; ++i) {
MonoDebugSourceInfo *sinfo = g_ptr_array_index (source_file_list, i);
add_line_number_file_name (w, sinfo->source_file, 0, 0);
}
void
-mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_program)
+mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, const char *cu_name, GSList *base_unwind_program)
{
char *s, *build_info;
int i;
emit_string (w, s);
g_free (build_info);
g_free (s);
- emit_string (w, "JITted code");
+ emit_string (w, cu_name);
emit_string (w, "");
emit_byte (w, DW_LANG_C);
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_pointer_value (w, 0);
/* Base types */
for (i = 0; i < G_N_ELEMENTS (basic_types); ++i) {
emit_section_change (w, ".debug_loc", 0);
emit_label (w, ".Ldebug_loc_start");
- /* debug_line section */
- /*
- * We emit some info even if emit_line is FALSE, as the
- * apple linker seems to require a .debug_line section.
- */
- if (!w->collect_line_info)
- emit_line_number_info_begin (w);
-
emit_cie (w);
}
static char*
token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
{
+ MonoError error;
char *res, *desc;
MonoMethod *cmethod;
MonoClass *klass;
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:
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);
prev_line = 1;
prev_il_offset = -1;
+ w->cur_file_index = -1;
for (i = 0; i < code_size; ++i) {
int line_diff, addr_diff;
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;
- prev_native_offset = i;
first = FALSE;
}
w->cur_file_index = file_index;
}
}
+ }
+
+ 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);
}
mono_debug_symfile_free_location (loc);
+ first = FALSE;
}
g_free (native_to_il_offset);
}
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;
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