* main.c (dump_cattrs_list): Newly carved out of dump_cattrs.
[mono.git] / mono / dis / main.c
index 08753d3e329ba79d3e3701507c37396b307935f5..090921b2085b0d30f2ce89e80236634f198b8dfd 100644 (file)
 #include <string.h>
 #include <glib.h>
 #include <stdlib.h>
+#include <errno.h>
 #include "meta.h"
 #include "util.h"
 #include "dump.h"
 #include "get.h"
 #include "dis-cil.h"
+#include <mono/metadata/loader.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/appdomain.h>
 
 FILE *output;
 
 /* True if you want to get a dump of the header data */
 gboolean dump_header_data_p = FALSE;
 
+gboolean substitute_with_mscorlib_p = FALSE;
+
 int dump_table = -1;
 
 static void
@@ -42,7 +48,29 @@ dump_header_data (MonoImage *img)
 }
 
 static void
-dis_directive_assembly (MonoMetadata *m)
+dump_cattrs (MonoImage *m, guint32 token, const char *indent)
+{
+       GList *list;
+
+       list = dis_get_custom_attrs (m, token);
+       dump_cattrs_list (list, indent);
+}
+
+static void
+dump_cattrs_list (GList *list,  const char *indent)
+{
+       GList *tmp;
+
+       for (tmp = list; tmp; tmp = tmp->next) {
+               fprintf (output, "%s%s\n", indent, (char*)tmp->data);
+               g_free (tmp->data);
+       }
+       g_list_free (list);
+}
+
+
+static void
+dis_directive_assembly (MonoImage *m)
 {
        MonoTableInfo *t  = &m->tables [MONO_TABLE_ASSEMBLY];
        guint32 cols [MONO_ASSEMBLY_SIZE];
@@ -52,27 +80,29 @@ dis_directive_assembly (MonoMetadata *m)
 
        mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
        
+       fprintf (output, ".assembly '%s'\n{\n",
+                mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]));
+       dump_cattrs (m, MONO_TOKEN_ASSEMBLY | 1, "  ");
        fprintf (output,
-                ".assembly %s\n"
-                "{\n"
                 "  .hash algorithm 0x%08x\n"
-                "  .ver  %d.%d.%d.%d"
-                "%s %s"
-                "%s"
-                "\n"
-                "}\n",
-                mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]),
+                "  .ver  %d:%d:%d:%d\n",
                 cols [MONO_ASSEMBLY_HASH_ALG],
                 cols [MONO_ASSEMBLY_MAJOR_VERSION], cols [MONO_ASSEMBLY_MINOR_VERSION], 
-                cols [MONO_ASSEMBLY_BUILD_NUMBER], cols [MONO_ASSEMBLY_REV_NUMBER],
-                cols [MONO_ASSEMBLY_CULTURE] ? "\n  .locale" : "",
-                cols [MONO_ASSEMBLY_CULTURE] ? mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_CULTURE]) : "",
-                cols [MONO_ASSEMBLY_PUBLIC_KEY] ? "\n  .publickey" : ""
-               );
+                cols [MONO_ASSEMBLY_BUILD_NUMBER], cols [MONO_ASSEMBLY_REV_NUMBER]);
+       if (cols [MONO_ASSEMBLY_CULTURE])
+               fprintf (output, "  .locale %s\n", mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_CULTURE]));
+       if (cols [MONO_ASSEMBLY_PUBLIC_KEY]) {
+               const char* b = mono_metadata_blob_heap (m, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
+               int len = mono_metadata_decode_blob_size (b, &b);
+               char *dump = data_dump (b, len, "\t\t");
+               fprintf (output, "  .publickey =%s", dump);
+               g_free (dump);
+       }
+       fprintf (output, "}\n");
 }
 
 static void
-dis_directive_assemblyref (MonoMetadata *m)
+dis_directive_assemblyref (MonoImage *m)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_ASSEMBLYREF];
        guint32 cols [MONO_ASSEMBLYREF_SIZE];
@@ -87,7 +117,7 @@ dis_directive_assemblyref (MonoMetadata *m)
                fprintf (output,
                         ".assembly extern %s\n"
                         "{\n"
-                        "  .ver %d.%d.%d.%d\n"
+                        "  .ver %d:%d:%d:%d\n"
                         "}\n",
                         mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]),
                         cols [MONO_ASSEMBLYREF_MAJOR_VERSION], cols [MONO_ASSEMBLYREF_MINOR_VERSION], 
@@ -96,26 +126,100 @@ dis_directive_assemblyref (MonoMetadata *m)
        }
 }
 
-static map_t visibility_map [] = {
+static void
+dis_directive_module (MonoImage *m)
+{
+       MonoTableInfo *t = &m->tables [MONO_TABLE_MODULE];
+       int i;
+
+       for (i = 0; i < t->rows; i++){
+               guint32 cols [MONO_MODULE_SIZE];
+               const char *name;
+               char *guid, *ename;
+               
+               mono_metadata_decode_row (t, i, cols, MONO_MODULE_SIZE);
+
+               name = mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]);
+               ename = get_escaped_name (name);
+               guid = get_guid (m, cols [MONO_MODULE_MVID]);
+               fprintf (output, ".module %s // GUID = %s\n\n", ename, guid);
+               g_free (ename);
+
+               dump_cattrs (m, MONO_TOKEN_MODULE | (i + 1), "");
+       }
+}
+
+static void
+dis_directive_moduleref (MonoImage *m)
+{
+       MonoTableInfo *t = &m->tables [MONO_TABLE_MODULEREF];
+       int i;
+
+       for (i = 0; i < t->rows; i++){
+               guint32 cols [MONO_MODULEREF_SIZE];
+               const char *name;
+               
+               mono_metadata_decode_row (t, i, cols, MONO_MODULEREF_SIZE);
+
+               name = mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]);
+               fprintf (output, ".module extern %s\n", name);
+       }
+       
+}
+
+static void
+dis_directive_file (MonoImage *m)
+{
+       MonoTableInfo *t = &m->tables [MONO_TABLE_FILE];
+       int i, j, len;
+       guint32 entry_point;
+
+       entry_point = mono_image_get_entry_point (m);
+
+       for (i = 0; i < t->rows; i++){
+               guint32 cols [MONO_FILE_SIZE];
+               const char *name, *hash;
+               guint32 token;
+
+               mono_metadata_decode_row (t, i, cols, MONO_FILE_SIZE);
+
+               name = mono_metadata_string_heap (m, cols [MONO_FILE_NAME]);
+
+               hash = mono_metadata_blob_heap (m, cols [MONO_FILE_HASH_VALUE]);
+               len = mono_metadata_decode_blob_size (hash, &hash);
+
+               fprintf (output, ".file %s%s .hash = (", name,
+                               cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA ? " nometadata" : "");
+
+               for (j = 0; j < len; ++j)
+                       fprintf (output, " %02X", hash [j] & 0xff);
+
+               token = mono_metadata_make_token (MONO_TABLE_FILE, i + 1);
+               fprintf (output, " )%s\n", (token == entry_point) ? " .entrypoint" : "");
+       }
+       
+}
+
+static dis_map_t visibility_map [] = {
        { TYPE_ATTRIBUTE_NOT_PUBLIC,           "private " },
        { TYPE_ATTRIBUTE_PUBLIC,               "public " },
-       { TYPE_ATTRIBUTE_NESTED_PUBLIC,        "nested-public " },
-       { TYPE_ATTRIBUTE_NESTED_PRIVATE,       "nested-private " },
-       { TYPE_ATTRIBUTE_NESTED_FAMILY,        "family " },
-       { TYPE_ATTRIBUTE_NESTED_ASSEMBLY,      "nested-assembly" },
-       { TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM, "nested-fam-and-assembly" },
-       { TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM,  "nested-fam-or-assembly" },
+       { TYPE_ATTRIBUTE_NESTED_PUBLIC,        "nested public " },
+       { TYPE_ATTRIBUTE_NESTED_PRIVATE,       "nested private " },
+       { TYPE_ATTRIBUTE_NESTED_FAMILY,        "nested family " },
+       { TYPE_ATTRIBUTE_NESTED_ASSEMBLY,      "nested assembly " },
+       { TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM, "nested famandassem " },
+       { TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM,  "nested famorassem " },
        { 0, NULL }
 };
 
