Merge pull request #4454 from kumpera/allow_sioc_with_managed_impl
[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  * 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 void
182 mono_debug_domain_create (MonoDomain *domain)
183 {
184         if (!mono_debug_initialized)
185                 return;
186
187         mono_debugger_lock ();
188
189         create_data_table (domain);
190
191         mono_debugger_unlock ();
192 }
193
194 void
195 mono_debug_domain_unload (MonoDomain *domain)
196 {
197         MonoDebugDataTable *table;
198
199         if (!mono_debug_initialized)
200                 return;
201
202         mono_debugger_lock ();
203
204         table = (MonoDebugDataTable *)g_hash_table_lookup (data_table_hash, domain);
205         if (!table) {
206                 g_warning (G_STRLOC ": unloading unknown domain %p / %d",
207                            domain, mono_domain_get_id (domain));
208                 mono_debugger_unlock ();
209                 return;
210         }
211
212         g_hash_table_remove (data_table_hash, domain);
213
214         mono_debugger_unlock ();
215 }
216
217 /*
218  * LOCKING: Assumes the debug lock is held.
219  */
220 static MonoDebugHandle *
221 mono_debug_get_image (MonoImage *image)
222 {
223         return (MonoDebugHandle *)g_hash_table_lookup (mono_debug_handles, image);
224 }
225
226 void
227 mono_debug_close_image (MonoImage *image)
228 {
229         MonoDebugHandle *handle;
230
231         if (!mono_debug_initialized)
232                 return;
233
234         mono_debugger_lock ();
235
236         handle = mono_debug_get_image (image);
237         if (!handle) {
238                 mono_debugger_unlock ();
239                 return;
240         }
241
242         g_hash_table_remove (mono_debug_handles, image);
243
244         mono_debugger_unlock ();
245 }
246
247 static MonoDebugHandle *
248 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
249 {
250         MonoDebugHandle *handle;
251
252         if (mono_image_is_dynamic (image))
253                 return NULL;
254
255         mono_debugger_lock ();
256
257         handle = mono_debug_get_image (image);
258         if (handle != NULL) {
259                 mono_debugger_unlock ();
260                 return handle;
261         }
262
263         handle = g_new0 (MonoDebugHandle, 1);
264
265         handle->image = image;
266         mono_image_addref (image);
267
268         /* Try a ppdb file first */
269         handle->ppdb = mono_ppdb_load_file (handle->image, raw_contents, size);
270
271         if (!handle->ppdb)
272                 handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, FALSE);
273
274         g_hash_table_insert (mono_debug_handles, image, handle);
275
276         mono_debugger_unlock ();
277
278         return handle;
279 }
280
281 static void
282 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
283 {
284         MonoDebugHandle *handle;
285         MonoImage *image;
286
287         mono_debugger_lock ();
288         image = mono_assembly_get_image (assembly);
289         handle = open_symfile_from_bundle (image);
290         if (!handle)
291                 mono_debug_open_image (image, NULL, 0);
292         mono_debugger_unlock ();
293 }
294
295 struct LookupMethodData
296 {
297         MonoDebugMethodInfo *minfo;
298         MonoMethod *method;
299 };
300
301 static void
302 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
303 {
304         MonoDebugHandle *handle = (MonoDebugHandle *) value;
305         struct LookupMethodData *data = (struct LookupMethodData *) user_data;
306
307         if (data->minfo)
308                 return;
309
310         if (handle->ppdb)
311                 data->minfo = mono_ppdb_lookup_method (handle, data->method);
312         else if (handle->symfile)
313                 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
314 }
315
316 static MonoDebugMethodInfo *
317 mono_debug_lookup_method_internal (MonoMethod *method)
318 {
319         struct LookupMethodData data;
320
321         data.minfo = NULL;
322         data.method = method;
323
324         if (!mono_debug_handles)
325                 return NULL;
326
327         g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
328         return data.minfo;
329 }
330
331 /**
332  * mono_debug_lookup_method:
333  *
334  * Lookup symbol file information for the method @method.  The returned
335  * `MonoDebugMethodInfo' is a private structure, but it can be passed to
336  * mono_debug_symfile_lookup_location().
337  */
338 MonoDebugMethodInfo *
339 mono_debug_lookup_method (MonoMethod *method)
340 {
341         MonoDebugMethodInfo *minfo;
342
343         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
344                 return NULL;
345
346         mono_debugger_lock ();
347         minfo = mono_debug_lookup_method_internal (method);
348         mono_debugger_unlock ();
349         return minfo;
350 }
351
352 typedef struct
353 {
354         gboolean found;
355         MonoImage *image;
356 } LookupImageData;
357
358 static void
359 lookup_image_func (gpointer key, gpointer value, gpointer user_data)
360 {
361         MonoDebugHandle *handle = (MonoDebugHandle *) value;
362         LookupImageData *data = (LookupImageData *) user_data;
363
364         if (data->found)
365                 return;
366
367         if (handle->image == data->image && handle->symfile)
368                 data->found = TRUE;
369 }
370
371 gboolean
372 mono_debug_image_has_debug_info (MonoImage *image)
373 {
374         LookupImageData data;
375
376         if (!mono_debug_handles)
377                 return FALSE;
378
379         memset (&data, 0, sizeof (data));
380         data.image = image;
381
382         mono_debugger_lock ();
383         g_hash_table_foreach (mono_debug_handles, lookup_image_func, &data);
384         mono_debugger_unlock ();
385         return data.found;
386 }
387
388 static inline void
389 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
390 {
391         do {
392                 guint8 byte = value & 0x7f;
393                 value >>= 7;
394                 if (value)
395                         byte |= 0x80;
396                 *ptr++ = byte;
397         } while (value);
398
399         *rptr = ptr;
400 }
401
402 static inline void
403 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
404 {
405         gboolean more = 1;
406
407         while (more) {
408                 guint8 byte = value & 0x7f;
409                 value >>= 7;
410
411                 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
412                         more = 0;
413                 else
414                         byte |= 0x80;
415                 *ptr++ = byte;
416         }
417
418         *rptr = ptr;
419 }
420
421 static void
422 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
423 {
424         write_leb128 (var->index, ptr, &ptr);
425         write_sleb128 (var->offset, ptr, &ptr);
426         write_leb128 (var->size, ptr, &ptr);
427         write_leb128 (var->begin_scope, ptr, &ptr);
428         write_leb128 (var->end_scope, ptr, &ptr);
429         WRITE_UNALIGNED (gpointer, ptr, var->type);
430         ptr += sizeof (gpointer);
431         *rptr = ptr;
432 }
433
434 MonoDebugMethodAddress *
435 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
436 {
437         MonoDebugDataTable *table;
438         MonoDebugMethodAddress *address;
439         guint8 buffer [BUFSIZ];
440         guint8 *ptr, *oldptr;
441         guint32 i, size, total_size, max_size;
442
443         mono_debugger_lock ();
444
445         table = lookup_data_table (domain);
446
447         max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
448                 (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
449
450         if (max_size > BUFSIZ)
451                 ptr = oldptr = (guint8 *)g_malloc (max_size);
452         else
453                 ptr = oldptr = buffer;
454
455         write_leb128 (jit->prologue_end, ptr, &ptr);
456         write_leb128 (jit->epilogue_begin, ptr, &ptr);
457
458         write_leb128 (jit->num_line_numbers, ptr, &ptr);
459         for (i = 0; i < jit->num_line_numbers; i++) {
460                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
461
462                 write_sleb128 (lne->il_offset, ptr, &ptr);
463                 write_sleb128 (lne->native_offset, ptr, &ptr);
464         }
465         write_leb128 (jit->has_var_info, ptr, &ptr);
466         if (jit->has_var_info) {
467                 *ptr++ = jit->this_var ? 1 : 0;
468                 if (jit->this_var)
469                         write_variable (jit->this_var, ptr, &ptr);
470
471                 write_leb128 (jit->num_params, ptr, &ptr);
472                 for (i = 0; i < jit->num_params; i++)
473                         write_variable (&jit->params [i], ptr, &ptr);
474
475                 write_leb128 (jit->num_locals, ptr, &ptr);
476                 for (i = 0; i < jit->num_locals; i++)
477                         write_variable (&jit->locals [i], ptr, &ptr);
478
479                 *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
480                 if (jit->gsharedvt_info_var) {
481                         write_variable (jit->gsharedvt_info_var, ptr, &ptr);
482                         write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
483                 }
484         }
485
486         size = ptr - oldptr;
487         g_assert (size < max_size);
488         total_size = size + sizeof (MonoDebugMethodAddress);
489
490         if (method_is_dynamic (method)) {
491                 address = (MonoDebugMethodAddress *)g_malloc0 (total_size);
492         } else {
493                 address = (MonoDebugMethodAddress *)mono_mempool_alloc (table->mp, total_size);
494         }
495
496         address->code_start = jit->code_start;
497         address->code_size = jit->code_size;
498
499         memcpy (&address->data, oldptr, size);
500         if (max_size > BUFSIZ)
501                 g_free (oldptr);
502
503         g_hash_table_insert (table->method_address_hash, method, address);
504
505         mono_debugger_unlock ();
506         return address;
507 }
508
509 void
510 mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
511 {
512         MonoDebugDataTable *table;
513         MonoDebugMethodAddress *address;
514
515         if (!mono_debug_initialized)
516                 return;
517
518         g_assert (method_is_dynamic (method));
519
520         mono_debugger_lock ();
521
522         table = lookup_data_table (domain);
523
524         address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
525         if (address)
526                 g_free (address);
527
528         g_hash_table_remove (table->method_address_hash, method);
529
530         mono_debugger_unlock ();
531 }
532
533 void
534 mono_debug_add_delegate_trampoline (gpointer code, int size)
535 {
536 }
537
538 static inline guint32
539 read_leb128 (guint8 *ptr, guint8 **rptr)
540 {
541         guint32 result = 0, shift = 0;
542
543         while (TRUE) {
544                 guint8 byte = *ptr++;
545
546                 result |= (byte & 0x7f) << shift;
547                 if ((byte & 0x80) == 0)
548                         break;
549                 shift += 7;
550         }
551
552         *rptr = ptr;
553         return result;
554 }
555
556 static inline gint32
557 read_sleb128 (guint8 *ptr, guint8 **rptr)
558 {
559         gint32 result = 0;
560         guint32 shift = 0;
561
562         while (TRUE) {
563                 guint8 byte = *ptr++;
564
565                 result |= (byte & 0x7f) << shift;
566                 shift += 7;
567
568                 if (byte & 0x80)
569                         continue;
570
571                 if ((shift < 32) && (byte & 0x40))
572                         result |= - (1 << shift);
573                 break;
574         }
575
576         *rptr = ptr;
577         return result;
578 }
579
580 static void
581 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
582 {
583         var->index = read_leb128 (ptr, &ptr);
584         var->offset = read_sleb128 (ptr, &ptr);
585         var->size = read_leb128 (ptr, &ptr);
586         var->begin_scope = read_leb128 (ptr, &ptr);
587         var->end_scope = read_leb128 (ptr, &ptr);
588         READ_UNALIGNED (MonoType *, ptr, var->type);
589         ptr += sizeof (gpointer);
590         *rptr = ptr;
591 }
592
593 void
594 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
595 {
596         if (!jit)
597                 return;
598         g_free (jit->line_numbers);
599         g_free (jit->this_var);
600         g_free (jit->params);
601         g_free (jit->locals);
602         g_free (jit->gsharedvt_info_var);
603         g_free (jit->gsharedvt_locals_var);
604         g_free (jit);
605 }
606
607 static MonoDebugMethodJitInfo *
608 mono_debug_read_method (MonoDebugMethodAddress *address)
609 {
610         MonoDebugMethodJitInfo *jit;
611         guint32 i;
612         guint8 *ptr;
613
614         jit = g_new0 (MonoDebugMethodJitInfo, 1);
615         jit->code_start = address->code_start;
616         jit->code_size = address->code_size;
617
618         ptr = (guint8 *) &address->data;
619
620         jit->prologue_end = read_leb128 (ptr, &ptr);
621         jit->epilogue_begin = read_leb128 (ptr, &ptr);
622
623         jit->num_line_numbers = read_leb128 (ptr, &ptr);
624         jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
625         for (i = 0; i < jit->num_line_numbers; i++) {
626                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
627
628                 lne->il_offset = read_sleb128 (ptr, &ptr);
629                 lne->native_offset = read_sleb128 (ptr, &ptr);
630         }
631         jit->has_var_info = read_leb128 (ptr, &ptr);
632         if (jit->has_var_info) {
633                 if (*ptr++) {
634                         jit->this_var = g_new0 (MonoDebugVarInfo, 1);
635                         read_variable (jit->this_var, ptr, &ptr);
636                 }
637
638                 jit->num_params = read_leb128 (ptr, &ptr);
639                 jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
640                 for (i = 0; i < jit->num_params; i++)
641                         read_variable (&jit->params [i], ptr, &ptr);
642
643                 jit->num_locals = read_leb128 (ptr, &ptr);
644                 jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
645                 for (i = 0; i < jit->num_locals; i++)
646                         read_variable (&jit->locals [i], ptr, &ptr);
647
648                 if (*ptr++) {
649                         jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
650                         jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
651                         read_variable (jit->gsharedvt_info_var, ptr, &ptr);
652                         read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
653                 }
654         }
655
656         return jit;
657 }
658
659 static MonoDebugMethodJitInfo *
660 find_method (MonoMethod *method, MonoDomain *domain)
661 {
662         MonoDebugDataTable *table;
663         MonoDebugMethodAddress *address;
664
665         table = lookup_data_table (domain);
666         address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method);
667
668         if (!address)
669                 return NULL;
670
671         return mono_debug_read_method (address);
672 }
673
674 MonoDebugMethodJitInfo *
675 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
676 {
677         MonoDebugMethodJitInfo *res;
678
679         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
680                 return NULL;
681
682         mono_debugger_lock ();
683         res = find_method (method, domain);
684         mono_debugger_unlock ();
685         return res;
686 }
687
688 MonoDebugMethodAddressList *
689 mono_debug_lookup_method_addresses (MonoMethod *method)
690 {
691         g_assert_not_reached ();
692         return NULL;
693 }
694
695 static gint32
696 il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
697 {
698         MonoDebugMethodJitInfo *jit;
699         int i;
700
701         jit = find_method (method, domain);
702         if (!jit || !jit->line_numbers)
703                 goto cleanup_and_fail;
704
705         for (i = jit->num_line_numbers - 1; i >= 0; i--) {
706                 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
707
708                 if (lne.native_offset <= native_offset) {
709                         mono_debug_free_method_jit_info (jit);
710                         return lne.il_offset;
711                 }
712         }
713
714 cleanup_and_fail:
715         mono_debug_free_method_jit_info (jit);
716         return -1;
717 }
718
719 /**
720  * mono_debug_il_offset_from_address:
721  *
722  *   Compute the IL offset corresponding to NATIVE_OFFSET inside the native
723  * code of METHOD in DOMAIN.
724  */
725 gint32
726 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
727 {
728         gint32 res;
729
730         mono_debugger_lock ();
731
732         res = il_offset_from_address (method, domain, native_offset);
733
734         mono_debugger_unlock ();
735
736         return res;
737 }
738
739 /**
740  * mono_debug_lookup_source_location:
741  * @address: Native offset within the @method's machine code.
742  *
743  * Lookup the source code corresponding to the machine instruction located at
744  * native offset @address within @method.
745  *
746  * The returned `MonoDebugSourceLocation' contains both file / line number
747  * information and the corresponding IL offset.  It must be freed by
748  * mono_debug_free_source_location().
749  */
750 MonoDebugSourceLocation *
751 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
752 {
753         MonoDebugMethodInfo *minfo;
754         MonoDebugSourceLocation *location;
755         gint32 offset;
756
757         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
758                 return NULL;
759
760         mono_debugger_lock ();
761         minfo = mono_debug_lookup_method_internal (method);
762         if (!minfo || !minfo->handle) {
763                 mono_debugger_unlock ();
764                 return NULL;
765         }
766
767         if (!minfo->handle->ppdb && (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))) {
768                 mono_debugger_unlock ();
769                 return NULL;
770         }
771
772         offset = il_offset_from_address (method, domain, address);
773         if (offset < 0) {
774                 mono_debugger_unlock ();
775                 return NULL;
776         }
777
778         if (minfo->handle->ppdb)
779                 location = mono_ppdb_lookup_location (minfo, offset);
780         else
781                 location = mono_debug_symfile_lookup_location (minfo, offset);
782         mono_debugger_unlock ();
783         return location;
784 }
785
786 MonoDebugSourceLocation *
787 mono_debug_method_lookup_location (MonoDebugMethodInfo *minfo, int il_offset)
788 {
789         MonoDebugSourceLocation *location;
790
791         mono_debugger_lock ();
792         if (minfo->handle->ppdb)
793                 location = mono_ppdb_lookup_location (minfo, il_offset);
794         else
795                 location = mono_debug_symfile_lookup_location (minfo, il_offset);
796         mono_debugger_unlock ();
797         return location;
798 }
799
800 /*
801  * mono_debug_lookup_locals:
802  *
803  *   Return information about the local variables of MINFO.
804  * The result should be freed using mono_debug_free_locals ().
805  */
806 MonoDebugLocalsInfo*
807 mono_debug_lookup_locals (MonoMethod *method)
808 {
809         MonoDebugMethodInfo *minfo;
810         MonoDebugLocalsInfo *res;
811
812         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
813                 return NULL;
814
815         mono_debugger_lock ();
816         minfo = mono_debug_lookup_method_internal (method);
817         if (!minfo || !minfo->handle) {
818                 mono_debugger_unlock ();
819                 return NULL;
820         }
821
822         if (minfo->handle->ppdb) {
823                 res = mono_ppdb_lookup_locals (minfo);
824         } else {
825                 if (!minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile))
826                         res = NULL;
827                 else
828                         res = mono_debug_symfile_lookup_locals (minfo);
829         }
830         mono_debugger_unlock ();
831
832         return res;
833 }
834
835 /*
836  * mono_debug_free_locals:
837  *
838  *   Free all the data allocated by mono_debug_lookup_locals ().
839  */
840 void
841 mono_debug_free_locals (MonoDebugLocalsInfo *info)
842 {
843         int i;
844
845         for (i = 0; i < info->num_locals; ++i)
846                 g_free (info->locals [i].name);
847         g_free (info->locals);
848         g_free (info->code_blocks);
849         g_free (info);
850 }
851
852 /*
853 * mono_debug_lookup_method_async_debug_info:
854 *
855 *   Return information about the async stepping information of method.
856 * The result should be freed using mono_debug_free_async_debug_info ().
857 */
858 MonoDebugMethodAsyncInfo*
859 mono_debug_lookup_method_async_debug_info (MonoMethod *method)
860 {
861         MonoDebugMethodInfo *minfo;
862         MonoDebugMethodAsyncInfo *res = NULL;
863
864         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
865                 return NULL;
866
867         mono_debugger_lock ();
868         minfo = mono_debug_lookup_method_internal (method);
869         if (!minfo || !minfo->handle) {
870                 mono_debugger_unlock ();
871                 return NULL;
872         }
873
874         if (minfo->handle->ppdb)
875                 res = mono_ppdb_lookup_method_async_debug_info (minfo);
876
877         mono_debugger_unlock ();
878
879         return res;
880 }
881
882 /*
883  * mono_debug_free_method_async_debug_info:
884  *
885  *   Free all the data allocated by mono_debug_lookup_method_async_debug_info ().
886  */
887 void
888 mono_debug_free_method_async_debug_info (MonoDebugMethodAsyncInfo *info)
889 {
890         if (info->num_awaits) {
891                 g_free (info->yield_offsets);
892                 g_free (info->resume_offsets);
893                 g_free (info->move_next_method_token);
894         }
895         g_free (info);
896 }
897
898 /**
899  * mono_debug_free_source_location:
900  * @location: A `MonoDebugSourceLocation'.
901  *
902  * Frees the @location.
903  */
904 void
905 mono_debug_free_source_location (MonoDebugSourceLocation *location)
906 {
907         if (location) {
908                 g_free (location->source_file);
909                 g_free (location);
910         }
911 }
912
913 static int (*get_seq_point) (MonoDomain *domain, MonoMethod *method, gint32 native_offset);
914
915 void
916 mono_install_get_seq_point (MonoGetSeqPointFunc func)
917 {
918         get_seq_point = func;
919 }
920
921 /**
922  * mono_debug_print_stack_frame:
923  * @native_offset: Native offset within the @method's machine code.
924  *
925  * Conventient wrapper around mono_debug_lookup_source_location() which can be
926  * used if you only want to use the location to print a stack frame.
927  */
928 gchar *
929 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
930 {
931         MonoDebugSourceLocation *location;
932         gchar *fname, *ptr, *res;
933         int offset;
934
935         fname = mono_method_full_name (method, TRUE);
936         for (ptr = fname; *ptr; ptr++) {
937                 if (*ptr == ':') *ptr = '.';
938         }
939
940         location = mono_debug_lookup_source_location (method, native_offset, domain);
941
942         if (!location) {
943                 if (mono_debug_initialized) {
944                         mono_debugger_lock ();
945                         offset = il_offset_from_address (method, domain, native_offset);
946                         mono_debugger_unlock ();
947                 } else {
948                         offset = -1;
949                 }
950
951                 if (offset < 0 && get_seq_point)
952                         offset = get_seq_point (domain, method, native_offset);
953
954                 if (offset < 0)
955                         res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
956                 else {
957                         char *mvid = mono_guid_to_string_minimal ((uint8_t*)method->klass->image->heap_guid.data);
958                         char *aotid = mono_runtime_get_aotid ();
959                         if (aotid)
960                                 res = g_strdup_printf ("at %s [0x%05x] in <%s#%s>:0" , fname, offset, mvid, aotid);
961                         else
962                                 res = g_strdup_printf ("at %s [0x%05x] in <%s>:0" , fname, offset, mvid);
963
964                         g_free (aotid);
965                         g_free (mvid);
966                 }
967                 g_free (fname);
968                 return res;
969         }
970
971         res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
972                                location->source_file, location->row);
973
974         g_free (fname);
975         mono_debug_free_source_location (location);
976         return res;
977 }
978
979 void
980 mono_set_is_debugger_attached (gboolean attached)
981 {
982         is_attached = attached;
983 }
984
985 gboolean
986 mono_is_debugger_attached (void)
987 {
988         return is_attached;
989 }
990
991 /*
992  * Bundles
993  */
994
995 typedef struct _BundledSymfile BundledSymfile;
996
997 struct _BundledSymfile {
998         BundledSymfile *next;
999         const char *aname;
1000         const mono_byte *raw_contents;
1001         int size;
1002 };
1003
1004 static BundledSymfile *bundled_symfiles = NULL;
1005
1006 void
1007 mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
1008 {
1009         BundledSymfile *bsymfile;
1010
1011         bsymfile = g_new0 (BundledSymfile, 1);
1012         bsymfile->aname = assembly_name;
1013         bsymfile->raw_contents = raw_contents;
1014         bsymfile->size = size;
1015         bsymfile->next = bundled_symfiles;
1016         bundled_symfiles = bsymfile;
1017 }
1018
1019 static MonoDebugHandle *
1020 open_symfile_from_bundle (MonoImage *image)
1021 {
1022         BundledSymfile *bsymfile;
1023
1024         for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
1025                 if (strcmp (bsymfile->aname, image->module_name))
1026                         continue;
1027
1028                 return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
1029         }
1030
1031         return NULL;
1032 }
1033
1034 void
1035 mono_debugger_lock (void)
1036 {
1037         g_assert (mono_debug_initialized);
1038         mono_os_mutex_lock (&debugger_lock_mutex);
1039 }
1040
1041 void
1042 mono_debugger_unlock (void)
1043 {
1044         g_assert (mono_debug_initialized);
1045         mono_os_mutex_unlock (&debugger_lock_mutex);
1046 }
1047
1048 /**
1049  * mono_debug_enabled:
1050  *
1051  * Returns true is debug information is enabled. This doesn't relate if a debugger is present or not.
1052  */
1053 mono_bool
1054 mono_debug_enabled (void)
1055 {
1056         return mono_debug_format != MONO_DEBUG_FORMAT_NONE;
1057 }
1058
1059 void
1060 mono_debug_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrArray **source_file_list, int **source_files, MonoSymSeqPoint **seq_points, int *n_seq_points)
1061 {
1062         if (minfo->handle->ppdb)
1063                 mono_ppdb_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);
1064         else
1065                 mono_debug_symfile_get_seq_points (minfo, source_file, source_file_list, source_files, seq_points, n_seq_points);
1066 }