+
+ return address;
+}
+
+static inline guint32
+read_leb128 (guint8 *ptr, guint8 **rptr)
+{
+ guint32 result = 0, shift = 0;
+
+ while (TRUE) {
+ guint8 byte = *ptr++;
+
+ result |= (byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+
+ *rptr = ptr;
+ return result;
+}
+
+static inline gint32
+read_sleb128 (guint8 *ptr, guint8 **rptr)
+{
+ gint32 result = 0;
+ guint32 shift = 0;
+
+ while (TRUE) {
+ guint8 byte = *ptr++;
+
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+
+ if (byte & 0x80)
+ continue;
+
+ if ((shift < 32) && (byte & 0x40))
+ result |= - (1 << shift);
+ break;
+ }
+
+ *rptr = ptr;
+ return result;
+}
+
+static void
+read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
+{
+ var->index = read_leb128 (ptr, &ptr);
+ var->offset = read_sleb128 (ptr, &ptr);
+ var->size = read_leb128 (ptr, &ptr);
+ var->begin_scope = read_leb128 (ptr, &ptr);
+ var->end_scope = read_leb128 (ptr, &ptr);
+ *rptr = ptr;
+}
+
+MonoDebugMethodJitInfo *
+mono_debug_read_method (MonoDebugMethodAddress *address)
+{
+ MonoDebugMethodJitInfo *jit;
+ guint32 i, il_offset = 0, native_offset = 0;
+ guint8 *ptr;
+
+ jit = g_new0 (MonoDebugMethodJitInfo, 1);
+ jit->code_start = address->code_start;
+ jit->code_size = address->code_size;
+ jit->wrapper_addr = address->wrapper_addr;
+
+ ptr = (guint8 *) &address->data;
+
+ jit->prologue_end = read_leb128 (ptr, &ptr);
+ jit->epilogue_begin = read_leb128 (ptr, &ptr);
+
+ jit->num_line_numbers = read_leb128 (ptr, &ptr);
+ jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
+ for (i = 0; i < jit->num_line_numbers; i++) {
+ MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
+
+ il_offset += read_sleb128 (ptr, &ptr);
+ native_offset += read_sleb128 (ptr, &ptr);
+
+ lne->il_offset = il_offset;
+ lne->native_offset = native_offset;
+ }
+
+ il_offset = 0;
+ native_offset = 0;
+ jit->num_lexical_blocks = read_leb128 (ptr, &ptr);
+ jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
+ for (i = 0; i < jit->num_lexical_blocks; i ++) {
+ MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
+
+ il_offset += read_sleb128 (ptr, &ptr);
+ native_offset += read_sleb128 (ptr, &ptr);
+
+ lbe->il_start_offset = il_offset;
+ lbe->native_start_offset = native_offset;
+
+ il_offset += read_sleb128 (ptr, &ptr);
+ native_offset += read_sleb128 (ptr, &ptr);
+
+ lbe->il_end_offset = il_offset;
+ lbe->native_end_offset = native_offset;
+ }
+
+ if (*ptr++) {
+ jit->this_var = g_new0 (MonoDebugVarInfo, 1);
+ read_variable (jit->this_var, ptr, &ptr);
+ }
+
+ jit->num_params = read_leb128 (ptr, &ptr);
+ jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
+ for (i = 0; i < jit->num_params; i++)
+ read_variable (&jit->params [i], ptr, &ptr);
+
+ jit->num_locals = read_leb128 (ptr, &ptr);
+ jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
+ for (i = 0; i < jit->num_locals; i++)
+ read_variable (&jit->locals [i], ptr, &ptr);
+
+ return jit;