-static map_t layout_map [] = {
+static dis_map_t layout_map [] = {
        { TYPE_ATTRIBUTE_AUTO_LAYOUT,          "auto " },
        { TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT,    "sequential " },
        { TYPE_ATTRIBUTE_EXPLICIT_LAYOUT,      "explicit " },
        { 0, NULL }
 };
 
-static map_t format_map [] = {
+static dis_map_t format_map [] = {
        { TYPE_ATTRIBUTE_ANSI_CLASS,           "ansi " },
        { TYPE_ATTRIBUTE_UNICODE_CLASS,        "unicode " },
        { TYPE_ATTRIBUTE_AUTO_CLASS,           "auto " },
@@ -161,10 +265,13 @@ typedef_flags (guint32 flags)
  * This routine displays all the decoded fields from @start to @end
  */
 static void
-dis_field_list (MonoMetadata *m, guint32 start, guint32 end)
+dis_field_list (MonoImage *m, guint32 start, guint32 end)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
        guint32 cols [MONO_FIELD_SIZE];
+       char *esname;
+       char rva_desc [32];
+       guint32 rva;
        int i;
 
        if (end > t->rows + 1) {
@@ -173,38 +280,56 @@ dis_field_list (MonoMetadata *m, guint32 start, guint32 end)
        }
                        
        for (i = start; i < end; i++){
-               char *sig, *flags;
+               char *sig, *flags, *attrs = NULL;
+               guint32 field_offset = -1;
                
                mono_metadata_decode_row (t, i, cols, MONO_FIELD_SIZE);
                sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
                flags = field_flags (cols [MONO_FIELD_FLAGS]);
+
+               if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
+                       mono_metadata_field_info (m, i, NULL, &rva, NULL);
+                       g_snprintf (rva_desc, sizeof (rva_desc), " at D_%08x", rva);
+               } else {
+                       rva_desc [0] = 0;
+               }
                
+               mono_metadata_field_info (m, i, &field_offset, NULL, NULL);
+               if (field_offset != -1)
+                       attrs = g_strdup_printf ("[%d]", field_offset);
+               esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
                if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_LITERAL){
-                       MonoTypeEnum type;
                        char *lit;
+                       guint32 const_cols [MONO_CONSTANT_SIZE];
+                       guint32 crow;
+                       
+                       if ((crow = mono_metadata_get_constant_index (m, MONO_TOKEN_FIELD_DEF | (i+1), 0))) {
+                               mono_metadata_decode_row (&m->tables [MONO_TABLE_CONSTANT], crow-1, const_cols, MONO_CONSTANT_SIZE);
+                               lit = get_constant (m, const_cols [MONO_CONSTANT_TYPE], const_cols [MONO_CONSTANT_VALUE]);
+                       } else {
+                               lit = g_strdup ("not found");
+                       }
                        
-                       type = get_field_literal_type (m, cols [MONO_FIELD_SIGNATURE]);
-                       lit = g_strdup ("FIXME:Do-not-know-how-to-get-this-from-the-constants-table");
-                       /* get_constant (m, type, cols [2]); */
                        
                        fprintf (output, "    .field %s %s %s = ",
-                                flags, sig,
-                                mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
+                                flags, sig, esname);
                        fprintf (output, "%s\n", lit);
                        g_free (lit);
-               } else 
-                       fprintf (output, "    .field %s %s %s\n",
-                                flags, sig,
-                                mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
+               } else
+                       fprintf (output, "    .field %s %s %s %s%s\n",
+                                attrs? attrs: "", flags, sig, esname, rva_desc);
+               g_free (attrs);
                g_free (flags);
                g_free (sig);
+               g_free (esname);
+               dump_cattrs (m, MONO_TOKEN_FIELD_DEF | (i + 1), "    ");
        }
 }
 
