5 #include <mono/metadata/metadata.h>
6 #include <mono/metadata/rawbuffer.h>
7 #include <mono/metadata/tokentype.h>
8 #include <mono/metadata/appdomain.h>
9 #include <mono/metadata/exception.h>
10 #include <mono/metadata/debug-symfile.h>
19 /* Keep in sync with Mono.CSharp.Debugger.MonoDwarfFileWriter */
21 #define MRT_target_address_size 0x01
22 #define MRT_il_offset 0x02
23 #define MRT_method_start_address 0x03
24 #define MRT_method_end_address 0x04
25 #define MRT_local_variable 0x05
26 #define MRT_method_parameter 0x06
27 #define MRT_type_sizeof 0x07
28 #define MRT_type_field_offset 0x08
29 #define MRT_mono_string_sizeof 0x09
30 #define MRT_mono_string_offset 0x0a
31 #define MRT_mono_array_sizeof 0x0b
32 #define MRT_mono_array_offset 0x0c
33 #define MRT_mono_array_bounds_sizeof 0x0d
34 #define MRT_mono_array_bounds_offset 0x0e
35 #define MRT_variable_start_scope 0x0f
36 #define MRT_variable_end_scope 0x10
37 #define MRT_mono_string_fieldsize 0x11
38 #define MRT_mono_array_fieldsize 0x12
39 #define MRT_type_field_fieldsize 0x13
40 #define MRT_mono_string_string_length 0x14
41 #define MRT_mono_string_byte_size 0x15
42 #define MRT_mono_string_data_location 0x16
43 #define MRT_static_type_field_offset 0x17
44 #define MRT_mono_array_data_location 0x18
45 #define MRT_mono_array_max_length 0x19
46 #define MRT_mono_array_length_byte_size 0x1a
48 #define MRI_string_offset_length 0x00
49 #define MRI_string_offset_chars 0x01
51 #define MRI_array_offset_bounds 0x00
52 #define MRI_array_offset_max_length 0x01
53 #define MRI_array_offset_vector 0x02
55 #define MRI_array_bounds_offset_lower 0x00
56 #define MRI_array_bounds_offset_length 0x01
58 #define MRS_debug_info 0x01
59 #define MRS_debug_abbrev 0x02
60 #define MRS_debug_line 0x03
61 #define MRS_mono_reloc_table 0x04
63 #define DW_OP_const4u 0x0c
64 #define DW_OP_const4s 0x0d
65 #define DW_OP_plus 0x22
66 #define DW_OP_reg0 0x50
67 #define DW_OP_breg0 0x70
68 #define DW_OP_fbreg 0x91
69 #define DW_OP_piece 0x93
70 #define DW_OP_nop 0x96
75 get_sections_elf32 (MonoDebugSymbolFile *symfile, gboolean emit_warnings)
78 Elf32_Shdr *section, *strtab_section;
82 header = (Elf32_Ehdr *)symfile->raw_contents;
83 if (header->e_version != EV_CURRENT) {
85 g_warning ("Symbol file %s has unknown ELF version %d",
86 symfile->file_name, header->e_version);
90 if (header->e_machine != EM_386) {
92 g_warning ("ELF file %s is for unknown architecture %d",
93 symfile->file_name, header->e_machine);
97 if (header->e_shentsize != sizeof (*section)) {
99 g_warning ("ELF file %s has unknown section header size "
100 "(expected %d, got %d)", symfile->file_name,
101 sizeof (*section), header->e_shentsize);
105 symfile->section_offsets = g_new0 (MonoDebugSymbolFileSection, MONO_DEBUG_SYMBOL_SECTION_MAX);
107 section = (Elf32_Shdr *)(symfile->raw_contents + header->e_shoff);
108 strtab_section = section + header->e_shstrndx;
109 strtab = symfile->raw_contents + strtab_section->sh_offset;
111 for (i = 0; i < header->e_shnum; i++, section++) {
112 const gchar *name = strtab + section->sh_name;
114 if (!strcmp (name, ".debug_info")) {
115 MonoDebugSymbolFileSection *sfs;
117 sfs = &symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_DEBUG_INFO];
118 sfs->type = MONO_DEBUG_SYMBOL_SECTION_DEBUG_INFO;
119 sfs->file_offset = section->sh_offset;
120 sfs->size = section->sh_size;
121 } else if (!strcmp (name, ".debug_line")) {
122 MonoDebugSymbolFileSection *sfs;
124 sfs = &symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_DEBUG_LINE];
125 sfs->type = MONO_DEBUG_SYMBOL_SECTION_DEBUG_LINE;
126 sfs->file_offset = section->sh_offset;
127 sfs->size = section->sh_size;
128 } else if (!strcmp (name, ".debug_abbrev")) {
129 MonoDebugSymbolFileSection *sfs;
131 sfs = &symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_DEBUG_ABBREV];
132 sfs->type = MONO_DEBUG_SYMBOL_SECTION_DEBUG_ABBREV;
133 sfs->file_offset = section->sh_offset;
134 sfs->size = section->sh_size;
135 } else if (!strcmp (name, ".mono_reloc_table")) {
136 MonoDebugSymbolFileSection *sfs;
138 sfs = &symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_RELOC_TABLE];
139 sfs->type = MONO_DEBUG_SYMBOL_SECTION_MONO_RELOC_TABLE;
140 sfs->file_offset = section->sh_offset;
141 sfs->size = section->sh_size;
142 } else if (!strcmp (name, ".mono_line_numbers")) {
143 MonoDebugSymbolFileSection *sfs;
145 sfs = &symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_LINE_NUMBERS];
146 sfs->type = MONO_DEBUG_SYMBOL_SECTION_MONO_LINE_NUMBERS;
147 sfs->file_offset = section->sh_offset;
148 sfs->size = section->sh_size;
149 } else if (!strcmp (name, ".mono_symbol_table")) {
150 MonoDebugSymbolFileSection *sfs;
152 sfs = &symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE];
153 sfs->type = MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE;
154 sfs->file_offset = section->sh_offset;
155 sfs->size = section->sh_size;
162 #endif /* HAVE_ELF_H */
165 get_sections (MonoDebugSymbolFile *symfile, gboolean emit_warnings)
169 static const char ELFMAG[] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, 0 };
171 if (!strncmp (symfile->raw_contents, ELFMAG, strlen (ELFMAG)))
172 return get_sections_elf32 (symfile, emit_warnings);
176 g_warning ("Symbol file %s has unknown file format", symfile->file_name);
182 read_line_numbers (MonoDebugSymbolFile *symfile)
184 const char *ptr, *start, *end;
188 if (!symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_LINE_NUMBERS].file_offset)
191 ptr = start = symfile->raw_contents +
192 symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_LINE_NUMBERS].file_offset;
194 version = *((guint16 *) ptr)++;
195 if (version != MONO_DEBUG_SYMBOL_FILE_VERSION) {
196 g_warning ("Symbol file %s has incorrect line number table version "
197 "(expected %d, got %d)", symfile->file_name,
198 MONO_DEBUG_SYMBOL_FILE_VERSION, version);
202 section_size = *((guint32 *) ptr)++;
203 end = ptr + section_size;
205 symfile->line_number_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
206 NULL, (GDestroyNotify) g_free);
209 MonoDebugLineNumberBlock *lnb;
210 guint32 token, source_offset;
213 token = * ((guint32 *) ptr)++;
214 method = mono_get_method (symfile->image, token, NULL);
218 lnb = g_new0 (MonoDebugLineNumberBlock, 1);
220 source_offset = * ((guint32 *) ptr)++;
221 lnb->source_file = (const char *) start + source_offset;
222 lnb->start_line = * ((guint32 *) ptr)++;
223 lnb->file_offset = * ((guint32 *) ptr)++;
225 g_hash_table_insert (symfile->line_number_table, method, lnb);
230 find_class_by_name (MonoDebugSymbolFile *symfile, const char *nspace, const char *name)
232 MonoAssembly **assembly;
235 klass = mono_class_from_name (symfile->image, nspace, name);
240 for (assembly = symfile->image->references; assembly && *assembly; assembly++) {
241 klass = mono_class_from_name ((*assembly)->image, nspace, name);
247 g_message (G_STRLOC ": Can't find class %s.%s", nspace, name);
253 read_symbol_table (MonoDebugSymbolFile *symfile)
255 const char *ptr, *start, *end;
259 if (!symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE].file_offset)
262 ptr = start = symfile->raw_contents +
263 symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_SYMBOL_TABLE].file_offset;
265 version = *((guint16 *) ptr)++;
266 if (version != MONO_DEBUG_SYMBOL_FILE_VERSION) {
267 g_warning ("Symbol file %s has incorrect line number table version "
268 "(expected %d, got %d)", symfile->file_name,
269 MONO_DEBUG_SYMBOL_FILE_VERSION, version);
273 section_size = *((guint32 *) ptr)++;
274 end = ptr + section_size;
276 g_free (symfile->type_table);
278 symfile->num_types = * ((guint32 *) ptr)++;
279 symfile->type_table = g_new0 (MonoClass *, symfile->num_types);
281 for (i = 0; i < symfile->num_types; i++) {
282 const char *name, *namespace;
286 ptr += strlen (namespace) + 1;
289 ptr += strlen (name) + 1;
291 klass = find_class_by_name (symfile, namespace, name);
294 symfile->type_table [i] = klass;
299 mono_debug_class_get (MonoDebugSymbolFile *symfile, guint32 type_token)
304 return mono_defaults.object_class;
306 if (type_token <= symfile->num_types)
307 return symfile->type_table [type_token - 1];
309 if ((klass = g_hash_table_lookup (symfile->image->class_cache, GUINT_TO_POINTER (type_token))))
315 MonoDebugSymbolFile *
316 mono_debug_open_symbol_file (MonoImage *image, const char *filename, gboolean emit_warnings)
318 MonoDebugSymbolFile *symfile;
323 fd = open (filename, O_RDWR);
326 g_warning ("Can't open symbol file: %s", filename);
330 file_size = lseek (fd, 0, SEEK_END);
331 lseek (fd, 0, SEEK_SET);
333 if (file_size == (off_t) -1) {
335 g_warning ("Can't get size of symbol file: %s", filename);
339 ptr = mono_raw_buffer_load (fd, 1, 0, file_size);
342 g_warning ("Can't read symbol file: %s", filename);
346 symfile = g_new0 (MonoDebugSymbolFile, 1);
348 symfile->file_name = g_strdup (filename);
349 symfile->image = image;
350 symfile->raw_contents = ptr;
351 symfile->raw_contents_size = file_size;
353 if (!get_sections (symfile, emit_warnings)) {
354 mono_debug_close_symbol_file (symfile);
358 read_symbol_table (symfile);
360 read_line_numbers (symfile);
366 mono_debug_close_symbol_file (MonoDebugSymbolFile *symfile)
371 if (symfile->raw_contents)
372 mono_raw_buffer_free (symfile->raw_contents);
376 if (symfile->line_number_table)
377 g_hash_table_destroy (symfile->line_number_table);
378 g_free (symfile->file_name);
379 g_free (symfile->section_offsets);
384 relocate_variable (MonoDebugVarInfo *var, void *base_ptr)
387 * ((guint8 *) base_ptr)++ = DW_OP_nop;
388 * ((guint8 *) base_ptr)++ = DW_OP_nop;
389 * ((guint8 *) base_ptr)++ = DW_OP_nop;
390 * ((guint8 *) base_ptr)++ = DW_OP_nop;
391 * ((guint8 *) base_ptr)++ = DW_OP_nop;
392 * ((guint8 *) base_ptr)++ = DW_OP_nop;
393 * ((guint8 *) base_ptr)++ = DW_OP_nop;
394 * ((guint8 *) base_ptr)++ = DW_OP_nop;
399 * Update the location description for a local variable or method parameter.
400 * MCS always reserves 8 bytes for us to do this, if we don't need them all
401 * we just fill up the rest with DW_OP_nop's.
404 switch (var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS) {
405 case MONO_DEBUG_VAR_ADDRESS_MODE_STACK:
407 * Variable is on the stack.
409 * If `index' is zero, use the normal frame register. Otherwise, bits
410 * 0..4 of `index' contain the frame register.
412 * Both DW_OP_fbreg and DW_OP_breg0 ... DW_OP_breg31 take an ULeb128
413 * argument - since this has an variable size, we set it to zero and
414 * manually add a 4 byte constant using DW_OP_plus.
417 /* Use the normal frame register (%ebp on the i386). */
418 * ((guint8 *) base_ptr)++ = DW_OP_fbreg;
420 /* Use a custom frame register. */
421 * ((guint8 *) base_ptr)++ = DW_OP_breg0 + (var->index & 0x001f);
422 * ((guint8 *) base_ptr)++ = 0;
423 * ((guint8 *) base_ptr)++ = DW_OP_const4s;
424 * ((gint32 *) base_ptr)++ = var->offset;
425 * ((guint8 *) base_ptr)++ = DW_OP_plus;
428 case MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER:
430 * Variable is in the register whose number is contained in bits 0..4
433 * We need to write exactly 8 bytes in this location description, so instead
434 * of filling up the rest with DW_OP_nop's just add the `offset' even if
437 * ((guint8 *) base_ptr)++ = DW_OP_reg0 + (var->index & 0x001f);
438 * ((guint8 *) base_ptr)++ = DW_OP_nop;
439 * ((guint8 *) base_ptr)++ = DW_OP_const4s;
440 * ((gint32 *) base_ptr)++ = var->offset;
441 * ((guint8 *) base_ptr)++ = DW_OP_plus;
444 case MONO_DEBUG_VAR_ADDRESS_MODE_TWO_REGISTERS:
446 * Variable is in two registers whose numbers are in bits 0..4 and 5..9 of
447 * the `index' field. Don't add `offset' since we have only two bytes left,
448 * fill them up with DW_OP_nop's.
450 * ((guint8 *) base_ptr)++ = DW_OP_reg0 + (var->index & 0x001f);
451 * ((guint8 *) base_ptr)++ = DW_OP_piece;
452 * ((guint8 *) base_ptr)++ = sizeof (int);
453 * ((guint8 *) base_ptr)++ = DW_OP_reg0 + ((var->index & 0x1f0) >> 5);
454 * ((guint8 *) base_ptr)++ = DW_OP_piece;
455 * ((guint8 *) base_ptr)++ = sizeof (int);
456 * ((guint8 *) base_ptr)++ = DW_OP_nop;
457 * ((guint8 *) base_ptr)++ = DW_OP_nop;
461 g_assert_not_reached ();
466 mono_debug_update_symbol_file (MonoDebugSymbolFile *symfile,
467 MonoDebugMethodInfoFunc method_info_func,
470 const char *reloc_ptr, *reloc_start, *reloc_end;
471 int version, already_relocated = 0;
474 read_symbol_table (symfile);
476 if (!symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_RELOC_TABLE].file_offset)
479 reloc_ptr = reloc_start = symfile->raw_contents +
480 symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_RELOC_TABLE].file_offset;
482 version = *((guint16 *) reloc_ptr)++;
483 if (version != MONO_DEBUG_SYMBOL_FILE_VERSION) {
484 g_warning ("Symbol file %s has incorrect relocation table version "
485 "(expected %d, got %d)", symfile->file_name,
486 MONO_DEBUG_SYMBOL_FILE_VERSION, version);
490 already_relocated = *reloc_ptr;
491 *((char *) reloc_ptr)++ = 1;
493 reloc_size = *((guint32 *) reloc_ptr)++;
494 reloc_end = reloc_ptr + reloc_size;
496 while (reloc_ptr < reloc_end) {
497 int type, size, section, offset;
502 size = * ((guint32 *) reloc_ptr)++;
507 section = *tmp_ptr++;
508 offset = *((guint32 *) tmp_ptr)++;
510 if (section >= MONO_DEBUG_SYMBOL_SECTION_MAX) {
511 g_warning ("Symbol file %s contains a relocation entry for unknown section %d",
512 symfile->file_name, section);
516 if (!symfile->section_offsets [section].file_offset) {
517 g_warning ("Symbol file %s contains a relocation entry for non-existing "
518 "section %d", symfile->file_name, section);
522 base_ptr = symfile->raw_contents + symfile->section_offsets [section].file_offset;
523 base_ptr = base_ptr + offset;
526 case MRT_target_address_size:
527 * (guint8 *) base_ptr = sizeof (void *);
529 case MRT_method_start_address: {
530 int token = *((guint32 *) tmp_ptr)++;
531 MonoDebugMethodInfo *minfo;
533 minfo = method_info_func (symfile, token, user_data);
536 * (void **) base_ptr = 0;
541 g_message ("Start of `%s' (%ld) relocated to %p", minfo->method->name,
542 token, minfo->code_start);
545 * (void **) base_ptr = minfo->code_start;
549 case MRT_method_end_address: {
550 int token = *((guint32 *) tmp_ptr)++;
551 MonoDebugMethodInfo *minfo;
553 minfo = method_info_func (symfile, token, user_data);
556 * (void **) base_ptr = 0;
560 * (void **) base_ptr = (char *)minfo->code_start + minfo->code_size;
564 case MRT_il_offset: {
565 guint32 token = *((guint32 *) tmp_ptr)++;
566 guint32 original = *((guint32 *) tmp_ptr)++;
567 MonoDebugMethodInfo *minfo;
571 minfo = method_info_func (symfile, token, user_data);
574 * (void **) base_ptr = 0;
578 address = minfo->code_size;
580 for (i = 0; i < minfo->num_il_offsets; i++) {
581 MonoDebugILOffsetInfo *il = &minfo->il_offsets [i];
583 if (il->offset >= original) {
584 address = il->address;
590 g_message ("Relocating IL offset %04x in `%s' to %d (%p)",
591 original, minfo->method->name, address,
592 minfo->code_start + address);
595 * (void **) base_ptr = minfo->code_start + address;
599 case MRT_local_variable: {
600 guint32 token = *((guint32 *) tmp_ptr)++;
601 guint32 original = *((guint32 *) tmp_ptr)++;
602 MonoDebugMethodInfo *minfo;
604 minfo = method_info_func (symfile, token, user_data);
607 relocate_variable (NULL, base_ptr);
611 if (original > minfo->num_locals) {
612 g_warning ("Symbol file %s contains relocation entry for non-existing "
613 "local variable %d, but method %s only has %d local variables.",
614 symfile->file_name, original, minfo->method->name,
616 g_message (G_STRLOC ": %d", token);
621 relocate_variable (&minfo->locals [original], base_ptr);
625 case MRT_method_parameter: {
626 guint32 token = *((guint32 *) tmp_ptr)++;
627 guint32 original = *((guint32 *) tmp_ptr)++;
628 MonoDebugMethodInfo *minfo;
630 minfo = method_info_func (symfile, token, user_data);
633 relocate_variable (NULL, base_ptr);
637 if (minfo->method->signature->hasthis) {
639 relocate_variable (minfo->this_var, base_ptr);
646 if (original > minfo->num_params) {
647 g_warning ("Symbol file %s contains relocation entry for non-existing "
648 "parameter %d, but method %s only has %d parameters.",
649 symfile->file_name, original, minfo->method->name,
654 relocate_variable (&minfo->params [original], base_ptr);
658 case MRT_type_sizeof: {
659 guint32 token = *((guint32 *) tmp_ptr)++;
660 MonoClass *klass = mono_debug_class_get (symfile, token);
665 mono_class_init (klass);
667 if (klass->enumtype || klass->valuetype)
668 * (gint8 *) base_ptr = klass->instance_size - sizeof (MonoObject);
670 * (gint8 *) base_ptr = klass->instance_size;
674 case MRT_type_field_offset: {
675 guint32 token = *((guint32 *) tmp_ptr)++;
676 guint32 original = *((guint32 *) tmp_ptr)++;
677 MonoClass *klass = mono_debug_class_get (symfile, token);
683 mono_class_init (klass);
685 if (original > klass->field.count) {
686 g_warning ("Symbol file %s contains invalid field offset entry.",
688 g_message (G_STRLOC ": %d", token);
689 /* G_BREAKPOINT (); */
696 off = klass->fields [original].offset;
697 if (klass->byval_arg.type == MONO_TYPE_VALUETYPE)
698 off -= sizeof (MonoObject);
701 g_message ("Setting field %d of type %u to offset %d", original,
705 * (guint32 *) base_ptr = off;
709 case MRT_mono_string_sizeof:
710 * (gint8 *) base_ptr = sizeof (MonoString);
713 case MRT_mono_string_offset: {
714 guint32 idx = *((guint32 *) tmp_ptr)++;
719 case MRI_string_offset_length:
720 off = (guchar *) &string.length - (guchar *) &string;
723 case MRI_string_offset_chars:
724 off = (guchar *) &string.chars - (guchar *) &string;
728 g_warning ("Symbol file %s contains invalid string offset entry",
733 * (guint32 *) base_ptr = off;
737 case MRT_mono_array_sizeof:
738 * (gint8 *) base_ptr = sizeof (MonoArray);
741 case MRT_mono_array_offset: {
742 guint32 idx = *((guint32 *) tmp_ptr)++;
747 case MRI_array_offset_bounds:
748 off = (guchar *) &array.bounds - (guchar *) &array;
751 case MRI_array_offset_max_length:
752 off = (guchar *) &array.max_length - (guchar *) &array;
755 case MRI_array_offset_vector:
756 off = (guchar *) &array.vector - (guchar *) &array;
760 g_warning ("Symbol file %s contains invalid array offset entry",
765 * (guint32 *) base_ptr = off;
770 case MRT_mono_array_bounds_sizeof:
771 * (gint8 *) base_ptr = sizeof (MonoArrayBounds);
774 case MRT_mono_array_bounds_offset: {
775 guint32 idx = *((guint32 *) tmp_ptr)++;
776 MonoArrayBounds bounds;
780 case MRI_array_bounds_offset_lower:
781 off = (guchar *) &bounds.lower_bound - (guchar *) &bounds;
784 case MRI_array_bounds_offset_length:
785 off = (guchar *) &bounds.length - (guchar *) &bounds;
789 g_warning ("Symbol file %s contains invalid array bounds offset entry",
794 * (guint32 *) base_ptr = off;
799 case MRT_variable_start_scope: {
800 guint32 token = *((guint32 *) tmp_ptr)++;
801 guint32 original = *((guint32 *) tmp_ptr)++;
802 MonoDebugMethodInfo *minfo;
805 minfo = method_info_func (symfile, token, user_data);
807 if (!minfo || !minfo->locals) {
808 * (void **) base_ptr = 0;
812 if (original > minfo->num_locals) {
813 g_warning ("Symbol file %s contains relocation entry for non-existing "
814 "local variable %d, but method %s only has %d local variables.",
815 symfile->file_name, original, minfo->method->name,
820 address = minfo->locals [original].begin_scope;
822 * (void **) base_ptr = minfo->code_start + address;
827 case MRT_variable_end_scope: {
828 guint32 token = *((guint32 *) tmp_ptr)++;
829 guint32 original = *((guint32 *) tmp_ptr)++;
830 MonoDebugMethodInfo *minfo;
833 minfo = method_info_func (symfile, token, user_data);
835 if (!minfo || !minfo->locals) {
836 * (void **) base_ptr = 0;
840 if (original > minfo->num_locals) {
841 g_warning ("Symbol file %s contains relocation entry for non-existing "
842 "local variable %d, but method %s only has %d local variables.",
843 symfile->file_name, original, minfo->method->name,
848 address = minfo->locals [original].end_scope;
850 * (void **) base_ptr = minfo->code_start + address;
855 case MRT_mono_string_fieldsize: {
856 guint32 idx = *((guint32 *) tmp_ptr)++;
861 case MRI_string_offset_length:
862 fieldsize = sizeof (string.length);
866 g_warning ("Symbol file %s contains invalid string fieldsize entry",
871 * (guint32 *) base_ptr = fieldsize;
876 case MRT_mono_array_fieldsize: {
877 guint32 idx = *((guint32 *) tmp_ptr)++;
882 case MRI_array_offset_bounds:
883 fieldsize = sizeof (array.bounds);
886 case MRI_array_offset_max_length:
887 fieldsize = sizeof (array.max_length);
890 case MRI_array_offset_vector:
891 fieldsize = sizeof (array.vector);
895 g_warning ("Symbol file %s contains invalid array fieldsize entry",
900 * (guint32 *) base_ptr = fieldsize;
905 case MRT_mono_string_string_length: {
907 guint32 offset = (guchar *) &string.length - (guchar *) &string;
909 * ((guint8 *) base_ptr)++ = DW_OP_const4u;
910 * ((gint32 *) base_ptr)++ = offset;
911 * ((guint8 *) base_ptr)++ = DW_OP_nop;
912 * ((guint8 *) base_ptr)++ = DW_OP_nop;
913 * ((guint8 *) base_ptr)++ = DW_OP_nop;
918 case MRT_mono_string_byte_size: {
921 * (guint32 *) base_ptr = sizeof (string.length);
926 case MRT_mono_string_data_location: {
928 guint32 offset = (guchar *) &string.chars - (guchar *) &string;
930 * ((guint8 *) base_ptr)++ = DW_OP_const4u;
931 * ((gint32 *) base_ptr)++ = offset;
932 * ((guint8 *) base_ptr)++ = DW_OP_nop;
933 * ((guint8 *) base_ptr)++ = DW_OP_nop;
934 * ((guint8 *) base_ptr)++ = DW_OP_nop;
939 case MRT_static_type_field_offset: {
940 guint32 token = *((guint32 *) tmp_ptr)++;
941 guint32 original = *((guint32 *) tmp_ptr)++;
942 MonoClass *klass = mono_debug_class_get (symfile, token);
949 mono_class_init (klass);
951 if (original > klass->field.count) {
952 g_warning ("Symbol file %s contains invalid field offset entry.",
960 vtable = mono_class_vtable (mono_domain_get (), klass);
962 off = klass->fields [original].offset;
965 g_message ("Setting field %d of type %u (%p) to offset %d", original,
969 * (void **) base_ptr = (char *) vtable->data + off;
974 case MRT_mono_array_data_location: {
976 guint32 offset = (guchar *) &array.vector - (guchar *) &array;
978 * ((guint8 *) base_ptr)++ = DW_OP_const4u;
979 * ((gint32 *) base_ptr)++ = offset;
980 * ((guint8 *) base_ptr)++ = DW_OP_nop;
981 * ((guint8 *) base_ptr)++ = DW_OP_nop;
982 * ((guint8 *) base_ptr)++ = DW_OP_nop;
987 case MRT_mono_array_max_length: {
989 guint32 offset = (guchar *) &array.max_length - (guchar *) &array;
991 * ((guint8 *) base_ptr)++ = DW_OP_const4u;
992 * ((gint32 *) base_ptr)++ = offset;
993 * ((guint8 *) base_ptr)++ = DW_OP_nop;
994 * ((guint8 *) base_ptr)++ = DW_OP_nop;
995 * ((guint8 *) base_ptr)++ = DW_OP_nop;
1000 case MRT_mono_array_length_byte_size: {
1003 * (guint32 *) base_ptr = sizeof (array.max_length);
1009 g_warning ("Symbol file %s contains unknown relocation entry %d",
1010 symfile->file_name, type);
1015 mono_raw_buffer_update (symfile->raw_contents, symfile->raw_contents_size);
1019 mono_debug_find_source_location (MonoDebugSymbolFile *symfile, MonoMethod *method, guint32 offset,
1020 guint32 *line_number)
1022 MonoDebugLineNumberBlock *lnb;
1025 if (!symfile->line_number_table)
1028 lnb = g_hash_table_lookup (symfile->line_number_table, method);
1032 ptr = symfile->raw_contents +
1033 symfile->section_offsets [MONO_DEBUG_SYMBOL_SECTION_MONO_LINE_NUMBERS].file_offset;
1035 ptr += lnb->file_offset;
1038 guint32 row, iloffset;
1040 row = * ((guint32 *) ptr)++;
1041 iloffset = * ((guint32 *) ptr)++;
1043 if (!row && !offset)
1048 if (iloffset >= offset) {
1051 return g_strdup (lnb->source_file);
1053 return g_strdup_printf ("%s:%d", lnb->source_file, row);