2 #include <mono/metadata/mono-debug.h>
3 #include <mono/metadata/mono-debug-debugger.h>
4 #include <mono/jit/debug-jit.h>
8 * This method is only called when running in the Mono Debugger.
11 mono_debugger_create_notification_function (gpointer *notification_address)
15 ptr = buf = g_malloc0 (16);
17 if (notification_address)
18 *notification_address = buf;
25 record_line_number (MonoDebugMethodJitInfo *jit, guint32 address, guint32 offset)
27 MonoDebugLineNumberEntry *lne = g_new0 (MonoDebugLineNumberEntry, 1);
29 lne->address = address;
32 g_array_append_val (jit->line_numbers, *lne);
36 debug_update_il_offsets (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoFlowGraph* cfg)
38 MonoMethodHeader *header;
39 guint32 address, offset;
42 jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
44 address = jit->prologue_end;
47 g_assert (((MonoMethodNormal*)method)->header);
48 header = ((MonoMethodNormal*)method)->header;
50 record_line_number (jit, address, offset);
52 /* start lines of basic blocks */
53 for (i = 0; i < cfg->block_count; ++i) {
56 for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
57 MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
59 if ((t->cli_addr == -1) || (t->cli_addr == offset) || (t->addr == address))
65 record_line_number (jit, address, offset);
69 record_line_number (jit, jit->epilogue_begin, header->code_size);
73 il_offset_from_position (MonoFlowGraph *cfg, MonoPosition *pos)
78 if (pos->abs_pos == 0)
81 if (pos->pos.bid >= cfg->block_count)
84 bblock = &cfg->bblocks [pos->pos.bid];
85 if (pos->pos.tid >= bblock->forest->len)
88 tree = (MBTree *) g_ptr_array_index (bblock->forest, pos->pos.tid);
90 return tree->cli_addr;
94 address_from_il_offset (MonoDebugMethodJitInfo *jit, guint32 il_offset)
98 for (i = jit->line_numbers->len - 1; i >= 0; i--) {
99 MonoDebugLineNumberEntry lne = g_array_index (
100 jit->line_numbers, MonoDebugLineNumberEntry, i);
102 if (lne.offset <= il_offset)
110 mono_debug_jit_add_method (MonoFlowGraph *cfg)
112 MonoMethod *method = cfg->method;
113 MonoClass *klass = method->klass;
114 MonoDebugMethodJitInfo *jit;
117 mono_class_init (klass);
119 if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
120 (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
121 (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
122 (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
125 jit = g_new0 (MonoDebugMethodJitInfo, 1);
126 jit->code_start = cfg->start;
127 jit->code_size = cfg->epilogue_end;
128 jit->prologue_end = cfg->prologue_end;
129 jit->epilogue_begin = cfg->epilog;
130 jit->num_params = method->signature->param_count;
131 jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
133 if (method->signature->hasthis) {
134 MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index;
136 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
137 jit->this_var->offset = ptr->offset;
138 jit->this_var->size = ptr->size;
141 for (i = 0; i < jit->num_params; i++) {
142 MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index +
143 method->signature->hasthis;
145 jit->params [i].offset = ptr [i].offset;
146 jit->params [i].size = ptr [i].size;
149 debug_update_il_offsets (method, jit, cfg);
151 if (!method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
152 MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
153 MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->locals_start_index;
154 MonoDebugVarInfo *locals;
156 locals = g_new0 (MonoDebugVarInfo, header->num_locals);
157 for (i = 0; i < header->num_locals; i++) {
158 gint32 begin_offset, end_offset;
159 gint32 begin_scope, end_scope;
161 if (ptr [i].reg >= 0) {
162 locals [i].index = ptr [i].reg | MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER;
163 locals [i].offset = 0;
165 locals [i].offset = ptr [i].offset;
167 locals [i].size = ptr [i].size;
169 begin_offset = il_offset_from_position (cfg, &ptr [i].range.first_use);
170 end_offset = il_offset_from_position (cfg, &ptr [i].range.last_use);
174 if (begin_offset >= 0)
175 begin_scope = address_from_il_offset (jit, begin_offset);
179 end_scope = address_from_il_offset (jit, end_offset);
184 locals [i].begin_scope = begin_scope;
186 locals [i].begin_scope = jit->prologue_end;
188 locals [i].end_scope = end_scope;
190 locals [i].end_scope = jit->epilogue_begin;
193 jit->num_locals = header->num_locals;
194 jit->locals = locals;
197 mono_debug_add_method (method, jit, cfg->domain);