-static map_t method_access_map [] = {
+static dis_map_t method_access_map [] = {
        { METHOD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
-       { METHOD_ATTRIBUTE_PRIVATE,             "private" },
-       { METHOD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem" },
+       { METHOD_ATTRIBUTE_PRIVATE,             "private " },
+       { METHOD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem " },
        { METHOD_ATTRIBUTE_ASSEM,               "assembly " },
        { METHOD_ATTRIBUTE_FAMILY,              "family " },
        { METHOD_ATTRIBUTE_FAM_OR_ASSEM,        "famorassem " },
@@ -212,7 +337,7 @@ static map_t method_access_map [] = {
        { 0, NULL }
 };
 
-static map_t method_flags_map [] = {
+static dis_map_t method_flags_map [] = {
        { METHOD_ATTRIBUTE_STATIC,              "static " },
        { METHOD_ATTRIBUTE_FINAL,               "final " },
        { METHOD_ATTRIBUTE_VIRTUAL,             "virtual " },
@@ -249,13 +374,13 @@ method_flags (guint32 f)
        return s;
 }
 
-static map_t pinvoke_flags_map [] = {
+static dis_map_t pinvoke_flags_map [] = {
        { PINVOKE_ATTRIBUTE_NO_MANGLE ,            "nomangle " },
        { PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR,   "lasterr " },
        { 0, NULL }
 };
 
-static map_t pinvoke_call_conv_map [] = {
+static dis_map_t pinvoke_call_conv_map [] = {
        { PINVOKE_ATTRIBUTE_CALL_CONV_WINAPI,      "winapi " },
        { PINVOKE_ATTRIBUTE_CALL_CONV_CDECL,       "cdecl " },
        { PINVOKE_ATTRIBUTE_CALL_CONV_STDCALL,     "stdcall " },
@@ -264,7 +389,7 @@ static map_t pinvoke_call_conv_map [] = {
        { 0, NULL }
 };
 
-static map_t pinvoke_char_set_map [] = {
+static dis_map_t pinvoke_char_set_map [] = {
        { PINVOKE_ATTRIBUTE_CHAR_SET_NOT_SPEC,     "" },
        { PINVOKE_ATTRIBUTE_CHAR_SET_ANSI,         "ansi " },
        { PINVOKE_ATTRIBUTE_CHAR_SET_UNICODE ,     "unicode " },
@@ -295,7 +420,7 @@ pinvoke_flags (guint32 f)
        return s;
 }
 
-static map_t method_impl_map [] = {
+static dis_map_t method_impl_map [] = {
        { METHOD_IMPL_ATTRIBUTE_IL,              "cil " },
        { METHOD_IMPL_ATTRIBUTE_NATIVE,          "native " },
        { METHOD_IMPL_ATTRIBUTE_OPTIL,           "optil " },
@@ -303,13 +428,13 @@ static map_t method_impl_map [] = {
        { 0, NULL }
 };
 
-static map_t managed_type_map [] = {
+static dis_map_t managed_type_map [] = {
        { METHOD_IMPL_ATTRIBUTE_UNMANAGED,       "unmanaged " },
        { METHOD_IMPL_ATTRIBUTE_MANAGED,         "managed " },
        { 0, NULL }
 };
 
-static map_t managed_impl_flags [] = {
+static dis_map_t managed_impl_flags [] = {
        { METHOD_IMPL_ATTRIBUTE_FORWARD_REF,     "fwdref " },
        { METHOD_IMPL_ATTRIBUTE_PRESERVE_SIG,    "preservesig " },
        { METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL,   "internalcall " },
@@ -336,45 +461,79 @@ method_impl_flags (guint32 f)
 }
 
 static void
-dis_locals (MonoMetadata *m, MonoMethodHeader *mh
+dis_locals (MonoImage *m, MonoMethodHeader *mh, const char *ptr
 {
        int i;
 
-       fprintf(output, "\t.locals %s(\n", mh->init_locals ? "init " : "");
+       if (show_tokens) {
+               unsigned char flags = *(const unsigned char *) ptr;
+               unsigned char format = flags & METHOD_HEADER_FORMAT_MASK;
+               guint16 fat_flags;
+               guint32 local_var_sig_tok, max_stack, code_size, init_locals;
+               int hsize;
+
+               g_assert (format == METHOD_HEADER_FAT_FORMAT);
+               fat_flags = read16 (ptr);
+               ptr += 2;
+               hsize = (fat_flags >> 12) & 0xf;
+               max_stack = read16 (ptr);
+               ptr += 2;
+               code_size = read32 (ptr);
+               ptr += 4;
+               local_var_sig_tok = read32 (ptr);
+               ptr += 4;
+
+               if (fat_flags & METHOD_HEADER_INIT_LOCALS)
+                       init_locals = 1;
+               else
+                       init_locals = 0;
+
+               fprintf(output, "\t.locals /*%08x*/ %s(\n",
+                       local_var_sig_tok, init_locals ? "init " : "");
+       } else
+               fprintf(output, "\t.locals %s(\n", mh->init_locals ? "init " : "");
+
        for (i=0; i < mh->num_locals; ++i) {
                char * desc;
+               if (i)
+                       fprintf(output, ",\n");
                /* print also byref and pinned attributes */
                desc = dis_stringify_type (m, mh->locals[i]);
-               fprintf(output, "\t\t%s\tV_%d\n", desc, i);
+               fprintf(output, "\t\t%s\tV_%d", desc, i);
                g_free(desc);
        }
-       fprintf(output, "\t)\n");
+       fprintf(output, ")\n");
 }
 
 static void
-dis_code (MonoMetadata *m, guint32 rva)
+dis_code (MonoImage *m, guint32 token, guint32 rva)
 {
        MonoMethodHeader *mh;
-       MonoCLIImageInfo *ii = m->image_info;
-       const char *ptr = mono_cli_rva_map (ii, rva);
-       char *loc;
+       const char *ptr = mono_image_rva_map (m, rva);
+       const char *loc;
+       gchar *override;
+       guint32 entry_point;
 
        if (rva == 0)
                return;
 
+       override = get_method_override (m, token);
+       if (override) {
+               fprintf (output, "\t.override method %s\n", override);
+               g_free (override);
+       }
+
        mh = mono_metadata_parse_mh (m, ptr);
-       if (ii->cli_cli_header.ch_entry_point){
-               loc = mono_metadata_locate_token (m, ii->cli_cli_header.ch_entry_point);
+       if ((entry_point = mono_image_get_entry_point (m))){
+               loc = mono_metadata_locate_token (m, entry_point);
                if (rva == read32 (loc))
                        fprintf (output, "\t.entrypoint\n");
        }
        
+       fprintf (output, "\t// Code size %d (0x%x)\n", mh->code_size, mh->code_size);
        fprintf (output, "\t.maxstack %d\n", mh->max_stack);
-       fprintf (output, "\t// Code size=%d (0x%x)\n", mh->code_size, mh->code_size);
-       printf ("\t// Values Code Size=%d/0x%x\n\n",
-               mh->code_size, mh->code_size);
        if (mh->num_locals)
-               dis_locals (m, mh);
+               dis_locals (m, mh, ptr);
        dissasemble_cil (m, mh);
        
 /*
@@ -386,7 +545,7 @@ dis_code (MonoMetadata *m, guint32 rva)
 }
 
 static char *
-pinvoke_info (MonoMetadata *m, guint32 mindex)
+pinvoke_info (MonoImage *m, guint32 mindex)
 {
        MonoTableInfo *im = &m->tables [MONO_TABLE_IMPLMAP];
        MonoTableInfo *mr = &m->tables [MONO_TABLE_MODULEREF];
@@ -411,7 +570,7 @@ pinvoke_info (MonoMetadata *m, guint32 mindex)
 
                        scope = mono_metadata_string_heap (m, mr_cols [MONO_MODULEREF_NAME]);
                                
-                       return g_strdup_printf ("(%s as %s %s)", scope, import,
+                       return g_strdup_printf ("(\"%s\" as \"%s\" %s)", scope, import,
                                                flags);
                        g_free (flags);
                }
@@ -420,6 +579,49 @@ pinvoke_info (MonoMetadata *m, guint32 mindex)
        return NULL;
 }
 
+static void
+dump_cattrs_for_method_params (MonoImage *m, guint32 midx, MonoMethodSignature *sig) {
+       MonoTableInfo *methodt;
+       MonoTableInfo *paramt;
+       guint param_index, lastp, i;
+
+       methodt = &m->tables [MONO_TABLE_METHOD];
+       paramt = &m->tables [MONO_TABLE_PARAM];
+       param_index = mono_metadata_decode_row_col (methodt, midx, MONO_METHOD_PARAMLIST);
+       if (midx + 1 < methodt->rows)
+               lastp = mono_metadata_decode_row_col (methodt, midx + 1, MONO_METHOD_PARAMLIST);
+       else
+               lastp = paramt->rows + 1;
+       for (i = param_index; i < lastp; ++i) {
+               char *lit;
+               int crow;
+               guint32 param_cols [MONO_PARAM_SIZE];
+               GList *list;
+               
+               list = dis_get_custom_attrs (m, MONO_TOKEN_PARAM_DEF | i);
+
+               mono_metadata_decode_row (paramt, i-1, param_cols, MONO_PARAM_SIZE);
+               if (!(param_cols[MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
+                       if(list != NULL)
+                               fprintf (output, "\t.param [%d]\n", param_cols[MONO_PARAM_SEQUENCE]);
+               } else {
+                       fprintf (output, "\t.param [%d] = ", param_cols[MONO_PARAM_SEQUENCE]);
+                 
+                       if(crow = mono_metadata_get_constant_index(m, MONO_TOKEN_PARAM_DEF | i, 0)) {
+                               guint32 const_cols [MONO_CONSTANT_SIZE];
+                               mono_metadata_decode_row( &m->tables[MONO_TABLE_CONSTANT], crow-1, const_cols, MONO_CONSTANT_SIZE);
+                               lit = get_constant(m, const_cols [MONO_CONSTANT_TYPE], const_cols [MONO_CONSTANT_VALUE]);
+                       }
+                       else {
+                               lit = g_strdup ("not found");
+                       }
+                 fprintf(output, "%s\n", lit);
+                 g_free(lit);
+               }
+               dump_cattrs_list (list, "\t");
+       }
+}
+
 /**
  * dis_method_list:
  * @m: metadata context
@@ -429,7 +631,7 @@ pinvoke_info (MonoMetadata *m, guint32 mindex)
  * This routine displays the methods in the Method Table from @start to @end
  */
 static void
-dis_method_list (MonoMetadata *m, guint32 start, guint32 end)
+dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 end)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_METHOD];
        guint32 cols [MONO_METHOD_SIZE];
@@ -446,31 +648,46 @@ dis_method_list (MonoMetadata *m, guint32 start, guint32 end)
                char *flags, *impl_flags;
                const char *sig;
                char *sig_str;
+               guint32 token;
                
                mono_metadata_decode_row (t, i, cols, MONO_METHOD_SIZE);
 
                flags = method_flags (cols [MONO_METHOD_FLAGS]);
-               impl_flags = method_impl_flags (cols [MONO_METHOD_IMPLFALGS]);
+               impl_flags = method_impl_flags (cols [MONO_METHOD_IMPLFLAGS]);
 
                sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
                mono_metadata_decode_blob_size (sig, &sig);
-               ms = mono_metadata_parse_method_signature (m, 1, sig, &sig);
-               sig_str = dis_stringify_method_signature (m, ms, i + 1);
-                       
+               ms = mono_metadata_parse_method_signature (m, i + 1, sig, &sig);
+               sig_str = dis_stringify_method_signature (m, ms, i + 1, FALSE);
+
+               fprintf (output, "    // method line %d\n", i + 1);
                fprintf (output, "    .method %s", flags);
 
-               if (cols [MONO_METHOD_FLAGS] & METHOD_ATTRIBUTE_PINVOKE_IMPL)
-                       fprintf (output, "%s", pinvoke_info (m, i));
+               if ((cols [MONO_METHOD_FLAGS] & METHOD_ATTRIBUTE_PINVOKE_IMPL) && (cols [MONO_METHOD_RVA] == 0)) {
+                       gchar *pi = pinvoke_info (m, i);
+                       if (pi) {
+                               fprintf (output, "%s", pi);
+                               g_free (pi);
+                       }
+               }
 
                fprintf (output, "\n           %s", sig_str);
                fprintf (output, " %s\n", impl_flags);
                g_free (flags);
                g_free (impl_flags);
+
+               token = MONO_TOKEN_METHOD_DEF | (i + 1);
                
                fprintf (output, "    {\n");
+               dump_cattrs (m, token, "        ");
+               dump_cattrs_for_method_params (m, i, ms);
+               /* FIXME: need to sump also param custom attributes */
                fprintf (output, "        // Method begins at RVA 0x%x\n", cols [MONO_METHOD_RVA]);
-               dis_code (m, cols [MONO_METHOD_RVA]);
-               fprintf (output, "    }\n\n");
+               if (cols [MONO_METHOD_IMPLFLAGS] & METHOD_IMPL_ATTRIBUTE_NATIVE)
+                       fprintf (output, "          // Disassembly of native methods is not supported\n");
+               else
+                       dis_code (m, token, cols [MONO_METHOD_RVA]);
+               fprintf (output, "    } // end of method %s::%s\n\n", klass_name, sig_str);
                mono_metadata_free_method_signature (ms);
                g_free (sig_str);
        }
@@ -487,7 +704,7 @@ static int
 table_locator (const void *a, const void *b)
 {
        plocator_t *loc = (plocator_t *) a;
-       char *bb = (char *) b;
+       const char *bb = (const char *) b;
        guint32 table_index = (bb - loc->t->base) / loc->t->row_size;
        guint32 col;
        
@@ -504,37 +721,18 @@ table_locator (const void *a, const void *b)
 }
 
 static void
-dis_property_methods (MonoMetadata *m, guint32 prop)
+dis_property_methods (MonoImage *m, guint32 prop)
 {
-       plocator_t loc;
-       guint start;
-       guint32 cols [MONO_METHOD_SEMA_SIZE];
+       guint start, end;
        MonoTableInfo *msemt = &m->tables [MONO_TABLE_METHODSEMANTICS];
+       guint32 cols [MONO_METHOD_SEMA_SIZE];
        char *sig;
-       char *type[] = {NULL, ".set", ".get", NULL, ".other"};
-
-       loc.t = msemt;
-       loc.col_idx = MONO_METHOD_SEMA_ASSOCIATION;
-       loc.idx = (prop << 1) | 1; /* Method association coded index */
+       const char *type[] = {NULL, ".set", ".get", NULL, ".other"};
 
-       if (!bsearch (&loc, msemt->base, msemt->rows, msemt->row_size, table_locator))
-               return;
-
-       start = loc.result;
-       /*
-        * We may end up in the middle of the rows... 
-        */
-       while (start > 0) {
-               if (loc.idx == mono_metadata_decode_row_col (msemt, start - 1, MONO_METHOD_SEMA_ASSOCIATION))
-                       start--;
-               else
-                       break;
-       }
-       while (start < msemt->rows) {
+       start = mono_metadata_methods_from_property (m, prop, &end);
+       while (start < end) {
                mono_metadata_decode_row (msemt, start, cols, MONO_METHOD_SEMA_SIZE);
-               if (cols [MONO_METHOD_SEMA_ASSOCIATION] != loc.idx)
-                       break;
-               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD]);
+               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD], TRUE);
                fprintf (output, "\t\t%s %s\n", type [cols [MONO_METHOD_SEMA_SEMANTICS]], sig);
                g_free (sig);
                ++start;
@@ -542,14 +740,14 @@ dis_property_methods (MonoMetadata *m, guint32 prop)
 }
 
 static char*
-dis_property_signature (MonoMetadata *m, guint32 prop_idx)
+dis_property_signature (MonoImage *m, guint32 prop_idx)
 {
        MonoTableInfo *propt = &m->tables [MONO_TABLE_PROPERTY];
        const char *ptr;
        guint32 pcount, i;
        guint32 cols [MONO_PROPERTY_SIZE];
        MonoType *type;
-       MonoParam *param;
+       MonoType *param;
        char *blurb;
        const char *name;
        int prop_flags;
@@ -565,24 +763,22 @@ dis_property_signature (MonoMetadata *m, guint32 prop_idx)
                g_warning("incorrect signature in propert blob: 0x%x", *ptr);
        ptr++;
        pcount = mono_metadata_decode_value (ptr, &ptr);
-       type = mono_metadata_parse_type (m, ptr, &ptr);
+       type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
        blurb = dis_stringify_type (m, type);
        if (prop_flags & 0x0200)
-               g_string_append (res, "special ");
+               g_string_append (res, "specialname ");
        if (prop_flags & 0x0400)
-               g_string_append (res, "runtime ");
-       if (prop_flags & 0x1000)
-               g_string_append (res, "hasdefault ");
+               g_string_append (res, "rtspecialname ");
        g_string_sprintfa (res, "%s %s (", blurb, name);
        g_free (blurb);
        mono_metadata_free_type (type);
        for (i = 0; i < pcount; i++) {
                if (i)
                        g_string_append (res, ", ");
-               param = mono_metadata_parse_param (m, 0, ptr, &ptr);
+               param = mono_metadata_parse_param (m, ptr, &ptr);
                blurb = dis_stringify_param (m, param);
                g_string_append (res, blurb);
-               mono_metadata_free_param (param);
+               mono_metadata_free_type (param);
                g_free (blurb);
        }
        g_string_append_c (res, ')');
@@ -593,35 +789,202 @@ dis_property_signature (MonoMetadata *m, guint32 prop_idx)
 }
 
 static void
-dis_property_list (MonoMetadata *m, guint32 typedef_row)
+dis_property_list (MonoImage *m, guint32 typedef_row)
 {
-       plocator_t loc;
-       guint32 start, end, i;
-       MonoTableInfo *tdef  = &m->tables [MONO_TABLE_PROPERTYMAP];
+       guint start, end, i;
+       start = mono_metadata_properties_from_typedef (m, typedef_row, &end);
 
-       loc.t = tdef;
-       loc.col_idx = MONO_PROPERTY_MAP_PARENT;
-       loc.idx = typedef_row + 1;
+       for (i = start; i < end; ++i) {
+               char *sig = dis_property_signature (m, i);
+               fprintf (output, "\t.property %s\n\t{\n", sig);
+               dump_cattrs (m, MONO_TOKEN_PROPERTY | (i + 1), "\t\t");
+               dis_property_methods (m, i);
+               fprintf (output, "\t}\n");
+               g_free (sig);
+       }
+}
 
-       if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
-               return;
+static char*
+dis_event_signature (MonoImage *m, guint32 event_idx)
+{
+       MonoTableInfo *et = &m->tables [MONO_TABLE_EVENT];
+       char *type, *result, *esname;
+       guint32 cols [MONO_EVENT_SIZE];
+       int event_flags;
+       GString *res = g_string_new ("");
        
-       start = mono_metadata_decode_row_col (tdef, loc.result, MONO_PROPERTY_MAP_PROPERTY_LIST);
-       if (loc.result + 1 < tdef->rows) {
-               end = mono_metadata_decode_row_col (tdef, loc.result + 1, MONO_PROPERTY_MAP_PROPERTY_LIST) - 1;
-       } else {
-               end = m->tables [MONO_TABLE_PROPERTY].rows;
+       mono_metadata_decode_row (et, event_idx, cols, MONO_EVENT_SIZE);
+       esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_EVENT_NAME]));
+       type = get_typedef_or_ref (m, cols [MONO_EVENT_TYPE]);
+       event_flags = cols [MONO_EVENT_FLAGS];
+
+       if (event_flags & 0x0200)
+               g_string_append (res, "specialname ");
+       if (event_flags & 0x0400)
+               g_string_append (res, "rtspecialname ");
+       g_string_sprintfa (res, "%s %s", type, esname);
+
+       g_free (type);
+       g_free (esname);
+       result = res->str;
+       g_string_free (res, FALSE);
+       return result;
+}
+
+static void
+dis_event_methods (MonoImage *m, guint32 event)
+{
+       guint start, end;
+       MonoTableInfo *msemt = &m->tables [MONO_TABLE_METHODSEMANTICS];
+       guint32 cols [MONO_METHOD_SEMA_SIZE];
+       char *sig;
+       const char *type = "";
+
+       start = mono_metadata_methods_from_event (m, event, &end);
+       while (start < end) {
+               mono_metadata_decode_row (msemt, start, cols, MONO_METHOD_SEMA_SIZE);
+               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD], TRUE);
+               switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
+               case METHOD_SEMANTIC_OTHER:
+                       type = ".other"; break;
+               case METHOD_SEMANTIC_ADD_ON:
+                       type = ".addon"; break;
+               case METHOD_SEMANTIC_REMOVE_ON:
+                       type = ".removeon"; break;
+               case METHOD_SEMANTIC_FIRE:
+                       type = ".fire"; break;
+               default:
+                       break;
+               }
+               fprintf (output, "\t\t%s %s\n", type, sig);
+               g_free (sig);
+               ++start;
        }
+}
 
-       for (i = start - 1; i < end; ++i) {
-               char *sig = dis_property_signature (m, i);
-               fprintf (output, "\t.property %s\n\t{\n", sig);
-               dis_property_methods (m, i + 1);
+static void
+dis_event_list (MonoImage *m, guint32 typedef_row)
+{
+       guint start, end, i;
+       start = mono_metadata_events_from_typedef (m, typedef_row, &end);
+
+       for (i = start; i < end; ++i) {
+               char *sig = dis_event_signature (m, i);
+               fprintf (output, "\t.event %s\n\t{\n", sig);
+               dump_cattrs (m, MONO_TOKEN_EVENT | (i + 1), "\t\t");
+               dis_event_methods (m, i);
                fprintf (output, "\t}\n");
                g_free (sig);
        }
 }
 
+static void
+dis_interfaces (MonoImage *m, guint32 typedef_row)
+{
+       plocator_t loc;
+       guint start;
+       gboolean first_interface = 1;
+       guint32 cols [MONO_INTERFACEIMPL_SIZE];
+       char *intf;
+       MonoTableInfo *table = &m->tables [MONO_TABLE_INTERFACEIMPL];
+
+       if (!table->base)
+               return;
+
+       loc.t = table;
+       loc.col_idx = MONO_INTERFACEIMPL_CLASS;
+       loc.idx = typedef_row;
+
+       if (!bsearch (&loc, table->base, table->rows, table->row_size, table_locator))
+               return;
+
+       start = loc.result;
+       /*
+        * We may end up in the middle of the rows... 
+        */
+       while (start > 0) {
+               if (loc.idx == mono_metadata_decode_row_col (table, start - 1, MONO_INTERFACEIMPL_CLASS))
+                       start--;
+               else
+                       break;
+       }
+       while (start < table->rows) {
+               mono_metadata_decode_row (table, start, cols, MONO_INTERFACEIMPL_SIZE);
+               if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx)
+                       break;
+               intf = get_typedef_or_ref (m, cols [MONO_INTERFACEIMPL_INTERFACE]);
+               if (first_interface) {
+                       fprintf (output, "  \timplements %s", intf);
+                       first_interface = 0;
+               } else {
+                       fprintf (output, ", %s", intf);
+               }
+               g_free (intf);
+               ++start;
+       }
+}
+
+/**
+ * dis_generic_param_and_constraints:
+ * @m: metadata context
+ * @table_type: Type of table (0 for typedef, 1 for methoddef)
+ * @row: Row in table
+ *
+ * Dissasembles the generic parameters for this type or method, also
+ * returns an allocated GString containing the generic constraints NULL
+ * if their are no generic constraints.
+ */
+static GString*
+dis_generic_param_and_constraints (MonoImage *m, int table_type, guint32 typedef_row)
+{
+        MonoTableInfo *t = &m->tables [MONO_TABLE_GENERICPARAM];
+        MonoTableInfo *ct = &m->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
+        GString* cnst_block = NULL;
+       guint32 cols [MONO_GENERICPARAM_SIZE];
+        guint32 ccols [MONO_GENPARCONSTRAINT_SIZE];
+       int i, own_tok, table, idx, found_count, cnst_start, cnst_ind;
+
+        g_assert (table_type != MONO_TYPEORMETHOD_TYPE || table_type != MONO_TYPEORMETHOD_METHOD);
+        
+        found_count = cnst_start = 0;
+       for (i = 1; i <= t->rows; i++) {
+               mono_metadata_decode_row (t, i-1, cols, MONO_GENERICPARAM_SIZE);
+                own_tok = cols [MONO_GENERICPARAM_OWNER];
+                table = own_tok & MONO_TYPEORMETHOD_MASK;
+                idx = own_tok >> MONO_TYPEORMETHOD_BITS;
+                
+                if (table != table_type || idx != typedef_row)
+                        continue;
+
+                if (found_count == 0)
+                        fprintf (output, "<");
+                else
+                        fprintf (output, ", ");
+
+                for (cnst_ind = cnst_start; cnst_ind < ct->rows; cnst_ind++) {
+                        char *sig;
+                        mono_metadata_decode_row (ct, cnst_ind, ccols, MONO_GENPARCONSTRAINT_SIZE);
+                        if (ccols [MONO_GENPARCONSTRAINT_GENERICPAR] != i)
+                                continue;
+                        if (cnst_block == NULL)
+                                cnst_block = g_string_new ("");
+                        sig = get_typedef_or_ref (m, ccols [MONO_GENPARCONSTRAINT_CONSTRAINT]);
+                       fprintf (output, "(%s) ", sig);
+                        g_free (sig);
+                        cnst_start = cnst_ind;
+                }
+
+               fprintf (output, "%s", mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
+               
+                found_count++;
+       }
+
+        if (found_count)
+                fprintf (output, ">");
+
+        return cnst_block;
+}
+
 /**
  * dis_type:
  * @m: metadata context
@@ -630,14 +993,18 @@ dis_property_list (MonoMetadata *m, guint32 typedef_row)
  * Disassembles the type whose index in the TypeDef table is @n.
  */
 static void
-dis_type (MonoMetadata *m, int n)
+dis_type (MonoImage *m, int n)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
+        GString *cnst_block = NULL;
        guint32 cols [MONO_TYPEDEF_SIZE];
        guint32 cols_next [MONO_TYPEDEF_SIZE];
-       const char *name;
+       const char *name, *nspace;
+       char *esname;
+       guint32 packing_size, class_size;
        gboolean next_is_valid, last;
-       
+       guint32 nested;
+
        mono_metadata_decode_row (t, n, cols, MONO_TYPEDEF_SIZE);
 
        if (t->rows > n + 1) {
@@ -646,19 +1013,42 @@ dis_type (MonoMetadata *m, int n)
        } else
                next_is_valid = 0;
 
-       fprintf (output, ".namespace %s\n{\n", mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]));
        name = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]);
+       nspace = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]);
+       if (*nspace)
+               fprintf (output, ".namespace %s\n{\n", nspace);
 
+       esname = get_escaped_name (name);
        if ((cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK) == TYPE_ATTRIBUTE_CLASS){
-               char *base = get_typedef_or_ref (m, cols [MONO_TYPEDEF_EXTENDS]);
-               fprintf (output, "  .class %s%s\n", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), name);
-               fprintf (output, "  \textends %s\n", base);
-               g_free (base);
-       } else
-               fprintf (output, "  .class interface %s%s\n", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), name);
-       
-       fprintf (output, "  {\n");
+               fprintf (output, "  .class %s%s", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), esname);
+               
+                cnst_block = dis_generic_param_and_constraints (m, MONO_TYPEORMETHOD_TYPE, n+1);
+                fprintf (output, "\n");
+               if (cols [MONO_TYPEDEF_EXTENDS]) {
+                       char *base = get_typedef_or_ref (m, cols [MONO_TYPEDEF_EXTENDS]);
+                       fprintf (output, "  \textends %s\n", base);
+                       g_free (base);
+               }
+       } else {
+               fprintf (output, "  .class interface %s%s", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), esname);
+
+                cnst_block = dis_generic_param_and_constraints (m, MONO_TYPEORMETHOD_TYPE, n+1);
+               fprintf (output, "\n");
+       }
 
