#define MRT_mono_string_fieldsize 0x11
#define MRT_mono_array_fieldsize 0x12
#define MRT_type_field_fieldsize 0x13
+#define MRT_mono_string_string_length 0x14
+#define MRT_mono_string_byte_size 0x15
+#define MRT_mono_string_data_location 0x16
+#define MRT_static_type_field_offset 0x17
+#define MRT_mono_array_data_location 0x18
+#define MRT_mono_array_max_length 0x19
+#define MRT_mono_array_length_byte_size 0x1a
#define MRI_string_offset_length 0x00
#define MRI_string_offset_chars 0x01
#define MRS_debug_line 0x03
#define MRS_mono_reloc_table 0x04
+#define DW_OP_const4u 0x0c
#define DW_OP_const4s 0x0d
#define DW_OP_plus 0x22
#define DW_OP_reg0 0x50
sfs->type = MONO_DEBUG_SYMBOL_SECTION_MONO_LINE_NUMBERS;
sfs->file_offset = section->sh_offset;
sfs->size = section->sh_size;
+ } else if (!strcmp (name, ".mono_symbol_table")) {
+ MonoDebugSymbolFileSection *sfs;
+
+ sfs = &symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE];
+ sfs->type = MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE;
+ sfs->file_offset = section->sh_offset;
+ sfs->size = section->sh_size;
}
}
}
static MonoClass *
-mono_debug_class_get (MonoDebugSymbolFile *symfile, guint32 type_token)
+find_class_by_name (MonoDebugSymbolFile *symfile, const char *nspace, const char *name)
{
+ MonoAssembly **assembly;
MonoClass *klass;
- if ((klass = g_hash_table_lookup (symfile->image->class_cache, GUINT_TO_POINTER (type_token))))
+ klass = mono_class_from_name (symfile->image, nspace, name);
+
+ if (klass)
return klass;
+ for (assembly = symfile->image->references; assembly && *assembly; assembly++) {
+ klass = mono_class_from_name ((*assembly)->image, nspace, name);
+
+ if (klass)
+ return klass;
+ }
+
+ g_message (G_STRLOC ": Can't find class %s.%s", nspace, name);
+
return NULL;
}
+static void
+read_symbol_table (MonoDebugSymbolFile *symfile)
+{
+ const char *ptr, *start, *end;
+ int version, i;
+ long section_size;
+
+ if (!symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE].file_offset)
+ return;
+
+ ptr = start = symfile->raw_contents +
+ symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE].file_offset;
+
+ version = *((guint16 *) ptr)++;
+ if (version != MONO_DEBUG_SYMBOL_FILE_VERSION) {
+ g_warning ("Symbol file %s has incorrect line number table version "
+ "(expected %d, got %d)", symfile->file_name,
+ MONO_DEBUG_SYMBOL_FILE_VERSION, version);
+ return;
+ }
+
+ section_size = *((guint32 *) ptr)++;
+ end = ptr + section_size;
+
+ g_free (symfile->type_table);
+
+ symfile->num_types = * ((guint32 *) ptr)++;
+ symfile->type_table = g_new0 (MonoClass *, symfile->num_types);
+
+ for (i = 0; i < symfile->num_types; i++) {
+ const char *name, *namespace;
+ MonoClass *klass;
+
+ namespace = ptr;
+ ptr += strlen (namespace) + 1;
+
+ name = ptr;
+ ptr += strlen (name) + 1;
+
+ klass = find_class_by_name (symfile, namespace, name);
+
+ if (klass)
+ symfile->type_table [i] = klass;
+ }
+}
+
+static MonoClass *
+mono_debug_class_get (MonoDebugSymbolFile *symfile, guint32 type_token)
+{
+ MonoClass *klass;
+
+ if (!type_token)
+ return mono_defaults.object_class;
+
+ if (type_token <= symfile->num_types)
+ return symfile->type_table [type_token - 1];
+
+ if ((klass = g_hash_table_lookup (symfile->image->class_cache, GUINT_TO_POINTER (type_token))))
+ return klass;
+
+ return NULL;
+}
+
MonoDebugSymbolFile *
mono_debug_open_symbol_file (MonoImage *image, const char *filename, gboolean emit_warnings)
{
return NULL;
}
+ read_symbol_table (symfile);
+
read_line_numbers (symfile);
return symfile;
int version, already_relocated = 0;
long reloc_size;
+ read_symbol_table (symfile);
+
if (!symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_RELOC_TABLE].file_offset)
return;
break;
}
+ case MRT_mono_string_string_length: {
+ MonoString string;
+ guint32 offset = (guchar *) &string.length - (guchar *) &string;
+
+ * ((guint8 *) base_ptr)++ = DW_OP_const4u;
+ * ((gint32 *) base_ptr)++ = offset;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+
+ break;
+ }
+
+ case MRT_mono_string_byte_size: {
+ MonoString string;
+
+ * (guint32 *) base_ptr = sizeof (string.length);
+
+ break;
+ }
+
+ case MRT_mono_string_data_location: {
+ MonoString string;
+ guint32 offset = (guchar *) &string.chars - (guchar *) &string;
+
+ * ((guint8 *) base_ptr)++ = DW_OP_const4u;
+ * ((gint32 *) base_ptr)++ = offset;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+
+ break;
+ }
+
+ case MRT_static_type_field_offset: {
+ guint32 token = *((guint32 *) tmp_ptr)++;
+ guint32 original = *((guint32 *) tmp_ptr)++;
+ MonoClass *klass = mono_debug_class_get (symfile, token);
+ MonoVTable *vtable;
+ guint32 off;
+
+ if (!klass)
+ continue;
+
+ mono_class_init (klass);
+
+ if (original > klass->field.count) {
+ g_warning ("Symbol file %s contains invalid field offset entry.",
+ symfile->file_name);
+ continue;
+ }
+
+ if (!klass->fields)
+ continue;
+
+ vtable = mono_class_vtable (mono_domain_get (), klass);
+
+ off = klass->fields [original].offset;
+
+#if 0
+ g_message ("Setting field %d of type %u (%p) to offset %d", original,
+ token, klass, off);
+#endif
+
+ * (void **) base_ptr = (char *) vtable->data + off;
+
+ break;
+ }
+
+ case MRT_mono_array_data_location: {
+ MonoArray array;
+ guint32 offset = (guchar *) &array.vector - (guchar *) &array;
+
+ * ((guint8 *) base_ptr)++ = DW_OP_const4u;
+ * ((gint32 *) base_ptr)++ = offset;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+
+ break;
+ }
+
+ case MRT_mono_array_max_length: {
+ MonoArray array;
+ guint32 offset = (guchar *) &array.max_length - (guchar *) &array;
+
+ * ((guint8 *) base_ptr)++ = DW_OP_const4u;
+ * ((gint32 *) base_ptr)++ = offset;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+ * ((guint8 *) base_ptr)++ = DW_OP_nop;
+
+ break;
+ }
+
+ case MRT_mono_array_length_byte_size: {
+ MonoArray array;
+
+ * (guint32 *) base_ptr = sizeof (array.max_length);
+
+ break;
+ }
default:
g_warning ("Symbol file %s contains unknown relocation entry %d",
}
gchar *
-mono_debug_find_source_location (MonoDebugSymbolFile *symfile, MonoMethod *method, guint32 offset)
+mono_debug_find_source_location (MonoDebugSymbolFile *symfile, MonoMethod *method, guint32 offset,
+ guint32 *line_number)
{
MonoDebugLineNumberBlock *lnb;
const char *ptr;
if (!row)
continue;
- if (iloffset >= offset)
- return g_strdup_printf ("%s:%d", lnb->source_file, row);
+ if (iloffset >= offset) {
+ if (line_number) {
+ *line_number = row;
+ return g_strdup (lnb->source_file);
+ } else
+ return g_strdup_printf ("%s:%d", lnb->source_file, row);
+ }
} while (1);
return NULL;