#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/debug-mono-symfile.h>
+#include <mono/metadata/mono-debug-debugger.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/class-internals.h>
-#include <mono/metadata/mono-debug-debugger.h>
#include <fcntl.h>
#include <unistd.h>
}
static int
-load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile)
+load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile, gboolean in_the_debugger)
{
const char *ptr, *start;
gchar *guid;
magic = read64(ptr);
ptr += sizeof(guint64);
if (magic != MONO_SYMBOL_FILE_MAGIC) {
- g_warning ("Symbol file %s is not a mono symbol file", symfile->filename);
+ if (!in_the_debugger)
+ g_warning ("Symbol file %s is not a mono symbol file", symfile->filename);
return FALSE;
}
version = read32(ptr);
ptr += sizeof(guint32);
if (version != MONO_SYMBOL_FILE_VERSION) {
- g_warning ("Symbol file %s has incorrect version "
- "(expected %d, got %ld)", symfile->filename,
- MONO_SYMBOL_FILE_VERSION, version);
+ if (!in_the_debugger)
+ g_warning ("Symbol file %s has incorrect version "
+ "(expected %d, got %ld)", symfile->filename,
+ MONO_SYMBOL_FILE_VERSION, version);
return FALSE;
}
ptr += 16;
if (strcmp (handle->image->guid, guid)) {
- g_warning ("Symbol file %s doesn't match image %s", symfile->filename,
- handle->image_file);
+ if (!in_the_debugger)
+ g_warning ("Symbol file %s doesn't match image %s", symfile->filename,
+ handle->image_file);
+ if (guid)
+ g_free (guid);
return FALSE;
}
symfile->method_hash = g_hash_table_new_full (
g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) free_method_info);
+ g_free (guid);
return TRUE;
}
MonoSymbolFile *
-mono_debug_open_mono_symbol_file (MonoDebugHandle *handle, gboolean create_symfile)
+mono_debug_open_mono_symbols (MonoDebugHandle *handle, const guint8 *raw_contents,
+ int size, gboolean in_the_debugger)
{
MonoSymbolFile *symfile;
FILE* f;
- mono_loader_lock ();
+ mono_debugger_lock ();
symfile = g_new0 (MonoSymbolFile, 1);
- symfile->filename = g_strdup_printf ("%s.mdb", mono_image_get_filename (handle->image));
+ if (raw_contents != NULL) {
+ symfile->raw_contents_size = size;
+ symfile->raw_contents = g_malloc (size);
+ memcpy(symfile->raw_contents, raw_contents, size);
+ symfile->filename = g_strdup_printf ("LoadedFromMemory");
+ } else {
+ symfile->filename = g_strdup_printf ("%s.mdb", mono_image_get_filename (handle->image));
- if ((f = fopen (symfile->filename, "rb")) > 0) {
- struct stat stat_buf;
+ if ((f = fopen (symfile->filename, "rb"))) {
+ struct stat stat_buf;
- if (fstat (fileno (f), &stat_buf) < 0) {
- g_warning ("stat of %s failed: %s", symfile->filename, g_strerror (errno));
- } else {
- symfile->raw_contents_size = stat_buf.st_size;
- symfile->raw_contents = mono_raw_buffer_load (fileno (f), FALSE, 0, stat_buf.st_size);
+ if (fstat (fileno (f), &stat_buf) < 0) {
+ if (!in_the_debugger)
+ g_warning ("stat of %s failed: %s",
+ symfile->filename, g_strerror (errno));
+ } else {
+ symfile->raw_contents_size = stat_buf.st_size;
+ symfile->raw_contents = mono_raw_buffer_load (fileno (f), FALSE, 0, stat_buf.st_size);
+ }
+
+ fclose (f);
}
-
- fclose (f);
}
- if (load_symfile (handle, symfile)) {
- mono_loader_unlock ();
+ if (load_symfile (handle, symfile, in_the_debugger)) {
+ mono_debugger_unlock ();
return symfile;
- } else if (!create_symfile) {
+ } else if (!in_the_debugger) {
mono_debug_close_mono_symbol_file (symfile);
- mono_loader_unlock ();
+ mono_debugger_unlock ();
return NULL;
}
- mono_loader_unlock ();
+ mono_debugger_unlock ();
return symfile;
}
if (!symfile)
return;
- mono_loader_lock ();
+ mono_debugger_lock ();
if (symfile->method_hash)
g_hash_table_destroy (symfile->method_hash);
if (symfile->raw_contents)
mono_raw_buffer_free ((gpointer) symfile->raw_contents);
-
+
+ if (symfile->filename)
+ g_free (symfile->filename);
g_free (symfile);
- mono_loader_unlock ();
+ mono_debugger_unlock ();
}
static int
return g_filename_from_utf8 (ptr, len, NULL, NULL, NULL);
}
-gchar *
-mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, guint32 offset,
- guint32 *line_number)
+/**
+ * mono_debug_symfile_lookup_location:
+ * @minfo: A `MonoDebugMethodInfo' which can be retrieved by
+ * mono_debug_lookup_method().
+ * @offset: IL offset within the corresponding method's CIL code.
+ *
+ * This function is similar to mono_debug_lookup_location(), but we
+ * already looked up the method and also already did the
+ * `native address -> IL offset' mapping.
+ */
+MonoDebugSourceLocation *
+mono_debug_symfile_lookup_location (MonoDebugMethodInfo *minfo, guint32 offset)
{
MonoSymbolFileLineNumberEntry *lne;
- MonoDebugMethodInfo *minfo;
+ MonoSymbolFile *symfile;
gchar *source_file = NULL;
const char *ptr;
- int i;
+ int count, i;
- mono_loader_lock ();
- if (!symfile->method_hash) {
- mono_loader_unlock ();
+ if ((symfile = minfo->handle->symfile) == NULL)
return NULL;
- }
- minfo = g_hash_table_lookup (symfile->method_hash, method);
- if (!minfo) {
- mono_loader_unlock ();
- return NULL;
- }
+ mono_debugger_lock ();
if (read32(&(minfo->entry->_source_index))) {
int offset = read32(&(symfile->offset_table->_source_table_offset)) +
ptr = symfile->raw_contents + read32(&(minfo->entry->_line_number_table_offset));
- lne = (MonoSymbolFileLineNumberEntry *) ptr;
+ count = read32(&(minfo->entry->_num_line_numbers));
+ lne = ((MonoSymbolFileLineNumberEntry *) ptr) + count - 1;
- for (i = 0; i < read32(&(minfo->entry->_num_line_numbers)); i++, lne++) {
- if (read32(&(lne->_offset)) < offset)
+ for (i = count - 1; i >= 0; i--, lne--) {
+ MonoDebugSourceLocation *location;
+
+ if (read32(&(lne->_offset)) > offset)
continue;
- if (line_number) {
- *line_number = read32(&(lne->_row));
- mono_loader_unlock ();
- if (source_file)
- return source_file;
- else
- return NULL;
- } else if (source_file) {
- gchar *retval = g_strdup_printf ("%s:%d", source_file, read32(&(lne->_row)));
- g_free (source_file);
- mono_loader_unlock ();
- return retval;
- } else {
- gchar* retval = g_strdup_printf ("%d", read32(&(lne->_row)));
- mono_loader_unlock ();
- return retval;
- }
+ location = g_new0 (MonoDebugSourceLocation, 1);
+ location->source_file = source_file;
+ location->row = read32(&(lne->_row));
+ location->il_offset = read32(&(lne->_offset));
+
+ mono_debugger_unlock ();
+ return location;
}
- mono_loader_unlock ();
+ mono_debugger_unlock ();
return NULL;
}
}
MonoDebugMethodInfo *
-mono_debug_find_method (MonoDebugHandle *handle, MonoMethod *method)
+mono_debug_symfile_lookup_method (MonoDebugHandle *handle, MonoMethod *method)
{
MonoSymbolFileMethodEntry *me;
MonoSymbolFileMethodIndexEntry *first_ie, *ie;
if (handle->image != mono_class_get_image (mono_method_get_class (method)))
return NULL;
- mono_loader_lock ();
+ mono_debugger_lock ();
first_ie = (MonoSymbolFileMethodIndexEntry *)
(symfile->raw_contents + read32(&(symfile->offset_table->_method_table_offset)));
sizeof (MonoSymbolFileMethodIndexEntry), compare_method);
if (!ie) {
- mono_loader_unlock ();
+ mono_debugger_unlock ();
return NULL;
}
g_hash_table_insert (symfile->method_hash, method, minfo);
- mono_loader_unlock ();
+ mono_debugger_unlock ();
return minfo;
}