#include <fcntl.h>
#include <unistd.h>
+#define RANGE_TABLE_CHUNK_SIZE 256
+
struct MonoSymbolFilePriv
{
int fd;
GHashTable *method_table;
GHashTable *method_hash;
MonoSymbolFileOffsetTable *offset_table;
- GPtrArray *range_table;
};
typedef struct
static int write_string_table (MonoSymbolFile *symfile);
static int create_symfile (MonoSymbolFile *symfile, gboolean emit_warnings);
static void close_symfile (MonoSymbolFile *symfile);
+static MonoDebugRangeInfo *allocate_range_entry (MonoSymbolFile *symfile);
static void
free_method_info (MonoDebugMethodInfo *minfo)
}
priv->offset_table = (MonoSymbolFileOffsetTable *) ptr;
- symfile->address_table_size = priv->offset_table->address_table_size;
-
- symfile->type_table_size = symfile->_priv->offset_table->type_count * sizeof (guint8 *);
- symfile->type_table = g_malloc0 (symfile->type_table_size);
/*
* Read method table.
symfile = g_new0 (MonoSymbolFile, 1);
symfile->magic = MONO_SYMBOL_FILE_MAGIC;
symfile->version = MONO_SYMBOL_FILE_VERSION;
+ symfile->dynamic_magic = MONO_SYMBOL_FILE_DYNAMIC_MAGIC;
+ symfile->dynamic_version = MONO_SYMBOL_FILE_DYNAMIC_VERSION;
symfile->image_file = g_strdup (image->name);
+ symfile->symbol_file = g_strdup (filename);
symfile->raw_contents = ptr;
symfile->raw_contents_size = file_size;
g_free (symfile->_priv->source_file);
g_free (symfile->_priv);
+ g_free (symfile->image_file);
+ g_free (symfile->symbol_file);
g_free (symfile);
}
return NULL;
}
-static void
-update_method_func (gpointer key, gpointer value, gpointer user_data)
+void
+mono_debug_symfile_add_method (MonoSymbolFile *symfile, MonoMethod *method)
{
- MonoSymbolFile *symfile = (MonoSymbolFile *) user_data;
- MonoSymbolFileMethodEntryPriv *mep = (MonoSymbolFileMethodEntryPriv *) value;
+ MonoSymbolFileMethodEntryPriv *mep;
MonoSymbolFileMethodAddress *address;
MonoDebugVarInfo *var_table;
MonoSymbolFileLineNumberEntry *lne;
MonoDebugRangeInfo *range;
+ guint32 size, line_size, line_offset, num_variables, variable_size, variable_offset;
+ guint32 *line_addresses;
+ guint8 *ptr;
int i;
+ mep = g_hash_table_lookup (symfile->_priv->method_table, method);
+ if (!mep)
+ return;
+
if (!mep->minfo) {
mep->minfo = g_hash_table_lookup (symfile->_priv->method_hash, mep->method);
if (!mep->minfo)
if (!mep->minfo->jit)
return;
- address = (MonoSymbolFileMethodAddress *)
- (symfile->address_table + mep->entry->address_table_offset);
+ symfile->generation++;
+
+ size = sizeof (MonoSymbolFileMethodAddress);
+
+ line_size = mep->entry->num_line_numbers * sizeof (MonoSymbolFileLineNumberEntry);
+ line_offset = size;
+ size += line_size;
+
+ num_variables = mep->entry->num_parameters + mep->entry->num_locals;
+ if (mep->entry->this_type_index)
+ num_variables++;
- address->is_valid = TRUE;
+ variable_size = num_variables * sizeof (MonoDebugVarInfo);
+ variable_offset = size;
+ size += variable_size;
+
+ address = g_malloc0 (size);
+ ptr = (guint8 *) address;
+
+ address->size = size;
address->start_address = GPOINTER_TO_UINT (mep->minfo->jit->code_start);
address->end_address = GPOINTER_TO_UINT (mep->minfo->jit->code_start + mep->minfo->jit->code_size);
+ address->line_table_offset = line_offset;
+ address->variable_table_offset = variable_offset;
- range = g_new0 (MonoDebugRangeInfo, 1);
+ range = allocate_range_entry (symfile);
+ range->file_offset = mep->minfo->file_offset;
range->start_address = address->start_address;
range->end_address = address->end_address;
- range->file_offset = mep->minfo->file_offset;
+ range->dynamic_data = address;
+ range->dynamic_size = size;
- var_table = (MonoDebugVarInfo *)
- (symfile->address_table + mep->entry->variable_table_offset);
+ var_table = (MonoDebugVarInfo *) (ptr + variable_offset);
if (mep->entry->this_type_index) {
if (!mep->minfo->jit->this_var) {
for (i = 0; i < mep->minfo->jit->num_locals; i++)
*var_table++ = mep->minfo->jit->locals [i];
- g_ptr_array_add (symfile->_priv->range_table, range);
-
lne = (MonoSymbolFileLineNumberEntry *)
(symfile->raw_contents + mep->entry->line_number_table_offset);
+ line_addresses = (guint32 *) (ptr + line_offset);
+
for (i = 0; i < mep->entry->num_line_numbers; i++, lne++) {
int j;
if (i == 0) {
- address->line_addresses [i] = 0;
+ line_addresses [i] = 0;
continue;
} else if (lne->offset == 0) {
- address->line_addresses [i] = mep->minfo->jit->prologue_end;
+ line_addresses [i] = mep->minfo->jit->prologue_end;
continue;
}
- address->line_addresses [i] = mep->minfo->jit->code_size;
+ line_addresses [i] = mep->minfo->jit->code_size;
for (j = 0; j < mep->minfo->num_il_offsets; j++) {
MonoSymbolFileLineNumberEntry *il = &mep->minfo->il_offsets [j];
if (il->offset >= lne->offset) {
- address->line_addresses [i] = mep->minfo->jit->il_addresses [j];
+ line_addresses [i] = mep->minfo->jit->il_addresses [j];
break;
}
}
}
}
-static gint
-range_table_compare_func (gconstpointer a, gconstpointer b)
-{
- const MonoDebugRangeInfo *r1 = (const MonoDebugRangeInfo *) a;
- const MonoDebugRangeInfo *r2 = (const MonoDebugRangeInfo *) b;
-
- if (r1->start_address < r2->start_address)
- return -1;
- else if (r1->start_address > r2->start_address)
- return 1;
- else
- return 0;
-}
-
-void
-mono_debug_update_mono_symbol_file (MonoSymbolFile *symfile)
-{
- int i;
-
- if (!symfile->_priv->method_table)
- return;
-
- symfile->_priv->range_table = g_ptr_array_new ();
-
- if (!symfile->address_table)
- symfile->address_table = g_malloc0 (symfile->address_table_size);
-
- g_hash_table_foreach (symfile->_priv->method_table, update_method_func, symfile);
-
- symfile->range_table_size = symfile->_priv->range_table->len * sizeof (MonoDebugRangeInfo);
- symfile->range_table = g_malloc0 (symfile->range_table_size);
-
- g_ptr_array_sort (symfile->_priv->range_table, range_table_compare_func);
-
- for (i = 0; i < symfile->_priv->range_table->len; i++) {
- MonoDebugRangeInfo *range = g_ptr_array_index (symfile->_priv->range_table, i);
-
- symfile->range_table [i] = *range;
- }
-
- g_ptr_array_free (symfile->_priv->range_table, TRUE);
- symfile->_priv->range_table = NULL;
-}
-
static void
free_method_entry (MonoSymbolFileMethodEntryPriv *mep)
{
line = mono_disasm_code_one (NULL, mep->method, ip, &ip);
g_free (line);
}
-
- mep->entry->address_table_offset = symfile->address_table_size;
- mep->entry->address_table_size = sizeof (MonoSymbolFileMethodAddress) +
- mep->entry->num_line_numbers * sizeof (guint32);
-
- symfile->address_table_size += mep->entry->address_table_size;
}
static void
return FALSE;
}
+ symfile->symbol_file = g_strdup (priv->file_name);
+
magic = MONO_SYMBOL_FILE_MAGIC;
if (write (priv->fd, &magic, sizeof (magic)) < 0)
return FALSE;
//
symfile->raw_contents_size = lseek (priv->fd, 0, SEEK_CUR);
- priv->offset_table->address_table_size = symfile->address_table_size;
lseek (priv->fd, offset, SEEK_SET);
if (write (priv->fd, priv->offset_table, sizeof (MonoSymbolFileOffsetTable)) < 0)
symfile->raw_contents = ptr;
- symfile->type_table_size = symfile->_priv->offset_table->type_count * sizeof (guint8 *);
- symfile->type_table = g_malloc0 (symfile->type_table_size);
-
//
// Load line number table.
//
symfile = g_new0 (MonoSymbolFile, 1);
symfile->magic = MONO_SYMBOL_FILE_MAGIC;
symfile->version = MONO_SYMBOL_FILE_VERSION;
+ symfile->dynamic_magic = MONO_SYMBOL_FILE_DYNAMIC_MAGIC;
+ symfile->dynamic_version = MONO_SYMBOL_FILE_DYNAMIC_VERSION;
symfile->is_dynamic = TRUE;
symfile->image_file = g_strdup (image->name);
return mono_type_get_object (domain, type);
}
+
+static MonoDebugRangeInfo *
+allocate_range_entry (MonoSymbolFile *symfile)
+{
+ MonoDebugRangeInfo *retval;
+ guint32 size, chunks;
+
+ symfile->range_entry_size = sizeof (MonoDebugRangeInfo);
+
+ if (!symfile->range_table) {
+ size = sizeof (MonoDebugRangeInfo) * RANGE_TABLE_CHUNK_SIZE;
+ symfile->range_table = g_malloc0 (size);
+ symfile->num_range_entries = 1;
+ return symfile->range_table;
+ }
+
+ if (!((symfile->num_range_entries + 1) % RANGE_TABLE_CHUNK_SIZE)) {
+ chunks = (symfile->num_range_entries + 1) / RANGE_TABLE_CHUNK_SIZE;
+ size = sizeof (MonoDebugRangeInfo) * RANGE_TABLE_CHUNK_SIZE * (chunks + 1);
+
+ symfile->range_table = g_realloc (symfile->range_table, size);
+ }
+
+ retval = symfile->range_table + symfile->num_range_entries;
+ symfile->num_range_entries++;
+ return retval;
+}
typedef struct MonoSymbolFileLineNumberEntry MonoSymbolFileLineNumberEntry;
typedef struct MonoSymbolFileMethodEntry MonoSymbolFileMethodEntry;
typedef struct MonoSymbolFileMethodAddress MonoSymbolFileMethodAddress;
+typedef struct MonoSymbolFileDynamicTable MonoSymbolFileDynamicTable;
typedef struct MonoDebugMethodInfo MonoDebugMethodInfo;
typedef struct MonoDebugMethodJitInfo MonoDebugMethodJitInfo;
guint32 type_count;
guint32 type_index_table_offset;
guint32 type_index_table_size;
- guint32 address_table_size;
};
struct MonoSymbolFileMethodEntry {
guint32 local_variable_table_offset;
guint32 source_file_offset;
guint32 line_number_table_offset;
- guint32 address_table_offset;
- guint32 variable_table_offset;
- guint32 address_table_size;
};
struct MonoSymbolFileMethodAddress {
- guint32 is_valid;
+ guint32 size;
guint64 start_address;
guint64 end_address;
- guint32 line_addresses [MONO_ZERO_LEN_ARRAY];
+ guint32 line_table_offset;
+ guint32 variable_table_offset;
+ guint8 data [MONO_ZERO_LEN_ARRAY];
};
struct MonoSymbolFileLineNumberEntry {
guint64 start_address;
guint64 end_address;
guint32 file_offset;
+ gpointer dynamic_data;
+ guint32 dynamic_size;
};
struct MonoSymbolFile {
guint64 magic;
guint32 version;
+ guint64 dynamic_magic;
+ guint32 dynamic_version;
guint32 is_dynamic;
char *image_file;
+ char *symbol_file;
/* Pointer to the mmap()ed contents of the file. */
guint8 *raw_contents;
guint32 raw_contents_size;
- /* Pointer to the malloced address table. */
- char *address_table;
- guint32 address_table_size;
- /* Pointer to the malloced range table. */
- MonoDebugRangeInfo *range_table;
- guint32 range_table_size;
/* Pointer to the malloced string table. */
guint8 *string_table;
guint32 string_table_size;
- /* Pointer to the malloced type table. */
- guint8 **type_table;
- guint32 type_table_size;
+ /* Pointer to the malloced range table. */
+ guint32 locked;
+ guint32 generation;
+ MonoDebugRangeInfo *range_table;
+ guint32 range_entry_size;
+ guint32 num_range_entries;
/* Private. */
MonoSymbolFilePriv *_priv;
};
-#define MONO_SYMBOL_FILE_VERSION 25
+#define MONO_SYMBOL_FILE_VERSION 26
#define MONO_SYMBOL_FILE_MAGIC 0x45e82623fd7fa614
+#define MONO_SYMBOL_FILE_DYNAMIC_VERSION 1
+#define MONO_SYMBOL_FILE_DYNAMIC_MAGIC 0x7aff65af4253d427
+
MonoSymbolFile *
mono_debug_open_mono_symbol_file (MonoImage *image,
const char *filename,
gboolean emit_warnings);
void
-mono_debug_update_mono_symbol_file (MonoSymbolFile *symbol_file);
+mono_debug_symfile_add_method (MonoSymbolFile *symfile,
+ MonoMethod *method);
void
mono_debug_close_mono_symbol_file (MonoSymbolFile *symfile);