};
MonoPPDBFile*
-mono_ppdb_load_file (MonoImage *image)
+mono_ppdb_load_file (MonoImage *image, const guint8 *raw_contents, int size)
{
MonoImage *ppdb_image;
const char *filename;
char *s, *ppdb_filename;
MonoImageOpenStatus status;
+#if 0
MonoTableInfo *tables;
guint32 cols [MONO_MODULE_SIZE];
const char *guid, *ppdb_guid;
+#endif
MonoPPDBFile *ppdb;
- /* ppdb files drop the .exe/.dll extension */
- filename = mono_image_get_filename (image);
- if (strlen (filename) > 4 && (!strcmp (filename + strlen (filename) - 4, ".exe"))) {
- s = g_strdup (filename);
- s [strlen (filename) - 4] = '\0';
- ppdb_filename = g_strdup_printf ("%s.pdb", s);
- g_free (s);
+ if (raw_contents) {
+ ppdb_image = mono_image_open_from_data_internal ((char*)raw_contents, size, TRUE, NULL, FALSE, TRUE, NULL);
} else {
- ppdb_filename = g_strdup_printf ("%s.pdb", filename);
- }
+ /* ppdb files drop the .exe/.dll extension */
+ filename = mono_image_get_filename (image);
+ if (strlen (filename) > 4 && (!strcmp (filename + strlen (filename) - 4, ".exe"))) {
+ s = g_strdup (filename);
+ s [strlen (filename) - 4] = '\0';
+ ppdb_filename = g_strdup_printf ("%s.pdb", s);
+ g_free (s);
+ } else {
+ ppdb_filename = g_strdup_printf ("%s.pdb", filename);
+ }
- ppdb_image = mono_image_open_metadata_only (ppdb_filename, &status);
+ ppdb_image = mono_image_open_metadata_only (ppdb_filename, &status);
+ }
if (!ppdb_image)
return NULL;
+#if 0
/* Check that the images match */
+ // FIXME: ppdb files no longer have a MODULE table */
tables = image->tables;
g_assert (tables [MONO_TABLE_MODULE].rows);
mono_metadata_decode_row (&tables [MONO_TABLE_MODULE], 0, cols, MONO_MODULE_SIZE);
mono_image_close (ppdb_image);
return NULL;
}
+#endif
ppdb = g_new0 (MonoPPDBFile, 1);
ppdb->image = ppdb_image;
const char *end;
char *docname;
int idx, size, docidx, iloffset, delta_il, delta_lines, delta_cols, start_line, start_col, adv_line, adv_col;
+ gboolean first = TRUE, first_non_hidden = TRUE;
MonoDebugSourceLocation *location;
g_assert (method->token);
size = mono_metadata_decode_blob_size (ptr, &ptr);
end = ptr + size;
- /* First record */
+ /* Header */
+ /* LocalSignature */
+ mono_metadata_decode_value (ptr, &ptr);
docidx = mono_metadata_decode_value (ptr, &ptr);
docname = get_docname (ppdb, image, docidx);
- iloffset = mono_metadata_decode_value (ptr, &ptr);
- delta_lines = mono_metadata_decode_value (ptr, &ptr);
- if (delta_lines == 0)
- delta_cols = mono_metadata_decode_value (ptr, &ptr);
- else
- delta_cols = mono_metadata_decode_signed_value (ptr, &ptr);
- start_line = mono_metadata_decode_value (ptr, &ptr);
- start_col = mono_metadata_decode_value (ptr, &ptr);
+ iloffset = 0;
+ start_line = 0;
+ start_col = 0;
while (ptr < end) {
- if (iloffset > offset)
- break;
-
delta_il = mono_metadata_decode_value (ptr, &ptr);
- if (delta_il == 0)
+ if (!first && delta_il == 0) {
+ /* Document record */
// FIXME:
g_assert_not_reached ();
+ }
+ if (!first && iloffset + delta_il > offset)
+ break;
+ iloffset += delta_il;
+ first = FALSE;
delta_lines = mono_metadata_decode_value (ptr, &ptr);
if (delta_lines == 0)
if (delta_lines == 0 && delta_cols == 0)
// FIXME:
g_assert_not_reached ();
- adv_line = mono_metadata_decode_signed_value (ptr, &ptr);
- adv_col = mono_metadata_decode_signed_value (ptr, &ptr);
-
- if (iloffset + delta_il > offset)
- break;
-
- iloffset += delta_il;
- start_line += adv_line;
- start_col += adv_col;
+ if (first_non_hidden) {
+ start_line = mono_metadata_decode_value (ptr, &ptr);
+ start_col = mono_metadata_decode_value (ptr, &ptr);
+ } else {
+ adv_line = mono_metadata_decode_signed_value (ptr, &ptr);
+ adv_col = mono_metadata_decode_signed_value (ptr, &ptr);
+ start_line += adv_line;
+ start_col += adv_col;
+ }
+ first_non_hidden = TRUE;
}
location = g_new0 (MonoDebugSourceLocation, 1);
const char *end;
MonoDebugSourceInfo *docinfo;
int i, method_idx, size, docidx, iloffset, delta_il, delta_lines, delta_cols, start_line, start_col, adv_line, adv_col;
+ gboolean first = TRUE, first_non_hidden = TRUE;
GArray *sps;
MonoSymSeqPoint sp;
GPtrArray *sfiles = NULL;
sps = g_array_new (FALSE, TRUE, sizeof (MonoSymSeqPoint));
- /* First record */
+ /* Header */
+ /* LocalSignature */
+ mono_metadata_decode_value (ptr, &ptr);
docidx = mono_metadata_decode_value (ptr, &ptr);
docinfo = get_docinfo (ppdb, image, docidx);
- iloffset = mono_metadata_decode_value (ptr, &ptr);
- delta_lines = mono_metadata_decode_value (ptr, &ptr);
- if (delta_lines == 0)
- delta_cols = mono_metadata_decode_value (ptr, &ptr);
- else
- delta_cols = mono_metadata_decode_signed_value (ptr, &ptr);
- start_line = mono_metadata_decode_value (ptr, &ptr);
- start_col = mono_metadata_decode_value (ptr, &ptr);
-
if (sfiles)
g_ptr_array_add (sfiles, docinfo);
- if (source_files)
- g_ptr_array_add (sindexes, GUINT_TO_POINTER (sfiles->len - 1));
-
- memset (&sp, 0, sizeof (sp));
- sp.il_offset = iloffset;
- sp.line = start_line;
- sp.column = start_col;
- sp.end_line = start_line + delta_lines;
- sp.end_column = start_col + delta_cols;
-
- g_array_append_val (sps, sp);
+ iloffset = 0;
+ start_line = 0;
+ start_col = 0;
while (ptr < end) {
delta_il = mono_metadata_decode_value (ptr, &ptr);
- if (delta_il == 0) {
+ if (!first && delta_il == 0) {
/* subsequent-document-record */
docidx = mono_metadata_decode_value (ptr, &ptr);
docinfo = get_docinfo (ppdb, image, docidx);
g_ptr_array_add (sfiles, docinfo);
continue;
}
+ iloffset += delta_il;
+ first = FALSE;
+
delta_lines = mono_metadata_decode_value (ptr, &ptr);
if (delta_lines == 0)
delta_cols = mono_metadata_decode_value (ptr, &ptr);
if (delta_lines == 0 && delta_cols == 0) {
/* Hidden sequence point */
- // FIXME: This seems to be followed by garbage
continue;
}
- adv_line = mono_metadata_decode_signed_value (ptr, &ptr);
- adv_col = mono_metadata_decode_signed_value (ptr, &ptr);
-
- iloffset += delta_il;
- start_line += adv_line;
- start_col += adv_col;
+ if (first_non_hidden) {
+ start_line = mono_metadata_decode_value (ptr, &ptr);
+ start_col = mono_metadata_decode_value (ptr, &ptr);
+ } else {
+ adv_line = mono_metadata_decode_signed_value (ptr, &ptr);
+ adv_col = mono_metadata_decode_signed_value (ptr, &ptr);
+ start_line += adv_line;
+ start_col += adv_col;
+ }
+ first_non_hidden = TRUE;
memset (&sp, 0, sizeof (sp));
sp.il_offset = iloffset;
g_array_free (sps, TRUE);
}
+
+MonoDebugLocalsInfo*
+mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo)
+{
+ MonoPPDBFile *ppdb = minfo->handle->ppdb;
+ MonoImage *image = ppdb->image;
+ MonoTableInfo *tables = image->tables;
+ MonoMethod *method = minfo->method;
+ guint32 cols [MONO_LOCALSCOPE_SIZE];
+ guint32 locals_cols [MONO_LOCALVARIABLE_SIZE];
+ int i, lindex, sindex, method_idx, start_scope_idx, scope_idx, locals_idx, locals_end_idx, nscopes;
+ MonoDebugLocalsInfo *res;
+ MonoMethodSignature *sig;
+
+ if (!method->token)
+ return NULL;
+
+ sig = mono_method_signature (method);
+ if (!sig)
+ return NULL;
+
+ method_idx = mono_metadata_token_index (method->token);
+
+ start_scope_idx = mono_metadata_localscope_from_methoddef (image, method_idx);
+
+ if (!start_scope_idx)
+ return NULL;
+
+ /* Compute number of locals and scopes */
+ scope_idx = start_scope_idx;
+ mono_metadata_decode_row (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1, cols, MONO_LOCALSCOPE_SIZE);
+ locals_idx = cols [MONO_LOCALSCOPE_VARIABLELIST];
+ while (TRUE) {
+ mono_metadata_decode_row (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1, cols, MONO_LOCALSCOPE_SIZE);
+ if (cols [MONO_LOCALSCOPE_METHOD] != method_idx)
+ break;
+ scope_idx ++;
+ }
+ nscopes = scope_idx - start_scope_idx;
+ if (scope_idx == tables [MONO_TABLE_LOCALSCOPE].rows) {
+ // FIXME:
+ g_assert_not_reached ();
+ locals_end_idx = -1;
+ } else {
+ locals_end_idx = cols [MONO_LOCALSCOPE_VARIABLELIST];
+ }
+
+ res = g_new0 (MonoDebugLocalsInfo, 1);
+ res->num_blocks = nscopes;
+ res->code_blocks = g_new0 (MonoDebugCodeBlock, res->num_blocks);
+ res->num_locals = locals_end_idx - locals_idx;
+ res->locals = g_new0 (MonoDebugLocalVar, res->num_locals);
+
+ lindex = 0;
+ for (sindex = 0; sindex < nscopes; ++sindex) {
+ scope_idx = start_scope_idx + sindex;
+ mono_metadata_decode_row (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1, cols, MONO_LOCALSCOPE_SIZE);
+
+ locals_idx = cols [MONO_LOCALSCOPE_VARIABLELIST];
+ if (scope_idx == tables [MONO_TABLE_LOCALSCOPE].rows) {
+ // FIXME:
+ g_assert_not_reached ();
+ } else {
+ locals_end_idx = mono_metadata_decode_row_col (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1 + 1, MONO_LOCALSCOPE_VARIABLELIST);
+ }
+
+ res->code_blocks [sindex].start_offset = cols [MONO_LOCALSCOPE_STARTOFFSET];
+ res->code_blocks [sindex].end_offset = cols [MONO_LOCALSCOPE_STARTOFFSET] + cols [MONO_LOCALSCOPE_LENGTH];
+
+ //printf ("Scope: %s %d %d %d-%d\n", mono_method_full_name (method, 1), cols [MONO_LOCALSCOPE_STARTOFFSET], cols [MONO_LOCALSCOPE_LENGTH], locals_idx, locals_end_idx);
+
+ for (i = locals_idx; i < locals_end_idx; ++i) {
+ mono_metadata_decode_row (&tables [MONO_TABLE_LOCALVARIABLE], i - 1, locals_cols, MONO_LOCALVARIABLE_SIZE);
+
+ res->locals [lindex].name = g_strdup (mono_metadata_string_heap (image, locals_cols [MONO_LOCALVARIABLE_NAME]));
+ res->locals [lindex].index = locals_cols [MONO_LOCALVARIABLE_INDEX];
+ res->locals [lindex].block = &res->code_blocks [sindex];
+ lindex ++;
+
+ //printf ("\t %s %d\n", mono_metadata_string_heap (image, locals_cols [MONO_LOCALVARIABLE_NAME]), locals_cols [MONO_LOCALVARIABLE_INDEX]);
+ }
+ }
+
+ return res;
+}