6eff0ecbda320d6a165b4be0582e800fa2fdc057
[mono.git] / mono / metadata / mono-debug.c
1 /*
2  * mono-debug.c: 
3  *
4  * Author:
5  *      Mono Project (http://www.mono-project.com)
6  *
7  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
8  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
9  * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
10  */
11
12 #include <config.h>
13 #include <mono/metadata/assembly.h>
14 #include <mono/metadata/tabledefs.h>
15 #include <mono/metadata/tokentype.h>
16 #include <mono/metadata/appdomain.h>
17 #include <mono/metadata/class-internals.h>
18 #include <mono/metadata/mono-debug.h>
19 #include <mono/metadata/mono-debug-debugger.h>
20 #include <mono/metadata/mono-endian.h>
21 #include <mono/metadata/gc-internal.h>
22 #include <string.h>
23
24 #define DATA_TABLE_CHUNK_SIZE           (16384-sizeof (MonoDebugDataChunk))
25
26 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
27
28 #if NO_UNALIGNED_ACCESS
29 #define RETURN_UNALIGNED(type, addr) \
30         { \
31                 type val; \
32                 memcpy(&val, p + offset, sizeof(val)); \
33                 return val; \
34         }
35 #define WRITE_UNALIGNED(type, addr, val) \
36         memcpy(addr, &val, sizeof(type))
37 #define READ_UNALIGNED(type, addr, val) \
38         memcpy(&val, addr, sizeof(type))
39 #else
40 #define RETURN_UNALIGNED(type, addr) \
41         return *(type*)(p + offset);
42 #define WRITE_UNALIGNED(type, addr, val) \
43         (*(type *)(addr) = (val))
44 #define READ_UNALIGNED(type, addr, val) \
45         val = (*(type *)(addr))
46 #endif
47
48 typedef enum {
49         MONO_DEBUG_DATA_ITEM_UNKNOWN            = 0,
50         MONO_DEBUG_DATA_ITEM_CLASS,
51         MONO_DEBUG_DATA_ITEM_METHOD,
52         MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE
53 } MonoDebugDataItemType;
54
55 typedef struct _MonoDebugDataChunk MonoDebugDataChunk;
56
57 struct _MonoDebugDataChunk {
58         guint32 total_size;
59         guint32 allocated_size;
60         guint32 current_offset;
61         guint32 dummy;
62         MonoDebugDataChunk *next;
63         guint8 data [MONO_ZERO_LEN_ARRAY];
64 };
65
66 struct _MonoDebugDataTable {
67         gint32 domain;
68         gint32 _dummy; /* alignment for next field. */
69         MonoDebugDataChunk *first_chunk;
70         MonoDebugDataChunk *current_chunk;
71         GHashTable *method_hash;
72         GHashTable *method_address_hash;
73 };
74
75 typedef struct {
76         const gchar *method_name;
77         const gchar *obsolete_cil_code;
78         guint32 wrapper_type;
79 } MonoDebugWrapperData;
80
81 typedef struct {
82         guint32 size;
83         guint32 symfile_id;
84         guint32 domain_id;
85         guint32 method_id;
86         MonoDebugWrapperData *wrapper_data;
87         MonoMethod *method;
88         GSList *address_list;
89 } MonoDebugMethodHeader;
90
91 struct _MonoDebugMethodAddress {
92         MonoDebugMethodHeader header;
93         const guint8 *code_start;
94         const guint8 *wrapper_addr;
95         guint32 code_size;
96         guint8 data [MONO_ZERO_LEN_ARRAY];
97 };
98
99 struct _MonoDebugClassEntry {
100         guint32 size;
101         guint8 data [MONO_ZERO_LEN_ARRAY];
102 };
103
104 typedef struct {
105         gpointer code;
106         guint32 size;
107 } MonoDebugDelegateTrampolineEntry;
108
109 MonoSymbolTable *mono_symbol_table = NULL;
110 MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
111 gint32 mono_debug_debugger_version = 5;
112 gint32 _mono_debug_using_mono_debugger = 0;
113
114 static gboolean mono_debug_initialized = FALSE;
115 static GHashTable *mono_debug_handles = NULL;
116
117 static GHashTable *data_table_hash = NULL;
118 static int next_symbol_file_id = 0;
119
120 static MonoDebugHandle     *mono_debug_open_image      (MonoImage *image, const guint8 *raw_contents, int size);
121
122 static MonoDebugHandle     *_mono_debug_get_image      (MonoImage *image);
123 static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
124                                                         gpointer user_data);
125 static void                 mono_debug_add_type        (MonoClass *klass);
126
127 static MonoDebugHandle     *open_symfile_from_bundle   (MonoImage *image);
128
129 void _mono_debug_init_corlib (MonoDomain *domain);
130
131 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
132 extern void (*mono_debugger_class_loaded_methods_func) (MonoClass *klass);
133
134 static MonoDebugDataTable *
135 create_data_table (MonoDomain *domain)
136 {
137         MonoDebugDataTable *table;
138         MonoDebugDataChunk *chunk;
139
140         table = g_new0 (MonoDebugDataTable, 1);
141         table->domain = domain ? mono_domain_get_id (domain) : -1;
142
143         table->method_address_hash = g_hash_table_new (NULL, NULL);
144         table->method_hash = g_hash_table_new (NULL, NULL);
145
146         chunk = g_malloc0 (sizeof (MonoDebugDataChunk) + DATA_TABLE_CHUNK_SIZE);
147         chunk->total_size = DATA_TABLE_CHUNK_SIZE;
148
149         table->first_chunk = table->current_chunk = chunk;
150
151         if (domain) {
152                 mono_debug_list_add (&mono_symbol_table->data_tables, table);
153                 g_hash_table_insert (data_table_hash, domain, table);
154         }
155
156         return table;
157 }
158
159 static void
160 free_header_data (gpointer key, gpointer value, gpointer user_data)
161 {
162         MonoDebugMethodHeader *header = (MonoDebugMethodHeader*)value;
163
164         if (header->wrapper_data) {
165                 g_free ((gpointer)header->wrapper_data->method_name);
166                 g_free (header->wrapper_data);
167         }
168         g_slist_free (header->address_list);
169 }
170
171 static void
172 free_data_table (MonoDebugDataTable *table)
173 {
174         MonoDebugDataChunk *chunk, *next_chunk;
175
176         g_hash_table_foreach (table->method_hash, free_header_data, NULL);
177         g_hash_table_destroy (table->method_hash);
178         g_hash_table_destroy (table->method_address_hash);
179
180         table->method_hash = NULL;
181         table->method_address_hash = NULL;
182
183         chunk = table->first_chunk;
184         while (chunk) {
185                 next_chunk = chunk->next;
186                 g_free (chunk);
187                 chunk = next_chunk;
188         }
189
190         table->first_chunk = table->current_chunk = NULL;
191         mono_debug_list_remove (&mono_symbol_table->data_tables, table);
192         g_free (table);
193 }
194
195 static MonoDebugDataTable *
196 lookup_data_table (MonoDomain *domain)
197 {
198         MonoDebugDataTable *table;
199
200         table = g_hash_table_lookup (data_table_hash, domain);
201         if (!table) {
202                 g_error ("lookup_data_table () failed for %p\n", domain);
203                 g_assert (table);
204         }
205         return table;
206 }
207
208 static void
209 free_debug_handle (MonoDebugHandle *handle)
210 {
211         if (handle->symfile)
212                 mono_debug_close_mono_symbol_file (handle->symfile);
213         /* decrease the refcount added with mono_image_addref () */
214         free_data_table (handle->type_table);
215         mono_image_close (handle->image);
216         g_free (handle->image_file);
217         g_free (handle);
218 }
219
220 /*
221  * Initialize debugging support.
222  *
223  * This method must be called after loading corlib,
224  * but before opening the application's main assembly because we need to set some
225  * callbacks here.
226  */
227 void
228 mono_debug_init (MonoDebugFormat format)
229 {
230         g_assert (!mono_debug_initialized);
231
232         if (_mono_debug_using_mono_debugger)
233                 format = MONO_DEBUG_FORMAT_DEBUGGER;
234
235         mono_debug_initialized = TRUE;
236         mono_debug_format = format;
237
238         /*
239          * This must be called before mono_debugger_initialize(), because the
240          * latter registers GC roots.
241          */
242         mono_gc_base_init ();
243
244         mono_debugger_initialize (_mono_debug_using_mono_debugger);
245
246         mono_debugger_lock ();
247
248         mono_symbol_table = g_new0 (MonoSymbolTable, 1);
249         mono_symbol_table->magic = MONO_DEBUGGER_MAGIC;
250         mono_symbol_table->version = MONO_DEBUGGER_MAJOR_VERSION;
251         mono_symbol_table->total_size = sizeof (MonoSymbolTable);
252
253         mono_debug_handles = g_hash_table_new_full
254                 (NULL, NULL, NULL, (GDestroyNotify) free_debug_handle);
255
256         data_table_hash = g_hash_table_new_full (
257                 NULL, NULL, NULL, (GDestroyNotify) free_data_table);
258
259         mono_debugger_class_init_func = mono_debug_add_type;
260         mono_debugger_class_loaded_methods_func = mono_debugger_class_initialized;
261         mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
262
263         mono_symbol_table->global_data_table = create_data_table (NULL);
264
265         mono_debugger_unlock ();
266 }
267
268 /*
269  * INTERNAL USE ONLY !
270  */
271 void
272 _mono_debug_init_corlib (MonoDomain *domain)
273 {
274         if (!mono_debug_initialized)
275                 return;
276
277         mono_symbol_table->corlib = mono_debug_open_image (mono_defaults.corlib, NULL, 0);
278         mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_CORLIB,
279                              (guint64) (gsize) mono_symbol_table->corlib, 0);
280 }
281
282 void
283 mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
284 {
285         if (!mono_debug_initialized)
286                 return;
287
288         mono_debug_open_image (image, raw_contents, size);
289 }
290
291
292 gboolean
293 mono_debug_using_mono_debugger (void)
294 {
295         return _mono_debug_using_mono_debugger;
296 }
297
298 void
299 mono_debug_cleanup (void)
300 {
301         if (mono_debug_handles)
302                 g_hash_table_destroy (mono_debug_handles);
303         mono_debug_handles = NULL;
304
305         if (data_table_hash) {
306                 g_hash_table_destroy (data_table_hash);
307                 data_table_hash = NULL;
308         }
309
310         if (mono_symbol_table) {
311                 if (mono_symbol_table->global_data_table)
312                         free_data_table (mono_symbol_table->global_data_table);
313
314                 g_free (mono_symbol_table);
315                 mono_symbol_table = NULL;
316         }
317 }
318
319 void
320 mono_debug_domain_create (MonoDomain *domain)
321 {
322         MonoDebugDataTable *table;
323
324         if (!mono_debug_initialized)
325                 return;
326
327         mono_debugger_lock ();
328
329         table = create_data_table (domain);
330
331         mono_debugger_event (MONO_DEBUGGER_EVENT_DOMAIN_CREATE, (guint64) (gsize) table,
332                              mono_domain_get_id (domain));
333
334         mono_debugger_unlock ();
335 }
336
337 void
338 mono_debug_domain_unload (MonoDomain *domain)
339 {
340         MonoDebugDataTable *table;
341
342         if (!mono_debug_initialized)
343                 return;
344
345         mono_debugger_lock ();
346
347         table = g_hash_table_lookup (data_table_hash, domain);
348         if (!table) {
349                 g_warning (G_STRLOC ": unloading unknown domain %p / %d",
350                            domain, mono_domain_get_id (domain));
351                 mono_debugger_unlock ();
352                 return;
353         }
354
355         mono_debugger_event (MONO_DEBUGGER_EVENT_DOMAIN_UNLOAD, (guint64) (gsize) table,
356                              mono_domain_get_id (domain));
357
358         g_hash_table_remove (data_table_hash, domain);
359
360         mono_debugger_unlock ();
361 }
362
363 /*
364  * LOCKING: Assumes the debug lock is held.
365  */
366 static MonoDebugHandle *
367 _mono_debug_get_image (MonoImage *image)
368 {
369         return g_hash_table_lookup (mono_debug_handles, image);
370 }
371
372 void
373 mono_debug_close_image (MonoImage *image)
374 {
375         MonoDebugHandle *handle;
376
377         if (!mono_debug_initialized)
378                 return;
379
380         mono_debugger_lock ();
381
382         handle = _mono_debug_get_image (image);
383         if (!handle) {
384                 mono_debugger_unlock ();
385                 return;
386         }
387
388         mono_debugger_event (MONO_DEBUGGER_EVENT_UNLOAD_MODULE, (guint64) (gsize) handle,
389                              handle->index);
390
391         mono_debug_list_remove (&mono_symbol_table->symbol_files, handle);
392         g_hash_table_remove (mono_debug_handles, image);
393
394         mono_debugger_unlock ();
395 }
396
397 static MonoDebugHandle *
398 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
399 {
400         MonoDebugHandle *handle;
401
402         if (mono_image_is_dynamic (image))
403                 return NULL;
404
405         mono_debugger_lock ();
406
407         handle = _mono_debug_get_image (image);
408         if (handle != NULL) {
409                 mono_debugger_unlock ();
410                 return handle;
411         }
412
413         handle = g_new0 (MonoDebugHandle, 1);
414         handle->index = ++next_symbol_file_id;
415
416         handle->image = image;
417         mono_image_addref (image);
418         handle->image_file = g_strdup (mono_image_get_filename (image));
419
420         handle->type_table = create_data_table (NULL);
421
422         handle->symfile = mono_debug_open_mono_symbols (
423                 handle, raw_contents, size, _mono_debug_using_mono_debugger);
424
425         mono_debug_list_add (&mono_symbol_table->symbol_files, handle);
426
427         g_hash_table_insert (mono_debug_handles, image, handle);
428
429         if (mono_symbol_table->corlib)
430                 mono_debugger_event (MONO_DEBUGGER_EVENT_LOAD_MODULE,
431                                      (guint64) (gsize) handle, 0);
432
433         mono_debugger_unlock ();
434
435         return handle;
436 }
437
438 static void
439 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
440 {
441         MonoDebugHandle *handle;
442         MonoImage *image;
443
444         mono_debugger_lock ();
445         image = mono_assembly_get_image (assembly);
446         handle = open_symfile_from_bundle (image);
447         if (!handle)
448                 mono_debug_open_image (image, NULL, 0);
449         mono_debugger_unlock ();
450 }
451
452 static guint8 *
453 allocate_data_item (MonoDebugDataTable *table, MonoDebugDataItemType type, guint32 size)
454 {
455         guint32 chunk_size;
456         guint8 *data;
457
458         size = ALIGN_TO (size, sizeof (gpointer));
459
460         if (size + 16 < DATA_TABLE_CHUNK_SIZE)
461                 chunk_size = DATA_TABLE_CHUNK_SIZE;
462         else
463                 chunk_size = size + 16;
464
465         g_assert (table->current_chunk->current_offset == table->current_chunk->allocated_size);
466
467         if (table->current_chunk->allocated_size + size + 8 >= table->current_chunk->total_size) {
468                 MonoDebugDataChunk *new_chunk;
469
470                 new_chunk = g_malloc0 (sizeof (MonoDebugDataChunk) + chunk_size);
471                 new_chunk->total_size = chunk_size;
472
473                 table->current_chunk->next = new_chunk;
474                 table->current_chunk = new_chunk;
475         }
476
477         data = &table->current_chunk->data [table->current_chunk->allocated_size];
478         table->current_chunk->allocated_size += size + 8;
479
480         * ((guint32 *) data) = size;
481         data += 4;
482         * ((guint32 *) data) = type;
483         data += 4;
484         return data;
485 }
486
487 static void
488 write_data_item (MonoDebugDataTable *table, const guint8 *data)
489 {
490         MonoDebugDataChunk *current_chunk = table->current_chunk;
491         guint32 size = * ((guint32 *) (data - 8));
492
493         g_assert (current_chunk->current_offset + size + 8 == current_chunk->allocated_size);
494         current_chunk->current_offset = current_chunk->allocated_size;
495 }
496
497 struct LookupMethodData
498 {
499         MonoDebugMethodInfo *minfo;
500         MonoMethod *method;
501 };
502
503 static void
504 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
505 {
506         MonoDebugHandle *handle = (MonoDebugHandle *) value;
507         struct LookupMethodData *data = (struct LookupMethodData *) user_data;
508
509         if (data->minfo)
510                 return;
511
512         if (handle->symfile)
513                 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
514 }
515
516 static MonoDebugMethodInfo *
517 _mono_debug_lookup_method (MonoMethod *method)
518 {
519         struct LookupMethodData data;
520
521         data.minfo = NULL;
522         data.method = method;
523
524         if (!mono_debug_handles)
525                 return NULL;
526
527         g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
528         return data.minfo;
529 }
530
531 /**
532  * mono_debug_lookup_method:
533  *
534  * Lookup symbol file information for the method @method.  The returned
535  * `MonoDebugMethodInfo' is a private structure, but it can be passed to
536  * mono_debug_symfile_lookup_location().
537  */
538 MonoDebugMethodInfo *
539 mono_debug_lookup_method (MonoMethod *method)
540 {
541         MonoDebugMethodInfo *minfo;
542
543         mono_debugger_lock ();
544         minfo = _mono_debug_lookup_method (method);
545         mono_debugger_unlock ();
546         return minfo;
547 }
548
549 static inline void
550 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
551 {
552         do {
553                 guint8 byte = value & 0x7f;
554                 value >>= 7;
555                 if (value)
556                         byte |= 0x80;
557                 *ptr++ = byte;
558         } while (value);
559
560         *rptr = ptr;
561 }
562
563 static inline void
564 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
565 {
566         gboolean more = 1;
567
568         while (more) {
569                 guint8 byte = value & 0x7f;
570                 value >>= 7;
571
572                 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
573                         more = 0;
574                 else
575                         byte |= 0x80;
576                 *ptr++ = byte;
577         }
578
579         *rptr = ptr;
580 }
581
582 static void
583 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
584 {
585         write_leb128 (var->index, ptr, &ptr);
586         write_sleb128 (var->offset, ptr, &ptr);
587         write_leb128 (var->size, ptr, &ptr);
588         write_leb128 (var->begin_scope, ptr, &ptr);
589         write_leb128 (var->end_scope, ptr, &ptr);
590         WRITE_UNALIGNED (gpointer, ptr, var->type);
591         ptr += sizeof (gpointer);
592         *rptr = ptr;
593 }
594
595 MonoDebugMethodAddress *
596 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
597 {
598         MonoMethod *declaring;
599         MonoDebugDataTable *table;
600         MonoDebugMethodHeader *header;
601         MonoDebugMethodAddress *address;
602         MonoDebugMethodInfo *minfo;
603         MonoDebugHandle *handle;
604         guint8 buffer [BUFSIZ];
605         guint8 *ptr, *oldptr;
606         guint32 i, size, total_size, max_size;
607         gboolean is_wrapper = FALSE;
608
609         mono_debugger_lock ();
610
611         table = lookup_data_table (domain);
612
613         handle = _mono_debug_get_image (method->klass->image);
614         minfo = _mono_debug_lookup_method (method);
615
616         if (!minfo || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
617             (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
618             (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
619             (method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
620             (method->wrapper_type != MONO_WRAPPER_NONE)) {
621                 is_wrapper = TRUE;
622         }
623
624         max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
625                 (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
626
627         if (max_size > BUFSIZ)
628                 ptr = oldptr = g_malloc (max_size);
629         else
630                 ptr = oldptr = buffer;
631
632         write_leb128 (jit->prologue_end, ptr, &ptr);
633         write_leb128 (jit->epilogue_begin, ptr, &ptr);
634
635         write_leb128 (jit->num_line_numbers, ptr, &ptr);
636         for (i = 0; i < jit->num_line_numbers; i++) {
637                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
638
639                 write_sleb128 (lne->il_offset, ptr, &ptr);
640                 write_sleb128 (lne->native_offset, ptr, &ptr);
641         }
642
643         *ptr++ = jit->this_var ? 1 : 0;
644         if (jit->this_var)
645                 write_variable (jit->this_var, ptr, &ptr);
646
647         write_leb128 (jit->num_params, ptr, &ptr);
648         for (i = 0; i < jit->num_params; i++)
649                 write_variable (&jit->params [i], ptr, &ptr);
650
651         write_leb128 (jit->num_locals, ptr, &ptr);
652         for (i = 0; i < jit->num_locals; i++)
653                 write_variable (&jit->locals [i], ptr, &ptr);
654
655         *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
656         if (jit->gsharedvt_info_var) {
657                 write_variable (jit->gsharedvt_info_var, ptr, &ptr);
658                 write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
659         }
660
661         size = ptr - oldptr;
662         g_assert (size < max_size);
663         total_size = size + sizeof (MonoDebugMethodAddress);
664
665         if (method->dynamic) {
666                 address = g_malloc0 (total_size);
667         } else {
668                 address = (MonoDebugMethodAddress *) allocate_data_item (
669                                   table, MONO_DEBUG_DATA_ITEM_METHOD, total_size);
670         }
671
672         address->header.size = total_size;
673         address->header.symfile_id = handle ? handle->index : 0;
674         address->header.domain_id = mono_domain_get_id (domain);
675         address->header.method_id = is_wrapper ? 0 : minfo->index;
676         address->header.method = method;
677
678         address->code_start = jit->code_start;
679         address->code_size = jit->code_size;
680
681         memcpy (&address->data, oldptr, size);
682         if (max_size > BUFSIZ)
683                 g_free (oldptr);
684
685         declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
686         header = g_hash_table_lookup (table->method_hash, declaring);
687
688         if (!header) {
689                 header = &address->header;
690                 g_hash_table_insert (table->method_hash, declaring, header);
691
692                 if (is_wrapper) {
693                         MonoDebugWrapperData *wrapper;
694
695                         header->wrapper_data = wrapper = g_new0 (MonoDebugWrapperData, 1);
696
697                         wrapper->wrapper_type = method->wrapper_type;
698                         wrapper->method_name = mono_method_full_name (declaring, TRUE);
699                         wrapper->obsolete_cil_code = "";
700                 }
701         } else {
702                 address->header.wrapper_data = header->wrapper_data;
703                 header->address_list = g_slist_prepend (header->address_list, address);
704         }
705
706         g_hash_table_insert (table->method_address_hash, method, address);
707
708         if (!method->dynamic)
709                 write_data_item (table, (guint8 *) address);
710
711         mono_debugger_unlock ();
712         return address;
713 }
714
715 void
716 mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
717 {
718         MonoMethod *declaring;
719         MonoDebugDataTable *table;
720         MonoDebugMethodHeader *header;
721         MonoDebugMethodAddress *address;
722
723         if (!mono_debug_initialized)
724                 return;
725
726         g_assert (method->dynamic);
727
728         mono_debugger_lock ();
729
730         table = lookup_data_table (domain);
731
732         declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
733         g_hash_table_remove (table->method_hash, declaring);
734
735         address = g_hash_table_lookup (table->method_address_hash, method);
736         if (address) {
737                 header = &address->header;
738
739                 if (header->wrapper_data) {
740                         g_free ((char*)header->wrapper_data->method_name);
741                         g_free (header->wrapper_data);
742                 }
743                 g_free (address);
744         }
745
746         g_hash_table_remove (table->method_address_hash, method);
747
748         mono_debugger_unlock ();
749 }
750
751 void
752 mono_debug_add_delegate_trampoline (gpointer code, int size)
753 {
754         MonoDebugDelegateTrampolineEntry *entry;
755
756         if (!mono_debug_initialized)
757                 return;
758
759         mono_debugger_lock ();
760
761         entry = (MonoDebugDelegateTrampolineEntry *) allocate_data_item (
762                 mono_symbol_table->global_data_table, MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE,
763                 sizeof (MonoDebugDelegateTrampolineEntry));
764         entry->code = code;
765         entry->size = size;
766
767         write_data_item (mono_symbol_table->global_data_table, (guint8 *) entry);
768
769         mono_debugger_unlock ();
770 }
771
772 static inline guint32
773 read_leb128 (guint8 *ptr, guint8 **rptr)
774 {
775         guint32 result = 0, shift = 0;
776
777         while (TRUE) {
778                 guint8 byte = *ptr++;
779
780                 result |= (byte & 0x7f) << shift;
781                 if ((byte & 0x80) == 0)
782                         break;
783                 shift += 7;
784         }
785
786         *rptr = ptr;
787         return result;
788 }
789
790 static inline gint32
791 read_sleb128 (guint8 *ptr, guint8 **rptr)
792 {
793         gint32 result = 0;
794         guint32 shift = 0;
795
796         while (TRUE) {
797                 guint8 byte = *ptr++;
798
799                 result |= (byte & 0x7f) << shift;
800                 shift += 7;
801
802                 if (byte & 0x80)
803                         continue;
804
805                 if ((shift < 32) && (byte & 0x40))
806                         result |= - (1 << shift);
807                 break;
808         }
809
810         *rptr = ptr;
811         return result;
812 }
813
814 static void
815 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
816 {
817         var->index = read_leb128 (ptr, &ptr);
818         var->offset = read_sleb128 (ptr, &ptr);
819         var->size = read_leb128 (ptr, &ptr);
820         var->begin_scope = read_leb128 (ptr, &ptr);
821         var->end_scope = read_leb128 (ptr, &ptr);
822         READ_UNALIGNED (gpointer, ptr, var->type);
823         ptr += sizeof (gpointer);
824         *rptr = ptr;
825 }
826
827 void
828 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
829 {
830         if (!jit)
831                 return;
832         g_free (jit->line_numbers);
833         g_free (jit->this_var);
834         g_free (jit->params);
835         g_free (jit->locals);
836         g_free (jit->gsharedvt_info_var);
837         g_free (jit->gsharedvt_locals_var);
838         g_free (jit);
839 }
840
841 static MonoDebugMethodJitInfo *
842 mono_debug_read_method (MonoDebugMethodAddress *address)
843 {
844         MonoDebugMethodJitInfo *jit;
845         guint32 i;
846         guint8 *ptr;
847
848         jit = g_new0 (MonoDebugMethodJitInfo, 1);
849         jit->code_start = address->code_start;
850         jit->code_size = address->code_size;
851         jit->wrapper_addr = address->wrapper_addr;
852
853         ptr = (guint8 *) &address->data;
854
855         jit->prologue_end = read_leb128 (ptr, &ptr);
856         jit->epilogue_begin = read_leb128 (ptr, &ptr);
857
858         jit->num_line_numbers = read_leb128 (ptr, &ptr);
859         jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
860         for (i = 0; i < jit->num_line_numbers; i++) {
861                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
862
863                 lne->il_offset = read_sleb128 (ptr, &ptr);
864                 lne->native_offset = read_sleb128 (ptr, &ptr);
865         }
866
867         if (*ptr++) {
868                 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
869                 read_variable (jit->this_var, ptr, &ptr);
870         }
871
872         jit->num_params = read_leb128 (ptr, &ptr);
873         jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
874         for (i = 0; i < jit->num_params; i++)
875                 read_variable (&jit->params [i], ptr, &ptr);
876
877         jit->num_locals = read_leb128 (ptr, &ptr);
878         jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
879         for (i = 0; i < jit->num_locals; i++)
880                 read_variable (&jit->locals [i], ptr, &ptr);
881
882         if (*ptr++) {
883                 jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
884                 jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
885                 read_variable (jit->gsharedvt_info_var, ptr, &ptr);
886                 read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
887         }
888
889         return jit;
890 }
891
892 static void
893 mono_debug_add_type (MonoClass *klass)
894 {
895         MonoDebugHandle *handle;
896         MonoDebugClassEntry *entry;
897         guint8 buffer [BUFSIZ];
898         guint8 *ptr, *oldptr;
899         guint32 size, total_size, max_size;
900         int base_offset = 0;
901
902         if (klass->generic_class || klass->rank ||
903             (klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR))
904                 return;
905
906         mono_debugger_lock ();
907
908         handle = _mono_debug_get_image (klass->image);
909         if (!handle) {
910                 mono_debugger_unlock ();
911                 return;
912         }
913
914         max_size = 12 + sizeof (gpointer);
915         if (max_size > BUFSIZ)
916                 ptr = oldptr = g_malloc (max_size);
917         else
918                 ptr = oldptr = buffer;
919
920         if (klass->valuetype)
921                 base_offset = - (int)(sizeof (MonoObject));
922
923         write_leb128 (klass->type_token, ptr, &ptr);
924         write_leb128 (klass->instance_size + base_offset, ptr, &ptr);
925         WRITE_UNALIGNED (gpointer, ptr, klass);
926         ptr += sizeof (gpointer);
927
928         size = ptr - oldptr;
929         g_assert (size < max_size);
930         total_size = size + sizeof (MonoDebugClassEntry);
931
932         g_assert (total_size + 9 < DATA_TABLE_CHUNK_SIZE);
933
934         entry = (MonoDebugClassEntry *) allocate_data_item (
935                 handle->type_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size);
936
937         entry->size = total_size;
938
939         memcpy (&entry->data, oldptr, size);
940
941         write_data_item (handle->type_table, (guint8 *) entry);
942
943         if (max_size > BUFSIZ)
944                 g_free (oldptr);
945
946         mono_debugger_unlock ();
947 }
948
949 static MonoDebugMethodJitInfo *
950 find_method (MonoMethod *method, MonoDomain *domain)
951 {
952         MonoDebugDataTable *table;
953         MonoDebugMethodAddress *address;
954
955         table = lookup_data_table (domain);
956         address = g_hash_table_lookup (table->method_address_hash, method);
957
958         if (!address)
959                 return NULL;
960
961         return mono_debug_read_method (address);
962 }
963
964 MonoDebugMethodJitInfo *
965 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
966 {
967         MonoDebugMethodJitInfo *res;
968
969         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
970                 return NULL;
971
972         mono_debugger_lock ();
973         res = find_method (method, domain);
974         mono_debugger_unlock ();
975         return res;
976 }
977
978 struct LookupMethodAddressData
979 {
980         MonoMethod *method;
981         MonoDebugMethodHeader *result;
982 };
983
984 static void
985 lookup_method_address_func (gpointer key, gpointer value, gpointer user_data)
986 {
987         MonoDebugDataTable *table = (MonoDebugDataTable *) value;
988         struct LookupMethodAddressData *data = (struct LookupMethodAddressData *) user_data;
989         MonoDebugMethodHeader *header;
990
991         header = g_hash_table_lookup (table->method_hash, data->method);
992         if (header)
993                 data->result = header;
994 }
995
996 MonoDebugMethodAddressList *
997 mono_debug_lookup_method_addresses (MonoMethod *method)
998 {
999         MonoDebugMethodAddressList *info;
1000         MonoDebugMethodHeader *header = NULL;
1001         struct LookupMethodAddressData data;
1002         MonoMethod *declaring;
1003         int count, size;
1004         GSList *list;
1005         guint8 *ptr;
1006
1007         g_assert ((mono_debug_debugger_version == 4) || (mono_debug_debugger_version == 5));
1008
1009         mono_debugger_lock ();
1010
1011         declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
1012
1013         data.method = declaring;
1014         data.result = NULL;
1015
1016         g_hash_table_foreach (data_table_hash, lookup_method_address_func, &data);
1017         header = data.result;
1018
1019         if (!header) {
1020                 mono_debugger_unlock ();
1021                 return NULL;
1022         }
1023
1024         count = g_slist_length (header->address_list) + 1;
1025         size = sizeof (MonoDebugMethodAddressList) + count * sizeof (gpointer);
1026
1027         info = g_malloc0 (size);
1028         info->size = size;
1029         info->count = count;
1030
1031         ptr = info->data;
1032
1033         WRITE_UNALIGNED (gpointer, ptr, header);
1034         ptr += sizeof (gpointer);
1035
1036         for (list = header->address_list; list; list = list->next) {
1037                 WRITE_UNALIGNED (gpointer, ptr, list->data);
1038                 ptr += sizeof (gpointer);
1039         }
1040
1041         mono_debugger_unlock ();
1042         return info;
1043 }
1044
1045 static gint32
1046 il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
1047 {
1048         MonoDebugMethodJitInfo *jit;
1049         int i;
1050
1051         jit = find_method (method, domain);
1052         if (!jit || !jit->line_numbers)
1053                 goto cleanup_and_fail;
1054
1055         for (i = jit->num_line_numbers - 1; i >= 0; i--) {
1056                 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
1057
1058                 if (lne.native_offset <= native_offset) {
1059                         mono_debug_free_method_jit_info (jit);
1060                         return lne.il_offset;
1061                 }
1062         }
1063
1064 cleanup_and_fail:
1065         mono_debug_free_method_jit_info (jit);
1066         return -1;
1067 }
1068
1069 /**
1070  * mono_debug_il_offset_from_address:
1071  *
1072  *   Compute the IL offset corresponding to NATIVE_OFFSET inside the native
1073  * code of METHOD in DOMAIN.
1074  */
1075 gint32
1076 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
1077 {
1078         gint32 res;
1079
1080         mono_debugger_lock ();
1081
1082         res = il_offset_from_address (method, domain, native_offset);
1083
1084         mono_debugger_unlock ();
1085
1086         return res;
1087 }
1088
1089 /**
1090  * mono_debug_lookup_source_location:
1091  * @address: Native offset within the @method's machine code.
1092  *
1093  * Lookup the source code corresponding to the machine instruction located at
1094  * native offset @address within @method.
1095  *
1096  * The returned `MonoDebugSourceLocation' contains both file / line number
1097  * information and the corresponding IL offset.  It must be freed by
1098  * mono_debug_free_source_location().
1099  */
1100 MonoDebugSourceLocation *
1101 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
1102 {
1103         MonoDebugMethodInfo *minfo;
1104         MonoDebugSourceLocation *location;
1105         gint32 offset;
1106
1107         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
1108                 return NULL;
1109
1110         mono_debugger_lock ();
1111         minfo = _mono_debug_lookup_method (method);
1112         if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
1113                 mono_debugger_unlock ();
1114                 return NULL;
1115         }
1116
1117         offset = il_offset_from_address (method, domain, address);
1118         if (offset < 0) {
1119                 mono_debugger_unlock ();
1120                 return NULL;
1121         }
1122
1123         location = mono_debug_symfile_lookup_location (minfo, offset);
1124         mono_debugger_unlock ();
1125         return location;
1126 }
1127
1128 /*
1129  * mono_debug_lookup_locals:
1130  *
1131  *   Return information about the local variables of MINFO.
1132  * The result should be freed using mono_debug_symfile_free_locals ().
1133  */
1134 MonoDebugLocalsInfo*
1135 mono_debug_lookup_locals (MonoMethod *method)
1136 {
1137         MonoDebugMethodInfo *minfo;
1138         MonoDebugLocalsInfo *res;
1139
1140         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
1141                 return NULL;
1142
1143         mono_debugger_lock ();
1144         minfo = _mono_debug_lookup_method (method);
1145         if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
1146                 mono_debugger_unlock ();
1147                 return NULL;
1148         }
1149
1150         res = mono_debug_symfile_lookup_locals (minfo);
1151         mono_debugger_unlock ();
1152
1153         return res;
1154 }
1155
1156 /**
1157  * mono_debug_free_source_location:
1158  * @location: A `MonoDebugSourceLocation'.
1159  *
1160  * Frees the @location.
1161  */
1162 void
1163 mono_debug_free_source_location (MonoDebugSourceLocation *location)
1164 {
1165         if (location) {
1166                 g_free (location->source_file);
1167                 g_free (location);
1168         }
1169 }
1170
1171 /**
1172  * mono_debug_print_stack_frame:
1173  * @native_offset: Native offset within the @method's machine code.
1174  *
1175  * Conventient wrapper around mono_debug_lookup_source_location() which can be
1176  * used if you only want to use the location to print a stack frame.
1177  */
1178 gchar *
1179 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
1180 {
1181         MonoDebugSourceLocation *location;
1182         gchar *fname, *ptr, *res;
1183         int offset;
1184
1185         fname = mono_method_full_name (method, TRUE);
1186         for (ptr = fname; *ptr; ptr++) {
1187                 if (*ptr == ':') *ptr = '.';
1188         }
1189
1190         location = mono_debug_lookup_source_location (method, native_offset, domain);
1191
1192         if (!location) {
1193                 if (mono_debug_initialized) {
1194                         mono_debugger_lock ();
1195                         offset = il_offset_from_address (method, domain, native_offset);
1196                         mono_debugger_unlock ();
1197                 } else {
1198                         offset = -1;
1199                 }
1200
1201                 if (offset < 0)
1202                         res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
1203                 else
1204                         res = g_strdup_printf ("at %s <IL 0x%05x, 0x%05x>", fname, offset, native_offset);
1205                 g_free (fname);
1206                 return res;
1207         }
1208
1209         res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
1210                                location->source_file, location->row);
1211
1212         g_free (fname);
1213         mono_debug_free_source_location (location);
1214         return res;
1215 }
1216
1217 void
1218 mono_debug_list_add (MonoDebugList **list, gconstpointer data)
1219 {
1220         MonoDebugList *element, **ptr;
1221
1222         element = g_new0 (MonoDebugList, 1);
1223         element->data = data;
1224
1225         for (ptr = list; *ptr; ptr = &(*ptr)->next)
1226                 ;
1227
1228         *ptr = element;
1229 }
1230
1231 void
1232 mono_debug_list_remove (MonoDebugList **list, gconstpointer data)
1233 {
1234         MonoDebugList **ptr;
1235         MonoDebugList *next;
1236
1237         for (ptr = list; *ptr; ptr = &(*ptr)->next) {
1238                 if ((*ptr)->data != data)
1239                         continue;
1240
1241                 next = (*ptr)->next;
1242                 g_free ((*ptr));
1243                 *ptr = next;
1244                 break;
1245         }
1246 }
1247
1248 static gboolean is_attached = FALSE;
1249
1250 void
1251 mono_set_is_debugger_attached (gboolean attached)
1252 {
1253         is_attached = attached;
1254 }
1255
1256 gboolean
1257 mono_is_debugger_attached (void)
1258 {
1259         return is_attached;
1260 }
1261
1262 /*
1263  * Bundles
1264  */
1265
1266 typedef struct _BundledSymfile BundledSymfile;
1267
1268 struct _BundledSymfile {
1269         BundledSymfile *next;
1270         const char *aname;
1271         const mono_byte *raw_contents;
1272         int size;
1273 };
1274
1275 static BundledSymfile *bundled_symfiles = NULL;
1276
1277 void
1278 mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
1279 {
1280         BundledSymfile *bsymfile;
1281
1282         bsymfile = g_new0 (BundledSymfile, 1);
1283         bsymfile->aname = assembly_name;
1284         bsymfile->raw_contents = raw_contents;
1285         bsymfile->size = size;
1286         bsymfile->next = bundled_symfiles;
1287         bundled_symfiles = bsymfile;
1288 }
1289
1290 static MonoDebugHandle *
1291 open_symfile_from_bundle (MonoImage *image)
1292 {
1293         BundledSymfile *bsymfile;
1294
1295         for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
1296                 if (strcmp (bsymfile->aname, image->module_name))
1297                         continue;
1298
1299                 return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
1300         }
1301
1302         return NULL;
1303 }