#include <config.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/param.h>
+#include <sys/stat.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/rawbuffer.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/debug-mono-symfile.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>
load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile)
{
const char *ptr, *start;
+ gchar *guid;
guint64 magic;
long version;
magic = read64(ptr);
ptr += sizeof(guint64);
if (magic != MONO_SYMBOL_FILE_MAGIC) {
- g_warning ("Symbol file %s is not a mono symbol file", handle->image_file);
+ g_warning ("Symbol file %s is not a mono symbol file", symfile->filename);
return FALSE;
}
ptr += sizeof(guint32);
if (version != MONO_SYMBOL_FILE_VERSION) {
g_warning ("Symbol file %s has incorrect version "
- "(expected %d, got %ld)", handle->image_file,
+ "(expected %d, got %ld)", symfile->filename,
MONO_SYMBOL_FILE_VERSION, version);
return FALSE;
}
- symfile->offset_table = (MonoSymbolFileOffsetTable *) ptr;
+ guid = mono_guid_to_string ((const guint8 *) ptr);
+ ptr += 16;
- symfile->method_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
- (GDestroyNotify) free_method_info);
+ if (strcmp (handle->image->guid, guid)) {
+ g_warning ("Symbol file %s doesn't match image %s", symfile->filename,
+ handle->image_file);
+ return FALSE;
+ }
- return TRUE;
-}
+ symfile->offset_table = (MonoSymbolFileOffsetTable *) ptr;
-static gconstpointer
-open_symfile (MonoImage *image, guint32 *size)
-{
- MonoTableInfo *table = mono_image_get_table_info (image, MONO_TABLE_MANIFESTRESOURCE);
- guint32 i, num_rows;
- guint32 cols [MONO_MANIFEST_SIZE];
- const char *val;
-
- num_rows = mono_table_info_get_rows (table);
- for (i = 0; i < num_rows; ++i) {
- mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
- val = mono_metadata_string_heap (image, cols [MONO_MANIFEST_NAME]);
- if (!strcmp (val, "MonoSymbolFile"))
- break;
- }
- if (i == num_rows)
- return NULL;
- g_assert (!cols [MONO_MANIFEST_IMPLEMENTATION]);
+ symfile->method_hash = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) free_method_info);
- return mono_image_get_resource (image, cols [MONO_MANIFEST_OFFSET], size);
+ return TRUE;
}
MonoSymbolFile *
mono_debug_open_mono_symbol_file (MonoDebugHandle *handle, gboolean create_symfile)
{
MonoSymbolFile *symfile;
+ FILE* f;
+ mono_loader_lock ();
symfile = g_new0 (MonoSymbolFile, 1);
- symfile->raw_contents = open_symfile (handle->image, &symfile->raw_contents_size);
-
- if (load_symfile (handle, symfile))
+ 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 (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);
+ }
+
+ fclose (f);
+ }
+
+ if (load_symfile (handle, symfile)) {
+ mono_loader_unlock ();
return symfile;
- else if (!create_symfile) {
+ } else if (!create_symfile) {
mono_debug_close_mono_symbol_file (symfile);
+ mono_loader_unlock ();
return NULL;
}
+ mono_loader_unlock ();
return symfile;
}
if (!symfile)
return;
+ mono_loader_lock ();
if (symfile->method_hash)
g_hash_table_destroy (symfile->method_hash);
+ if (symfile->raw_contents)
+ mono_raw_buffer_free ((gpointer) symfile->raw_contents);
+
g_free (symfile);
+ mono_loader_unlock ();
+}
+
+static int
+read_leb128 (const char *ptr, const char **rptr)
+{
+ int ret = 0;
+ int shift = 0;
+ char b;
+
+ do {
+ b = *ptr++;
+
+ ret = ret | ((b & 0x7f) << shift);
+ shift += 7;
+ } while ((b & 0x80) == 0x80);
+
+ if (rptr)
+ *rptr = ptr;
+
+ return ret;
}
static gchar *
read_string (const char *ptr)
{
- int len = read32 (ptr);
- ptr += sizeof(guint32);
+ int len = read_leb128 (ptr, &ptr);
return g_filename_from_utf8 (ptr, len, NULL, NULL, NULL);
}
const char *ptr;
int i;
- if (!symfile->method_hash)
+ mono_loader_lock ();
+ if (!symfile->method_hash) {
+ mono_loader_unlock ();
return NULL;
+ }
minfo = g_hash_table_lookup (symfile->method_hash, method);
- if (!minfo)
+ if (!minfo) {
+ mono_loader_unlock ();
return NULL;
+ }
if (read32(&(minfo->entry->_source_index))) {
int offset = read32(&(symfile->offset_table->_source_table_offset)) +
if (line_number) {
*line_number = read32(&(lne->_row));
+ mono_loader_unlock ();
if (source_file)
return source_file;
else
} 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;
- } else
- return g_strdup_printf ("%d", read32(&(lne->_row)));
+ }
}
+ mono_loader_unlock ();
return NULL;
}
MonoDebugLineNumberEntry lne = g_array_index (
jit->line_numbers, MonoDebugLineNumberEntry, i);
- if (lne.offset <= il_offset)
- return lne.address;
+ if (lne.il_offset <= il_offset)
+ return lne.native_offset;
}
return -1;
if (handle->image != mono_class_get_image (mono_method_get_class (method)))
return NULL;
+ mono_loader_lock ();
first_ie = (MonoSymbolFileMethodIndexEntry *)
(symfile->raw_contents + read32(&(symfile->offset_table->_method_table_offset)));
read32(&(symfile->offset_table->_method_count)),
sizeof (MonoSymbolFileMethodIndexEntry), compare_method);
- if (!ie)
+ if (!ie) {
+ mono_loader_unlock ();
return NULL;
+ }
me = (MonoSymbolFileMethodEntry *) (symfile->raw_contents + read32(&(ie->_file_offset)));
g_hash_table_insert (symfile->method_hash, method, minfo);
+ mono_loader_unlock ();
return minfo;
}