+       g_free (esname);
+       dis_interfaces (m, n + 1);
+       fprintf (output, "  {\n");
+        if (cnst_block) {
+                fprintf (output, "%s", cnst_block->str);
+                g_string_free (cnst_block, TRUE);
+        }
+       dump_cattrs (m, MONO_TOKEN_TYPE_DEF | (n + 1), "    ");
+
+       if (mono_metadata_packing_from_typedef (m, n + 1, &packing_size, &class_size)) {
+               fprintf (output, "    .pack %d\n", packing_size);
+               fprintf (output, "    .size %d\n", class_size);
+       }
        /*
         * The value in the table is always valid, we know we have fields
         * if the value stored is different than the next record.
@@ -678,12 +1068,73 @@ dis_type (MonoMetadata *m, int n)
        else
                last = m->tables [MONO_TABLE_METHOD].rows;
        
-       if (cols [MONO_TYPEDEF_METHOD_LIST] < m->tables [MONO_TABLE_METHOD].rows)
-               dis_method_list (m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last);
+       if (cols [MONO_TYPEDEF_METHOD_LIST] && cols [MONO_TYPEDEF_METHOD_LIST] <= m->tables [MONO_TABLE_METHOD].rows)
+               dis_method_list (name, m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last);
 
        dis_property_list (m, n);
+       dis_event_list (m, n);
+
+       t = &m->tables [MONO_TABLE_NESTEDCLASS];
+       nested = mono_metadata_nesting_typedef (m, n + 1, 1);
+       while (nested) {
+               dis_type (m, mono_metadata_decode_row_col (t, nested - 1, MONO_NESTED_CLASS_NESTED) - 1);
+               nested = mono_metadata_nesting_typedef (m, n + 1, nested + 1);
+       }
        
-       fprintf (output, "  }\n}\n\n");
+       fprintf (output, "  } // end of class %s%s%s\n", nspace, *nspace? ".": "", name);
+       if (*nspace)
+               fprintf (output, "}\n");
+       fprintf (output, "\n");
+}
+
+
+/**
+ * dis_globals
+ * @m: metadata context
+ *
+ * disassembles all the global fields and methods
+ */
+static void
+dis_globals (MonoImage *m)
+{
+        MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
+       guint32 cols [MONO_TYPEDEF_SIZE];
+       guint32 cols_next [MONO_TYPEDEF_SIZE];
+       gboolean next_is_valid, last;
+        gchar *name;
+
+        name = g_strdup ("<Module>");
+
+        mono_metadata_decode_row (t, 0, cols, MONO_TYPEDEF_SIZE);
+
+       if (t->rows > 1) {
+               mono_metadata_decode_row (t, 1, cols_next, MONO_TYPEDEF_SIZE);
+               next_is_valid = 1;
+       } else
+               next_is_valid = 0;
+        
+       /*
+        * The value in the table is always valid, we know we have fields
+        * if the value stored is different than the next record.
+        */
+
+       if (next_is_valid)
+               last = cols_next [MONO_TYPEDEF_FIELD_LIST] - 1;
+       else
+               last = m->tables [MONO_TABLE_FIELD].rows;
+                       
+       if (cols [MONO_TYPEDEF_FIELD_LIST] && cols [MONO_TYPEDEF_FIELD_LIST] <= m->tables [MONO_TABLE_FIELD].rows)
+               dis_field_list (m, cols [MONO_TYPEDEF_FIELD_LIST] - 1, last);
+       fprintf (output, "\n");
+
+       if (next_is_valid)
+               last = cols_next [MONO_TYPEDEF_METHOD_LIST] - 1;
+       else
+               last = m->tables [MONO_TABLE_METHOD].rows;
+       
+       if (cols [MONO_TYPEDEF_METHOD_LIST] && cols [MONO_TYPEDEF_METHOD_LIST] <= m->tables [MONO_TABLE_METHOD].rows)
+               dis_method_list (name, m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last);
+
 }
 
 /**
@@ -693,36 +1144,96 @@ dis_type (MonoMetadata *m, int n)
  * disassembles all types in the @m context
  */
 static void
