Minor fixes for building mono in Visual Studio.
[mono.git] / mono / metadata / mono-debug.c
1 #include <config.h>
2 #include <mono/metadata/assembly.h>
3 #include <mono/metadata/tabledefs.h>
4 #include <mono/metadata/tokentype.h>
5 #include <mono/metadata/appdomain.h>
6 #include <mono/metadata/class-internals.h>
7 #include <mono/metadata/mono-debug.h>
8 #include <mono/metadata/mono-debug-debugger.h>
9 #include <mono/metadata/mono-endian.h>
10 #include <string.h>
11
12 #define SYMFILE_TABLE_CHUNK_SIZE        16
13 #define DATA_TABLE_PTR_CHUNK_SIZE       256
14 #define DATA_TABLE_CHUNK_SIZE           32768
15
16 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
17
18 #if NO_UNALIGNED_ACCESS
19 #define RETURN_UNALIGNED(type, addr) \
20         { \
21                 type val; \
22                 memcpy(&val, p + offset, sizeof(val)); \
23                 return val; \
24         }
25 #define WRITE_UNALIGNED(type, addr, val) \
26         memcpy(addr, &val, sizeof(type))
27 #else
28 #define RETURN_UNALIGNED(type, addr) \
29         return *(type*)(p + offset);
30 #define WRITE_UNALIGNED(type, addr, val) \
31         (*(type *)(addr) = (val))
32 #endif
33
34 MonoSymbolTable *mono_symbol_table = NULL;
35 MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
36
37 static gboolean in_the_mono_debugger = FALSE;
38 static gboolean mono_debug_initialized = FALSE;
39 GHashTable *mono_debug_handles = NULL;
40
41 static GHashTable *method_hash = NULL;
42
43 static MonoDebugHandle     *mono_debug_open_image      (MonoImage *image);
44 static void                 mono_debug_close_image     (MonoDebugHandle *debug);
45
46 static MonoDebugHandle     *_mono_debug_get_image      (MonoImage *image);
47 static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
48                                                         gpointer user_data);
49 static void                 mono_debug_start_add_type  (MonoClass *klass);
50 static void                 mono_debug_add_type        (MonoClass *klass);
51
52 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
53 extern void (*mono_debugger_start_class_init_func) (MonoClass *klass);
54
55 typedef struct {
56         guint32 symfile_id;
57         guint32 domain_id;
58         guint32 method_id;
59 } MethodHashEntry;
60
61 static guint
62 method_hash_hash (gconstpointer data)
63 {
64         const MethodHashEntry *entry = (const MethodHashEntry *) data;
65         return entry->symfile_id | (entry->domain_id << 16);
66 }
67
68 static gint
69 method_hash_equal (gconstpointer ka, gconstpointer kb)
70 {
71         const MethodHashEntry *a = (const MethodHashEntry *) ka;
72         const MethodHashEntry *b = (const MethodHashEntry *) kb;
73
74         if ((a->symfile_id != b->symfile_id) || (a->method_id != b->method_id) || (a->domain_id != b->domain_id))
75                 return 0;
76         return 1;
77 }
78
79 /*
80  * Initialize debugging support.
81  *
82  * This method must be called after loading corlib,
83  * but before opening the application's main assembly because we need to set some
84  * callbacks here.
85  */
86 void
87 mono_debug_init (MonoDebugFormat format)
88 {
89         g_assert (!mono_debug_initialized);
90
91         mono_debug_initialized = TRUE;
92         mono_debug_format = format;
93         in_the_mono_debugger = format == MONO_DEBUG_FORMAT_DEBUGGER;
94
95         mono_debugger_initialize (in_the_mono_debugger);
96
97         mono_debugger_lock ();
98
99         mono_symbol_table = g_new0 (MonoSymbolTable, 1);
100         mono_symbol_table->magic = MONO_DEBUGGER_MAGIC;
101         mono_symbol_table->version = MONO_DEBUGGER_VERSION;
102         mono_symbol_table->total_size = sizeof (MonoSymbolTable);
103
104         mono_debug_handles = g_hash_table_new_full
105                 (NULL, NULL, NULL, (GDestroyNotify) mono_debug_close_image);
106         method_hash = g_hash_table_new (method_hash_hash, method_hash_equal);
107
108         mono_debugger_start_class_init_func = mono_debug_start_add_type;
109         mono_debugger_class_init_func = mono_debug_add_type;
110         mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
111
112         if (!in_the_mono_debugger)
113                 mono_debugger_unlock ();
114 }
115
116 void
117 mono_debug_init_1 (MonoDomain *domain)
118 {
119         MonoDebugHandle *handle = mono_debug_open_image (mono_get_corlib ());
120
121         mono_symbol_table->corlib = handle;
122 }
123
124 /*
125  * Initialize debugging support - part 2.
126  *
127  * This method must be called after loading the application's main assembly.
128  */
129 void
130 mono_debug_init_2 (MonoAssembly *assembly)
131 {
132         mono_debug_open_image (mono_assembly_get_image (assembly));
133 }
134
135 gboolean
136 mono_debug_using_mono_debugger (void)
137 {
138         return in_the_mono_debugger;
139 }
140
141 void
142 mono_debug_cleanup (void)
143 {
144         mono_debugger_cleanup ();
145
146         if (mono_debug_handles)
147                 g_hash_table_destroy (mono_debug_handles);
148         mono_debug_handles = NULL;
149 }
150
151 static MonoDebugHandle *
152 _mono_debug_get_image (MonoImage *image)
153 {
154         return g_hash_table_lookup (mono_debug_handles, image);
155 }
156
157 static MonoDebugHandle *
158 allocate_debug_handle (MonoSymbolTable *table)
159 {
160         MonoDebugHandle *handle;
161
162         if (!table->symbol_files)
163                 table->symbol_files = g_new0 (MonoDebugHandle *, SYMFILE_TABLE_CHUNK_SIZE);
164         else if (!((table->num_symbol_files + 1) % SYMFILE_TABLE_CHUNK_SIZE)) {
165                 guint32 chunks = (table->num_symbol_files + 1) / SYMFILE_TABLE_CHUNK_SIZE;
166                 guint32 size = sizeof (MonoDebugHandle *) * SYMFILE_TABLE_CHUNK_SIZE * (chunks + 1);
167
168                 table->symbol_files = g_realloc (table->symbol_files, size);
169         }
170
171         handle = g_new0 (MonoDebugHandle, 1);
172         handle->index = table->num_symbol_files;
173         table->symbol_files [table->num_symbol_files++] = handle;
174         return handle;
175 }
176
177 static MonoDebugHandle *
178 mono_debug_open_image (MonoImage *image)
179 {
180         MonoDebugHandle *handle;
181
182         if (mono_image_is_dynamic (image))
183                 return NULL;
184
185         handle = _mono_debug_get_image (image);
186         if (handle != NULL)
187                 return handle;
188
189         handle = allocate_debug_handle (mono_symbol_table);
190
191         handle->image = image;
192         mono_image_addref (image);
193         handle->image_file = g_strdup (mono_image_get_filename (image));
194
195         g_hash_table_insert (mono_debug_handles, image, handle);
196
197         handle->symfile = mono_debug_open_mono_symbol_file (handle, in_the_mono_debugger);
198         if (in_the_mono_debugger)
199                 mono_debugger_add_symbol_file (handle);
200
201         return handle;
202 }
203
204 static void
205 mono_debug_close_image (MonoDebugHandle *handle)
206 {
207         if (handle->symfile)
208                 mono_debug_close_mono_symbol_file (handle->symfile);
209         /* decrease the refcount added with mono_image_addref () */
210         mono_image_close (handle->image);
211         g_free (handle->image_file);
212         g_free (handle->_priv);
213         g_free (handle);
214 }
215
216 static void
217 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
218 {
219         mono_debugger_lock ();
220         mono_debug_open_image (mono_assembly_get_image (assembly));
221         mono_debugger_unlock ();
222 }
223
224 /*
225  * Allocate a new data item of size `size'.
226  * Returns the global offset which is to be used to reference this data item and
227  * a pointer (in the `ptr' argument) which is to be used to write it.
228  */
229 static guint8 *
230 allocate_data_item (MonoDebugDataItemType type, guint32 size)
231 {
232         guint32 chunk_size;
233         guint8 *data;
234
235         g_assert (mono_symbol_table);
236
237         size = ALIGN_TO (size, sizeof (gpointer));
238
239         if (size + 16 < DATA_TABLE_CHUNK_SIZE)
240                 chunk_size = DATA_TABLE_CHUNK_SIZE;
241         else
242                 chunk_size = size + 16;
243
244         /* Initialize things if necessary. */
245         if (!mono_symbol_table->current_data_table) {
246                 mono_symbol_table->current_data_table = g_malloc0 (chunk_size);
247                 mono_symbol_table->current_data_table_size = chunk_size;
248                 mono_symbol_table->current_data_table_offset = sizeof (gpointer);
249
250                 * ((guint32 *) mono_symbol_table->current_data_table) = chunk_size;
251         }
252
253  again:
254         /* First let's check whether there's still enough room in the current_data_table. */
255         if (mono_symbol_table->current_data_table_offset + size + 8 < mono_symbol_table->current_data_table_size) {
256                 data = ((guint8 *) mono_symbol_table->current_data_table) + mono_symbol_table->current_data_table_offset;
257                 mono_symbol_table->current_data_table_offset += size + 8;
258
259                 * ((guint32 *) data) = size;
260                 data += 4;
261                 * ((guint32 *) data) = type;
262                 data += 4;
263                 return data;
264         }
265
266         /* Add the current_data_table to the data_tables vector and ... */
267         if (!mono_symbol_table->data_tables) {
268                 guint32 tsize = sizeof (gpointer) * DATA_TABLE_PTR_CHUNK_SIZE;
269                 mono_symbol_table->data_tables = g_malloc0 (tsize);
270         }
271
272         if (!((mono_symbol_table->num_data_tables + 1) % DATA_TABLE_PTR_CHUNK_SIZE)) {
273                 guint32 chunks = (mono_symbol_table->num_data_tables + 1) / DATA_TABLE_PTR_CHUNK_SIZE;
274                 guint32 tsize = sizeof (gpointer) * DATA_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
275
276                 mono_symbol_table->data_tables = g_realloc (mono_symbol_table->data_tables, tsize);
277         }
278
279         mono_symbol_table->data_tables [mono_symbol_table->num_data_tables++] = mono_symbol_table->current_data_table;
280
281         /* .... allocate a new current_data_table. */
282         mono_symbol_table->current_data_table = g_malloc0 (chunk_size);
283         mono_symbol_table->current_data_table_size = chunk_size;
284         mono_symbol_table->current_data_table_offset = sizeof (gpointer);
285         * ((guint32 *) mono_symbol_table->current_data_table) = chunk_size;
286
287         goto again;
288 }
289
290 struct LookupMethodData
291 {
292         MonoDebugMethodInfo *minfo;
293         MonoMethod *method;
294 };
295
296 static void
297 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
298 {
299         MonoDebugHandle *handle = (MonoDebugHandle *) value;
300         struct LookupMethodData *data = (struct LookupMethodData *) user_data;
301
302         if (data->minfo)
303                 return;
304
305         if (handle->symfile)
306                 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
307 }
308
309 static MonoDebugMethodInfo *
310 _mono_debug_lookup_method (MonoMethod *method)
311 {
312         struct LookupMethodData data;
313
314         data.minfo = NULL;
315         data.method = method;
316
317         if (!mono_debug_handles)
318                 return NULL;
319
320         g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
321         return data.minfo;
322 }
323
324 /**
325  * mono_debug_lookup_method:
326  *
327  * Lookup symbol file information for the method @method.  The returned
328  * `MonoDebugMethodInfo' is a private structure, but it can be passed to
329  * mono_debug_symfile_lookup_location().
330  */
331 MonoDebugMethodInfo *
332 mono_debug_lookup_method (MonoMethod *method)
333 {
334         MonoDebugMethodInfo *minfo;
335
336         mono_debugger_lock ();
337         minfo = _mono_debug_lookup_method (method);
338         mono_debugger_unlock ();
339         return minfo;
340 }
341
342 static inline void
343 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
344 {
345         do {
346                 guint8 byte = value & 0x7f;
347                 value >>= 7;
348                 if (value)
349                         byte |= 0x80;
350                 *ptr++ = byte;
351         } while (value);
352
353         *rptr = ptr;
354 }
355
356 static inline void
357 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
358 {
359         gboolean more = 1;
360
361         while (more) {
362                 guint8 byte = value & 0x7f;
363                 value >>= 7;
364
365                 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
366                         more = 0;
367                 else
368                         byte |= 0x80;
369                 *ptr++ = byte;
370         }
371
372         *rptr = ptr;
373 }
374
375 static void
376 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
377 {
378         write_leb128 (var->index, ptr, &ptr);
379         write_sleb128 (var->offset, ptr, &ptr);
380         write_leb128 (var->size, ptr, &ptr);
381         write_leb128 (var->begin_scope, ptr, &ptr);
382         write_leb128 (var->end_scope, ptr, &ptr);
383         *rptr = ptr;
384 }
385
386 static MonoDebugWrapperData *
387 mono_debug_add_wrapper (MonoMethod *method, MonoDebugMethodJitInfo *jit)
388 {
389         MonoMethodHeader *header;
390         MonoDebugWrapperData *wrapper;
391         char buffer [BUFSIZ];
392         guint8 *ptr, *oldptr;
393         guint32 i, size, total_size, max_size;
394         gint32 last_il_offset = 0, last_native_offset = 0;
395         const unsigned char* il_code;
396         guint32 il_codesize;
397
398         if (!in_the_mono_debugger)
399                 return NULL;
400
401         mono_debugger_lock ();
402
403         header = mono_method_get_header (method);
404
405         max_size = 28 * jit->num_line_numbers;
406         if (max_size > BUFSIZ)
407                 ptr = oldptr = g_malloc (max_size);
408         else
409                 ptr = oldptr = buffer;
410
411         write_leb128 (jit->prologue_end, ptr, &ptr);
412         write_leb128 (jit->epilogue_begin, ptr, &ptr);
413         write_leb128 (jit->num_line_numbers, ptr, &ptr);
414         for (i = 0; i < jit->num_line_numbers; i++) {
415                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
416
417                 write_sleb128 (lne->il_offset - last_il_offset, ptr, &ptr);
418                 write_sleb128 (lne->native_offset - last_native_offset, ptr, &ptr);
419
420                 last_il_offset = lne->il_offset;
421                 last_native_offset = lne->native_offset;
422         }
423
424         write_leb128 (method->wrapper_type, ptr, &ptr);
425
426         size = ptr - oldptr;
427         g_assert (size < max_size);
428         total_size = size + sizeof (MonoDebugWrapperData);
429
430         if (total_size + 9 >= DATA_TABLE_CHUNK_SIZE) {
431                 // FIXME: Maybe we should print a warning here.
432                 //        This should only happen for very big methods, for instance
433                 //        with more than 40.000 line numbers and more than 5.000
434                 //        local variables.
435                 mono_debugger_unlock ();
436                 return NULL;
437         }
438
439         wrapper = (MonoDebugWrapperData *) allocate_data_item (MONO_DEBUG_DATA_ITEM_WRAPPER, total_size);
440
441         wrapper->method = method;
442         wrapper->size = total_size;
443         wrapper->code_start = jit->code_start;
444         wrapper->code_size = jit->code_size;
445         wrapper->name = mono_method_full_name (method, TRUE);
446
447         il_code = mono_method_header_get_code (header, &il_codesize, NULL);
448         wrapper->cil_code = mono_disasm_code (
449                 NULL, method, il_code, il_code + il_codesize);
450
451         memcpy (&wrapper->data, oldptr, size);
452
453         if (max_size > BUFSIZ)
454                 g_free (oldptr);
455
456         mono_debugger_unlock ();
457
458         return wrapper;
459 }
460
461 /*
462  * This is called by the JIT to tell the debugging code about a newly
463  * compiled method.
464  */
465 MonoDebugMethodAddress *
466 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
467 {
468         MonoDebugMethodAddress *address;
469         char buffer [BUFSIZ];
470         guint8 *ptr, *oldptr;
471         guint32 i, size, total_size, max_size;
472         gint32 last_il_offset = 0, last_native_offset = 0;
473         MonoDebugHandle *handle;
474         MonoDebugMethodInfo *minfo;
475         MethodHashEntry *hash;
476
477         if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
478             (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
479             (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
480             (method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
481             (method->wrapper_type != MONO_WRAPPER_NONE)) {
482                 mono_debug_add_wrapper (method, jit);
483                 return NULL;
484         }
485
486         mono_debugger_lock ();
487
488         handle = _mono_debug_get_image (method->klass->image);
489         if (!handle || !handle->symfile || !handle->symfile->offset_table) {
490                 mono_debug_add_wrapper (method, jit);
491                 mono_debugger_unlock ();
492                 return NULL;
493         }
494
495         minfo = _mono_debug_lookup_method (method);
496         if (!minfo) {
497                 mono_debugger_unlock ();
498                 return NULL;
499         }
500
501         max_size = 24 + 8 * jit->num_line_numbers + 16 * minfo->num_lexical_blocks + 20 * (1 + jit->num_params + jit->num_locals);
502         if (max_size > BUFSIZ)
503                 ptr = oldptr = g_malloc (max_size);
504         else
505                 ptr = oldptr = buffer;
506
507         write_leb128 (jit->prologue_end, ptr, &ptr);
508         write_leb128 (jit->epilogue_begin, ptr, &ptr);
509
510         write_leb128 (jit->num_line_numbers, ptr, &ptr);
511         for (i = 0; i < jit->num_line_numbers; i++) {
512                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
513
514                 write_sleb128 (lne->il_offset - last_il_offset, ptr, &ptr);
515                 write_sleb128 (lne->native_offset - last_native_offset, ptr, &ptr);
516
517                 last_il_offset = lne->il_offset;
518                 last_native_offset = lne->native_offset;
519         }
520
521         jit->num_lexical_blocks = minfo->num_lexical_blocks;
522         jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
523         for (i = 0; i < jit->num_lexical_blocks; i ++) {
524                 MonoDebugLexicalBlockEntry *jit_lbe = &jit->lexical_blocks [i];
525                 MonoSymbolFileLexicalBlockEntry *minfo_lbe = &minfo->lexical_blocks [i];
526                 jit_lbe->il_start_offset = read32 (&(minfo_lbe->_start_offset));
527                 jit_lbe->native_start_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_start_offset);
528
529                 jit_lbe->il_end_offset = read32 (&(minfo_lbe->_end_offset));
530                 jit_lbe->native_end_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_end_offset);
531         }
532
533         last_il_offset = 0;
534         last_native_offset = 0;
535         write_leb128 (jit->num_lexical_blocks, ptr, &ptr);
536         for (i = 0; i < jit->num_lexical_blocks; i++) {
537                 MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
538
539                 write_sleb128 (lbe->il_start_offset - last_il_offset, ptr, &ptr);
540                 write_sleb128 (lbe->native_start_offset - last_native_offset, ptr, &ptr);
541
542                 last_il_offset = lbe->il_start_offset;
543                 last_native_offset = lbe->native_start_offset;
544
545                 write_sleb128 (lbe->il_end_offset - last_il_offset, ptr, &ptr);
546                 write_sleb128 (lbe->native_end_offset - last_native_offset, ptr, &ptr);
547
548                 last_il_offset = lbe->il_end_offset;
549                 last_native_offset = lbe->native_end_offset;
550         }
551
552         *ptr++ = jit->this_var ? 1 : 0;
553         if (jit->this_var)
554                 write_variable (jit->this_var, ptr, &ptr);
555
556         write_leb128 (jit->num_params, ptr, &ptr);
557         for (i = 0; i < jit->num_params; i++)
558                 write_variable (&jit->params [i], ptr, &ptr);
559
560         write_leb128 (jit->num_locals, ptr, &ptr);
561         for (i = 0; i < jit->num_locals; i++)
562                 write_variable (&jit->locals [i], ptr, &ptr);
563
564         size = ptr - oldptr;
565         g_assert (size < max_size);
566         total_size = size + sizeof (MonoDebugMethodAddress);
567
568         if (total_size + 9 >= DATA_TABLE_CHUNK_SIZE) {
569                 // FIXME: Maybe we should print a warning here.
570                 //        This should only happen for very big methods, for instance
571                 //        with more than 40.000 line numbers and more than 5.000
572                 //        local variables.
573                 mono_debugger_unlock ();
574                 return NULL;
575         }
576
577         address = (MonoDebugMethodAddress *) allocate_data_item (MONO_DEBUG_DATA_ITEM_METHOD, total_size);
578
579         address->size = total_size;
580         address->symfile_id = handle->index;
581         address->domain_id = mono_domain_get_id (domain);
582         address->method_id = minfo->index;
583         address->code_start = jit->code_start;
584         address->code_size = jit->code_size;
585         address->wrapper_addr = jit->wrapper_addr;
586
587         memcpy (&address->data, oldptr, size);
588
589         if (max_size > BUFSIZ)
590                 g_free (oldptr);
591
592         hash = g_new0 (MethodHashEntry, 1);
593         hash->symfile_id = address->symfile_id;
594         hash->domain_id = address->domain_id;
595         hash->method_id = address->method_id;
596
597         g_hash_table_insert (method_hash, hash, address);
598
599         mono_debugger_unlock ();
600
601         return address;
602 }
603
604 static inline guint32
605 read_leb128 (guint8 *ptr, guint8 **rptr)
606 {
607         guint32 result = 0, shift = 0;
608
609         while (TRUE) {
610                 guint8 byte = *ptr++;
611
612                 result |= (byte & 0x7f) << shift;
613                 if ((byte & 0x80) == 0)
614                         break;
615                 shift += 7;
616         }
617
618         *rptr = ptr;
619         return result;
620 }
621
622 static inline gint32
623 read_sleb128 (guint8 *ptr, guint8 **rptr)
624 {
625         gint32 result = 0;
626         guint32 shift = 0;
627
628         while (TRUE) {
629                 guint8 byte = *ptr++;
630
631                 result |= (byte & 0x7f) << shift;
632                 shift += 7;
633
634                 if (byte & 0x80)
635                         continue;
636
637                 if ((shift < 32) && (byte & 0x40))
638                         result |= - (1 << shift);
639                 break;
640         }
641
642         *rptr = ptr;
643         return result;
644 }
645
646 static void
647 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
648 {
649         var->index = read_leb128 (ptr, &ptr);
650         var->offset = read_sleb128 (ptr, &ptr);
651         var->size = read_leb128 (ptr, &ptr);
652         var->begin_scope = read_leb128 (ptr, &ptr);
653         var->end_scope = read_leb128 (ptr, &ptr);
654         *rptr = ptr;
655 }
656
657 MonoDebugMethodJitInfo *
658 mono_debug_read_method (MonoDebugMethodAddress *address)
659 {
660         MonoDebugMethodJitInfo *jit;
661         guint32 i, il_offset = 0, native_offset = 0;
662         guint8 *ptr;
663
664         if (address->jit)
665                 return address->jit;
666
667         jit = address->jit = g_new0 (MonoDebugMethodJitInfo, 1);
668         jit->code_start = address->code_start;
669         jit->code_size = address->code_size;
670         jit->wrapper_addr = address->wrapper_addr;
671
672         ptr = (guint8 *) &address->data;
673
674         jit->prologue_end = read_leb128 (ptr, &ptr);
675         jit->epilogue_begin = read_leb128 (ptr, &ptr);
676
677         jit->num_line_numbers = read_leb128 (ptr, &ptr);
678         jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
679         for (i = 0; i < jit->num_line_numbers; i++) {
680                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
681
682                 il_offset += read_sleb128 (ptr, &ptr);
683                 native_offset += read_sleb128 (ptr, &ptr);
684
685                 lne->il_offset = il_offset;
686                 lne->native_offset = native_offset;
687         }
688
689         il_offset = 0;
690         native_offset = 0;
691         jit->num_lexical_blocks = read_leb128 (ptr, &ptr);
692         jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
693         for (i = 0; i < jit->num_lexical_blocks; i ++) {
694                 MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
695
696                 il_offset += read_sleb128 (ptr, &ptr);
697                 native_offset += read_sleb128 (ptr, &ptr);
698
699                 lbe->il_start_offset = il_offset;
700                 lbe->native_start_offset = native_offset;
701
702                 il_offset += read_sleb128 (ptr, &ptr);
703                 native_offset += read_sleb128 (ptr, &ptr);
704
705                 lbe->il_end_offset = il_offset;
706                 lbe->native_end_offset = native_offset;
707         }
708
709         if (*ptr++) {
710                 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
711                 read_variable (jit->this_var, ptr, &ptr);
712         }
713
714         jit->num_params = read_leb128 (ptr, &ptr);
715         jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
716         for (i = 0; i < jit->num_params; i++)
717                 read_variable (&jit->params [i], ptr, &ptr);
718
719         jit->num_locals = read_leb128 (ptr, &ptr);
720         jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
721         for (i = 0; i < jit->num_locals; i++)
722                 read_variable (&jit->locals [i], ptr, &ptr);
723
724         return jit;
725 }
726
727 void
728 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
729 {
730         if (jit->address)
731                 jit->address->jit = NULL;
732
733         g_free (jit->line_numbers);
734         g_free (jit->this_var);
735         g_free (jit->params);
736         g_free (jit->locals);
737         g_free (jit);
738 }
739
740 /*
741  * This is called via the `mono_debugger_class_init_func' from mono_class_init() each time
742  * a new class is initialized.
743  */
744 static void
745 mono_debug_start_add_type (MonoClass *klass)
746 {
747         MonoDebugHandle *handle;
748
749         handle = _mono_debug_get_image (klass->image);
750         if (!handle)
751                 return;
752 }
753
754 static void
755 mono_debug_add_type (MonoClass *klass)
756 {
757         MonoDebugHandle *handle;
758         MonoDebugClassEntry *entry;
759         char buffer [BUFSIZ];
760         guint8 *ptr, *oldptr;
761         guint32 size, total_size, max_size;
762         int base_offset = 0;
763
764         handle = _mono_debug_get_image (klass->image);
765         if (!handle)
766                 return;
767
768         if (klass->generic_class || klass->rank ||
769             (klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR))
770                 return;
771
772         max_size = 12 + sizeof (gpointer);
773         if (max_size > BUFSIZ)
774                 ptr = oldptr = g_malloc (max_size);
775         else
776                 ptr = oldptr = buffer;
777
778         if (klass->valuetype)
779                 base_offset = - (int)(sizeof (MonoObject));
780
781         write_leb128 (klass->type_token, ptr, &ptr);
782         write_leb128 (klass->instance_size + base_offset, ptr, &ptr);
783         WRITE_UNALIGNED (gpointer, ptr, klass);
784         ptr += sizeof (gpointer);
785
786         size = ptr - oldptr;
787         g_assert (size < max_size);
788         total_size = size + sizeof (MonoDebugClassEntry);
789
790         g_assert (total_size + 9 < DATA_TABLE_CHUNK_SIZE);
791
792         entry = (MonoDebugClassEntry *) allocate_data_item (MONO_DEBUG_DATA_ITEM_CLASS, total_size);
793
794         entry->size = total_size;
795         entry->symfile_id = handle->index;
796
797         memcpy (&entry->data, oldptr, size);
798
799         if (max_size > BUFSIZ)
800                 g_free (oldptr);
801
802         mono_debugger_start_add_type (handle, klass);
803 }
804
805 static MonoDebugMethodJitInfo *
806 find_method (MonoDebugMethodInfo *minfo, MonoDomain *domain)
807 {
808         MethodHashEntry lookup;
809         MonoDebugMethodAddress *address;
810
811         lookup.symfile_id = minfo->handle->index;
812         lookup.domain_id = mono_domain_get_id (domain);
813         lookup.method_id = minfo->index;
814
815         address = g_hash_table_lookup (method_hash, &lookup);
816         if (!address)
817                 return NULL;
818
819         return mono_debug_read_method (address);
820 }
821
822 static gint32
823 il_offset_from_address (MonoDebugMethodInfo *minfo, MonoDomain *domain, guint32 native_offset)
824 {
825         MonoDebugMethodJitInfo *jit;
826         int i;
827
828         jit = find_method (minfo, domain);
829         if (!jit || !jit->line_numbers)
830                 return -1;
831
832         for (i = jit->num_line_numbers - 1; i >= 0; i--) {
833                 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
834
835                 if (lne.native_offset <= native_offset)
836                         return lne.il_offset;
837         }
838
839         return -1;
840 }
841
842 /**
843  * mono_debug_lookup_source_location:
844  * @address: Native offset within the @method's machine code.
845  *
846  * Lookup the source code corresponding to the machine instruction located at
847  * native offset @address within @method.
848  *
849  * The returned `MonoDebugSourceLocation' contains both file / line number
850  * information and the corresponding IL offset.  It must be freed by
851  * mono_debug_free_source_location().
852  */
853 MonoDebugSourceLocation *
854 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
855 {
856         MonoDebugMethodInfo *minfo;
857         MonoDebugSourceLocation *location;
858         gint32 offset;
859
860         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
861                 return NULL;
862
863         mono_debugger_lock ();
864         minfo = _mono_debug_lookup_method (method);
865         if (!minfo || !minfo->handle || !minfo->handle->symfile || !minfo->handle->symfile->offset_table) {
866                 mono_debugger_unlock ();
867                 return NULL;
868         }
869
870         offset = il_offset_from_address (minfo, domain, address);
871         if (offset < 0) {
872                 mono_debugger_unlock ();
873                 return NULL;
874         }
875
876         location = mono_debug_symfile_lookup_location (minfo, offset);
877         mono_debugger_unlock ();
878         return location;
879 }
880
881 /**
882  * mono_debug_free_source_location:
883  * @location: A `MonoDebugSourceLocation'.
884  *
885  * Frees the @location.
886  */
887 void
888 mono_debug_free_source_location (MonoDebugSourceLocation *location)
889 {
890         if (location) {
891                 g_free (location->source_file);
892                 g_free (location);
893         }
894 }
895
896 /**
897  * mono_debug_print_stack_frame:
898  * @native_offset: Native offset within the @method's machine code.
899  *
900  * Conventient wrapper around mono_debug_lookup_source_location() which can be
901  * used if you only want to use the location to print a stack frame.
902  */
903 gchar *
904 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
905 {
906         MonoDebugSourceLocation *location;
907         gchar *fname, *ptr, *res;
908
909         fname = mono_method_full_name (method, TRUE);
910         for (ptr = fname; *ptr; ptr++) {
911                 if (*ptr == ':') *ptr = '.';
912         }
913
914         location = mono_debug_lookup_source_location (method, native_offset, domain);
915
916         if (!location) {
917                 res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
918                 g_free (fname);
919                 return res;
920         }
921
922         res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
923                                location->source_file, location->row);
924
925         g_free (fname);
926         mono_debug_free_source_location (location);
927         return res;
928 }