Weekend work
authorMiguel de Icaza <miguel@gnome.org>
Mon, 25 Jun 2001 17:22:30 +0000 (17:22 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Mon, 25 Jun 2001 17:22:30 +0000 (17:22 -0000)
svn path=/trunk/mono/; revision=32

mono/dis/Makefile.am
mono/dis/main.c
mono/metadata/ChangeLog
mono/metadata/Makefile.am
mono/metadata/eltype.h [new file with mode: 0644]
mono/metadata/fieldattr.h [new file with mode: 0644]
mono/metadata/metadata.c
mono/metadata/metadata.h

index fdb8662c28c1033ad16e19de72e918370a040f04..a554734338b01096186832f6893cf95f0807b286 100644 (file)
@@ -3,7 +3,9 @@ INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)
 bin_PROGRAMS = monodis
 
 monodis_SOURCES =      \
-       main.c
+       main.c          \
+       util.c          \
+       util.h
 
 monodis_LDADD =                        \
        ../metadata/libmetadata.a       \
index 9ea7a311efcefeab4ce4a72748ad35a197fc52d7..fbbabdafcc429badea2c97f11d9c04e962aabf28 100644 (file)
@@ -14,6 +14,9 @@
 #include <mono/metadata/cil-coff.h>
 #include <mono/metadata/endian.h>
 #include <mono/metadata/typeattr.h>
+#include <mono/metadata/fieldattr.h>
+#include <mono/metadata/eltype.h>
+#include "util.h"
 
 FILE *output;
 
@@ -113,23 +116,6 @@ dis_directive_assemblyref (metadata_t *m)
        }
 }
 
-typedef struct {
-       int code;
-       char *str;
-} map_t;
-
-static const char *
-map (int code, map_t *table)
-{
-       int i;
-
-       for (i = 0; table [i].str != NULL; i++)
-               if (table [i].code == code)
-                       return table [i].str;
-       g_assert_not_reached ();
-       return "";
-}
-
 static map_t visibility_map [] = {
        { TYPE_ATTRIBUTE_NOT_PUBLIC,           "not-public " },
        { TYPE_ATTRIBUTE_PUBLIC,               "public " },
@@ -186,31 +172,433 @@ typedef_flags (guint32 flags)
        return buffer;
 }
 
