Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / metadata / mono-debug.c
1 /**
2  * \file
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  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11  */
12
13 #include <config.h>
14 #include <mono/metadata/assembly.h>
15 #include <mono/metadata/tabledefs.h>
16 #include <mono/metadata/tokentype.h>
17 #include <mono/metadata/appdomain.h>
18 #include <mono/metadata/class-internals.h>
19 #include <mono/metadata/mono-debug.h>
20 #include <mono/metadata/debug-internals.h>
21 #include <mono/metadata/mono-endian.h>
22 #include <mono/metadata/gc-internals.h>
23 #include <mono/metadata/mempool.h>
24 #include <mono/metadata/debug-mono-symfile.h>
25 #include <mono/metadata/debug-mono-ppdb.h>
26 #include <mono/metadata/exception-internals.h>
27 #include <mono/metadata/runtime.h>
28 #include <string.h>
29
30 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
31
32 #if NO_UNALIGNED_ACCESS
33 #define WRITE_UNALIGNED(type, addr, val) \
34         memcpy(addr, &val, sizeof(type))
35 #define READ_UNALIGNED(type, addr, val) \
36         memcpy(&val, addr, sizeof(type))
37 #else
38 #define WRITE_UNALIGNED(type, addr, val) \
39         (*(type *)(addr) = (val))
40 #define READ_UNALIGNED(type, addr, val) \
41         val = (*(type *)(addr))
42 #endif
43
44 /* This contains per-domain info */
45 struct _MonoDebugDataTable {
46         MonoMemPool *mp;
47         GHashTable *method_address_hash;
48 };
49
50 /* This contains JIT debugging information about a method in serialized format */
51 struct _MonoDebugMethodAddress {
52         const guint8 *code_start;
53         guint32 code_size;
54         guint8 data [MONO_ZERO_LEN_ARRAY];
55 };
56
57 static MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
58
59 static gboolean mono_debug_initialized = FALSE;
60 /* Maps MonoImage -> MonoMonoDebugHandle */
61 static GHashTable *mono_debug_handles;
62 /* Maps MonoDomain -> MonoDataTable */
63 static GHashTable *data_table_hash;
64
65 static mono_mutex_t debugger_lock_mutex;
66
67 static gboolean is_attached = FALSE;
68
69 static MonoDebugHandle     *mono_debug_open_image      (MonoImage *image, const guint8 *raw_contents, int size);
70
71 static MonoDebugHandle     *mono_debug_get_image      (MonoImage *image);
72 static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
73                                                         gpointer user_data);
74
75 static MonoDebugHandle     *open_symfile_from_bundle   (MonoImage *image);
76
77 static MonoDebugDataTable *
78 create_data_table (MonoDomain *domain)
79 {
80         MonoDebugDataTable *table;
81
82         table = g_new0 (MonoDebugDataTable, 1);
83
84         table->mp = mono_mempool_new ();
85         table->method_address_hash = g_hash_table_new (NULL, NULL);
86
87         if (domain)
88                 g_hash_table_insert (data_table_hash, domain, table);
89
90         return table;
91 }
92
93 static void
94 free_data_table (MonoDebugDataTable *table)
95 {
96         mono_mempool_destroy (table->mp);
97         g_hash_table_destroy (table->method_address_hash);
98
99         g_free (table);
100 }
101
102 static MonoDebugDataTable *
103 lookup_data_table (MonoDomain *domain)
104 {
105         MonoDebugDataTable *table;
106
107         table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain);
108         if (!table) {
109                 g_error ("lookup_data_table () failed for %p\n", domain);
110                 g_assert (table);
111         }
112         return table;
113 }
114
115 static void
116 free_debug_handle (MonoDebugHandle *handle)
117 {
118         if (handle->ppdb)
119                 mono_ppdb_close (handle);
120         if (handle->symfile)
121                 mono_debug_close_mono_symbol_file (handle->symfile);
122         /* decrease the refcount added with mono_image_addref () */
123         mono_image_close (handle->image);
124         g_free (handle);
125 }
126
127 /*
128  * Initialize debugging support.
129  *
130  * This method must be called after loading corlib,
131  * but before opening the application's main assembly because we need to set some
132  * callbacks here.
133  */
134 void
135 mono_debug_init (MonoDebugFormat format)
136 {
137         g_assert (!mono_debug_initialized);
138         if (format == MONO_DEBUG_FORMAT_DEBUGGER)
139                 g_error ("The mdb debugger is no longer supported.");
140
141         mono_debug_initialized = TRUE;
142         mono_debug_format = format;
143
144         mono_os_mutex_init_recursive (&debugger_lock_mutex);
145
146         mono_debugger_lock ();
147
148         mono_debug_handles = g_hash_table_new_full
149                 (NULL, NULL, NULL, (GDestroyNotify) free_debug_handle);
150
151         data_table_hash = g_hash_table_new_full (
152                 NULL, NULL, NULL, (GDestroyNotify) free_data_table);
153
154         mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
155
156         mono_debugger_unlock ();
157 }
158
159 void
160 mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
161 {
162         if (!mono_debug_initialized)
163                 return;
164
165         mono_debug_open_image (image, raw_contents, size);
166 }
167
168 void
169 mono_debug_cleanup (void)
170 {
171         if (mono_debug_handles)
172                 g_hash_table_destroy (mono_debug_handles);
173         mono_debug_handles = NULL;
174
175         if (data_table_hash) {
176                 g_hash_table_destroy (data_table_hash);
177                 data_table_hash = NULL;
178         }
179 }
180
181 /**
182  * mono_debug_domain_create:
183  */
184 void
185 mono_debug_domain_create (MonoDomain *domain)
186 {
187         if (!mono_debug_initialized)
188                 return;
189
190         mono_debugger_lock ();
191
192         create_data_table (domain);
193
194         mono_debugger_unlock ();
195 }
196
197 void
198 mono_debug_domain_unload (MonoDomain *domain)
199 {
200         MonoDebugDataTable *table;
201
202         if (!mono_debug_initialized)
203                 return;
204
205         mono_debugger_lock ();
206
207         table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain);
208         if (!table) {
209                 g_warning (G_STRLOC ": unloading unknown domain %p / %d",
210                            domain, mono_domain_get_id (domain));
211                 mono_debugger_unlock ();
212                 return;
213         }
214
215         g_hash_table_remove (data_table_hash, domain);
216
217         mono_debugger_unlock ();
218 }
219
220 /*
221  * LOCKING: Assumes the debug lock is held.
222  */
223 static MonoDebugHandle *
224 mono_debug_get_image (MonoImage *image)
225 {
226         return (MonoDebugHandle *)g_hash_table_lookup (mono_debug_handles, image);
227 }
228
229 /**
230  * mono_debug_close_image:
231  */
232 void
233 mono_debug_close_image (MonoImage *image)
234 {
235         MonoDebugHandle *handle;
236
237         if (!mono_debug_initialized)
238                 return;
239
240         mono_debugger_lock ();
241
242         handle = mono_debug_get_image (image);
243         if (!handle) {
244                 mono_debugger_unlock ();
245                 return;
246         }
247
248         g_hash_table_remove (mono_debug_handles, image);
249
250         mono_debugger_unlock ();
251 }
252
253 static MonoDebugHandle *
254 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
255 {
256         MonoDebugHandle *handle;
257
258         if (mono_image_is_dynamic (image))
259                 return NULL;
260
261         mono_debugger_lock ();
262
263         handle = mono_debug_get_image (image);
264         if (handle != NULL) {
265                 mono_debugger_unlock ();
266                 return handle;
267         }
268
269         handle = g_new0 (MonoDebugHandle, 1);
270
271         handle->image = image;
272         mono_image_addref (image);
273
274         /* Try a ppdb file first */
275         handle->ppdb = mono_ppdb_load_file (handle->image, raw_contents, size);
276
277         if (!handle->ppdb)
278                 handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, FALSE);
279
280         g_hash_table_insert (mono_debug_handles, image, handle);
281
282         mono_debugger_unlock ();
283
284         return handle;
285 }
286
287 static void
288 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
289 {
290         MonoDebugHandle *handle;
291         MonoImage *image;
292
293         mono_debugger_lock ();
294         image = mono_assembly_get_image (assembly);
295         handle = open_symfile_from_bundle (image);
296         if (!handle)
297                 mono_debug_open_image (image, NULL, 0);
298         mono_debugger_unlock ();
299 }
300
301 struct LookupMethodData
302 {
303         MonoDebugMethodInfo *minfo;
304         MonoMethod *method;
305 };
306
307 static void
308 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
309 {
310         MonoDebugHandle *handle = (MonoDebugHandle *) value;
311         struct LookupMethodData *data = (struct LookupMethodData *) user_data;
312
313         if (data->minfo)
314                 return;
315
316         if (handle->ppdb)
317                 data->minfo = mono_ppdb_lookup_method (handle, data->method);
318         else if (handle->symfile)
319                 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
320 }
321
322 static MonoDebugMethodInfo *
323 mono_debug_lookup_method_internal (MonoMethod *method)
324 {
325         struct LookupMethodData data;
326
327         data.minfo = NULL;
328         data.method = method;
329
330         if (!mono_debug_handles)
331                 return NULL;
332
333         g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
334         return data.minfo;
335 }
336
337 /**
338  * mono_debug_lookup_method:
339  *
340  * Lookup symbol file information for the method \p method.  The returned
341  * \c MonoDebugMethodInfo is a private structure, but it can be passed to
342  * \c mono_debug_symfile_lookup_location.
343  */
344 MonoDebugMethodInfo *
345 mono_debug_lookup_method (MonoMethod *method)
346 {
347         MonoDebugMethodInfo *minfo;
348
349         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
350                 return NULL;
351
352         mono_debugger_lock ();
353         minfo = mono_debug_lookup_method_internal (method);
354         mono_debugger_unlock ();
355         return minfo;
356 }
357
358 typedef struct
359 {
360         gboolean found;
361         MonoImage *image;
362 } LookupImageData;
363
364 static void
365 lookup_image_func (gpointer key, gpointer value, gpointer user_data)
366 {
367         MonoDebugHandle *handle = (MonoDebugHandle *) value;
368         LookupImageData *data = (LookupImageData *) user_data;
369
370         if (data->found)
371                 return;
372
373         if (handle->image == data->image && handle->symfile)
374                 data->found = TRUE;
375 }
376
377 gboolean
378 mono_debug_image_has_debug_info (MonoImage *image)
379 {
380         LookupImageData data;
381
382         if (!mono_debug_handles)
383                 return FALSE;
384
385         memset (&data, 0, sizeof (data));
386         data.image = image;
387
388         mono_debugger_lock ();
389         g_hash_table_foreach (mono_debug_handles, lookup_image_func, &data);
390         mono_debugger_unlock ();
391         return data.found;
392 }
393
394 static inline void
395 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
396 {
397         do {
398                 guint8 byte = value & 0x7f;
399                 value >>= 7;
400                 if (value)
401                         byte |= 0x80;
402                 *ptr++ = byte;
403         } while (value);
404
405         *rptr = ptr;
406 }
407
408 static inline void
409 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
410 {
411         gboolean more = 1;
412
413         while (more) {
414                 guint8 byte = value & 0x7f;
415                 value >>= 7;
416
417                 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
418                         more = 0;
419                 else
420                         byte |= 0x80;
421                 *ptr++ = byte;
422         }
423
424         *rptr = ptr;
425 }
426
427 static void
428 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
429 {
430         write_leb128 (var->index, ptr, &ptr);
431         write_sleb128 (var->offset, ptr, &ptr);
432         write_leb128 (var->size, ptr, &ptr);
433         write_leb128 (var->begin_scope, ptr, &ptr);
434         write_leb128 (var->end_scope, ptr, &ptr);
435         WRITE_UNALIGNED (gpointer, ptr, var->type);
436         ptr += sizeof (gpointer);
437         *rptr = ptr;
438 }
439
440 /**
441  * mono_debug_add_method:
442  */
443 MonoDebugMethodAddress *
444 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
445 {
446         MonoDebugDataTable *table;
447         MonoDebugMethodAddress *address;
448         guint8 buffer [BUFSIZ];
449         guint8 *ptr, *oldptr;
450         guint32 i, size, total_size, max_size;
451
452         mono_debugger_lock ();
453
454         table = lookup_data_table (domain);
455
456         max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
457                 (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
458
459         if (max_size > BUFSIZ)
460                 ptr = oldptr = (guint8 *)g_malloc (max_size);
461         else
462                 ptr = oldptr = buffer;
463
464         write_leb128 (jit->prologue_end, ptr, &ptr);
465         write_leb128 (jit->epilogue_begin, ptr, &ptr);
466
467         write_leb128 (jit->num_line_numbers, ptr, &ptr);
468         for (i = 0; i < jit->num_line_numbers; i++) {
469                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
470
471                 write_sleb128 (lne->il_offset, ptr, &ptr);
472                 write_sleb128 (lne->native_offset, ptr, &ptr);
473         }
474         write_leb128 (jit->has_var_info, ptr, &ptr);
475         if (jit->has_var_info) {
476                 *ptr++ = jit->this_var ? 1 : 0;
477                 if (jit->this_var)
478                         write_variable (jit->this_var, ptr, &ptr);
479
480                 write_leb128 (jit->num_params, ptr, &ptr);
481                 for (i = 0; i < jit->num_params; i++)
482                         write_variable (&jit->params [i], ptr, &ptr);
483
484                 write_leb128 (jit->num_locals, ptr, &ptr);
485                 for (i = 0; i < jit->num_locals; i++)
486                         write_variable (&jit->locals [i], ptr, &ptr);
487
488                 *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
489                 if (jit->gsharedvt_info_var) {
490                         write_variable (jit->gsharedvt_info_var, ptr, &ptr);
491                         write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
492                 }
493         }
494
495         size = ptr - oldptr;
496         g_assert (size < max_size);
497         total_size = size + sizeof (MonoDebugMethodAddress);
498
499         if (method_is_dynamic (method)) {
500                 address = (MonoDebugMethodAddress *)g_malloc0 (total_size);
501         } else {
502                 address = (MonoDebugMethodAddress *)mono_mempool_alloc (table->mp, total_size);
503         }
504
505         address->code_start = jit->code_start;
506         address->code_size = jit->code_size;
507
508         memcpy (&address->data, oldptr, size);
509         if (max_size > BUFSIZ)
510                 g_free (oldptr);
511
512         g_hash_table_insert (table->method_address_hash, method, address);
513
514         mono_debugger_unlock ();
515         return address;
516 }
517
518 void
519 mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
520 {
521         MonoDebugDataTable *table;
522         MonoDebugMethodAddress *address;
523
524         if (!mono_debug_initialized)
525                 return;
526
527         g_assert (method_is_dynamic (method));
528
529         mono_debugger_lock ();
530
531         table = lookup_data_table (domain);
532
533         address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
534         if (address)
535                 g_free (address);
536
537         g_hash_table_remove (table->method_address_hash, method);
538
539         mono_debugger_unlock ();
540 }
541
542 /**
543  * mono_debug_add_delegate_trampoline:
544  */
545 void
546 mono_debug_add_delegate_trampoline (gpointer code, int size)
547 {
548 }
549
550 static inline guint32
551 read_leb128 (guint8 *ptr, guint8 **rptr)
552 {
553         guint32 result = 0, shift = 0;
554
555         while (TRUE) {
556                 guint8 byte = *ptr++;
557
558                 result |= (byte & 0x7f) << shift;
559                 if ((byte & 0x80) == 0)
560                         break;
561                 shift += 7;
562         }
563
564         *rptr = ptr;
565         return result;
566 }
567
568 static inline gint32
569 read_sleb128 (guint8 *ptr, guint8 **rptr)
570 {
571         gint32 result = 0;
572         guint32 shift = 0;
573
574         while (TRUE) {
575                 guint8 byte = *ptr++;
576
577                 result |= (byte & 0x7f) << shift;
578                 shift += 7;
579
580                 if (byte & 0x80)
581                         continue;
582
583                 if ((shift < 32) && (byte & 0x40))
584                         result |= - (1 << shift);
585                 break;
586         }
587
588         *rptr = ptr;
589         return result;
590 }
591
592 static void
593 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
594 {
595         var->index = read_leb128 (ptr, &ptr);
596         var->offset = read_sleb128 (ptr, &ptr);
597         var->size = read_leb128 (ptr, &ptr);
598         var->begin_scope = read_leb128 (ptr, &ptr);
599         var->end_scope = read_leb128 (ptr, &ptr);
600         READ_UNALIGNED (MonoType *, ptr, var->type);
601         ptr += sizeof (gpointer);
602         *rptr = ptr;
603 }
604
605 void
606 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
607 {
608         if (!jit)
609                 return;
610         g_free (jit->line_numbers);
611         g_free (jit->this_var);
612         g_free (jit->params);
613         g_free (jit->locals);
614         g_free (jit->gsharedvt_info_var);
615         g_free (jit->gsharedvt_locals_var);
616         g_free (jit);
617 }
618
619 static MonoDebugMethodJitInfo *
620 mono_debug_read_method (MonoDebugMethodAddress *address)
621 {
622         MonoDebugMethodJitInfo *jit;
623         guint32 i;
624         guint8 *ptr;
625
626         jit = g_new0 (MonoDebugMethodJitInfo, 1);
627         jit->code_start = address->code_start;
628         jit->code_size = address->code_size;
629
630         ptr = (guint8 *) &address->data;
631
632         jit->prologue_end = read_leb128 (ptr, &ptr);
633         jit->epilogue_begin = read_leb128 (ptr, &ptr);
634
635         jit->num_line_numbers = read_leb128 (ptr, &ptr);
636         jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
637         for (i = 0; i < jit->num_line_numbers; i++) {
638                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
639
640                 lne->il_offset = read_sleb128 (ptr, &ptr);
641                 lne->native_offset = read_sleb128 (ptr, &ptr);
642         }
643         jit->has_var_info = read_leb128 (ptr, &ptr);
644         if (jit->has_var_info) {
645                 if (*ptr++) {
646                         jit->this_var = g_new0 (MonoDebugVarInfo, 1);
647                         read_variable (jit->this_var, ptr, &ptr);
648                 }
649
650                 jit->num_params = read_leb128 (ptr, &ptr);
651                 jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
652                 for (i = 0; i < jit->num_params; i++)
653                         read_variable (&jit->params [i], ptr, &ptr);
654
655                 jit->num_locals = read_leb128 (ptr, &ptr);
656                 jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
657                 for (i = 0; i < jit->num_locals; i++)
658                         read_variable (&jit->locals [i], ptr, &ptr);
659
660                 if (*ptr++) {
661                         jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
662                         jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
663                         read_variable (jit->gsharedvt_info_var, ptr, &ptr);
664                         read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
665                 }
666         }
667
668         return jit;
669 }
670
671 static MonoDebugMethodJitInfo *
672 find_method (MonoMethod *method, MonoDomain *domain)
673 {
674         MonoDebugDataTable *table;
675         MonoDebugMethodAddress *address;
676
677         table = lookup_data_table (domain);
678         address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
679
680         if (!address)
681                 return NULL;
682
683         return mono_debug_read_method (address);
684 }
685
686 MonoDebugMethodJitInfo *
687 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
688 {
689         MonoDebugMethodJitInfo *res;
690
691         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
692                 return NULL;
693
694         mono_debugger_lock ();
695         res = find_method (method, domain);
696         mono_debugger_unlock ();
697         return res;
698 }
699
700 MonoDebugMethodAddressList *
701 mono_debug_lookup_method_addresses (MonoMethod *method)
702 {
703         g_assert_not_reached ();
704         return NULL;
705 }
706
707 static gint32
708 il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
709 {
710         MonoDebugMethodJitInfo *jit;
711         int i;
712
713         jit = find_method (method, domain);
714         if (!jit || !jit->line_numbers)
715                 goto cleanup_and_fail;
716
717         for (i = jit->num_line_numbers - 1; i >= 0; i--) {
718                 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
719
720                 if (lne.native_offset <= native_offset) {
721                         mono_debug_free_method_jit_info (jit);
722                         return lne.il_offset;
723                 }
724         }
725
726 cleanup_and_fail:
727         mono_debug_free_method_jit_info (jit);
728         return -1;
729 }
730
731 /**
732  * mono_debug_il_offset_from_address:
733  *
734  * Compute the IL offset corresponding to \p native_offset inside the native
735  * code of \p method in \p domain.
736  */
737 gint32
738 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
739 {
740         gint32 res;
741
742         mono_debugger_lock ();
743
744         res = il_offset_from_address (method, domain, native_offset);
745
746         mono_debugger_unlock ();
747
748         return res;
749 }
750
751 /**
752  * mono_debug_lookup_source_location:
753  * \param address Native offset within the \p method's machine code.
754  * Lookup the source code corresponding to the machine instruction located at
755  * native offset \p address within \p method.
756  * The returned \c MonoDebugSourceLocation contains both file / line number
757  * information and the corresponding IL offset.  It must be freed by
758  * \c mono_debug_free_source_location.
759  */
760 MonoDebugSourceLocation *
761 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
762 {
763         MonoDebugMethodInfo *minfo;
764         MonoDebugSourceLocation *location;
765         gint32 offset;
766
767         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
768                 return NULL;
769
770         mono_debugger_lock ();
771         minfo = mono_debug_lookup_method_internal (method);
772         if (!minfo || !minfo->handle) {
773                 mono_debugger_unlock ();
774                 return NULL;
775         }
776
777         if (!minfo->handle->ppdb && (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))) {
778                 mono_debugger_unlock ();
779                 return NULL;
780         }
781
782         offset = il_offset_from_address (method, domain, address);
783         if (offset < 0) {
784                 mono_debugger_unlock ();
785                 return NULL;
786         }
787
788         if (minfo->handle->ppdb)
789                 location = mono_ppdb_lookup_location (minfo, offset);
790         else
791                 location = mono_debug_symfile_lookup_location (minfo, offset);
792         mono_debugger_unlock ();
793         return location;
794 }
795
796 /**
797  * mono_debug_lookup_source_location_by_il:
798  *
799  *   Same as mono_debug_lookup_source_location but take an IL_OFFSET argument.
800  */
801 MonoDebugSourceLocation *
802 mono_debug_lookup_source_location_by_il (MonoMethod *method, guint32 il_offset, MonoDomain *domain)
803 {
804         MonoDebugMethodInfo *minfo;
805         MonoDebugSourceLocation *location;
806
807         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
808                 return NULL;
809
810         mono_debugger_lock ();
811         minfo = mono_debug_lookup_method_internal (method);
812         if (!minfo || !minfo->handle) {
813                 mono_debugger_unlock ();
814                 return NULL;
815         }
816
817         if (!minfo->handle->ppdb && (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))) {
818                 mono_debugger_unlock ();
819                 return NULL;
820         }
821
822         if (minfo->handle->ppdb)
823                 location = mono_ppdb_lookup_location (minfo, il_offset);
824         else
825                 location = mono_debug_symfile_lookup_location (minfo, il_offset);
826         mono_debugger_unlock ();
827         return location;
828 }
829
830 MonoDebugSourceLocation *
831 mono_debug_method_lookup_location (MonoDebugMethodInfo *minfo, int il_offset)
832 {
833         MonoDebugSourceLocation *location;
834
835         mono_debugger_lock ();
836         if (minfo->handle->ppdb)
837                 location = mono_ppdb_lookup_location (minfo, il_offset);
838         else
839                 location = mono_debug_symfile_lookup_location (minfo, il_offset);
840         mono_debugger_unlock ();
841         return location;
842 }
843
844 /*
845  * mono_debug_lookup_locals:
846  *
847  *   Return information about the local variables of MINFO.
848  * The result should be freed using mono_debug_free_locals ().
849  */
850 MonoDebugLocalsInfo*
851 mono_debug_lookup_locals (MonoMethod *method)
852 {
853         MonoDebugMethodInfo *minfo;
854         MonoDebugLocalsInfo *res;
855
856         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
857                 return NULL;
858
859         mono_debugger_lock ();
860         minfo = mono_debug_lookup_method_internal (method);
861         if (!minfo || !minfo->handle) {
862                 mono_debugger_unlock ();
863                 return NULL;
864         }
865
866         if (minfo->handle->ppdb) {
867                 res = mono_ppdb_lookup_locals (minfo);
868         } else {
869                 if (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))
870                         res = NULL;
871                 else
872                         res = mono_debug_symfile_lookup_locals (minfo);
873         }
874         mono_debugger_unlock ();
875
876         return res;
877 }
878
879 /*
880  * mono_debug_free_locals:
881  *
882  *   Free all the data allocated by mono_debug_lookup_locals ().
883  */
884 void
885 mono_debug_free_locals (MonoDebugLocalsInfo *info)
886 {
887         int i;
888
889         for (i = 0; i < info->num_locals; ++i)
890                 g_free (info->locals [i].name);
891         g_free (info->locals);
892         g_free (info->code_blocks);
893         g_free (info);
894 }
895
896 /*
897 * mono_debug_lookup_method_async_debug_info:
898 *
899 *   Return information about the async stepping information of method.
900 * The result should be freed using mono_debug_free_async_debug_info ().
901 */
902 MonoDebugMethodAsyncInfo*
903 mono_debug_lookup_method_async_debug_info (MonoMethod *method)
904 {
905         MonoDebugMethodInfo *minfo;
906         MonoDebugMethodAsyncInfo *res = NULL;
907
908         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
909                 return NULL;
910
911         mono_debugger_lock ();
912         minfo = mono_debug_lookup_method_internal (method);
913         if (!minfo || !minfo->handle) {
914                 mono_debugger_unlock ();
915                 return NULL;
916         }
917
918         if (minfo->handle->ppdb)
919                 res = mono_ppdb_lookup_method_async_debug_info (minfo);
920
921         mono_debugger_unlock ();
922
923         return res;
924 }
925
926 /*
927  * mono_debug_free_method_async_debug_info:
928  *
929  *   Free all the data allocated by mono_debug_lookup_method_async_debug_info ().
930  */
931 void
932 mono_debug_free_method_async_debug_info (MonoDebugMethodAsyncInfo *info)
933 {
934         if (info->num_awaits) {
935                 g_free (info->yield_offsets);
936                 g_free (info->resume_offsets);
937                 g_free (info->move_next_method_token);
938         }
939         g_free (info);
940 }
941
942 /**
943  * mono_debug_free_source_location:
944  * \param location A \c MonoDebugSourceLocation
945  * Frees the \p location.
946  */
947 void
948 mono_debug_free_source_location (MonoDebugSourceLocation *location)
949 {
950         if (location) {
951                 g_free (location->source_file);
952                 g_free (location);
953         }
954 }
955
956 static int (*get_seq_point) (MonoDomain *domain, MonoMethod *method, gint32 native_offset);
957
958 void
959 mono_install_get_seq_point (MonoGetSeqPointFunc func)
960 {
961         get_seq_point = func;
962 }
963
964 /**
965  * mono_debug_print_stack_frame:
966  * \param native_offset Native offset within the \p method's machine code.
967  * Conventient wrapper around \c mono_debug_lookup_source_location which can be
968  * used if you only want to use the location to print a stack frame.
969  */
970 gchar *
971 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
972 {
973         MonoDebugSourceLocation *location;
974         gchar *fname, *ptr, *res;
975         int offset;
976
977         fname = mono_method_full_name (method, TRUE);
978         for (ptr = fname; *ptr; ptr++) {
979                 if (*ptr == ':') *ptr = '.';
980         }
981
982         location = mono_debug_lookup_source_location (method, native_offset, domain);
983
984         if (!location) {
985                 if (mono_debug_initialized) {
986                         mono_debugger_lock ();
987                         offset = il_offset_from_address (method, domain, native_offset);
988                         mono_debugger_unlock ();
989                 } else {
990                         offset = -1;
991                 }
992
993                 if (offset < 0 && get_seq_point)
994                         offset = get_seq_point (domain, method, native_offset);
995
996                 if (offset < 0)
997                         res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
998                 else {
999                         char *mvid = mono_guid_to_string_minimal ((uint8_t*)method->klass->image->heap_guid.data);
1000                         char *aotid = mono_runtime_get_aotid ();
1001                         if (aotid)
1002                                 res = g_strdup_printf ("at %s [0x%05x] in <%s#%s>:0" , fname, offset, mvid, aotid);
1003                         else
1004                                 res = g_strdup_printf ("at %s [0x%05x] in <%s>:0" , fname, offset, mvid);
1005
1006                         g_free (aotid);
1007                         g_free (mvid);
1008                 }
1009                 g_free (fname);
1010                 return res;
1011         }
1012
1013         res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
1014                                location->source_file, location->row);
1015
1016         g_free (fname);
1017         mono_debug_free_source_location (location);
1018         return res;
1019 }
1020
1021 void
1022 mono_set_is_debugger_attached (gboolean attached)
1023 {
1024         is_attached = attached;
1025 }
1026
1027 gboolean
1028 mono_is_debugger_attached (void)
1029 {
1030         return is_attached;
1031 }
1032
1033 /*
1034  * Bundles
1035  */
1036
1037 typedef struct _BundledSymfile BundledSymfile;
1038
1039 struct _BundledSymfile {
1040         BundledSymfile *next;
1041         const char *aname;
1042         const mono_byte *raw_contents;
1043         int size;
1044 };
1045
1046 static BundledSymfile *bundled_symfiles = NULL;
1047
1048 /**
1049  * mono_register_symfile_for_assembly:
1050  */
1051 void
1052 mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
1053 {
1054         BundledSymfile *bsymfile;
1055
1056         bsymfile = g_new0 (BundledSymfile, 1);
1057         bsymfile->aname = assembly_name;
1058         bsymfile->raw_contents = raw_contents;
1059         bsymfile->size = size;
1060         bsymfile->next = bundled_symfiles;
1061         bundled_symfiles = bsymfile;
1062 }
1063
1064 static MonoDebugHandle *
1065 open_symfile_from_bundle (MonoImage *image)
1066 {
1067         BundledSymfile *bsymfile;
1068
1069         for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
1070                 if (strcmp (bsymfile->aname, image->module_name))
1071                         continue;
1072
1073                 return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
1074         }
1075
1076         return NULL;
1077 }
1078
1079 void
1080 mono_debugger_lock (void)
1081 {
1082         g_assert (mono_debug_initialized);
1083         mono_os_mutex_lock (&debugger_lock_mutex);
1084 }
1085
1086 void
1087 mono_debugger_unlock (void)
1088 {
1089         g_assert (mono_debug_initialized);
1090         mono_os_mutex_unlock (&debugger_lock_mutex);
1091 }
1092
1093 /**
1094  * mono_debug_enabled:
1095  *
1096  * Returns true is debug information is enabled. This doesn't relate if a debugger is present or not.
1097  */
1098 mono_bool
1099 mono_debug_enabled (void)
1100 {
1101         return mono_debug_format != MONO_DEBUG_FORMAT_NONE;
1102 }
1103
1104 void
1105 mono_debug_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points)
1106 {
1107         if (minfo->handle->ppdb)
1108                 mono_ppdb_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);
1109         else
1110                 mono_debug_symfile_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);
1111 }