static void
dwarf2_write_byte (FILE *f, int byte)
{
- fprintf (f, "\t.byte\t\t%d\n", byte);
+ fprintf (f, "\t.byte %d\n", byte);
}
static void
dwarf2_write_2byte (FILE *f, int word)
{
- fprintf (f, "\t.2byte\t\t%d\n", word);
+ fprintf (f, "\t.word %d\n", word);
}
static void
dwarf2_write_pair (FILE *f, int a, int b)
{
- fprintf (f, "\t.uleb128\t\t%d, %d\n", a, b);
+ fprintf (f, "\t.uleb128 %d, %d\n", a, b);
}
static void
dwarf2_write_long (FILE *f, unsigned long value)
{
- fprintf (f, "\t.long\t\t%lu\n", value);
+ fprintf (f, "\t.long %lu\n", value);
}
static void
-dwarf2_write_address (FILE *f, void *address)
+dwarf2_write_address (FILE *f, const void *address)
{
- fprintf (f, "\t.long\t\t%p\n", address);
+ fprintf (f, "\t.long 0x%lx\n", (long) address);
}
static void
dwarf2_write_string (FILE *f, const char *string)
{
- fprintf (f, "\t.string\t\t\"%s\"\n", string);
+ fprintf (f, "\t.string \"%s\"\n", string);
}
static void
dwarf2_write_sleb128 (FILE *f, long value)
{
- fprintf (f, "\t.sleb128\t%ld\n", value);
+ fprintf (f, "\t.sleb128 %ld\n", value);
}
static void
dwarf2_write_uleb128 (FILE *f, unsigned long value)
{
- fprintf (f, "\t.uleb128\t%lu\n", value);
+ fprintf (f, "\t.uleb128 %lu\n", value);
}
static void
dwarf2_write_section_start (FILE *f, const char *section)
{
- fprintf (f, "\t.section\t.%s\n", section);
-}
-
-static void
-dwarf2_write_section_end (FILE *f)
-{
- fprintf (f, "\t.previous\n\n");
+ fprintf (f, "\t.section .%s\n", section);
}
static void
static void
dwarf2_write_section_size (FILE *f, const char *start_label, const char *end_label)
{
- fprintf (f, "\t.long\t\t.L_%s - .L_%s\n", end_label, start_label);
+ fprintf (f, "\t.long .L_%s - .L_%s\n", end_label, start_label);
}
static void
dwarf2_write_ref4 (FILE *f, const char *target_label)
{
- fprintf (f, "\t.long\t\t.L_%s\n", target_label);
+ fprintf (f, "\t.long .L_%s\n", target_label);
}
static void
dwarf2_write_type_ref (FILE *f, unsigned long type_index)
{
- fprintf (f, "\t.long\t\t.L_TYPE_%lu - .L_debug_info_b\n", type_index);
+ fprintf (f, "\t.long .L_TYPE_%lu - .L_debug_info_b\n", type_index);
}
static void
dwarf2_write_type_ptr_ref (FILE *f, unsigned long idx)
{
- fprintf (f, "\t.long\t\t.L_TYPE_PTR_%lu - .L_debug_info_b\n", idx);
+ fprintf (f, "\t.long .L_TYPE_PTR_%lu - .L_debug_info_b\n", idx);
}
static void
dwarf2_write_relative_ref (FILE *f, const gchar *name, unsigned long idx)
{
- fprintf (f, "\t.long\t\t.L_%s_%lu - .L_debug_info_b\n", name, idx);
+ fprintf (f, "\t.long .L_%s_%lu - .L_debug_info_b\n", name, idx);
}
static void
}
static void
-dwarf2_write_dw_lne_set_address (FILE *f, void *address)
+dwarf2_write_dw_lne_set_address (FILE *f, const void *address)
{
dwarf2_write_byte (f, 0);
dwarf2_write_byte (f, sizeof (address) + 1);
char start [BUFSIZ], end [BUFSIZ];
static long label_index = 0;
+ // Don't include any static fields, they aren't supported yet.
+ // If a struct contains a static field which has the same type as
+ // the struct itself, we'd get a recursion loop there.
+ if (klass->fields [idx].type->attrs & FIELD_ATTRIBUTE_STATIC)
+ return;
+
sprintf (start, "DSF1_%ld", ++label_index);
sprintf (end, "DSF2_%ld", label_index);
dwarf2_write_string_type (debug, klass, idx);
break;
default:
+#if 0
g_message (G_STRLOC ": %s.%s - 0x%x - 0x%x", klass->name_space, klass->name,
klass->byval_arg.type, klass->flags);
+#endif
// DW_TAG_basic_type
dwarf2_write_byte (debug->f, ABBREV_BASE_TYPE);
}
static void
-dwarf2_write_parameter (MonoDebugHandle *debug, DebugMethodInfo *minfo, const gchar *name,
+dwarf2_write_parameter (MonoDebugHandle *debug, MonoDebugMethodInfo *minfo, const gchar *name,
MonoDebugVarInfo *var, MonoClass *klass)
{
static long label_index = 0;
dwarf2_write_label (debug->f, start);
dwarf2_write_variable_location (debug, var);
dwarf2_write_label (debug->f, end);
- dwarf2_write_long (debug->f, minfo->method_info.prologue_end);
+ dwarf2_write_long (debug->f, minfo->jit->prologue_end);
}
static void
-dwarf2_write_variable (MonoDebugHandle *debug, DebugMethodInfo *minfo, const gchar *name,
+dwarf2_write_variable (MonoDebugHandle *debug, MonoDebugMethodInfo *minfo, const gchar *name,
MonoDebugVarInfo *var, MonoClass *klass)
{
static long label_index = 0;
dwarf2_write_label (debug->f, start);
dwarf2_write_variable_location (debug, var);
dwarf2_write_label (debug->f, end);
- dwarf2_write_address (debug->f, minfo->method_info.code_start + var->begin_scope);
- dwarf2_write_address (debug->f, minfo->method_info.code_start + var->end_scope);
+ dwarf2_write_address (debug->f, minfo->jit->code_start + var->begin_scope);
+ dwarf2_write_address (debug->f, minfo->jit->code_start + var->end_scope);
}
static void
-write_method_lines_dwarf2 (MonoDebugHandle *debug, DebugMethodInfo *minfo)
+write_method_lines_dwarf2 (MonoDebugHandle *debug, MonoDebugMethodInfo *minfo)
{
guint32 st_line = 0;
- gpointer st_address = 0;
+ gconstpointer st_address = 0;
+ DebugMethodInfo *priv = minfo->user_data;
int i;
- if (!minfo->line_numbers)
+ if (!minfo->jit || !minfo->jit->line_numbers)
return;
// Start of statement program
- dwarf2_write_dw_lns_set_file (debug->f, minfo->source_file);
- dwarf2_write_dw_lns_advance_line (debug->f, minfo->start_line - 1);
- dwarf2_write_dw_lne_set_address (debug->f, minfo->method_info.code_start);
+ dwarf2_write_dw_lns_set_file (debug->f, priv->source_file);
+ dwarf2_write_dw_lns_advance_line (debug->f, priv->start_line - 1);
+ dwarf2_write_dw_lne_set_address (debug->f, minfo->jit->code_start);
dwarf2_write_dw_lns_negate_stmt (debug->f);
dwarf2_write_dw_lns_copy (debug->f);
- st_line = minfo->start_line;
- st_address = minfo->method_info.code_start;
+ st_line = priv->start_line;
+ st_address = 0;
- for (i = 1; i < minfo->line_numbers->len; i++) {
- DebugLineNumberInfo *lni = g_ptr_array_index (minfo->line_numbers, i);
+ for (i = 1; i < minfo->jit->line_numbers->len; i++) {
+ MonoDebugLineNumberEntry lne = g_array_index (
+ minfo->jit->line_numbers, MonoDebugLineNumberEntry, i);
gint32 line_inc, addr_inc, opcode;
int used_standard_opcode = 0;
- line_inc = lni->line - st_line;
- addr_inc = (char *)lni->address - (char *)st_address;
+ line_inc = lne.line - st_line;
+ addr_inc = (char *)lne.address - (char *)st_address;
if (addr_inc < 0) {
- dwarf2_write_dw_lne_set_address (debug->f, lni->address);
+ dwarf2_write_dw_lne_set_address (debug->f, lne.address + minfo->jit->code_start);
used_standard_opcode = 1;
} else if (addr_inc && !line_inc) {
dwarf2_write_dw_lns_advance_pc (debug->f, addr_inc);
}
dwarf2_write_dw_lne_set_address (debug->f,
- (char *)minfo->method_info.code_start +
- minfo->method_info.epilogue_begin);
- dwarf2_write_dw_lns_advance_line (debug->f, minfo->last_line - st_line);
+ (char *)minfo->jit->code_start +
+ minfo->jit->epilogue_begin);
+ dwarf2_write_dw_lns_advance_line (debug->f, priv->last_line - st_line);
dwarf2_write_dw_lns_copy (debug->f);
dwarf2_write_dw_lns_copy (debug->f);
write_method_lines_dwarf2 (user_data, value);
}
+static void
+write_method_lines_func_1 (gpointer key, gpointer value, gpointer user_data)
+{
+ AssemblyDebugInfo *info = (AssemblyDebugInfo *) value;
+
+ g_hash_table_foreach (info->methods, write_method_lines_func, user_data);
+}
+
static void
write_line_numbers (MonoDebugHandle *debug)
{
dwarf2_write_byte (debug->f, 0);
dwarf2_write_label (debug->f, "DL3");
- g_hash_table_foreach (debug->methods, write_method_lines_func, debug);
+ g_hash_table_foreach (debug->images, write_method_lines_func_1, debug);
dwarf2_write_label (debug->f, "debug_line_e");
- dwarf2_write_section_end (debug->f);
}
static void
}
static void
-write_method_dwarf2 (MonoDebugHandle *debug, DebugMethodInfo *minfo)
+write_method_dwarf2 (MonoDebugHandle *debug, MonoDebugMethodInfo *minfo)
{
int is_external = 0, i;
MonoType *ret_type = NULL;
+ DebugMethodInfo *priv = minfo->user_data;
gchar **names;
- if (minfo->method_info.method->signature->ret->type != MONO_TYPE_VOID)
- ret_type = minfo->method_info.method->signature->ret;
+ if (!minfo->jit)
+ return;
+
+ if (minfo->method->signature->ret->type != MONO_TYPE_VOID)
+ ret_type = minfo->method->signature->ret;
// DW_TAG_subprogram
if (ret_type)
dwarf2_write_byte (debug->f, ABBREV_SUBPROGRAM_RETVAL);
else
dwarf2_write_byte (debug->f, ABBREV_SUBPROGRAM);
- dwarf2_write_string (debug->f, minfo->name);
+ dwarf2_write_string (debug->f, priv->name);
dwarf2_write_byte (debug->f, is_external);
- dwarf2_write_address (debug->f, minfo->method_info.code_start);
- dwarf2_write_address (debug->f, (char *)minfo->method_info.code_start + minfo->method_info.code_size);
+ dwarf2_write_address (debug->f, minfo->jit->code_start);
+ dwarf2_write_address (debug->f, (char *)minfo->jit->code_start + minfo->jit->code_size);
dwarf2_write_byte (debug->f, DW_CC_nocall);
if (ret_type) {
MonoClass *klass = mono_class_from_mono_type (ret_type);
dwarf2_write_type_ref (debug->f, type_index);
}
- if (minfo->method_info.method->signature->hasthis)
- dwarf2_write_parameter (debug, minfo, "this", minfo->method_info.this_var,
- minfo->method_info.method->klass);
+ if (minfo->method->signature->hasthis)
+ dwarf2_write_parameter (debug, minfo, "this", minfo->jit->this_var,
+ minfo->method->klass);
- names = g_new (char *, minfo->method_info.method->signature->param_count);
- mono_method_get_param_names (minfo->method_info.method, (const char **) names);
+ names = g_new (char *, minfo->method->signature->param_count);
+ mono_method_get_param_names (minfo->method, (const char **) names);
- for (i = 0; i < minfo->method_info.num_params; i++) {
- MonoType *type = minfo->method_info.method->signature->params [i];
+ for (i = 0; i < minfo->jit->num_params; i++) {
+ MonoType *type = minfo->method->signature->params [i];
MonoClass *klass = mono_class_from_mono_type (type);
- dwarf2_write_parameter (debug, minfo, names [i], &minfo->method_info.params [i], klass);
+ dwarf2_write_parameter (debug, minfo, names [i], &minfo->jit->params [i], klass);
}
g_free (names);
- for (i = 0; i < minfo->method_info.num_locals; i++) {
- MonoMethodHeader *header = ((MonoMethodNormal*) minfo->method_info.method)->header;
+ for (i = 0; i < minfo->jit->num_locals; i++) {
+ MonoMethodHeader *header = ((MonoMethodNormal*) minfo->method)->header;
MonoClass *klass = mono_class_from_mono_type (header->locals [i]);
char name [BUFSIZ];
sprintf (name, "V_%d", i);
- dwarf2_write_variable (debug, minfo, name, &minfo->method_info.locals [i], klass);
+ dwarf2_write_variable (debug, minfo, name, &minfo->jit->locals [i], klass);
}
dwarf2_write_byte (debug->f, 0);
write_method_dwarf2 (user_data, value);
}
+static void
+write_method_func_1 (gpointer key, gpointer value, gpointer user_data)
+{
+ AssemblyDebugInfo *info = (AssemblyDebugInfo *) value;
+
+ g_hash_table_foreach (info->methods, write_method_func, user_data);
+}
+
void
mono_debug_write_dwarf2 (MonoDebugHandle *debug)
{
- char *buf;
-
if (!(debug->f = fopen (debug->filename, "w"))) {
g_warning ("Can't create dwarf file `%s': %s", debug->filename, g_strerror (errno));
return;
}
+ // Produce assembler code which is free of comments and extra whitespaces.
+ fprintf (debug->f, "#NOAPP\n");
+
// DWARF 2 Abbreviation table.
dwarf2_write_section_start (debug->f, "debug_abbrev");
dwarf2_write_label (debug->f, "debug_abbrev");
dwarf2_write_pair (debug->f, 0, 0);
dwarf2_write_label (debug->f, "debug_abbrev_e");
- dwarf2_write_section_end (debug->f);
// Line numbers
write_line_numbers (debug);
dwarf2_write_ref4 (debug->f, "debug_lines_b");
// Methods
- g_hash_table_foreach (debug->methods, write_method_func, debug);
+ g_hash_table_foreach (debug->images, write_method_func_1, debug);
// Derived types
g_hash_table_foreach (debug->type_hash, write_class, debug);
dwarf2_write_label (debug->f, "debug_info_e");
- dwarf2_write_section_end (debug->f);
-
fclose (debug->f);
debug->f = NULL;
- /* yes, it's completely unsafe */
- buf = g_strdup_printf ("as %s -o %s", debug->filename, debug->objfile);
- system (buf);
- g_free (buf);
+ if (!(debug->flags & MONO_DEBUG_FLAGS_DONT_ASSEMBLE)) {
+ char *buf;
+
+ /* yes, it's completely unsafe */
+ buf = g_strdup_printf ("as %s -o %s", debug->filename, debug->objfile);
+ system (buf);
+ g_free (buf);
+ }
}