-dis_types (MonoMetadata *m)
+dis_types (MonoImage *m)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
        int i;
+       guint32 flags;
+
+        dis_globals (m);
+        
+       for (i = 1; i < t->rows; i++) {
+               flags = mono_metadata_decode_row_col (t, i, MONO_TYPEDEF_FLAGS);
+               flags &= TYPE_ATTRIBUTE_VISIBILITY_MASK;
+               if (flags == TYPE_ATTRIBUTE_PUBLIC || flags == TYPE_ATTRIBUTE_NOT_PUBLIC)
+                       dis_type (m, i);
+       }
+}
+
+/**
+ * dis_data:
+ * @m: metadata context
+ *
+ * disassembles all data blobs references in the FieldRVA table in the @m context
+ */
+static void
+dis_data (MonoImage *m)
+{
+       MonoTableInfo *t = &m->tables [MONO_TABLE_FIELDRVA];
+       MonoTableInfo *ft = &m->tables [MONO_TABLE_FIELD];
+       int i, b;
+       const char *rva, *sig;
+       guint32 align, size;
+       guint32 cols [MONO_FIELD_RVA_SIZE];
+       MonoType *type;
 
-       for (i = 1; i < t->rows; i++)
-               dis_type (m, i);
+       for (i = 0; i < t->rows; i++) {
+               mono_metadata_decode_row (t, i, cols, MONO_FIELD_RVA_SIZE);
+               rva = mono_image_rva_map (m, cols [MONO_FIELD_RVA_RVA]);
+               sig = mono_metadata_blob_heap (m, mono_metadata_decode_row_col (ft, cols [MONO_FIELD_RVA_FIELD] -1, MONO_FIELD_SIGNATURE));
+               mono_metadata_decode_value (sig, &sig);
+               /* FIELD signature == 0x06 */
+               g_assert (*sig == 0x06);
+               type = mono_metadata_parse_field_type (m, 0, sig + 1, &sig);
+               mono_class_init (mono_class_from_mono_type (type));
+               size = mono_type_size (type, &align);
+               fprintf (output, ".data D_%08x = bytearray (", cols [MONO_FIELD_RVA_RVA]);
+               for (b = 0; b < size; ++b) {
+                       if (!(b % 16))
+                               fprintf (output, "\n\t");
+                       fprintf (output, " %02X", rva [b] & 0xff);
+               }
+               fprintf (output, ") // size: %d\n", size);
+       }
 }
 
 struct {
-       char *name;
+       const char *name;
        int table;
-       void (*dumper) (MonoMetadata *m);
+       void (*dumper) (MonoImage *m);
 } table_list [] = {
-       { "--assembly",    MONO_TABLE_ASSEMBLY,    dump_table_assembly },
-       { "--assemblyref", MONO_TABLE_ASSEMBLYREF, dump_table_assemblyref },
-       { "--fields",      MONO_TABLE_FIELD,       dump_table_field },
-       { "--memberref",   MONO_TABLE_MEMBERREF,   dump_table_memberref },
-       { "--param",       MONO_TABLE_PARAM,       dump_table_param },
-       { "--typedef",     MONO_TABLE_TYPEDEF,     dump_table_typedef },
-       { "--typeref",     MONO_TABLE_TYPEREF,     dump_table_typeref },
-       { "--classlayout", MONO_TABLE_CLASSLAYOUT, dump_table_class_layout },
-       { "--constant",    MONO_TABLE_CONSTANT,    dump_table_constant },
-       { "--property",    MONO_TABLE_PROPERTY,    dump_table_property },
-       { "--propertymap", MONO_TABLE_PROPERTYMAP, dump_table_property_map },
-       { "--event",       MONO_TABLE_EVENT,       dump_table_event },
-       { "--file",        MONO_TABLE_FILE,        dump_table_file },
-       { "--moduleref",   MONO_TABLE_MODULEREF,   dump_table_moduleref },
-       { "--method",      MONO_TABLE_METHOD,      dump_table_method },
-       { "--methodsem",   MONO_TABLE_METHODSEMANTICS,      dump_table_methodsem },
+       { "--assembly",    MONO_TABLE_ASSEMBLY,         dump_table_assembly },
+       { "--assemblyref", MONO_TABLE_ASSEMBLYREF,      dump_table_assemblyref },
+       { "--classlayout", MONO_TABLE_CLASSLAYOUT,      dump_table_class_layout },
+       { "--constant",    MONO_TABLE_CONSTANT,         dump_table_constant },
+       { "--customattr",  MONO_TABLE_CUSTOMATTRIBUTE,  dump_table_customattr },
+       { "--declsec",     MONO_TABLE_DECLSECURITY,     dump_table_declsec },
+       { "--event",       MONO_TABLE_EVENT,            dump_table_event },
+       { "--exported",    MONO_TABLE_EXPORTEDTYPE,     dump_table_exported },
+       { "--fields",      MONO_TABLE_FIELD,            dump_table_field },
+       { "--file",        MONO_TABLE_FILE,             dump_table_file },
+       { "--genericpar",  MONO_TABLE_GENERICPARAM,     dump_table_genericpar },
+       { "--interface",   MONO_TABLE_INTERFACEIMPL,    dump_table_interfaceimpl },
+       { "--manifest",    MONO_TABLE_MANIFESTRESOURCE, dump_table_manifest },
+       { "--marshal",     MONO_TABLE_FIELDMARSHAL,     dump_table_field_marshal },
+       { "--memberref",   MONO_TABLE_MEMBERREF,        dump_table_memberref },
+       { "--method",      MONO_TABLE_METHOD,           dump_table_method },
+       { "--methodimpl",  MONO_TABLE_METHODIMPL,       dump_table_methodimpl },
+       { "--methodsem",   MONO_TABLE_METHODSEMANTICS,  dump_table_methodsem },
+       { "--methodspec",  MONO_TABLE_METHODSPEC,       dump_table_methodspec },
+       { "--moduleref",   MONO_TABLE_MODULEREF,        dump_table_moduleref },
+       { "--module",      MONO_TABLE_MODULE,           dump_table_module },
+       { "--nested",      MONO_TABLE_NESTEDCLASS,      dump_table_nestedclass },
+       { "--param",       MONO_TABLE_PARAM,            dump_table_param },
+       { "--parconst",    MONO_TABLE_GENERICPARAMCONSTRAINT, dump_table_parconstraint },
+       { "--property",    MONO_TABLE_PROPERTY,         dump_table_property },
+       { "--propertymap", MONO_TABLE_PROPERTYMAP,      dump_table_property_map },
+       { "--typedef",     MONO_TABLE_TYPEDEF,          dump_table_typedef },
+       { "--typeref",     MONO_TABLE_TYPEREF,          dump_table_typeref },
+       { "--typespec",    MONO_TABLE_TYPESPEC,         dump_table_typespec },
+       { "--implmap",     MONO_TABLE_IMPLMAP,          dump_table_implmap },
+       { "--standalonesig", MONO_TABLE_STANDALONESIG,  dump_table_standalonesig },
+       { "--blob",        NULL,                        dump_stream_blob },
        { NULL, -1 }
 };
 