-static void
-dis_fields (metadata_t *m, guint32 idx)
+static map_t access_map [] = {
+       { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
+       { FIELD_ATTRIBUTE_PRIVATE,             "private " },
+       { FIELD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem " },
+       { FIELD_ATTRIBUTE_ASSEMBLY,            "assembly " },
+       { FIELD_ATTRIBUTE_FAMILY,              "family " },
+       { FIELD_ATTRIBUTE_FAM_OR_ASSEM,        "famorassem " },
+       { FIELD_ATTRIBUTE_PUBLIC,              "public " },
+       { 0, NULL }
+};
+
+static map_t field_flags_map [] = {
+       { FIELD_ATTRIBUTE_STATIC,              "static " },
+       { FIELD_ATTRIBUTE_INIT_ONLY,           "initonly " },
+       { FIELD_ATTRIBUTE_LITERAL,             "literal " },
+       { FIELD_ATTRIBUTE_NOT_SERIALIZED,      "notserialized " },
+       { FIELD_ATTRIBUTE_SPECIAL_NAME,        "specialname " },
+       { FIELD_ATTRIBUTE_PINVOKE_IMPL,        "FIXME:pinvokeimpl " },
+       { 0, NULL }
+};
+
+static map_t element_type_map [] = {
+       { ELEMENT_TYPE_END        , "end" },
+       { ELEMENT_TYPE_VOID       , "System.Void" },
+       { ELEMENT_TYPE_BOOLEAN    , "System.Bool" },
+       { ELEMENT_TYPE_CHAR       , "System.Char" }, 
+       { ELEMENT_TYPE_I1         , "System.SByte" },
+       { ELEMENT_TYPE_U1         , "System.Byte" }, 
+       { ELEMENT_TYPE_I2         , "System.Int16" },
+       { ELEMENT_TYPE_U2         , "System.UInt16" },
+       { ELEMENT_TYPE_I4         , "System.Int32" },
+       { ELEMENT_TYPE_U4         , "System.UInt32" },
+       { ELEMENT_TYPE_I8         , "System.Int64" },
+       { ELEMENT_TYPE_U8         , "System.UInt64" },
+       { ELEMENT_TYPE_R4         , "System.Single" },
+       { ELEMENT_TYPE_R8         , "System.Double" },
+       { ELEMENT_TYPE_STRING     , "System.String" },
+       { ELEMENT_TYPE_TYPEDBYREF , "TypedByRef" },
+       { ELEMENT_TYPE_I          , "System.Int32" },
+       { ELEMENT_TYPE_U          , "System.UPtr" },
+       { ELEMENT_TYPE_OBJECT     , "System.Object" },
+       { 0, NULL }
+};
+
+/**
+ * field_flags:
+ *
+ * Returns a stringified version of a Field's flags
+ */
+static char *
+field_flags (guint32 f)
 {
-       fprintf (output, "FIELD_LIST: %d\n", idx);
+       static char buffer [1024];
+       int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
+       
+       buffer [0] = 0;
+
+       strcat (buffer, map (access, access_map));
+       strcat (buffer, flags (f, field_flags_map));
+       return g_strdup (buffer);
 }
 
-static void
-dis_methods (metadata_t *m, guint32 idx)
+/**
+ * get_encoded_value:
+ * @ptr: pointer to decode from
+ * @len: result value is stored here.
+ *
+ * This routine decompresses 32-bit values as specified in the "Blob and
+ * Signature" section (22.2)
+ *
+ * Returns: updated pointer location
+ */
+static const char *
+get_encoded_value (const char *_ptr, guint32 *len)
+{
+       const unsigned char *ptr = (unsigned char *) _ptr;
+       unsigned char b = *ptr;
+       
+       if ((b & 0x80) == 0){
+               *len = b;
+               return ptr+1;
+       } else if ((b & 0x40) == 0){
+               *len = ((b & 0x3f) << 8 | ptr [1]);
+               return ptr + 2;
+       }
+       *len = ((b & 0x1f) << 24) |
+               (ptr [1] << 16) |
+               (ptr [2] << 8) |
+               ptr [3];
+       
+       return ptr + 4;
+}
+
+/**
+ * get_custom_mod:
+ *
+ * Decodes a CustomMod (22.2.7)
+ *
+ * Returns: updated pointer location
+ */
+static const char *
+get_custom_mod (const char *ptr, char **return_value)
+{
+       if ((*ptr == ELEMENT_TYPE_CMOD_OPT) ||
+           (*ptr == ELEMENT_TYPE_CMOD_REQD)){
+               fprintf (stderr, "FIXME: still do not support CustomMods (22.2.7)");
+               exit (1);
+       }
+       *return_value = NULL;
+       return ptr;
+}
+
+static char *
+get_typedef (metadata_t *m, int idx)
+{
+       guint32 cols [6];
+
+       expand (&m->tables [META_TABLE_TYPEDEF], idx - 1, cols, CSIZE (cols));
+
+       return g_strdup_printf (
+               "%s.%s",
+               mono_metadata_string_heap (m, cols [2]),
+               mono_metadata_string_heap (m, cols [1]));
+}
+
+static char *
+get_module (metadata_t *m, int idx)
+{
+       guint32 cols [9];
+
+/*     g_assert (idx <= m->tables [META_TABLE_MODULE].rows); */
+           
+/*     return g_strdup_printf ("IDX=0x%x", idx); */
+       expand (&m->tables [META_TABLE_ASSEMBLYREF], 0, cols, CSIZE (cols));
+
+       return g_strdup (mono_metadata_string_heap (m, cols [6]));
+}
+
+static char *
+get_typeref (metadata_t *m, int idx)
+{
+       guint32 cols [3];
+       const char *s, *t;
+       char *x, *ret;
+       guint32 rs_idx, table;
+       
+       expand (&m->tables [META_TABLE_TYPEREF], idx - 1, cols, CSIZE (cols));
+
+       t = mono_metadata_string_heap (m, cols [1]);
+       s = mono_metadata_string_heap (m, cols [2]);
+       rs_idx = cols [0] >> 3;
+       table = cols [0] & 7;
+       printf ("------------ %d %d --------\n", rs_idx, table);
+               
+       switch (table){
+       case 0: /* Module */
+               x = get_module (m, rs_idx);
+               ret = g_strdup_printf ("[%08x:%s] %s.%s", cols [0], x, s, t);
+               g_free (x);
+               break;
+
+       case 1: /* ModuleRef */
+               ret = g_strdup_printf ("TypeRef: ModuleRef (%s.%s)", s, t);
+               
+       case 3: /* AssemblyRef */
+               ret = g_strdup_printf ("TypeRef: AssemblyRef (%s.%s)", s, t);
+               
+       case 4: /* TypeRef */
+               ret =  g_strdup_printf ("TypeRef: TYPEREF! (%s.%s)", s, t);
+
+       default:
+               ret = g_strdup ("ERROR");
+       }
+
+       return ret;
+}
+
+static char *
+typedef_or_ref (metadata_t *m, guint32 dor_token)
+{
+       int table = dor_token & 0x03;
+       int idx = dor_token >> 2;
+       char *s, *temp = NULL;
+               
+       switch (table){
+       case 0: /* TypeDef */
+               temp = get_typedef (m, idx);
+               s = g_strdup_printf ("%s", temp);
+               break;
+               
+       case 1: /* TypeRef */
+               temp = get_typeref (m, idx);
+               s = g_strdup_printf ("/* 0x%08x */ %s", dor_token, temp);
+               break;
+               
+       case 2: /* TypeSpec */
+               s = g_strdup_printf ("TypeSpec: 0x%08x", dor_token);
+               break;
+               
+       }
+
+       if (temp)
+               g_free (temp);
+
+       return s;
+}
+
+/** 
+ * get_encoded_typedef_or_ref:
+ * @m: metadata context 
+ * @ptr: location to decode from.
+ * @result: pointer to string where resulting decoded string is stored
+ *
+ * result will point to a g_malloc()ed string.
+ *
+ * Returns: the new ptr to continue decoding
+ */
+static const char *
+get_encoded_typedef_or_ref (metadata_t *m, const char *ptr, char **result)
+{
+       guint32 token;
+       
+       ptr = get_encoded_value (ptr, &token);
+
+       *result = typedef_or_ref (m, token);
+
+       return ptr;
+}
+
+/**
+ * methoddefref_signature:
+ * @m: metadata context 
+ * @ptr: location to decode from.
+ * @result: pointer to string where resulting decoded string is stored
+ *
+ * This routine decodes into a string a MethodDef or a MethodRef.
+ *
+ * result will point to a g_malloc()ed string.
+ *
+ * Returns: the new ptr to continue decoding
+ */
+static const char *
+methoddefref_signature (metadata_t *m, const char *ptr, char **result)
 {
+       *result = g_strdup ("method-def-or-ref");
+       
+       return ptr;
+}
+
+/**
+ * get_type:
+ * @m: metadata context 
+ * @ptr: location to decode from.
+ * @result: pointer to string where resulting decoded string is stored
+ *
+ * This routine returs in @result the stringified type pointed by @ptr.
+ *
+ * Returns: the new ptr to continue decoding
+ */
+static const char *
+get_type (metadata_t *m, const char *ptr, char **result)
+{
+       char c;
+       
+       c = *ptr++;
+       
+       switch (c){
+       case ELEMENT_TYPE_BOOLEAN:
+       case ELEMENT_TYPE_CHAR:
+       case ELEMENT_TYPE_I1:
+       case ELEMENT_TYPE_U1:
+       case ELEMENT_TYPE_I2:
+       case ELEMENT_TYPE_U2:
+       case ELEMENT_TYPE_I4:
+       case ELEMENT_TYPE_U4:
+       case ELEMENT_TYPE_I8:
+       case ELEMENT_TYPE_U8:
+       case ELEMENT_TYPE_R4:
+       case ELEMENT_TYPE_R8:
+       case ELEMENT_TYPE_I:
+       case ELEMENT_TYPE_STRING:
+       case ELEMENT_TYPE_OBJECT:
+               *result = g_strdup (map (c, element_type_map));
+               break;
+               
+       case ELEMENT_TYPE_VALUETYPE:
+       case ELEMENT_TYPE_CLASS:
+               ptr = get_encoded_typedef_or_ref (m, ptr, result);
+               break;
+               
+       case ELEMENT_TYPE_FNPTR:
+               ptr = methoddefref_signature (m, ptr, result);
+               break;
+               
+       case ELEMENT_TYPE_ARRAY:
+               *result = g_strdup ("ARRAY:TODO");
+               break;
+               
+       case ELEMENT_TYPE_SZARRAY:
+               *result = g_strdup ("SZARRAY:TODO");
+       }
+       
+       return ptr;
+}
+
+/**
+ * 
+ * Returns a stringified representation of a FieldSig (22.2.4)
+ */
+static char *
+field_signature (metadata_t *m, guint32 blob_signature)
+{
+       char *allocated_modifier_string, *allocated_type_string;
+       const char *ptr = mono_metadata_blob_heap (m, blob_signature);
+       const char *base;
+       int len;
+       static char buffer [8192];
+       
+       ptr = get_encoded_value (ptr, &len);
+       base = ptr;
+       /* FIELD is 0x06 */
+       g_assert (*ptr == 0x06);
+       hex_dump (ptr, 0, len);
+       ptr++; len--;
+       
+       ptr = get_custom_mod (ptr, &allocated_modifier_string);
+       ptr = get_type (m, ptr, &allocated_type_string);
+       
+       sprintf (buffer, "LEN=%d::::   ", len);
+       strcat (buffer, allocated_type_string);
+       
+       if (allocated_modifier_string)
+               g_free (allocated_modifier_string);
+       if (allocated_type_string)
+               g_free (allocated_modifier_string);
+       
+       return g_strdup (buffer);
 }
 
+/**
+ * decode_literal:
+ * @m: metadata context
+ * @token: token to decode
+ *
+ * decodes the literal indexed by @token.
+ */
 static char *
-typedef_or_ref (guint32 index)
+decode_literal (metadata_t *m, guint32 token)
 {
-       return "";
+       return g_strdup ("LITERAL_VALUE");
 }
-              
+
+/**
+ * dis_field_list:
+ * @m: metadata context
+ * @start: starting index into the Field Table.
+ * @end: ending index into Field table.
+ *
+ * This routine displays all the decoded fields from @start to @end
+ */
 static void
-dis_type (metadata_t *m, metadata_tableinfo_t *t, int n)
+dis_field_list (metadata_t *m, guint32 start, guint32 end)
 {
+       metadata_tableinfo_t *t = &m->tables [META_TABLE_FIELD];
+       guint32 cols [3];
+       int i;
+
+       if (end > t->rows + 1){
+               fprintf (output, "ERROR index out of range in fields");
+               exit (1);
+       }
+                       
+       for (i = start; i < end; i++){
+               char *sig, *flags;
+               
+               expand (t, i, cols, CSIZE (cols));
+               sig = field_signature (m, cols [2]);
+               flags = field_flags (cols [0]);
+               
+               if (cols [0] & FIELD_ATTRIBUTE_LITERAL){
+                       char *lit = decode_literal (m, cols [2]);
+                       
+                       fprintf (output, "    .field %s %s %s = ",
+                                flags, sig,
+                                mono_metadata_string_heap (m, cols [1]));
+                       fprintf (output, "%s\n", lit);
+                       g_free (lit);
+               } else 
+                       fprintf (output, "    .field %s %s %s\n",
+                                flags, sig,
+                                mono_metadata_string_heap (m, cols [1]));
+               g_free (flags);
+               g_free (sig);
+       }
+}
+
+/**
+ * dis_field_list:
+ * @m: metadata context
+ * @start: starting index into the Method Table.
+ * @end: ending index into Method table.
+ *
+ * This routine displays the methods in the Method Table from @start to @end
+ */
+static void
+dis_method_list (metadata_t *m, guint32 start, guint32 end)
+{
+}
+
+/**
+ * dis_type:
+ * @m: metadata context
+ * @n: index of type to disassemble
+ *
+ * Disassembles the type whose index in the TypeDef table is @n.
+ */
+static void
+dis_type (metadata_t *m, int n)
+{
+       metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
        guint32 cols [6];
+       guint32 cols_next [6];
        const char *name;
        char *tn;
        
        expand (t, n, cols, CSIZE (cols));
+       expand (t, n + 1, cols_next, CSIZE (cols_next));
 
        name = mono_metadata_string_heap (m, cols [1]);
 
@@ -220,24 +608,43 @@ dis_type (metadata_t *m, metadata_tableinfo_t *t, int n)
                tn = "interface";
        
        fprintf (output, "  .%s %s%s\n", tn, typedef_flags (cols [0]), name);
-       fprintf (output, "  \textends %s\n", typedef_or_ref (cols [3]));
+       fprintf (output, "  \textends %s\n", typedef_or_ref (m, cols [3]));
        fprintf (output, "  {\n");
-       dis_fields (m, cols [4]);
-       dis_methods (m, cols [5]);
+
+       /*
+        * The value in the table is always valid, we know we have fields
+        * if the value stored is different than the next record.
+        */
+       if (cols [4] != cols_next [4])
+               dis_field_list (m, cols [4] - 1, cols_next [4] - 1);
+       if (cols [4] != cols_next [5])
+               dis_method_list (m, cols [5], cols_next [5]);
+
        fprintf (output, "  }\n");
 }
 
+/**
+ * dis_types:
+ * @m: metadata context
+ *
+ * disassembles all types in the @m context
+ */
 static void
 dis_types (metadata_t *m)
 {
        metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
        int i;
 
-       for (i = 0; i < t->rows; i++){
-               dis_type (m, t, i);
-       }
+       for (i = 0; i < t->rows; i++)
+               dis_type (m, i);
 }
 
+/**
+ * disassemble_file:
+ * @file: file containing CIL code.
+ *
+ * Disassembles the @file file.
+ */
 static void
 disassemble_file (const char *file)
 {
index d733e5f5bd891d08ebf05060cbc902f7524081e8..658133e7e2aad05d81e465d77e6600080ca2d54b 100644 (file)
@@ -1,3 +1,7 @@
+2001-06-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * typeattr.h: New file, TypeAttribute flags. 
+
 2001-06-21  Miguel de Icaza  <miguel@ximian.com>
 
        * mono/metadata/assembly.c (mono_assembly_ensure_section_idx,
index b40e781f9a37eff62f90838c7da73410772b91d6..a792d1a1286019dbecfe19bdddc1f7e390a658fd 100644 (file)
@@ -8,7 +8,9 @@ libmetadata_a_SOURCES = \
        assembly.h      \
        assembly.c      \
        cil-coff.h      \
+       eltype.h        \
        endian.h        \
+       fieldattr.h     \
        metadata.c      \
        metadata.h      \
        rawbuffer.c     \
diff --git a/mono/metadata/eltype.h b/mono/metadata/eltype.h
new file mode 100644 (file)
index 0000000..1a95c32
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _MONO_METADATA_ELTYPE_H_
+#define _MONO_METADATA_ELTYPE_H_
+
+typedef enum {
+       ELEMENT_TYPE_END        = 0x00,       /* End of List */
+       ELEMENT_TYPE_VOID       = 0x01,
+       ELEMENT_TYPE_BOOLEAN    = 0x02,
+       ELEMENT_TYPE_CHAR       = 0x03,
+       ELEMENT_TYPE_I1         = 0x04,
+       ELEMENT_TYPE_U1         = 0x05,
+       ELEMENT_TYPE_I2         = 0x06,
+       ELEMENT_TYPE_U2         = 0x07,
+       ELEMENT_TYPE_I4         = 0x08,
+       ELEMENT_TYPE_U4         = 0x09,
+       ELEMENT_TYPE_I8         = 0x0a,
+       ELEMENT_TYPE_U8         = 0x0b,
+       ELEMENT_TYPE_R4         = 0x0c,
+       ELEMENT_TYPE_R8         = 0x0d,
+       ELEMENT_TYPE_STRING     = 0x0e,
+       ELEMENT_TYPE_PTR        = 0x0f,       /* arg: <type> token */
+       ELEMENT_TYPE_BYREF      = 0x10,       /* arg: <type> token */
+       ELEMENT_TYPE_VALUETYPE  = 0x11,       /* arg: <type> token */
+       ELEMENT_TYPE_CLASS      = 0x12,       /* arg: <type> token */
+       ELEMENT_TYPE_ARRAY      = 0x14,       /* type, rank, boundsCount, bound1, loCount, lo1 */
+       ELEMENT_TYPE_TYPEDBYREF = 0x15,
+       ELEMENT_TYPE_I          = 0x18,
+       ELEMENT_TYPE_U          = 0x19,
+       ELEMENT_TYPE_FNPTR      = 0x1b,       /* arg: full method signature */
+       ELEMENT_TYPE_OBJECT     = 0x1c,
+       ELEMENT_TYPE_SZARRAY    = 0x1d,       /* 0-based one-dim-array */
+       ELEMENT_TYPE_CMOD_REQD  = 0x1f,       /* arg: typedef or typeref token */
+       ELEMENT_TYPE_CMOD_OPT   = 0x20,       /* optional arg: typedef or typref token */
+       ELEMENT_TYPE_INTERNAL   = 0x21,       /* CLR internal type */
+
+       ELEMENT_TYPE_MODIFIER   = 0x40,       /* Or with the following types */
+       ELEMENT_TYPE_SENTINEL   = 0x41,       /* Sentinel for varargs method signature */
+       ELEMENT_TYPE_PINNED     = 0x45,       /* Local var that points to pinned object */
+} ElementTypeEnum;
+
+#endif /* _MONO_METADATA_ELTYPE_H_ */
diff --git a/mono/metadata/fieldattr.h b/mono/metadata/fieldattr.h
new file mode 100644 (file)
index 0000000..8b2e50e
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _MONO_METADATA_FIELDATTR_H_
+#define _MONO_METADATA_FIELDATTR_H_
+/*
+ * Flags for bitmasks in the metadata tables
+ */
+
+/*
+ * Field Attributes (21.1.5).
+ */
+
+#define FIELD_ATTRIBUTE_FIELD_ACCESS_MASK     0x0007
+#define FIELD_ATTRIBUTE_COMPILER_CONTROLLED   0x0000
+#define FIELD_ATTRIBUTE_PRIVATE               0x0001
+#define FIELD_ATTRIBUTE_FAM_AND_ASSEM         0x0002
+#define FIELD_ATTRIBUTE_ASSEMBLY              0x0003
+#define FIELD_ATTRIBUTE_FAMILY                0x0004
+#define FIELD_ATTRIBUTE_FAM_OR_ASSEM          0x0005
+#define FIELD_ATTRIBUTE_PUBLIC                0x0006
+
+#define FIELD_ATTRIBUTE_STATIC                0x0010
+#define FIELD_ATTRIBUTE_INIT_ONLY             0x0020
+#define FIELD_ATTRIBUTE_LITERAL               0x0040
+#define FIELD_ATTRIBUTE_NOT_SERIALIZED        0x0080
+#define FIELD_ATTRIBUTE_SPECIAL_NAME          0x0200
+#define FIELD_ATTRIBUTE_PINVOKE_IMPL          0x2000
+
+/* For runtime use only */
+#define FIELD_ATTRIBUTE_RESERVED_MASK         0x9500
+#define FIELD_ATTRIBUTE_RT_SPECIAL_NAME       0x0400
+#define FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL     0x1000
+#define FIELD_ATTRIBUTE_HAS_DEFAULT           0x8000
+#define FIELD_ATTRIBUTE_HAS_FIELD_RVA         0x0100
+
+#endif
index 9427b87065b01588f885b5407a85f79b092cc80b..9943f4cdbe7a67931ec833ce88669419c3b20baf 100644 (file)
@@ -604,3 +604,11 @@ mono_metadata_string_heap (metadata_t *meta, guint32 index)
 {
        return meta->raw_metadata + meta->heap_strings.sh_offset + index;
 }
+
+
+const char *
+mono_metadata_blob_heap (metadata_t *meta, guint32 index)
+{
+       return meta->raw_metadata + meta->heap_blob.sh_offset + index;
+}
+
index 1fbb662bc2e269c425c0b5606185b8c569bfb213..af754f0054a1a41c1938ec843907a0301c4f6cd1 100644 (file)
@@ -171,3 +171,4 @@ char          *mono_metadata_locate       (metadata_t *meta, int table, int idx)
 char          *mono_metadata_locate_token (metadata_t *meta, guint32 token);
 
 const char    *mono_metadata_string_heap  (metadata_t *meta, guint32 index);
+const char    *mono_metadata_blob_heap    (metadata_t *meta, guint32 index);