5 #include <mono/metadata/metadata.h>
6 #include <mono/metadata/tabledefs.h>
7 #include <mono/metadata/rawbuffer.h>
8 #include <mono/metadata/tokentype.h>
9 #include <mono/metadata/appdomain.h>
10 #include <mono/metadata/exception.h>
11 #include <mono/metadata/debug-helpers.h>
12 #include <mono/metadata/debug-mono-symfile.h>
17 #define RANGE_TABLE_CHUNK_SIZE 256
19 struct MonoSymbolFilePriv
25 guint32 string_table_size;
26 guint32 string_offset_size;
28 GHashTable *method_table;
29 GHashTable *method_hash;
30 MonoSymbolFileOffsetTable *offset_table;
37 MonoDebugMethodInfo *minfo;
38 MonoSymbolFileMethodEntry *entry;
39 guint32 method_name_offset;
42 } MonoSymbolFileMethodEntryPriv;
44 static int write_string_table (MonoSymbolFile *symfile);
45 static int create_symfile (MonoSymbolFile *symfile, gboolean emit_warnings);
46 static void close_symfile (MonoSymbolFile *symfile);
47 static MonoDebugRangeInfo *allocate_range_entry (MonoSymbolFile *symfile);
48 static gpointer write_type (MonoSymbolFile *symfile, int index, MonoType *type);
51 free_method_info (MonoDebugMethodInfo *minfo)
58 load_symfile (MonoSymbolFile *symfile)
60 MonoSymbolFilePriv *priv = symfile->_priv;
61 MonoSymbolFileMethodEntry *me;
62 const char *ptr, *start;
67 ptr = start = symfile->raw_contents;
69 magic = *((guint64 *) ptr)++;
70 if (magic != MONO_SYMBOL_FILE_MAGIC) {
71 g_warning ("Symbol file %s has is not a mono symbol file", priv->file_name);
75 version = *((guint32 *) ptr)++;
76 if (version != MONO_SYMBOL_FILE_VERSION) {
77 g_warning ("Symbol file %s has incorrect line number table version "
78 "(expected %d, got %ld)", priv->file_name,
79 MONO_SYMBOL_FILE_VERSION, version);
83 priv->offset_table = (MonoSymbolFileOffsetTable *) ptr;
90 priv->method_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
91 (GDestroyNotify) g_free);
92 priv->method_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
93 (GDestroyNotify) free_method_info);
95 ptr = symfile->raw_contents + priv->offset_table->method_table_offset;
96 me = (MonoSymbolFileMethodEntry *) ptr;
98 for (i = 0; i < priv->offset_table->method_count; i++, me++) {
99 MonoMethod *method = mono_get_method (priv->image, me->token, NULL);
100 MonoSymbolFileMethodEntryPriv *mep;
101 MonoDebugMethodInfo *minfo;
106 if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
107 (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
108 (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
109 g_assert_not_reached ();
111 if (!((MonoMethodNormal *) method)->header) {
112 g_warning (G_STRLOC ": Internal error: method %s.%s doesn't have a header",
113 method->klass->name, method->name);
117 minfo = g_new0 (MonoDebugMethodInfo, 1);
118 minfo->file_offset = ((const char *) me) - start;
119 minfo->method = method;
120 minfo->symfile = symfile;
121 minfo->num_il_offsets = me->num_line_numbers;
122 minfo->il_offsets = (MonoSymbolFileLineNumberEntry *)
123 (symfile->raw_contents + me->line_number_table_offset);
125 mep = g_new0 (MonoSymbolFileMethodEntryPriv, 1);
126 mep->method = method;
131 mep->method_name_offset = priv->string_table_size;
132 mep->name = g_strdup_printf ("%s%s.%s", method->klass->name_space,
133 method->klass->name, method->name);
134 priv->string_table_size += strlen (mep->name) + 1;
136 g_hash_table_insert (priv->method_table, method, mep);
137 g_hash_table_insert (priv->method_hash, method, minfo);
140 priv->type_table = g_new0 (gpointer, priv->offset_table->type_count);
142 if (!write_string_table (symfile))
149 mono_debug_open_mono_symbol_file (MonoImage *image, const char *filename, gboolean emit_warnings)
151 MonoSymbolFile *symfile;
152 MonoSymbolFilePriv *priv;
157 fd = open (filename, O_RDONLY);
160 g_warning ("Can't open symbol file: %s", filename);
164 file_size = lseek (fd, 0, SEEK_END);
165 lseek (fd, 0, SEEK_SET);
167 if (file_size == (off_t) -1) {
169 g_warning ("Can't get size of symbol file: %s", filename);
173 ptr = mono_raw_buffer_load (fd, FALSE, 0, file_size);
176 g_warning ("Can't read symbol file: %s", filename);
180 symfile = g_new0 (MonoSymbolFile, 1);
181 symfile->magic = MONO_SYMBOL_FILE_MAGIC;
182 symfile->version = MONO_SYMBOL_FILE_VERSION;
183 symfile->dynamic_magic = MONO_SYMBOL_FILE_DYNAMIC_MAGIC;
184 symfile->dynamic_version = MONO_SYMBOL_FILE_DYNAMIC_VERSION;
185 symfile->image_file = g_strdup (image->name);
186 symfile->symbol_file = g_strdup (filename);
187 symfile->raw_contents = ptr;
188 symfile->raw_contents_size = file_size;
190 symfile->_priv = priv = g_new0 (MonoSymbolFilePriv, 1);
194 priv->file_name = g_strdup (filename);
196 if (!load_symfile (symfile)) {
197 mono_debug_close_mono_symbol_file (symfile);
205 close_symfile (MonoSymbolFile *symfile)
207 MonoSymbolFilePriv *priv = symfile->_priv;
209 if (symfile->raw_contents) {
210 mono_raw_buffer_free (symfile->raw_contents);
211 symfile->raw_contents = NULL;
219 if (priv->method_table) {
220 g_hash_table_destroy (priv->method_table);
221 priv->method_table = NULL;
224 if (priv->method_hash) {
225 g_hash_table_destroy (priv->method_hash);
226 priv->method_hash = NULL;
229 if (symfile->is_dynamic)
230 unlink (priv->file_name);
232 if (symfile->image_file) {
233 g_free (symfile->image_file);
234 symfile->image_file = NULL;
237 if (priv->file_name) {
238 g_free (priv->file_name);
239 priv->file_name = NULL;
246 mono_debug_close_mono_symbol_file (MonoSymbolFile *symfile)
251 close_symfile (symfile);
253 g_free (symfile->_priv->source_file);
254 g_free (symfile->_priv);
255 g_free (symfile->image_file);
256 g_free (symfile->symbol_file);
261 write_string (int fd, const char *string)
263 guint32 length = strlen (string);
265 if (write (fd, &length, sizeof (length)) < 0)
268 if (write (fd, string, strlen (string)) < 0)
275 read_string (const char *ptr)
277 int len = *((guint32 *) ptr)++;
279 return g_filename_from_utf8 (ptr, len, NULL, NULL, NULL);
283 mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, guint32 offset,
284 guint32 *line_number)
286 MonoSymbolFilePriv *priv = symfile->_priv;
287 MonoSymbolFileLineNumberEntry *lne;
288 MonoSymbolFileMethodEntryPriv *mep;
289 gchar *source_file = NULL;
293 if (!priv->method_table || symfile->is_dynamic)
296 mep = g_hash_table_lookup (priv->method_table, method);
300 if (mep->entry->source_file_offset)
301 source_file = read_string (symfile->raw_contents + mep->entry->source_file_offset);
303 ptr = symfile->raw_contents + mep->entry->line_number_table_offset;
305 lne = (MonoSymbolFileLineNumberEntry *) ptr;
307 for (i = 0; i < mep->entry->num_line_numbers; i++, lne++) {
308 if (lne->offset < offset)
312 *line_number = lne->row;
317 } else if (source_file) {
318 gchar *retval = g_strdup_printf ("%s:%d", source_file, lne->row);
319 g_free (source_file);
322 return g_strdup_printf ("%d", lne->row);
329 mono_debug_symfile_add_method (MonoSymbolFile *symfile, MonoMethod *method)
331 MonoSymbolFileMethodEntryPriv *mep;
332 MonoSymbolFileMethodAddress *address;
333 MonoDebugVarInfo *var_table;
334 MonoSymbolFileLineNumberEntry *lne;
335 MonoDebugRangeInfo *range;
336 guint32 size, line_size, line_offset, num_variables, variable_size, variable_offset;
337 guint32 type_size, type_offset, *line_addresses, *type_index_table;
338 gpointer *type_table;
342 mep = g_hash_table_lookup (symfile->_priv->method_table, method);
347 mep->minfo = g_hash_table_lookup (symfile->_priv->method_hash, mep->method);
352 if (!mep->minfo->jit)
355 symfile->generation++;
357 size = sizeof (MonoSymbolFileMethodAddress);
359 line_size = mep->entry->num_line_numbers * sizeof (MonoSymbolFileLineNumberEntry);
363 num_variables = mep->entry->num_parameters + mep->entry->num_locals;
364 if (mep->entry->this_type_index)
367 variable_size = num_variables * sizeof (MonoDebugVarInfo);
368 variable_offset = size;
369 size += variable_size;
371 type_size = num_variables * sizeof (gpointer);
375 address = g_malloc0 (size);
376 ptr = (guint8 *) address;
378 address->size = size;
379 address->start_address = GPOINTER_TO_UINT (mep->minfo->jit->code_start);
380 address->end_address = GPOINTER_TO_UINT (mep->minfo->jit->code_start + mep->minfo->jit->code_size);
381 address->line_table_offset = line_offset;
382 address->variable_table_offset = variable_offset;
383 address->type_table_offset = type_offset;
385 range = allocate_range_entry (symfile);
386 range->file_offset = mep->minfo->file_offset;
387 range->start_address = address->start_address;
388 range->end_address = address->end_address;
389 range->dynamic_data = address;
390 range->dynamic_size = size;
392 var_table = (MonoDebugVarInfo *) (ptr + variable_offset);
393 type_table = (gpointer *) (ptr + type_offset);
395 type_index_table = (guint32 *)
396 (symfile->raw_contents + mep->entry->type_index_table_offset);
398 if (mep->entry->this_type_index) {
399 if (!mep->minfo->jit->this_var) {
400 g_warning (G_STRLOC ": Method %s.%s doesn't have `this'.",
401 mep->method->klass->name, mep->method->name);
404 *var_table++ = *mep->minfo->jit->this_var;
405 *type_table++ = write_type (symfile, mep->entry->this_type_index,
406 &method->klass->this_arg);
410 if (mep->minfo->jit->num_params != mep->entry->num_parameters) {
411 g_warning (G_STRLOC ": Method %s.%s has %d parameters, but symbol file claims it has %d.",
412 mep->method->klass->name, mep->method->name, mep->minfo->jit->num_params,
413 mep->entry->num_parameters);
414 var_table += mep->entry->num_parameters;
416 for (i = 0; i < mep->minfo->jit->num_params; i++) {
417 *var_table++ = mep->minfo->jit->params [i];
418 *type_table++ = write_type (symfile, type_index_table [i],
419 method->signature->params [i]);
423 if (mep->minfo->jit->num_locals != mep->entry->num_locals) {
425 g_warning (G_STRLOC ": Method %s.%s has %d locals, but symbol file claims it has %d.",
426 mep->method->klass->name, mep->method->name, mep->minfo->jit->num_locals,
427 mep->entry->num_locals);
429 var_table += mep->entry->num_locals;
431 for (i = 0; i < mep->minfo->jit->num_locals; i++)
432 *var_table++ = mep->minfo->jit->locals [i];
434 lne = (MonoSymbolFileLineNumberEntry *)
435 (symfile->raw_contents + mep->entry->line_number_table_offset);
437 line_addresses = (guint32 *) (ptr + line_offset);
439 for (i = 0; i < mep->entry->num_line_numbers; i++, lne++) {
443 line_addresses [i] = 0;
445 } else if (lne->offset == 0) {
446 line_addresses [i] = mep->minfo->jit->prologue_end;
450 line_addresses [i] = mep->minfo->jit->code_size;
452 for (j = 0; j < mep->minfo->num_il_offsets; j++) {
453 MonoSymbolFileLineNumberEntry *il = &mep->minfo->il_offsets [j];
455 if (il->offset >= lne->offset) {
456 line_addresses [i] = mep->minfo->jit->il_addresses [j];
464 free_method_entry (MonoSymbolFileMethodEntryPriv *mep)
472 create_method (MonoSymbolFile *symfile, guint32 token, MonoMethod *method)
474 MonoSymbolFileMethodEntryPriv *mep;
475 MonoDebugMethodInfo *minfo;
477 g_assert (method->klass->image == symfile->_priv->image);
479 mep = g_new0 (MonoSymbolFileMethodEntryPriv, 1);
480 mep->entry = g_new0 (MonoSymbolFileMethodEntry, 1);
481 mep->entry->token = token;
482 mep->entry->source_file_offset = symfile->_priv->offset_table->source_table_offset;
484 mep->method_name_offset = symfile->_priv->string_table_size;
485 mep->name = g_strdup_printf ("%s%s.%s", method->klass->name_space,
486 method->klass->name, method->name);
487 symfile->_priv->string_table_size += strlen (mep->name) + 1;
489 minfo = g_new0 (MonoDebugMethodInfo, 1);
490 minfo->method = method;
491 minfo->symfile = symfile;
494 mep->method = method;
496 symfile->_priv->offset_table->method_count++;
498 g_hash_table_insert (symfile->_priv->method_table, method, mep);
499 g_hash_table_insert (symfile->_priv->method_hash, method, minfo);
503 write_method (gpointer key, gpointer value, gpointer user_data)
505 MonoSymbolFile *symfile = (MonoSymbolFile *) user_data;
506 MonoSymbolFileMethodEntryPriv *mep = (MonoSymbolFileMethodEntryPriv *) value;
508 if (symfile->_priv->error)
511 mep->minfo->file_offset = lseek (symfile->_priv->fd, 0, SEEK_CUR);
513 if (write (symfile->_priv->fd, mep->entry, sizeof (MonoSymbolFileMethodEntry)) < 0) {
514 symfile->_priv->error = TRUE;
520 write_line_numbers (gpointer key, gpointer value, gpointer user_data)
522 MonoSymbolFile *symfile = (MonoSymbolFile *) user_data;
523 MonoSymbolFilePriv *priv = symfile->_priv;
524 MonoSymbolFileMethodEntryPriv *mep = (MonoSymbolFileMethodEntryPriv *) value;
525 MonoSymbolFileLineNumberEntry lne;
526 const unsigned char *ip, *start, *end;
527 MonoMethodHeader *header;
532 if ((mep->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
533 (mep->method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
534 (mep->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
535 g_assert_not_reached ();
537 header = ((MonoMethodNormal *) mep->method)->header;
540 mep->entry->line_number_table_offset = lseek (priv->fd, 0, SEEK_CUR);
541 ++mep->entry->num_line_numbers;
546 if (write (priv->fd, &lne, sizeof (MonoSymbolFileLineNumberEntry)) < 0) {
551 ip = start = header->code;
552 end = ip + header->code_size;
557 ++mep->entry->num_line_numbers;
558 lne.offset = ip - start;
561 if (write (priv->fd, &lne, sizeof (MonoSymbolFileLineNumberEntry)) < 0) {
566 line = mono_disasm_code_one (NULL, mep->method, ip, &ip);
572 create_methods (MonoSymbolFile *symfile)
574 MonoImage *image = symfile->_priv->image;
575 MonoTableInfo *table = &image->tables [MONO_TABLE_METHOD];
578 for (idx = 1; idx <= table->rows; idx++) {
579 guint32 token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
580 MonoMethod *method = mono_get_method (image, token, NULL);
582 if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
583 (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
584 (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
587 if (method->wrapper_type != MONO_WRAPPER_NONE)
590 if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
591 (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
592 (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
593 g_assert_not_reached ();
595 if (!((MonoMethodNormal *) method)->header) {
596 g_warning (G_STRLOC ": Internal error: method %s.%s doesn't have a header",
597 method->klass->name, method->name);
601 create_method (symfile, token, method);
606 load_line_numbers (gpointer key, gpointer value, gpointer user_data)
608 MonoSymbolFile *symfile = (MonoSymbolFile *) user_data;
609 MonoSymbolFileMethodEntryPriv *mep = (MonoSymbolFileMethodEntryPriv *) value;
611 mep->minfo->num_il_offsets = mep->entry->num_line_numbers;
612 mep->minfo->il_offsets = (MonoSymbolFileLineNumberEntry *)
613 (symfile->raw_contents + mep->entry->line_number_table_offset);
617 create_symfile (MonoSymbolFile *symfile, gboolean emit_warnings)
619 MonoSymbolFilePriv *priv = symfile->_priv;
625 priv->fd = g_file_open_tmp (NULL, &priv->file_name, NULL);
626 if (priv->fd == -1) {
628 g_warning ("Can't create symbol file");
632 symfile->symbol_file = g_strdup (priv->file_name);
634 magic = MONO_SYMBOL_FILE_MAGIC;
635 if (write (priv->fd, &magic, sizeof (magic)) < 0)
638 version = MONO_SYMBOL_FILE_VERSION;
639 if (write (priv->fd, &version, sizeof (version)) < 0)
642 offset = lseek (priv->fd, 0, SEEK_CUR);
644 priv->offset_table = g_new0 (MonoSymbolFileOffsetTable, 1);
645 if (write (priv->fd, priv->offset_table, sizeof (MonoSymbolFileOffsetTable)) < 0)
649 // Write source file table.
651 if (priv->source_file) {
652 priv->offset_table->source_table_offset = lseek (priv->fd, 0, SEEK_CUR);
653 if (!write_string (priv->fd, priv->source_file))
655 priv->offset_table->source_table_size = lseek (priv->fd, 0, SEEK_CUR) -
656 priv->offset_table->source_table_offset;
660 // Create method table.
663 priv->method_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
664 (GDestroyNotify) free_method_entry);
665 priv->method_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
666 (GDestroyNotify) free_method_info);
668 create_methods (symfile);
671 // Write line numbers.
674 priv->offset_table->line_number_table_offset = lseek (priv->fd, 0, SEEK_CUR);
676 g_hash_table_foreach (priv->method_table, write_line_numbers, symfile);
680 priv->offset_table->line_number_table_size = lseek (priv->fd, 0, SEEK_CUR) -
681 priv->offset_table->line_number_table_offset;
684 // Write method table.
687 priv->offset_table->method_table_offset = lseek (priv->fd, 0, SEEK_CUR);
689 g_hash_table_foreach (priv->method_table, write_method, symfile);
693 priv->offset_table->method_table_size = lseek (priv->fd, 0, SEEK_CUR) -
694 priv->offset_table->method_table_offset;
697 // Write offset table.
700 symfile->raw_contents_size = lseek (priv->fd, 0, SEEK_CUR);
702 lseek (priv->fd, offset, SEEK_SET);
703 if (write (priv->fd, priv->offset_table, sizeof (MonoSymbolFileOffsetTable)) < 0)
706 lseek (priv->fd, symfile->raw_contents_size, SEEK_SET);
708 ptr = mono_raw_buffer_load (priv->fd, TRUE, 0, symfile->raw_contents_size);
712 symfile->raw_contents = ptr;
715 // Load line number table.
717 g_hash_table_foreach (priv->method_table, load_line_numbers, symfile);
721 priv->type_table = g_new0 (gpointer, priv->offset_table->type_count);
723 if (!write_string_table (symfile))
730 mono_debug_create_mono_symbol_file (MonoImage *image)
732 MonoSymbolFile *symfile;
734 symfile = g_new0 (MonoSymbolFile, 1);
735 symfile->magic = MONO_SYMBOL_FILE_MAGIC;
736 symfile->version = MONO_SYMBOL_FILE_VERSION;
737 symfile->dynamic_magic = MONO_SYMBOL_FILE_DYNAMIC_MAGIC;
738 symfile->dynamic_version = MONO_SYMBOL_FILE_DYNAMIC_VERSION;
739 symfile->is_dynamic = TRUE;
740 symfile->image_file = g_strdup (image->name);
742 symfile->_priv = g_new0 (MonoSymbolFilePriv, 1);
743 symfile->_priv->image = image;
745 if (!create_symfile (symfile, TRUE)) {
746 mono_debug_close_mono_symbol_file (symfile);
753 MonoDebugMethodInfo *
754 mono_debug_find_method (MonoSymbolFile *symfile, MonoMethod *method)
756 return g_hash_table_lookup (symfile->_priv->method_hash, method);
760 write_method_name (gpointer key, gpointer value, gpointer user_data)
762 MonoSymbolFile *symfile = (MonoSymbolFile *) user_data;
763 MonoSymbolFileMethodEntryPriv *mep = (MonoSymbolFileMethodEntryPriv *) value;
764 MonoSymbolFilePriv *priv = symfile->_priv;
765 guint8 *offset_ptr, *string_ptr;
768 offset = mep->method_name_offset + priv->string_offset_size;
770 offset_ptr = symfile->string_table + mep->index * 4;
771 string_ptr = symfile->string_table + offset;
773 *((guint32 *) offset_ptr) = offset;
774 strcpy (string_ptr, mep->name);
778 write_string_table (MonoSymbolFile *symfile)
780 MonoSymbolFilePriv *priv = symfile->_priv;
782 priv->string_offset_size = priv->offset_table->method_count * 4;
784 symfile->string_table_size = priv->string_table_size + priv->string_offset_size;
785 symfile->string_table = g_malloc0 (symfile->string_table_size);
787 g_hash_table_foreach (symfile->_priv->method_table, write_method_name, symfile);
791 MonoReflectionMethod *
792 ves_icall_MonoDebugger_GetMethod (MonoReflectionAssembly *assembly, guint32 token)
796 method = mono_get_method (assembly->assembly->image, token, NULL);
798 return mono_method_get_object (mono_domain_get (), method, NULL);
802 ves_icall_MonoDebugger_GetLocalTypeFromSignature (MonoReflectionAssembly *assembly, MonoArray *signature)
810 MONO_CHECK_ARG_NULL (assembly);
811 MONO_CHECK_ARG_NULL (signature);
813 domain = mono_domain_get();
814 image = assembly->assembly->image;
816 ptr = mono_array_addr (signature, char, 0);
817 g_assert (*ptr++ == 0x07);
818 len = mono_metadata_decode_value (ptr, &ptr);
821 type = mono_metadata_parse_type (image, MONO_PARSE_LOCAL, 0, ptr, &ptr);
823 return mono_type_get_object (domain, type);
826 static MonoDebugRangeInfo *
827 allocate_range_entry (MonoSymbolFile *symfile)
829 MonoDebugRangeInfo *retval;
830 guint32 size, chunks;
832 symfile->range_entry_size = sizeof (MonoDebugRangeInfo);
834 if (!symfile->range_table) {
835 size = sizeof (MonoDebugRangeInfo) * RANGE_TABLE_CHUNK_SIZE;
836 symfile->range_table = g_malloc0 (size);
837 symfile->num_range_entries = 1;
838 return symfile->range_table;
841 if (!((symfile->num_range_entries + 1) % RANGE_TABLE_CHUNK_SIZE)) {
842 chunks = (symfile->num_range_entries + 1) / RANGE_TABLE_CHUNK_SIZE;
843 size = sizeof (MonoDebugRangeInfo) * RANGE_TABLE_CHUNK_SIZE * (chunks + 1);
845 symfile->range_table = g_realloc (symfile->range_table, size);
848 retval = symfile->range_table + symfile->num_range_entries;
849 symfile->num_range_entries++;
854 write_type (MonoSymbolFile *symfile, int index, MonoType *type)
856 guint8 buffer [BUFSIZ], *ptr = buffer, *retval;
859 if (symfile->_priv->type_table [index])
860 return symfile->_priv->type_table [index];
863 *((guint32 *) ptr)++ = 0;
865 switch (type->type) {
866 case MONO_TYPE_VALUETYPE:
867 case MONO_TYPE_CLASS: {
868 MonoClass *klass = type->data.klass;
870 mono_class_init (klass);
871 *((guint32 *) ptr)++ = type->data.klass->instance_size;
875 case MONO_TYPE_BOOLEAN:
878 *((guint32 *) ptr)++ = 1;
884 *((guint32 *) ptr)++ = 2;
890 *((guint32 *) ptr)++ = 4;
896 *((guint32 *) ptr)++ = 8;
899 case MONO_TYPE_STRING: {
902 *((guint32 *) ptr)++ = -5;
904 *ptr++ = sizeof (MonoString);
905 *ptr++ = (guint8*)&string.length - (guint8*)&string;
906 *ptr++ = sizeof (string.length);
907 *ptr++ = (guint8*)&string.chars - (guint8*)&string;
911 case MONO_TYPE_ARRAY: {
914 *((guint32 *) ptr)++ = -4;
916 *ptr++ = sizeof (MonoArray);
917 *ptr++ = (guint8*)&array.max_length - (guint8*)&array;
918 *ptr++ = sizeof (array.max_length);
923 g_message (G_STRLOC ": %d - %p - %x,%x,%x", index, type, type->attrs,
924 type->type, type->byref);
926 *((guint32 *) ptr)++ = -1;
933 retval = g_malloc0 (size + 4);
934 memcpy (retval + 4, buffer, size);
935 *((guint32 *) retval) = size;
937 symfile->_priv->type_table [index] = retval;