@@ -736,10 +1247,10 @@ static void
 disassemble_file (const char *file)
 {
        MonoAssembly *ass;
-       enum MonoImageOpenStatus status;
+       MonoImageOpenStatus status;
        MonoImage *img;
 
-       ass = mono_assembly_open (file, NULL, &status);
+       ass = mono_assembly_open (file, &status);
        if (ass == NULL){
                fprintf (stderr, "Error while trying to process %s\n", file);
                return;
@@ -754,7 +1265,11 @@ disassemble_file (const char *file)
                
                dis_directive_assemblyref (img);
                dis_directive_assembly (img);
+               dis_directive_file (img);
+               dis_directive_module (img);
+               dis_directive_moduleref (img);
                dis_types (img);
+               dis_data (img);
        }
        
        mono_image_close (img);
@@ -763,7 +1278,7 @@ disassemble_file (const char *file)
 static void
 usage (void)
 {
-       GString *args = g_string_new ("[--help] ");
+       GString *args = g_string_new ("[--output=filename] [--help] [--mscorlib]\n");
        int i;
        
        for (i = 0; table_list [i].name != NULL; i++){
@@ -785,13 +1300,31 @@ main (int argc, char *argv [])
        int i, j;
 
        output = stdout;
+       init_key_table ();
        for (i = 1; i < argc; i++){
                if (argv [i][0] == '-'){
                        if (argv [i][1] == 'h')
                                usage ();
                        else if (argv [i][1] == 'd')
                                dump_header_data_p = TRUE;
-                       else if (strcmp (argv [i], "--help") == 0)
+                       else if (strcmp (argv [i], "--mscorlib") == 0) {
+                               substitute_with_mscorlib_p = TRUE;
+                               continue;
+                       } else if (strcmp (argv [i], "--show-method-tokens") == 0) {
+                               show_method_tokens = TRUE;
+                               continue;
+                       } else if (strcmp (argv [i], "--show-tokens") == 0) {
+                               show_tokens = TRUE;
+                               continue;
+                       } else if (strncmp (argv [i], "--output=", 9) == 0) {
+                               output = fopen (argv [i]+9, "w");
+                               if (output == NULL) {
+                                       fprintf (stderr, "Can't open output file `%s': %s\n",
+                                                argv [i]+9, strerror (errno));
+                                       exit (1);
+                               }
+                               continue;
+                       } else if (strcmp (argv [i], "--help") == 0)
                                usage ();
                        for (j = 0; table_list [j].name != NULL; j++) {
                                if (strcmp (argv [i], table_list [j].name) == 0)
@@ -806,7 +1339,7 @@ main (int argc, char *argv [])
        if (input_files == NULL)
                usage ();
        
-       mono_init ();
+       mono_init (argv [0]);
 
        for (l = input_files; l; l = l->next)
                disassemble_file (l->data);