#include <mono/metadata/tokentype.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/debug-mono-symfile.h>
-#include <mono/jit/codegen.h>
-#include <mono/jit/debug.h>
#include "debug-private.h"
-#include "helpers.h"
/*
* NOTE: Functions and variables starting with `mono_debug_' and `debug_' are
/* Caution: This function MUST be called before touching the symbol table! */
static void release_symbol_file_table (void);
-static MonoDebugHandle *mono_debug_handle = NULL;
-static gboolean mono_debug_initialized = FALSE;
+MonoDebugHandle *mono_debug_handle = NULL;
+gboolean mono_debug_initialized = FALSE;
static CRITICAL_SECTION debugger_lock_mutex;
guint8 *ptr, *buf;
ptr = buf = g_malloc0 (16);
- x86_breakpoint (buf);
+ mono_debug_codegen_breakpoint (&buf);
if (notification_address)
*notification_address = buf;
- x86_ret (buf);
+ mono_debug_codegen_ret (&buf);
return ptr;
}
g_warning ("Error while processing --debug-args arguments: %s", message);
}
-static gchar *
-replace_suffix (const char *filename, const char *new_suffix)
-{
- const char *pos = strrchr (filename, '.');
-
- if (!pos)
- return g_strdup_printf ("%s.%s", filename, new_suffix);
- else {
- int len = pos - filename;
- gchar *retval = g_malloc0 (len + strlen (new_suffix) + 2);
- memcpy (retval, filename, len);
- retval [len] = '.';
- memcpy (retval + len + 1, new_suffix, strlen (new_suffix) + 1);
- return retval;
- }
-}
-
MonoDebugHandle*
mono_debug_open (MonoAssembly *assembly, MonoDebugFormat format, const char **args)
{
}
}
-static void
-record_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, guint32 line)
-{
- MonoDebugLineNumberEntry *lne = g_new0 (MonoDebugLineNumberEntry, 1);
-
- lne->address = address;
- lne->offset = offset;
- lne->line = line;
-
- g_array_append_val (minfo->jit->line_numbers, *lne);
-}
-
-static void
-debug_generate_method_lines (AssemblyDebugInfo *info, MonoDebugMethodInfo *minfo, MonoFlowGraph* cfg)
-{
- guint32 st_address, st_line;
- DebugMethodInfo *priv = minfo->user_data;
- int i;
-
- if (!priv || !info->moffsets)
- return;
-
- minfo->jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
-
- st_line = priv->first_line;
- st_address = minfo->jit->prologue_end;
-
- /* This is the first actual code line of the method. */
- record_line_number (minfo, st_address, 0, st_line);
-
- /* start lines of basic blocks */
- for (i = 0; i < cfg->block_count; ++i) {
- int j;
-
- for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
- MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
- gint32 line_inc = 0, addr_inc;
-
- if (!i && !j) {
- st_line = priv->first_line;
- st_address = t->addr;
- }
-
- addr_inc = t->addr - st_address;
- st_address += addr_inc;
-
- if (t->cli_addr != -1) {
- int *lines = info->moffsets + st_line;
- int *k = lines;
-
- while ((*k != -1) && (*k < t->cli_addr))
- k++;
-
- line_inc = k - lines;
- }
-
- st_line += line_inc;
-
- if (t->cli_addr != -1)
- record_line_number (minfo, st_address, t->cli_addr, st_line);
- }
- }
-}
-
-static void
-generate_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, int debug)
+void
+_mono_debug_generate_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, int debug)
{
int i;
}
}
-static void
-debug_update_il_offsets (AssemblyDebugInfo *info, MonoDebugMethodInfo *minfo, MonoFlowGraph* cfg)
-{
- MonoMethodHeader *header;
- guint32 address, offset;
- int debug = 0;
- int i;
-
- g_assert (info->symfile);
- g_assert (!minfo->jit->line_numbers);
- minfo->jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
-
- address = minfo->jit->prologue_end;
- offset = 0;
-
- g_assert (((MonoMethodNormal*)minfo->method)->header);
- header = ((MonoMethodNormal*)minfo->method)->header;
-
-#if 0
- if (!strcmp (minfo->method->name, "Test") || !strcmp (minfo->method->name, "Main")) {
- MonoMethodHeader *header = ((MonoMethodNormal*)minfo->method)->header;
-
- debug = 1;
- mono_disassemble_code (minfo->jit->code_start, minfo->jit->code_size,
- minfo->method->name);
-
- printf ("\nDisassembly:\n%s\n", mono_disasm_code (
- NULL, minfo->method, header->code, header->code + header->code_size));
- g_message (G_STRLOC ": %x - %x", minfo->jit->prologue_end, minfo->jit->epilogue_begin);
- }
-#endif
-
- generate_line_number (minfo, address, offset, debug);
-
- /* start lines of basic blocks */
- for (i = 0; i < cfg->block_count; ++i) {
- int j;
-
- for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
- MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
-
- if ((t->cli_addr == -1) || (t->cli_addr == offset) || (t->addr == address))
- continue;
-
- offset = t->cli_addr;
- address = t->addr;
-
- generate_line_number (minfo, address, offset, debug);
- }
- }
-
- generate_line_number (minfo, minfo->jit->epilogue_begin, header->code_size, debug);
-
- if (debug) {
- for (i = 0; i < minfo->jit->line_numbers->len; i++) {
- MonoDebugLineNumberEntry lne = g_array_index (
- minfo->jit->line_numbers, MonoDebugLineNumberEntry, i);
-
- g_message (G_STRLOC ": %x,%x,%d", lne.address, lne.offset, lne.line);
- }
- }
-
- if (minfo->jit->line_numbers->len) {
- MonoDebugLineNumberEntry lne = g_array_index (
- minfo->jit->line_numbers, MonoDebugLineNumberEntry, 0);
-
- minfo->jit->prologue_end = lne.address;
- }
-}
-
-static AssemblyDebugInfo *
-mono_debug_get_image (MonoDebugHandle* debug, MonoImage *image)
+AssemblyDebugInfo *
+_mono_debug_get_image (MonoDebugHandle* debug, MonoImage *image)
{
return g_hash_table_lookup (debug->images, image);
}
AssemblyDebugInfo *info;
MonoAssembly **ptr;
- info = mono_debug_get_image (debug, image);
+ info = _mono_debug_get_image (debug, image);
if (info != NULL)
return info;
return -1;
}
-static gint32
-address_from_il_offset (MonoDebugMethodInfo *minfo, guint32 il_offset)
+gint32
+_mono_debug_address_from_il_offset (MonoDebugMethodInfo *minfo, guint32 il_offset)
{
int i;
if (!mono_debug_handle)
return;
- info = mono_debug_get_image (mono_debug_handle, klass->image);
+ info = _mono_debug_get_image (mono_debug_handle, klass->image);
g_assert (info);
if (mono_debug_handle->format != MONO_DEBUG_FORMAT_MONO)
}
}
-static gint32
-il_offset_from_position (MonoFlowGraph *cfg, MonoPosition *pos)
-{
- MonoBBlock *bblock;
- MBTree *tree;
-
- if (pos->abs_pos == 0)
- return -1;
-
- if (pos->pos.bid >= cfg->block_count)
- return -1;
-
- bblock = &cfg->bblocks [pos->pos.bid];
- if (pos->pos.tid >= bblock->forest->len)
- return -1;
-
- tree = (MBTree *) g_ptr_array_index (bblock->forest, pos->pos.tid);
-
- return tree->cli_addr;
-}
-
struct LookupMethodData
{
MonoDebugMethodInfo *minfo;
data->minfo = g_hash_table_lookup (info->methods, data->method);
}
-static MonoDebugMethodInfo *
-lookup_method (MonoMethod *method)
+MonoDebugMethodInfo *
+_mono_debug_lookup_method (MonoMethod *method)
{
struct LookupMethodData data = { NULL, method };
return data.minfo;
}
-void
-mono_debug_add_method (MonoFlowGraph *cfg)
-{
- MonoMethod *method = cfg->method;
- MonoClass *klass = method->klass;
- AssemblyDebugInfo* info;
- MonoDebugMethodJitInfo *jit;
- MonoDebugMethodInfo *minfo;
- int i;
-
- if (!mono_debug_handle)
- return;
-
- mono_class_init (klass);
-
- if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
- (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
- (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
- (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
- return;
-
- info = mono_debug_get_image (mono_debug_handle, klass->image);
- g_assert (info);
-
- if (method->wrapper_type != MONO_WRAPPER_NONE) {
- DebugWrapperInfo *winfo = g_new0 (DebugWrapperInfo, 1);
-
- winfo->method = method;
- winfo->code_start = cfg->start;
- winfo->code_size = cfg->epilogue_end;
-
- g_hash_table_insert (info->wrapper_methods, method, winfo);
- return;
- }
-
- minfo = lookup_method (method);
- if (!minfo || minfo->jit)
- return;
-
- mono_debug_lock ();
-
- mono_debug_handle->dirty = TRUE;
-
- minfo->jit = jit = g_new0 (MonoDebugMethodJitInfo, 1);
- jit->code_start = cfg->start;
- jit->code_size = cfg->epilogue_end;
- jit->prologue_end = cfg->prologue_end;
- jit->epilogue_begin = cfg->epilog;
- jit->num_params = method->signature->param_count;
- jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
-
- if (method->signature->hasthis) {
- MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index;
-
- jit->this_var = g_new0 (MonoDebugVarInfo, 1);
- jit->this_var->offset = ptr->offset;
- jit->this_var->size = ptr->size;
- }
-
- for (i = 0; i < jit->num_params; i++) {
- MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index +
- method->signature->hasthis;
-
- jit->params [i].offset = ptr [i].offset;
- jit->params [i].size = ptr [i].size;
- }
-
- debug_generate_method_lines (info, minfo, cfg);
- if (info->format == MONO_DEBUG_FORMAT_MONO)
- debug_update_il_offsets (info, minfo, cfg);
-
- if (!method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
- MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
- MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->locals_start_index;
- MonoDebugVarInfo *locals;
-
- locals = g_new0 (MonoDebugVarInfo, header->num_locals);
- for (i = 0; i < header->num_locals; i++) {
- gint32 begin_offset, end_offset;
- gint32 begin_scope, end_scope;
-
- if (ptr [i].reg >= 0) {
- locals [i].index = ptr [i].reg | MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER;
- locals [i].offset = 0;
- } else
- locals [i].offset = ptr [i].offset;
-
- locals [i].size = ptr [i].size;
-
- begin_offset = il_offset_from_position (cfg, &ptr [i].range.first_use);
- end_offset = il_offset_from_position (cfg, &ptr [i].range.last_use);
- if (end_offset >= 0)
- end_offset++;
-
- if (begin_offset >= 0)
- begin_scope = address_from_il_offset (minfo, begin_offset);
- else
- begin_scope = -1;
- if (end_offset >= 0)
- end_scope = address_from_il_offset (minfo, end_offset);
- else
- end_scope = -1;
-
- if (begin_scope > 0)
- locals [i].begin_scope = begin_scope;
- else
- locals [i].begin_scope = jit->prologue_end;
- if (end_scope > 0)
- locals [i].end_scope = end_scope;
- else
- locals [i].end_scope = jit->epilogue_begin;
- }
-
- jit->num_locals = header->num_locals;
- jit->locals = locals;
- }
-
- if (info->symfile) {
- mono_debug_symfile_add_method (info->symfile, method);
- mono_debugger_event (MONO_DEBUGGER_EVENT_METHOD_ADDED, info->symfile, method);
- }
-
- mono_debug_unlock ();
-}
-
void
mono_debug_add_wrapper (MonoMethod *method, MonoMethod *wrapper_method)
{
mono_class_init (klass);
- info = mono_debug_get_image (mono_debug_handle, klass->image);
+ info = _mono_debug_get_image (mono_debug_handle, klass->image);
g_assert (info);
- minfo = lookup_method (method);
+ minfo = _mono_debug_lookup_method (method);
if (!minfo || minfo->jit)
return;
gchar *
mono_debug_source_location_from_address (MonoMethod *method, guint32 address, guint32 *line_number)
{
- MonoDebugMethodInfo *minfo = lookup_method (method);
+ MonoDebugMethodInfo *minfo = _mono_debug_lookup_method (method);
if (!minfo)
return NULL;
if (address < 0)
return -1;
- minfo = lookup_method (method);
+ minfo = _mono_debug_lookup_method (method);
if (!minfo || !minfo->il_offsets)
return -1;
if (il_offset < 0)
return -1;
- minfo = lookup_method (method);
+ minfo = _mono_debug_lookup_method (method);
if (!minfo || !minfo->il_offsets)
return -1;
- return address_from_il_offset (minfo, il_offset);
+ return _mono_debug_address_from_il_offset (minfo, il_offset);
}
static void