Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs48
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest.cs136
-rw-r--r--mono/metadata/blob.h2
-rw-r--r--mono/metadata/debug-mono-ppdb.c124
-rw-r--r--mono/metadata/debug-mono-ppdb.h3
-rw-r--r--mono/metadata/debug-mono-symfile.h11
-rw-r--r--mono/metadata/metadata.c86
-rw-r--r--mono/metadata/mono-debug-debugger.h3
-rw-r--r--mono/metadata/mono-debug.c46
-rw-r--r--mono/metadata/mono-debug.h4
-rw-r--r--mono/metadata/row-indexes.h7
11 files changed, 463 insertions, 7 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
index 1687bcbc72d..6cfa088437f 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
@@ -13,6 +13,7 @@ using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
+using System.Threading.Tasks;
using MonoTests.Helpers;
public class TestsBase
@@ -431,6 +432,7 @@ public class Tests : TestsBase, ITest2
ss_recursive_chaotic ();
ss_fp_clobber ();
ss_no_frames ();
+ ss_await ();
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
@@ -718,6 +720,52 @@ public class Tests : TestsBase, ITest2
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_await ()
+ {
+ ss_await_1 ().Wait ();//in
+ ss_await_1 ().Wait ();//over
+ ss_await_1 ().Wait ();//out before
+ ss_await_1 ().Wait ();//out after
+ ss_await_1_exc (true, true).Wait ();//in
+ ss_await_1_exc (true, true).Wait ();//over
+ ss_await_1_exc (true, true).Wait ();//out
+ try {
+ ss_await_1_exc (true, false).Wait ();//in
+ } catch { }
+ try {
+ ss_await_1_exc (true, false).Wait ();//over
+ } catch { }
+ try {
+ ss_await_1_exc (true, false).Wait ();//out
+ } catch { }
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static async Task<int> ss_await_1 () {
+ var a = 1;
+ await Task.Delay (10);
+ return a + 2;
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static async Task<int> ss_await_1_exc (bool exc, bool handled)
+ {
+ var a = 1;
+ await Task.Delay (10);
+ if (exc) {
+ if (handled) {
+ try {
+ throw new Exception ();
+ } catch {
+ }
+ } else {
+ throw new Exception ();
+ }
+ }
+ return a + 2;
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void ss_no_frames_2 () {
}
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
index f6312cb1703..ce74b4fd5fb 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
@@ -943,6 +943,142 @@ public class DebuggerTests
f = e.Thread.GetFrames ()[0];
AssertValue (7.0, f.GetValue (f.Method.GetParameters ()[0]));
req.Disable ();
+
+ e = run_until ("ss_await");
+ e = step_in_await ("ss_await", e);//ss_await_1 ().Wait ();//in
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//var a = 1;
+ e = step_in_await ("MoveNext", e);//await Task.Delay (10);
+ e = step_in_await ("MoveNext", e);//return a + 2;
+ e = step_in_await ("MoveNext", e);//}
+ e = step_in_await ("ss_await", e);//ss_await_1 ().Wait ();//in
+
+ e = step_in_await ("ss_await", e);//ss_await_1 ().Wait ();//over
+ e = step_in_await ("MoveNext", e);//{
+ e = step_over_await ("MoveNext", e);//var a = 1;
+ e = step_over_await ("MoveNext", e);//await Task.Delay (10);
+ e = step_over_await ("MoveNext", e);//return a + 2;
+ e = step_over_await ("MoveNext", e);//}
+ e = step_over_await ("ss_await", e);//ss_await_1 ().Wait ();//over
+
+ e = step_in_await ("ss_await", e);//ss_await_1 ().Wait ();//out before
+ e = step_in_await ("MoveNext", e);//{
+ e = step_out_await ("ss_await", e);//ss_await_1 ().Wait ();//out before
+
+ e = step_in_await ("ss_await", e);//ss_await_1 ().Wait ();//out after
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//var a = 1;
+ e = step_in_await ("MoveNext", e);//await Task.Delay (10);
+ e = step_in_await ("MoveNext", e);//return a + 2;
+ e = step_out_await ("ss_await", e);//ss_await_1 ().Wait ();//out after
+
+ e = step_in_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//in
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//var a = 1;
+ e = step_in_await ("MoveNext", e);//await Task.Delay (10);
+ e = step_in_await ("MoveNext", e);//if (exc)
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//if (handled)
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//try {
+ e = step_in_await ("MoveNext", e);//throw new Exception ();
+ e = step_in_await ("MoveNext", e);//catch
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//}
+ e = step_in_await ("MoveNext", e);//}
+ e = step_in_await ("MoveNext", e);//}
+ e = step_in_await ("MoveNext", e);//return a + 2;
+ e = step_in_await ("MoveNext", e);//}
+ e = step_in_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//in
+
+ e = step_in_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//over
+ e = step_in_await ("MoveNext", e);//{
+ e = step_over_await ("MoveNext", e);//var a = 1;
+ e = step_over_await ("MoveNext", e);//await Task.Delay (10);
+ e = step_over_await ("MoveNext", e);//if (exc)
+ e = step_over_await ("MoveNext", e);//{
+ e = step_over_await ("MoveNext", e);//if (handled)
+ e = step_over_await ("MoveNext", e);//{
+ e = step_over_await ("MoveNext", e);//try {
+ e = step_over_await ("MoveNext", e);//throw new Exception ();
+ e = step_over_await ("MoveNext", e);//catch
+ e = step_over_await ("MoveNext", e);//{
+ e = step_over_await ("MoveNext", e);//}
+ e = step_over_await ("MoveNext", e);//}
+ e = step_over_await ("MoveNext", e);//}
+ e = step_over_await ("MoveNext", e);//return a + 2;
+ e = step_over_await ("MoveNext", e);//}
+ e = step_over_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//over
+
+ e = step_in_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//out
+ e = step_in_await ("MoveNext", e);//{
+ e = step_out_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//out
+
+ e = step_in_await ("ss_await", e);//try {
+ e = step_in_await ("ss_await", e);//ss_await_1_exc (true, false).Wait ();//in
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//var a = 1;
+ e = step_in_await ("MoveNext", e);//await Task.Delay (10);
+ e = step_in_await ("MoveNext", e);//if (exc)
+ e = step_in_await ("MoveNext", e);//{
+ e = step_in_await ("MoveNext", e);//if (handled)
+ e = step_in_await ("MoveNext", e);//} else {
+ e = step_in_await ("MoveNext", e);//throw new Exception ();
+ e = step_in_await ("ss_await", e);//catch
+ e = step_in_await ("ss_await", e);//{
+ e = step_in_await ("ss_await", e);//}
+ e = step_in_await ("ss_await", e);//try {
+
+ e = step_in_await ("ss_await", e);//ss_await_1_exc (true, false).Wait ();//over
+ e = step_in_await ("MoveNext", e);//{
+ e = step_over_await ("MoveNext", e);//var a = 1;
+ e = step_over_await ("MoveNext", e);//await Task.Delay (10);
+ e = step_over_await ("MoveNext", e);//if (exc)
+ e = step_over_await ("MoveNext", e);//{
+ e = step_over_await ("MoveNext", e);//if (handled)
+ e = step_over_await ("MoveNext", e);//} else {
+ e = step_over_await ("MoveNext", e);//throw new Exception ();
+ e = step_over_await ("ss_await", e);//catch
+ e = step_over_await ("ss_await", e);//{
+ e = step_over_await ("ss_await", e);//}
+ e = step_over_await ("ss_await", e);//try {
+
+ e = step_in_await ("ss_await", e);//ss_await_1_exc (true, false).Wait ();//out
+ e = step_in_await ("MoveNext", e);//{
+ e = step_out_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//out
+ }
+
+ Event step_in_await (string method, Event e)
+ {
+ if (step_req != null)
+ step_req.Disable ();
+ create_step (e);
+ step_req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
+ var ef = step_into ();
+ assert_location (ef, method);
+ return ef;
+ }
+
+ Event step_over_await (string method, Event e)
+ {
+ if (step_req != null)
+ step_req.Disable ();
+ create_step (e);
+ step_req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
+ var ef = step_over ();
+ assert_location (ef, method);
+ return ef;
+ }
+
+ Event step_out_await (string method, Event e)
+ {
+ if (step_req != null)
+ step_req.Disable ();
+ create_step (e);
+ step_req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
+ var ef = step_out ();
+ assert_location (ef, method);
+ return ef;
}
[Test]
diff --git a/mono/metadata/blob.h b/mono/metadata/blob.h
index dcc3c842595..5e81e1af7e1 100644
--- a/mono/metadata/blob.h
+++ b/mono/metadata/blob.h
@@ -105,7 +105,7 @@ typedef enum {
MONO_TABLE_LOCALVARIABLE,
MONO_TABLE_LOCALCONSTANT,
MONO_TABLE_IMPORTSCOPE,
- MONO_TABLE_ASYNCMETHOD,
+ MONO_TABLE_STATEMACHINEMETHOD,
MONO_TABLE_CUSTOMDEBUGINFORMATION
#define MONO_TABLE_LAST MONO_TABLE_CUSTOMDEBUGINFORMATION
diff --git a/mono/metadata/debug-mono-ppdb.c b/mono/metadata/debug-mono-ppdb.c
index 8357099a551..581f364423a 100644
--- a/mono/metadata/debug-mono-ppdb.c
+++ b/mono/metadata/debug-mono-ppdb.c
@@ -26,6 +26,7 @@
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/cil-coff.h>
+#include <mono/utils/bsearch.h>
#include "debug-mono-ppdb.h"
@@ -595,3 +596,126 @@ mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo)
return res;
}
+
+/*
+* We use this to pass context information to the row locator
+*/
+typedef struct {
+ int idx; /* The index that we are trying to locate */
+ int col_idx; /* The index in the row where idx may be stored */
+ MonoTableInfo *t; /* pointer to the table */
+ guint32 result;
+} locator_t;
+
+static int
+table_locator (const void *a, const void *b)
+{
+ locator_t *loc = (locator_t *)a;
+ const char *bb = (const char *)b;
+ guint32 table_index = (bb - loc->t->base) / loc->t->row_size;
+ guint32 col;
+
+ col = mono_metadata_decode_row_col(loc->t, table_index, loc->col_idx);
+
+ if (loc->idx == col) {
+ loc->result = table_index;
+ return 0;
+ }
+ if (loc->idx < col)
+ return -1;
+ else
+ return 1;
+}
+
+static gboolean
+compare_guid (guint8* guid1, guint8* guid2) {
+ for (int i = 0; i < 16; i++) {
+ if (guid1 [i] != guid2 [i])
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// for parent_type see HasCustomDebugInformation table at
+// https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md
+static const char*
+lookup_custom_debug_information (MonoImage* image, guint32 token, uint8_t parent_type, guint8* guid)
+{
+ MonoTableInfo *tables = image->tables;
+ MonoTableInfo *table = &tables[MONO_TABLE_CUSTOMDEBUGINFORMATION];
+ locator_t loc;
+
+ if (!table->base)
+ return 0;
+
+ loc.idx = (mono_metadata_token_index (token) << 5) | parent_type;
+ loc.col_idx = MONO_CUSTOMDEBUGINFORMATION_PARENT;
+ loc.t = table;
+
+ if (!mono_binary_search (&loc, table->base, table->rows, table->row_size, table_locator))
+ return NULL;
+ // Great we found one of possibly many CustomDebugInformations of this entity they are distinguished by KIND guid
+ // First try on this index found by binary search...(it's most likeley to be only one and binary search found the one we want)
+ if (compare_guid (guid, (guint8*)mono_metadata_guid_heap (image, mono_metadata_decode_row_col (table, loc.result, MONO_CUSTOMDEBUGINFORMATION_KIND))))
+ return mono_metadata_blob_heap (image, mono_metadata_decode_row_col (table, loc.result, MONO_CUSTOMDEBUGINFORMATION_VALUE));
+
+ // Move forward from binary found index, until parent token differs
+ for (int i = loc.result + 1; i < table->rows; i++)
+ {
+ if (mono_metadata_decode_row_col (table, i, MONO_CUSTOMDEBUGINFORMATION_PARENT) != loc.idx)
+ break;
+ if (compare_guid (guid, (guint8*)mono_metadata_guid_heap (image, mono_metadata_decode_row_col (table, i, MONO_CUSTOMDEBUGINFORMATION_KIND))))
+ return mono_metadata_blob_heap (image, mono_metadata_decode_row_col (table, i, MONO_CUSTOMDEBUGINFORMATION_VALUE));
+ }
+
+ // Move backward from binary found index, until parent token differs
+ for (int i = loc.result - 1; i >= 0; i--) {
+ if (mono_metadata_decode_row_col (table, i, MONO_CUSTOMDEBUGINFORMATION_PARENT) != loc.idx)
+ break;
+ if (compare_guid (guid, (guint8*)mono_metadata_guid_heap (image, mono_metadata_decode_row_col (table, i, MONO_CUSTOMDEBUGINFORMATION_KIND))))
+ return mono_metadata_blob_heap (image, mono_metadata_decode_row_col (table, i, MONO_CUSTOMDEBUGINFORMATION_VALUE));
+ }
+ return NULL;
+}
+
+MonoDebugMethodAsyncInfo*
+mono_ppdb_lookup_method_async_debug_info (MonoDebugMethodInfo *minfo)
+{
+ MonoMethod *method = minfo->method;
+ MonoPPDBFile *ppdb = minfo->handle->ppdb;
+ MonoImage *image = ppdb->image;
+
+ // Guid is taken from Roslyn source code:
+ // https://github.com/dotnet/roslyn/blob/1ad4b58/src/Dependencies/CodeAnalysis.Metadata/PortableCustomDebugInfoKinds.cs#L9
+ guint8 async_method_stepping_information_guid [16] = { 0xC5, 0x2A, 0xFD, 0x54, 0x25, 0xE9, 0x1A, 0x40, 0x9C, 0x2A, 0xF9, 0x4F, 0x17, 0x10, 0x72, 0xF8 };
+ char const *blob = lookup_custom_debug_information (image, method->token, 0, async_method_stepping_information_guid);
+ if (!blob)
+ return NULL;
+ int blob_len = mono_metadata_decode_blob_size (blob, &blob);
+ MonoDebugMethodAsyncInfo* res = g_new0 (MonoDebugMethodAsyncInfo, 1);
+ char const *pointer = blob;
+
+ // Format of this blob is taken from Roslyn source code:
+ // https://github.com/dotnet/roslyn/blob/1ad4b58/src/Compilers/Core/Portable/PEWriter/MetadataWriter.PortablePdb.cs#L566
+
+ pointer += 4;//catch_handler_offset
+ while (pointer - blob < blob_len) {
+ res->num_awaits++;
+ pointer += 8;//yield_offsets+resume_offsets
+ mono_metadata_decode_value (pointer, &pointer);//move_next_method_token
+ }
+ g_assert(pointer - blob == blob_len); //Check that we used all blob data
+ pointer = blob; //reset pointer after we figured num_awaits
+
+ res->yield_offsets = g_new (uint32_t, res->num_awaits);
+ res->resume_offsets = g_new (uint32_t, res->num_awaits);
+ res->move_next_method_token = g_new (uint32_t, res->num_awaits);
+
+ res->catch_handler_offset = read32 (pointer); pointer += 4;
+ for (int i = 0; i < res->num_awaits; i++) {
+ res->yield_offsets [i] = read32 (pointer); pointer += 4;
+ res->resume_offsets [i] = read32 (pointer); pointer += 4;
+ res->move_next_method_token [i] = mono_metadata_decode_value (pointer, &pointer);
+ }
+ return res;
+} \ No newline at end of file
diff --git a/mono/metadata/debug-mono-ppdb.h b/mono/metadata/debug-mono-ppdb.h
index decf5e8d04b..274f2ef0c91 100644
--- a/mono/metadata/debug-mono-ppdb.h
+++ b/mono/metadata/debug-mono-ppdb.h
@@ -35,4 +35,7 @@ mono_ppdb_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrAr
MonoDebugLocalsInfo*
mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo);
+MonoDebugMethodAsyncInfo*
+mono_ppdb_lookup_method_async_debug_info (MonoDebugMethodInfo *minfo);
+
#endif
diff --git a/mono/metadata/debug-mono-symfile.h b/mono/metadata/debug-mono-symfile.h
index 3b3459f3258..bd8252843e5 100644
--- a/mono/metadata/debug-mono-symfile.h
+++ b/mono/metadata/debug-mono-symfile.h
@@ -103,6 +103,17 @@ struct _MonoDebugLocalsInfo {
MonoDebugCodeBlock *code_blocks;
};
+/*
+* Information about method await yield and resume offsets retrieved from a symbol file.
+*/
+struct _MonoDebugMethodAsyncInfo {
+ uint32_t catch_handler_offset;
+ int num_awaits;
+ uint32_t *yield_offsets;
+ uint32_t *resume_offsets;
+ uint32_t *move_next_method_token;
+};
+
struct _MonoDebugLineNumberEntry {
uint32_t il_offset;
uint32_t native_offset;
diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c
index 2fdcb1f6bff..586712cfa90 100644
--- a/mono/metadata/metadata.c
+++ b/mono/metadata/metadata.c
@@ -109,7 +109,10 @@ enum {
MONO_MT_HS_IDX,
/* ResolutionScope coded index: Module, ModuleRef, AssemblytRef, TypeRef */
- MONO_MT_RS_IDX
+ MONO_MT_RS_IDX,
+
+ /* CustomDebugInformation parent encoded index */
+ MONO_MT_HASCUSTDEBUG_IDX
};
const static unsigned char TableSchemas [] = {
@@ -397,7 +400,28 @@ const static unsigned char TableSchemas [] = {
MONO_MT_STRING_IDX, /* Name */
MONO_MT_END,
-#define NULL_SCHEMA_OFFSET LOCALVARIABLE_SCHEMA_OFFSET + 4
+#define LOCALCONSTANT_SCHEMA_OFFSET LOCALVARIABLE_SCHEMA_OFFSET + 4
+ MONO_MT_STRING_IDX, /* Name (String heap index) */
+ MONO_MT_BLOB_IDX, /* Signature (Blob heap index, LocalConstantSig blob) */
+ MONO_MT_END,
+
+#define IMPORTSCOPE_SCHEMA_OFFSET LOCALCONSTANT_SCHEMA_OFFSET + 3
+ MONO_MT_TABLE_IDX, /* Parent (ImportScope row id or nil) */
+ MONO_MT_BLOB_IDX, /* Imports (Blob index, encoding: Imports blob) */
+ MONO_MT_END,
+
+#define ASYNCMETHOD_SCHEMA_OFFSET IMPORTSCOPE_SCHEMA_OFFSET + 3
+ MONO_MT_TABLE_IDX, /* MoveNextMethod (MethodDef row id) */
+ MONO_MT_TABLE_IDX, /* KickoffMethod (MethodDef row id) */
+ MONO_MT_END,
+
+#define CUSTOMDEBUGINFORMATION_SCHEMA_OFFSET ASYNCMETHOD_SCHEMA_OFFSET + 3
+ MONO_MT_HASCUSTDEBUG_IDX, /* Parent (HasCustomDebugInformation coded index) */
+ MONO_MT_GUID_IDX, /* Kind (Guid heap index) */
+ MONO_MT_BLOB_IDX, /* Value (Blob heap index) */
+ MONO_MT_END,
+
+#define NULL_SCHEMA_OFFSET CUSTOMDEBUGINFORMATION_SCHEMA_OFFSET + 4
MONO_MT_END
};
@@ -455,7 +479,11 @@ table_description [] = {
DOCUMENT_SCHEMA_OFFSET, /* 0x30 */
METHODBODY_SCHEMA_OFFSET,
LOCALSCOPE_SCHEMA_OFFSET,
- LOCALVARIABLE_SCHEMA_OFFSET
+ LOCALVARIABLE_SCHEMA_OFFSET,
+ LOCALCONSTANT_SCHEMA_OFFSET,
+ IMPORTSCOPE_SCHEMA_OFFSET,
+ ASYNCMETHOD_SCHEMA_OFFSET,
+ CUSTOMDEBUGINFORMATION_SCHEMA_OFFSET
};
#ifdef HAVE_ARRAY_ELEM_INIT
@@ -673,8 +701,13 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
break;
case MONO_TABLE_METHODBODY:
g_assert (i == 0);
- field_size = idx_size (meta, MONO_TABLE_DOCUMENT);
- break;
+ field_size = idx_size (meta, MONO_TABLE_DOCUMENT); break;
+ case MONO_TABLE_IMPORTSCOPE:
+ g_assert(i == 0);
+ field_size = idx_size (meta, MONO_TABLE_IMPORTSCOPE); break;
+ case MONO_TABLE_STATEMACHINEMETHOD:
+ g_assert(i == 0 || i == 1);
+ field_size = idx_size(meta, MONO_TABLE_METHOD); break;
default:
g_error ("Can't handle MONO_MT_TABLE_IDX for table %d element %d", tableindex, i);
}
@@ -727,12 +760,53 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
n = MAX (n, meta->tables [MONO_TABLE_FILE].rows);
n = MAX (n, meta->tables [MONO_TABLE_EXPORTEDTYPE].rows);
n = MAX (n, meta->tables [MONO_TABLE_MANIFESTRESOURCE].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_GENERICPARAM].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_METHODSPEC].rows);
/* 5 bits to encode */
field_size = rtsize (meta, n, 16-5);
break;
/*
+ * HasCustomAttribute: points to any table but
+ * itself.
+ */
+
+ case MONO_MT_HASCUSTDEBUG_IDX:
+ n = MAX(meta->tables[MONO_TABLE_METHOD].rows,
+ meta->tables[MONO_TABLE_FIELD].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_TYPEREF].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_TYPEDEF].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_PARAM].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_INTERFACEIMPL].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_MEMBERREF].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_MODULE].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_DECLSECURITY].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_PROPERTY].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_EVENT].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_STANDALONESIG].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_MODULEREF].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_TYPESPEC].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_ASSEMBLY].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_ASSEMBLYREF].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_FILE].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_EXPORTEDTYPE].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_MANIFESTRESOURCE].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_GENERICPARAM].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_GENERICPARAMCONSTRAINT].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_METHODSPEC].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_DOCUMENT].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_LOCALSCOPE].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_LOCALVARIABLE].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_LOCALCONSTANT].rows);
+ n = MAX(n, meta->tables[MONO_TABLE_IMPORTSCOPE].rows);
+
+ /* 5 bits to encode */
+ field_size = rtsize(meta, n, 16 - 5);
+ break;
+
+ /*
* CustomAttributeType: TypeDef, TypeRef, MethodDef,
* MemberRef and String.
*/
@@ -1125,7 +1199,7 @@ mono_metadata_decode_blob_size (const char *xptr, const char **rptr)
* @rptr: the new position of the pointer
*
* This routine decompresses 32-bit values as specified in the "Blob and
- * Signature" section (22.2)
+ * Signature" section (23.2)
*
* Returns: the decoded value
*/
diff --git a/mono/metadata/mono-debug-debugger.h b/mono/metadata/mono-debug-debugger.h
index 6b042252419..c7e5385f933 100644
--- a/mono/metadata/mono-debug-debugger.h
+++ b/mono/metadata/mono-debug-debugger.h
@@ -20,4 +20,7 @@ mono_debug_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrA
MONO_API void
mono_debug_free_locals (MonoDebugLocalsInfo *info);
+void
+mono_debug_free_method_async_debug_info (MonoDebugMethodAsyncInfo *info);
+
#endif /* __MONO_DEBUG_DEBUGGER_H__ */
diff --git a/mono/metadata/mono-debug.c b/mono/metadata/mono-debug.c
index 4d81eefb8d1..2eba05b36fa 100644
--- a/mono/metadata/mono-debug.c
+++ b/mono/metadata/mono-debug.c
@@ -848,6 +848,52 @@ mono_debug_free_locals (MonoDebugLocalsInfo *info)
g_free (info);
}
+/*
+* mono_debug_lookup_method_async_debug_info:
+*
+* Return information about the async stepping information of method.
+* The result should be freed using mono_debug_free_async_debug_info ().
+*/
+MonoDebugMethodAsyncInfo*
+mono_debug_lookup_method_async_debug_info (MonoMethod *method)
+{
+ MonoDebugMethodInfo *minfo;
+ MonoDebugMethodAsyncInfo *res = NULL;
+
+ if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
+ return NULL;
+
+ mono_debugger_lock ();
+ minfo = mono_debug_lookup_method_internal (method);
+ if (!minfo || !minfo->handle) {
+ mono_debugger_unlock ();
+ return NULL;
+ }
+
+ if (minfo->handle->ppdb)
+ res = mono_ppdb_lookup_method_async_debug_info (minfo);
+
+ mono_debugger_unlock ();
+
+ return res;
+}
+
+/*
+ * mono_debug_free_method_async_debug_info:
+ *
+ * Free all the data allocated by mono_debug_lookup_method_async_debug_info ().
+ */
+void
+mono_debug_free_method_async_debug_info (MonoDebugMethodAsyncInfo *info)
+{
+ if (info->num_awaits) {
+ g_free (info->yield_offsets);
+ g_free (info->resume_offsets);
+ g_free (info->move_next_method_token);
+ }
+ g_free (info);
+}
+
/**
* mono_debug_free_source_location:
* @location: A `MonoDebugSourceLocation'.
diff --git a/mono/metadata/mono-debug.h b/mono/metadata/mono-debug.h
index c9350a7023a..8f20018f274 100644
--- a/mono/metadata/mono-debug.h
+++ b/mono/metadata/mono-debug.h
@@ -30,6 +30,7 @@ typedef struct _MonoDebugClassEntry MonoDebugClassEntry;
typedef struct _MonoDebugMethodInfo MonoDebugMethodInfo;
typedef struct _MonoDebugLocalsInfo MonoDebugLocalsInfo;
+typedef struct _MonoDebugMethodAsyncInfo MonoDebugMethodAsyncInfo;
typedef struct _MonoDebugSourceLocation MonoDebugSourceLocation;
typedef struct _MonoDebugList MonoDebugList;
@@ -186,6 +187,9 @@ mono_debug_add_delegate_trampoline (void* code, int size);
MONO_API MonoDebugLocalsInfo*
mono_debug_lookup_locals (MonoMethod *method);
+MonoDebugMethodAsyncInfo*
+mono_debug_lookup_method_async_debug_info (MonoMethod *method);
+
MonoDebugSourceLocation *
mono_debug_method_lookup_location (MonoDebugMethodInfo *minfo, int il_offset);
diff --git a/mono/metadata/row-indexes.h b/mono/metadata/row-indexes.h
index eff71fb54ad..bf66ecad465 100644
--- a/mono/metadata/row-indexes.h
+++ b/mono/metadata/row-indexes.h
@@ -339,6 +339,13 @@ enum {
MONO_LOCALVARIABLE_SIZE
};
+enum {
+ MONO_CUSTOMDEBUGINFORMATION_PARENT,
+ MONO_CUSTOMDEBUGINFORMATION_KIND,
+ MONO_CUSTOMDEBUGINFORMATION_VALUE,
+ MONO_CUSTOMDEBUGINFORMATION_SIZE
+};
+
/*
* Coded Tokens
* The _BITS entry is for the bits used in the token.