[corlib] Fixed performance regression in qsort() functions
[mono.git] / mono / dis / main.c
index 95f075f92490272762b1a1d1def09a1e8b65d048..d4719cac40c0592b98bbef8dcbf4c5dce0af19a1 100644 (file)
@@ -24,6 +24,7 @@
 #include "dump.h"
 #include "get.h"
 #include "dis-cil.h"
+#include "declsec.h"
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/loader.h>
@@ -146,26 +147,44 @@ dump_declarative_security (MonoImage *m, guint32 objectType, guint32 token, cons
                action = get_il_security_action (cols [MONO_DECL_SECURITY_ACTION]);
                idx = cols [MONO_DECL_SECURITY_PARENT];
                if (((idx & MONO_HAS_DECL_SECURITY_MASK) == objectType) && ((idx >> MONO_HAS_DECL_SECURITY_BITS) == token)) {
-                       char *dump = data_dump (blob, len, indent);
-                       fprintf (output, "%s.permissionset %s = %s", indent, action, dump);
+                       char *dump;
+                       if (blob [0] == MONO_DECLSEC_FORMAT_20) {
+                               /* 2.0 declarative security format */
+                               dump = dump_declsec_entry20 (m, blob, indent);
+                               fprintf (output, "%s.permissionset %s = %s\n", indent, action, dump);
+                       } else {
+                               /* 1.x declarative security metadata format */
+                               dump = data_dump (blob, len, indent);
+                               fprintf (output, "%s.permissionset %s = %s", indent, action, dump);
+                       }
                        g_free (dump);
                }
        }
 }
 
+static char *
+assembly_flags (guint32 f)
+{
+       if (f & ASSEMBLYREF_RETARGETABLE_FLAG)
+               return g_strdup ("retargetable ");
+       return g_strdup ("");
+}
+
 static void
 dis_directive_assembly (MonoImage *m)
 {
        MonoTableInfo *t  = &m->tables [MONO_TABLE_ASSEMBLY];
        guint32 cols [MONO_ASSEMBLY_SIZE];
+       char *flags;
        
        if (t->base == NULL)
                return;
 
        mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
+       flags = assembly_flags (cols [MONO_ASSEMBLY_FLAGS]);
        
-       fprintf (output, ".assembly '%s'\n{\n",
-                mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]));
+       fprintf (output, ".assembly %s'%s'\n{\n",
+                flags, mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]));
        dump_cattrs (m, MONO_TOKEN_ASSEMBLY | 1, "  ");
        dump_declarative_security (m, OBJECT_TYPE_ASSEMBLYDEF, 1, "  ");
        fprintf (output,
@@ -174,9 +193,16 @@ dis_directive_assembly (MonoImage *m)
                 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]);
-       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]) {
+       if (cols [MONO_ASSEMBLY_CULTURE]){
+               const char *locale = mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_CULTURE]);
+               glong items_read, items_written;
+               gunichar2 *render = g_utf8_to_utf16 (locale, strlen (locale), &items_read, &items_written, NULL);
+               char *dump = data_dump ((const char *) render, items_written * sizeof (gunichar2), "\t\t");
+               fprintf (output, "  .locale %s\n", dump);
+               g_free (dump);
+               g_free (render);
+               
+       } 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");
@@ -184,6 +210,8 @@ dis_directive_assembly (MonoImage *m)
                g_free (dump);
        }
        fprintf (output, "}\n");
+       
+       g_free (flags);
 }
 
 static void
@@ -197,20 +225,23 @@ dis_directive_assemblyref (MonoImage *m)
                return;
 
        for (i = 0; i < t->rows; i++){
-               char *esc;
+               char *esc, *flags;
 
                mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
 
                esc = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
+               flags = assembly_flags (cols [MONO_ASSEMBLYREF_FLAGS]);
                
                fprintf (output,
-                        ".assembly extern %s\n"
+                        ".assembly extern %s%s\n"
                         "{\n"
                         "  .ver %d:%d:%d:%d\n",
+                        flags,
                         esc,
                         cols [MONO_ASSEMBLYREF_MAJOR_VERSION], cols [MONO_ASSEMBLYREF_MINOR_VERSION], 
                         cols [MONO_ASSEMBLYREF_BUILD_NUMBER], cols [MONO_ASSEMBLYREF_REV_NUMBER]
                        );
+               dump_cattrs (m, MONO_TOKEN_ASSEMBLY_REF | (i + 1), "  ");
                if (cols [MONO_ASSEMBLYREF_CULTURE]){
                        fprintf (output, "  .locale %s\n", mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_CULTURE]));
                }
@@ -222,6 +253,7 @@ dis_directive_assemblyref (MonoImage *m)
                        g_free (dump);
                }
                fprintf (output, "}\n");
+               g_free (flags);
                g_free (esc);
        }
 }
@@ -257,16 +289,22 @@ dis_directive_moduleref (MonoImage *m)
 
        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);
+               fprintf (output, ".module extern '%s'\n", mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]));
        }
        
 }
 
+static void
+dis_nt_header (MonoImage *m)
+{
+       MonoCLIImageInfo *image_info = m->image_info;
+       if (image_info && image_info->cli_header.nt.pe_stack_reserve != 0x100000)
+               fprintf (output, ".stackreserve 0x%x\n", image_info->cli_header.nt.pe_stack_reserve);
+}
+
 static void
 dis_directive_file (MonoImage *m)
 {
@@ -380,13 +418,15 @@ typedef_flags (guint32 flags)
        if (flags & TYPE_ATTRIBUTE_SEALED)
                strcat (buffer, "sealed ");
        if (flags & TYPE_ATTRIBUTE_SPECIAL_NAME)
-               strcat (buffer, "special-name ");
+               strcat (buffer, "specialname ");
        if (flags & TYPE_ATTRIBUTE_IMPORT)
                strcat (buffer, "import ");
        if (flags & TYPE_ATTRIBUTE_SERIALIZABLE)
                strcat (buffer, "serializable ");
        if (flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT)
                strcat (buffer, "beforefieldinit ");
+       if (flags & TYPE_ATTRIBUTE_FORWARDER)
+               strcat (buffer, "forwarder ");
 
        return buffer;
 }
@@ -400,7 +440,7 @@ typedef_flags (guint32 flags)
  * This routine displays all the decoded fields from @start to @end
  */
 static void
-dis_field_list (MonoImage *m, guint32 start, guint32 end, MonoGenericContext *context)
+dis_field_list (MonoImage *m, guint32 start, guint32 end, MonoGenericContainer *container)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
        guint32 cols [MONO_FIELD_SIZE];
@@ -416,13 +456,23 @@ dis_field_list (MonoImage *m, guint32 start, guint32 end, MonoGenericContext *co
                        
        for (i = start; i < end; i++){
                char *sig, *flags, *attrs = NULL;
+               char *marshal_str = NULL;
                guint32 field_offset = -1;
 
                if (!should_include_field (i + 1))
                        continue;
                mono_metadata_decode_row (t, i, cols, MONO_FIELD_SIZE);
-               sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], context);
+               sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], container);
                flags = field_flags (cols [MONO_FIELD_FLAGS]);
+               
+               if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL) {
+                       const char *tp;
+                       MonoMarshalSpec *spec;
+                       
+                       tp = mono_metadata_get_marshal_info (m, i, TRUE);
+                       spec = mono_metadata_parse_marshal_spec (m, tp);
+                       marshal_str = dis_stringify_marshal_spec (spec);
+               }
 
                if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
                        mono_metadata_field_info (m, i, NULL, &rva, NULL);
@@ -447,16 +497,16 @@ dis_field_list (MonoImage *m, guint32 start, guint32 end, MonoGenericContext *co
                                lit = g_strdup ("not found");
                        }
                        
-                       
-                       fprintf (output, "    .field %s %s %s = ",
-                                flags, sig, esname);
+                       fprintf (output, "    .field %s%s%s %s = ",
+                                flags, marshal_str ? marshal_str : " ", sig, esname);
                        fprintf (output, "%s\n", lit);
                        g_free (lit);
                } else
-                       fprintf (output, "    .field %s %s %s %s%s\n",
-                                attrs? attrs: "", flags, sig, esname, rva_desc);
+                       fprintf (output, "    .field %s %s%s%s %s%s\n",
+                                attrs? attrs: "", flags, marshal_str ? marshal_str : " ", sig, esname, rva_desc);
                g_free (attrs);
                g_free (flags);
+               g_free (marshal_str);
                g_free (sig);
                g_free (esname);
                dump_cattrs (m, MONO_TOKEN_FIELD_DEF | (i + 1), "    ");
@@ -485,9 +535,10 @@ static dis_map_t method_flags_map [] = {
        { METHOD_ATTRIBUTE_RT_SPECIAL_NAME,     "rtspecialname " },
        { METHOD_ATTRIBUTE_UNMANAGED_EXPORT,    "export " },
 /* MS ilasm doesn't compile this statement - is must be added automagically when permissionset are present */
-/*     { METHOD_ATTRIBUTE_HAS_SECURITY,        "hassecurity" }, */
-       { METHOD_ATTRIBUTE_REQUIRE_SEC_OBJECT,  "requiresecobj" },
+       { METHOD_ATTRIBUTE_HAS_SECURITY,        "" /*"hassecurity"*/ },
+       { METHOD_ATTRIBUTE_REQUIRE_SEC_OBJECT,  "requiresecobj " },
        { METHOD_ATTRIBUTE_PINVOKE_IMPL,        "pinvokeimpl " }, 
+       { METHOD_ATTRIBUTE_STRICT,                  "strict " }, 
        { 0, NULL }
 };
 
@@ -501,10 +552,11 @@ method_flags (guint32 f)
 {
        GString *str = g_string_new ("");
        int access = f & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK;
+       int rest = f & ~access;
        char *s;
        
        g_string_append (str, map (access, method_access_map));
-       g_string_append (str, flags (f, method_flags_map));
+       g_string_append (str, flags (rest, method_flags_map));
 
        s = str->str;
        g_string_free (str, FALSE);
@@ -515,10 +567,10 @@ method_flags (guint32 f)
 static dis_map_t pinvoke_flags_map [] = {
        { PINVOKE_ATTRIBUTE_NO_MANGLE ,            "nomangle " },
        { PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR,   "lasterr " },
-       { PINVOKE_ATTRIBUTE_BEST_FIT_ENABLED,      "bestfit:on" },
-       { PINVOKE_ATTRIBUTE_BEST_FIT_DISABLED,      "bestfit:off" },
-       { PINVOKE_ATTRIBUTE_THROW_ON_UNMAPPABLE_ENABLED, "charmaperror:on" },
-       { PINVOKE_ATTRIBUTE_THROW_ON_UNMAPPABLE_DISABLED, "charmaperror:off" },
+       { PINVOKE_ATTRIBUTE_BEST_FIT_ENABLED,      "bestfit:on " },
+       { PINVOKE_ATTRIBUTE_BEST_FIT_DISABLED,      "bestfit:off " },
+       { PINVOKE_ATTRIBUTE_THROW_ON_UNMAPPABLE_ENABLED, "charmaperror:on " },
+       { PINVOKE_ATTRIBUTE_THROW_ON_UNMAPPABLE_DISABLED, "charmaperror:off " },
        { 0, NULL }
 };
 
@@ -528,7 +580,8 @@ static dis_map_t pinvoke_call_conv_map [] = {
        { PINVOKE_ATTRIBUTE_CALL_CONV_STDCALL,     "stdcall " },
        { PINVOKE_ATTRIBUTE_CALL_CONV_THISCALL,    "thiscall " },
        { PINVOKE_ATTRIBUTE_CALL_CONV_FASTCALL,    "fastcall " },
-       { 0, NULL }
+       { 0, "" },
+       { -1, NULL }
 };
 
 static dis_map_t pinvoke_char_set_map [] = {
@@ -550,11 +603,12 @@ pinvoke_flags (guint32 f)
        GString *str = g_string_new ("");
        int cset = f & PINVOKE_ATTRIBUTE_CHAR_SET_MASK;
        int cconv = f & PINVOKE_ATTRIBUTE_CALL_CONV_MASK;
+       int rest = f & ~(cset | cconv);
        char *s;
-       
+
        g_string_append (str, map (cset, pinvoke_char_set_map));
        g_string_append (str, map (cconv, pinvoke_call_conv_map));
-       g_string_append (str, flags (f, pinvoke_flags_map));
+       g_string_append (str, flags (rest, pinvoke_flags_map));
 
        s = g_strdup(str->str);
        g_string_free (str, FALSE);
@@ -562,46 +616,6 @@ pinvoke_flags (guint32 f)
        return s;
 }
 
-static dis_map_t method_impl_map [] = {
-       { METHOD_IMPL_ATTRIBUTE_IL,              "cil " },
-       { METHOD_IMPL_ATTRIBUTE_NATIVE,          "native " },
-       { METHOD_IMPL_ATTRIBUTE_OPTIL,           "optil " },
-       { METHOD_IMPL_ATTRIBUTE_RUNTIME,         "runtime " },
-       { 0, NULL }
-};
-
-static dis_map_t managed_type_map [] = {
-       { METHOD_IMPL_ATTRIBUTE_UNMANAGED,       "unmanaged " },
-       { METHOD_IMPL_ATTRIBUTE_MANAGED,         "managed " },
-       { 0, NULL }
-};
-
-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 " },
-       { METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED,    "synchronized " },
-       { METHOD_IMPL_ATTRIBUTE_NOINLINING,      "noinline " },
-       { 0, NULL }
-};
-
-static char *
-method_impl_flags (guint32 f)
-{
-       GString *str = g_string_new ("");
-       char *s;
-       int code_type = f & METHOD_IMPL_ATTRIBUTE_CODE_TYPE_MASK;
-       int managed_type = f & METHOD_IMPL_ATTRIBUTE_MANAGED_MASK;
-
-       g_string_append (str, map (code_type, method_impl_map));
-       g_string_append (str, map (managed_type, managed_type_map));
-       g_string_append (str, flags (f, managed_impl_flags));
-       
-       s = str->str;
-       g_string_free (str, FALSE);
-       return s;
-}
-
 static void
 dis_locals (MonoImage *m, MonoMethodHeader *mh, const char *ptr) 
 {
@@ -648,7 +662,7 @@ dis_locals (MonoImage *m, MonoMethodHeader *mh, const char *ptr)
 }
 
 static void
-dis_code (MonoImage *m, guint32 token, guint32 rva, MonoGenericContext *context)
+dis_code (MonoImage *m, guint32 token, guint32 rva, MonoGenericContainer *container)
 {
        MonoMethodHeader *mh;
        const char *ptr = mono_image_rva_map (m, rva);
@@ -659,31 +673,33 @@ dis_code (MonoImage *m, guint32 token, guint32 rva, MonoGenericContext *context)
        if (rva == 0)
                return;
 
-       override = get_method_override (m, token, context);
+       override = get_method_override (m, token, container);
        if (override) {
                fprintf (output, "\t.override %s\n", override);
                g_free (override);
        }
 
-       mh = mono_metadata_parse_mh_full (m, context, ptr);
-       if ((entry_point = mono_image_get_entry_point (m))){
+       mh = mono_metadata_parse_mh_full (m, container, ptr);
+       entry_point = mono_image_get_entry_point (m);
+       if (entry_point && mono_metadata_token_index (entry_point) && mono_metadata_token_table (entry_point) == MONO_TABLE_METHOD) {
                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);
-       if (mh->num_locals)
-               dis_locals (m, mh, ptr);
-       dissasemble_cil (m, mh, context);
-       
+       if (mh) {
+               fprintf (output, "\t// Code size %d (0x%x)\n", mh->code_size, mh->code_size);
+               fprintf (output, "\t.maxstack %d\n", mh->max_stack);
+               if (mh->num_locals)
+                       dis_locals (m, mh, ptr);
+               disassemble_cil (m, mh, container);
 /*
   hex_dump (mh->code, 0, mh->code_size);
   printf ("\nAfter the code\n");
   hex_dump (mh->code + mh->code_size, 0, 64);
 */
-       mono_metadata_free_mh (mh);
+               mono_metadata_free_mh (mh);
+       }
 }
 
 static char *
@@ -721,6 +737,39 @@ pinvoke_info (MonoImage *m, guint32 mindex)
        return NULL;
 }
 
+/*
+ * dump_cattrs_for_type_params
+ *
+ * @m: 
+ * @token: TypeOrMethodDef token, owner for GenericParam
+ *
+ * Dumps the custom attributes for @token's type parameters
+ */
+static void
+dump_cattrs_for_type_params (MonoImage *m, guint32 token, const char *indent)
+{
+       MonoTableInfo *tdef  = &m->tables [MONO_TABLE_GENERICPARAM];
+       guint32 cols [MONO_GENERICPARAM_SIZE];
+       guint32 owner = 0, i;
+       GList *list = NULL;
+
+       if (! (i = mono_metadata_get_generic_param_row (m, token, &owner)))
+               return;
+
+       mono_metadata_decode_row (tdef, i - 1, cols, MONO_GENERICPARAM_SIZE);
+       do {
+               list = dis_get_custom_attrs (m, mono_metadata_make_token (MONO_TABLE_GENERICPARAM, i));
+               if (list) {
+                       fprintf (output, "%s.param type %s\n", indent, mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
+                       dump_cattrs_list (list, indent);
+               }
+
+               if (++i > tdef->rows)
+                       break;
+               mono_metadata_decode_row (tdef, i - 1, cols, MONO_GENERICPARAM_SIZE);
+       } while (cols [MONO_GENERICPARAM_OWNER] == owner);
+}
+
 static void
 dump_cattrs_for_method_params (MonoImage *m, guint32 midx, MonoMethodSignature *sig) {
        MonoTableInfo *methodt;
@@ -773,7 +822,7 @@ dump_cattrs_for_method_params (MonoImage *m, guint32 midx, MonoMethodSignature *
  * This routine displays the methods in the Method Table from @start to @end
  */
 static void
-dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 end, MonoGenericContext *context)
+dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 end, MonoGenericContainer *type_container)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_METHOD];
        guint32 cols [MONO_METHOD_SIZE];
@@ -788,9 +837,8 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en
        for (i = start; i < end; i++){
                MonoMethodSignature *ms;
                MonoGenericContainer *container;
-               MonoGenericContext *method_context = context;
                char *flags, *impl_flags;
-               const char *sig;
+               const char *sig, *method_name;
                char *sig_str;
                guint32 token;
 
@@ -799,18 +847,25 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en
                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_IMPLFLAGS]);
+               impl_flags = get_method_impl_flags (cols [MONO_METHOD_IMPLFLAGS]);
 
                sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
                mono_metadata_decode_blob_size (sig, &sig);
 
-               container = mono_metadata_load_generic_params (
-                       m, MONO_TOKEN_METHOD_DEF | (i + 1), context ? context->container : NULL);
+               container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | (i + 1), type_container);
                if (container)
-                       method_context = (MonoGenericContext *) container;
-
-               ms = mono_metadata_parse_method_signature_full (m, method_context, i + 1, sig, &sig);
-               sig_str = dis_stringify_method_signature (m, ms, i + 1, method_context, FALSE);
+                       mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | (i + 1), container);
+               else 
+                       container = type_container;
+
+               ms = mono_metadata_parse_method_signature_full (m, container, i + 1, sig, &sig);
+               if (ms != NULL){
+                       sig_str = dis_stringify_method_signature (m, ms, i + 1, container, FALSE);
+                       method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
+               } else {
+                       sig_str = NULL;
+                       method_name = g_strdup ("<NULL METHOD SIGNATURE>");
+               }
 
                fprintf (output, "    // method line %d\n", i + 1);
                fprintf (output, "    .method %s", flags);
@@ -832,15 +887,19 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en
                
                fprintf (output, "    {\n");
                dump_cattrs (m, token, "        ");
+               dump_cattrs_for_type_params (m, MONO_TOKEN_METHOD_DEF | (i + 1), "        ");
                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]);
                dump_declarative_security (m, OBJECT_TYPE_METHODDEF, i + 1, "        ");
                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], method_context);
-               fprintf (output, "    } // end of method %s::%s\n\n", klass_name, sig_str);
+                       dis_code (m, token, cols [MONO_METHOD_RVA], container);
+               if (klass_name)
+                       fprintf (output, "    } // end of method %s::%s\n\n", klass_name, method_name);
+               else
+                       fprintf (output, "    } // end of global method %s\n\n", method_name);
                mono_metadata_free_method_signature (ms);
                g_free (sig_str);
        }
@@ -874,7 +933,7 @@ table_locator (const void *a, const void *b)
 }
 
 static void
-dis_property_methods (MonoImage *m, guint32 prop, MonoGenericContext *context)
+dis_property_methods (MonoImage *m, guint32 prop, MonoGenericContainer *container)
 {
        guint start, end;
        MonoTableInfo *msemt = &m->tables [MONO_TABLE_METHODSEMANTICS];
@@ -887,13 +946,13 @@ dis_property_methods (MonoImage *m, guint32 prop, MonoGenericContext *context)
                mono_metadata_decode_row (msemt, start, cols, MONO_METHOD_SEMA_SIZE);
                if (!should_include_method (cols [MONO_METHOD_SEMA_METHOD]))
                        continue;
-               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD], context, TRUE);
+               sig = dis_stringify_method_signature_full (m, NULL, cols [MONO_METHOD_SEMA_METHOD], container, TRUE, FALSE);
                fprintf (output, "\t\t%s %s\n", type [cols [MONO_METHOD_SEMA_SEMANTICS]], sig);
                g_free (sig);
        }
 }
 static char*
-dis_property_signature (MonoImage *m, guint32 prop_idx, MonoGenericContext *context)
+dis_property_signature (MonoImage *m, guint32 prop_idx, MonoGenericContainer *container)
 {
        MonoTableInfo *propt = &m->tables [MONO_TABLE_PROPERTY];
        const char *ptr;
@@ -911,29 +970,28 @@ dis_property_signature (MonoImage *m, guint32 prop_idx, MonoGenericContext *cont
        prop_flags = cols [MONO_PROPERTY_FLAGS];
        ptr = mono_metadata_blob_heap (m, cols [MONO_PROPERTY_TYPE]);
        mono_metadata_decode_blob_size (ptr, &ptr);
-       /* ECMA claims 0x08 ... */
-       if (*ptr != 0x28 && *ptr != 0x08)
-               g_warning("incorrect signature in propert blob: 0x%x", *ptr);
+       if (!(*ptr & 0x08))
+               g_warning("incorrect signature in property blob: 0x%x", *ptr);
+       if (*ptr & 0x20)
+               g_string_append (res, "instance ");
        ptr++;
        pcount = mono_metadata_decode_value (ptr, &ptr);
-       type = mono_metadata_parse_type_full (m, context, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       type = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, ptr, &ptr);
        blurb = dis_stringify_type (m, type, TRUE);
        if (prop_flags & 0x0200)
                g_string_append (res, "specialname ");
        if (prop_flags & 0x0400)
                g_string_append (res, "rtspecialname ");
        qk = get_escaped_name (name);
-       g_string_sprintfa (res, "%s %s (", blurb, qk);
+       g_string_append_printf (res, "%s %s (", blurb, qk);
        g_free (qk);
        g_free (blurb);
-       mono_metadata_free_type (type);
        for (i = 0; i < pcount; i++) {
                if (i)
                        g_string_append (res, ", ");
-               param = mono_metadata_parse_type_full (m, context, MONO_PARSE_PARAM, 0, ptr, &ptr);
+               param = mono_metadata_parse_type_full (m, container, MONO_PARSE_PARAM, 0, ptr, &ptr);
                blurb = dis_stringify_param (m, param);
                g_string_append (res, blurb);
-               mono_metadata_free_type (param);
                g_free (blurb);
        }
        g_string_append_c (res, ')');
@@ -944,23 +1002,23 @@ dis_property_signature (MonoImage *m, guint32 prop_idx, MonoGenericContext *cont
 }
 
 static void
-dis_property_list (MonoImage *m, guint32 typedef_row, MonoGenericContext *context)
+dis_property_list (MonoImage *m, guint32 typedef_row, MonoGenericContainer *container)
 {
        guint start, end, i;
        start = mono_metadata_properties_from_typedef (m, typedef_row, &end);
 
        for (i = start; i < end; ++i) {
-               char *sig = dis_property_signature (m, i, context);
+               char *sig = dis_property_signature (m, i, container);
                fprintf (output, "\t.property %s\n\t{\n", sig);
                dump_cattrs (m, MONO_TOKEN_PROPERTY | (i + 1), "\t\t");
-               dis_property_methods (m, i, context);
+               dis_property_methods (m, i, container);
                fprintf (output, "\t}\n");
                g_free (sig);
        }
 }
 
 static char*
-dis_event_signature (MonoImage *m, guint32 event_idx, MonoGenericContext *context)
+dis_event_signature (MonoImage *m, guint32 event_idx, MonoGenericContainer *container)
 {
        MonoTableInfo *et = &m->tables [MONO_TABLE_EVENT];
        char *type, *result, *esname;
@@ -970,14 +1028,14 @@ dis_event_signature (MonoImage *m, guint32 event_idx, MonoGenericContext *contex
        
        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], context);
+       type = get_typedef_or_ref (m, cols [MONO_EVENT_TYPE], container);
        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_string_append_printf (res, "%s %s", type, esname);
 
        g_free (type);
        g_free (esname);
@@ -987,7 +1045,7 @@ dis_event_signature (MonoImage *m, guint32 event_idx, MonoGenericContext *contex
 }
 
 static void
-dis_event_methods (MonoImage *m, guint32 event, MonoGenericContext *context)
+dis_event_methods (MonoImage *m, guint32 event, MonoGenericContainer *container)
 {
        guint start, end;
        MonoTableInfo *msemt = &m->tables [MONO_TABLE_METHODSEMANTICS];
@@ -1000,7 +1058,7 @@ dis_event_methods (MonoImage *m, guint32 event, MonoGenericContext *context)
                mono_metadata_decode_row (msemt, start, cols, MONO_METHOD_SEMA_SIZE);
                if (!should_include_method (cols [MONO_METHOD_SEMA_METHOD]))
                        continue;
-               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD], context, TRUE);
+               sig = dis_stringify_method_signature_full (m, NULL, cols [MONO_METHOD_SEMA_METHOD], container, TRUE, FALSE);
                switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
                case METHOD_SEMANTIC_OTHER:
                        type = ".other"; break;
@@ -1019,23 +1077,23 @@ dis_event_methods (MonoImage *m, guint32 event, MonoGenericContext *context)
 }
 
 static void
-dis_event_list (MonoImage *m, guint32 typedef_row, MonoGenericContext *context)
+dis_event_list (MonoImage *m, guint32 typedef_row, MonoGenericContainer *container)
 {
        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, context);
+               char *sig = dis_event_signature (m, i, container);
                fprintf (output, "\t.event %s\n\t{\n", sig);
                dump_cattrs (m, MONO_TOKEN_EVENT | (i + 1), "\t\t");
-               dis_event_methods (m, i, context);
+               dis_event_methods (m, i, container);
                fprintf (output, "\t}\n");
                g_free (sig);
        }
 }
 
 static void
-dis_interfaces (MonoImage *m, guint32 typedef_row, MonoGenericContext *context)
+dis_interfaces (MonoImage *m, guint32 typedef_row, MonoGenericContainer *container)
 {
        plocator_t loc;
        guint start;
@@ -1068,7 +1126,7 @@ dis_interfaces (MonoImage *m, guint32 typedef_row, MonoGenericContext *context)
                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], context);
+               intf = get_typedef_or_ref (m, cols [MONO_INTERFACEIMPL_INTERFACE], container);
                if (first_interface) {
                        fprintf (output, "  \timplements %s", intf);
                        first_interface = 0;
@@ -1114,10 +1172,16 @@ dis_type (MonoImage *m, int n, int is_nested, int forward)
 
        name = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]);
        nspace = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]);
-       if (*nspace && !is_nested) 
-               fprintf (output, ".namespace %s\n{\n", nspace);
+       if (*nspace && !is_nested) {
+               char *esnspace;
+               esnspace = get_escaped_name (nspace);
+               fprintf (output, ".namespace %s\n{\n", esnspace);
+               g_free (esnspace);
+       }
 
        container = mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | (n + 1), NULL);
+       if (container)
+               mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_TYPE_DEF | (n + 1), container);
 
        esname = get_escaped_name (name);
        if ((cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK) == TYPE_ATTRIBUTE_CLASS){
@@ -1125,13 +1189,12 @@ dis_type (MonoImage *m, int n, int is_nested, int forward)
                
                 param = get_generic_param (m, container);
                if (param) {
-                       fprintf (output, param);
+                       fprintf (output, "%s", param);
                        g_free (param);
                }
                 fprintf (output, "\n");
                if (cols [MONO_TYPEDEF_EXTENDS]) {
-                       char *base = get_typedef_or_ref (
-                               m, cols [MONO_TYPEDEF_EXTENDS], (MonoGenericContext *) container);
+                       char *base = get_typedef_or_ref (m, cols [MONO_TYPEDEF_EXTENDS], container);
                        fprintf (output, "  \textends %s\n", base);
                        g_free (base);
                }
@@ -1140,17 +1203,18 @@ dis_type (MonoImage *m, int n, int is_nested, int forward)
 
                 param = get_generic_param (m, container);
                if (param) {
-                       fprintf (output, param);
+                       fprintf (output, "%s", param);
                        g_free (param);
                }
                fprintf (output, "\n");
        }
 
        g_free (esname);
-       dis_interfaces (m, n + 1, (MonoGenericContext *) container);
+       dis_interfaces (m, n + 1, container);
        fprintf (output, "  {\n");
         if (!forward) {
                dump_cattrs (m, MONO_TOKEN_TYPE_DEF | (n + 1), "    ");
+               dump_cattrs_for_type_params (m, MONO_TOKEN_TYPE_DEF | (n + 1), "    ");
                dump_declarative_security (m, OBJECT_TYPE_TYPEDEF, (n + 1), "    ");
 
                if (mono_metadata_packing_from_typedef (m, n + 1, &packing_size, &class_size)) {
@@ -1168,7 +1232,7 @@ dis_type (MonoImage *m, int n, int is_nested, int forward)
                        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, (MonoGenericContext *) container);
+                       dis_field_list (m, cols [MONO_TYPEDEF_FIELD_LIST] - 1, last, container);
                fprintf (output, "\n");
 
                if (next_is_valid)
@@ -1177,10 +1241,10 @@ dis_type (MonoImage *m, int n, int is_nested, int forward)
                        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, (MonoGenericContext *) container);
+                       dis_method_list (name, m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last, container);
 
-               dis_property_list (m, n, (MonoGenericContext *) container);
-               dis_event_list (m, n, (MonoGenericContext *) container);
+               dis_property_list (m, n, container);
+               dis_event_list (m, n, container);
         }
 
        t = &m->tables [MONO_TABLE_NESTEDCLASS];
@@ -1210,9 +1274,6 @@ dis_globals (MonoImage *m)
        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);
 
@@ -1242,12 +1303,11 @@ dis_globals (MonoImage *m)
                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, NULL);
+               dis_method_list (NULL, m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last, NULL);
 
 }
 
-static void
-dis_mresource (MonoImage *m)
+static void dis_resources_worker (MonoImage *m, gboolean just_print)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_MANIFESTRESOURCE];
        int i;
@@ -1260,10 +1320,21 @@ dis_mresource (MonoImage *m)
 
                mono_metadata_decode_row (t, i, cols, MONO_MANIFEST_SIZE);
                name = mono_metadata_string_heap (m, cols [MONO_MANIFEST_NAME]);
+
+               if (just_print)
+                       fprintf (output, "%8x: %s", cols [MONO_MANIFEST_OFFSET], name);
                
-               if (! (res = mono_image_get_resource (m, cols [MONO_MANIFEST_OFFSET], &size)))
+               if (! (res = mono_image_get_resource (m, cols [MONO_MANIFEST_OFFSET], &size))) {
+                       if (just_print)
+                               fprintf (output, " (absent from image)\n");
                        continue;       
+               }
 
+               if (just_print) {
+                       fprintf (output, " (size %u)\n", size);
+                       continue;
+               }
+               
                if ( (fp = fopen (name, "ab")) ) {
                        if (ftell (fp) == 0)
                                fwrite (res, size, 1, fp);
@@ -1276,6 +1347,107 @@ dis_mresource (MonoImage *m)
        }               
 }
 
+static void
+dis_mresource (MonoImage *m)
+{
+       dis_resources_worker (m, FALSE);
+}
+
+static void
+dis_presource (MonoImage *m)
+{
+       dis_resources_worker (m, TRUE);
+}
+
+static char *
+exported_type_flags (guint32 flags)
+{
+       static char buffer [1024];
+       int visibility = flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+
+       buffer [0] = 0;
+
+       if (flags & TYPE_ATTRIBUTE_FORWARDER) {
+               strcat (buffer, "forwarder ");
+               return buffer;
+       }
+
+       strcat (buffer, map (visibility, visibility_map));
+       return buffer;
+}
+
+static char *
+get_escaped_fullname (MonoImage *m, guint32 nspace_idx, guint32 name_idx)
+{
+       const char *name, *nspace;
+       char *fullname, *esfullname;
+
+       nspace = mono_metadata_string_heap (m, nspace_idx);
+       name = mono_metadata_string_heap (m, name_idx);
+
+       fullname = g_strdup_printf ("%s%s%s", nspace, *nspace ? "." : "", name);
+       esfullname = get_escaped_name (fullname);
+
+       g_free (fullname);
+
+       return esfullname;
+}
+
+static void
+dis_exported_types (MonoImage *m)
+{
+       MonoTableInfo *t = &m->tables [MONO_TABLE_EXPORTEDTYPE];
+       int i;
+
+       for (i = 1; i <= t->rows; i++) {
+               char *fullname;
+               guint32 impl, idx, type_token;
+               guint32 cols [MONO_EXP_TYPE_SIZE];
+
+               mono_metadata_decode_row (t, i - 1, cols, MONO_EXP_TYPE_SIZE);
+
+               fullname = get_escaped_fullname (m, cols [MONO_EXP_TYPE_NAMESPACE], cols [MONO_EXP_TYPE_NAME]);
+
+               fprintf (output, "\n");
+               fprintf (output, ".class extern %s%s\n", exported_type_flags (cols [MONO_EXP_TYPE_FLAGS]), fullname);
+               fprintf (output, "{\n");
+
+               g_free (fullname);
+
+               impl = cols [MONO_EXP_TYPE_IMPLEMENTATION];
+               if (impl) {
+                       idx = impl >> MONO_IMPLEMENTATION_BITS;
+                       switch (impl & MONO_IMPLEMENTATION_MASK) {
+                       case MONO_IMPLEMENTATION_FILE:
+                               fprintf (output, "    .file '%s'\n",
+                                       mono_metadata_string_heap (m, mono_metadata_decode_row_col (&m->tables [MONO_TABLE_FILE], idx - 1, MONO_FILE_NAME)));
+                               break;
+                       case MONO_IMPLEMENTATION_ASSEMBLYREF:
+                               fprintf (output, "    .assembly extern '%s'\n",
+                                       mono_metadata_string_heap (m, mono_metadata_decode_row_col (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, MONO_ASSEMBLYREF_NAME)));
+                               break;
+                       case MONO_IMPLEMENTATION_EXP_TYPE:
+                               fullname = get_escaped_fullname (
+                                       m,
+                                       mono_metadata_decode_row_col (&m->tables [MONO_TABLE_EXPORTEDTYPE], idx - 1, MONO_EXP_TYPE_NAMESPACE),
+                                       mono_metadata_decode_row_col (&m->tables [MONO_TABLE_EXPORTEDTYPE], idx - 1, MONO_EXP_TYPE_NAME));
+                               fprintf (output, "    .class extern %s\n", fullname);
+                               g_free (fullname);
+                               break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+                       }
+               }
+
+               type_token = cols [MONO_EXP_TYPE_TYPEDEF];
+               if (type_token)
+                       fprintf (output, "    .class 0x%08x\n", type_token | MONO_TOKEN_TYPE_DEF);
+
+               fprintf (output, "}\n");
+       }
+}
+
 /**
  * dis_types:
  * @m: metadata context
@@ -1299,6 +1471,24 @@ dis_types (MonoImage *m, int forward)
        }
 }
 
+static const char *
+get_uninitialized_data_type (guint32 size)
+{
+       switch (size) {
+       case 1:
+               return "int8";
+       case 2:
+               return "int16";
+       case 4:
+               return "int32";
+       case 8:
+               return "int64";
+       default:
+               g_error ("get_uninitialized_data_type for size: %d\n", size);
+       }
+       return NULL;
+}
+
 /**
  * dis_data:
  * @m: metadata context
@@ -1312,7 +1502,8 @@ dis_data (MonoImage *m)
        MonoTableInfo *ft = &m->tables [MONO_TABLE_FIELD];
        int i, b;
        const char *rva, *sig;
-       guint32 align, size;
+       guint32 size;
+       gint align;
        guint32 cols [MONO_FIELD_RVA_SIZE];
        MonoType *type;
 
@@ -1326,13 +1517,18 @@ dis_data (MonoImage *m)
                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);
+
+               if (rva) {
+                       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);
+               } else
+                       fprintf (output, ".data D_%08x = %s [%d]\n",
+                               cols [MONO_FIELD_RVA_RVA], get_uninitialized_data_type (size), size);
        }
 }
 
@@ -1362,6 +1558,8 @@ struct {
        { "--methodspec",  MONO_TABLE_METHODSPEC,       dump_table_methodspec },
        { "--moduleref",   MONO_TABLE_MODULEREF,        dump_table_moduleref },
        { "--module",      MONO_TABLE_MODULE,           dump_table_module },
+       { "--mresources",  0,   dis_mresource },
+       { "--presources", 0, dis_presource },
        { "--nested",      MONO_TABLE_NESTEDCLASS,      dump_table_nestedclass },
        { "--param",       MONO_TABLE_PARAM,            dump_table_param },
        { "--parconst",    MONO_TABLE_GENERICPARAMCONSTRAINT, dump_table_parconstraint },
@@ -1371,8 +1569,16 @@ struct {
        { "--typeref",     MONO_TABLE_TYPEREF,          dump_table_typeref },
        { "--typespec",    MONO_TABLE_TYPESPEC,         dump_table_typespec },
        { "--implmap",     MONO_TABLE_IMPLMAP,          dump_table_implmap },
+       { "--fieldrva",    MONO_TABLE_FIELDRVA,     dump_table_fieldrva },
        { "--standalonesig", MONO_TABLE_STANDALONESIG,  dump_table_standalonesig },
-       { "--blob",        0,                   dump_stream_blob },
+       { "--methodptr", MONO_TABLE_METHOD_POINTER,  dump_table_methodptr },
+       { "--fieldptr", MONO_TABLE_FIELD_POINTER,  dump_table_fieldptr },
+       { "--paramptr", MONO_TABLE_PARAM_POINTER,  dump_table_paramptr },
+       { "--eventptr", MONO_TABLE_EVENT_POINTER,  dump_table_eventptr },
+       { "--propertyptr", MONO_TABLE_PROPERTY_POINTER,  dump_table_propertyptr },
+       { "--blob", 0, dump_stream_blob },
+       { "--strings", 0, dump_stream_strings },
+       { "--userstrings", 0, dump_stream_us },
        { NULL, -1, }
 };
 
@@ -1385,18 +1591,19 @@ struct {
 static void
 disassemble_file (const char *file)
 {
-       MonoAssembly *ass;
        MonoImageOpenStatus status;
        MonoImage *img;
+       MonoAssembly *assembly;
+
 
-       ass = mono_assembly_open (file, &status);
-       if (ass == NULL){
+       img = mono_image_open (file, &status);
+       if (!img) {
                fprintf (stderr, "Error while trying to process %s\n", file);
                return;
+       } else {
+               assembly = mono_assembly_load_from_full (img, file, &status, FALSE);
        }
 
-       img = ass->image;
-
        setup_filter (img);
 
        if (dump_table != -1){
@@ -1410,6 +1617,8 @@ disassemble_file (const char *file)
                dis_directive_mresource (img);
                dis_directive_module (img);
                dis_directive_moduleref (img);
+               dis_exported_types (img);
+               dis_nt_header (img);
                 if (dump_managed_resources)
                        dis_mresource (img);
                if (dump_forward_decls) {
@@ -1602,6 +1811,109 @@ load_filter (const char* filename)
        sort_filter_elems ();
 }
 
+
+static gboolean
+try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2,
+                                       const gchar *path3, const gchar *path4, gboolean refonly)
+{
+       gchar *fullpath;
+
+       *assembly = NULL;
+       fullpath = g_build_filename (path1, path2, path3, path4, NULL);
+       if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR))
+               *assembly = mono_assembly_open_full (fullpath, NULL, refonly);
+
+       g_free (fullpath);
+       return (*assembly != NULL);
+}
+
+static MonoAssembly *
+real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolean refonly)
+{
+       MonoAssembly *result = NULL;
+       gchar **path;
+       gchar *filename;
+       const gchar *local_culture;
+       gint len;
+
+       if (!culture || *culture == '\0') {
+               local_culture = "";
+       } else {
+               local_culture = culture;
+       }
+
+       filename =  g_strconcat (name, ".dll", NULL);
+       len = strlen (filename);
+
+       for (path = search_path; *path; path++) {
+               if (**path == '\0')
+                       continue; /* Ignore empty ApplicationBase */
+
+               /* See test cases in bug #58992 and bug #57710 */
+               /* 1st try: [culture]/[name].dll (culture may be empty) */
+               strcpy (filename + len - 4, ".dll");
+               if (try_load_from (&result, *path, local_culture, "", filename, refonly))
+                       break;
+
+               /* 2nd try: [culture]/[name].exe (culture may be empty) */
+               strcpy (filename + len - 4, ".exe");
+               if (try_load_from (&result, *path, local_culture, "", filename, refonly))
+                       break;
+
+               /* 3rd try: [culture]/[name]/[name].dll (culture may be empty) */
+               strcpy (filename + len - 4, ".dll");
+               if (try_load_from (&result, *path, local_culture, name, filename, refonly))
+                       break;
+
+               /* 4th try: [culture]/[name]/[name].exe (culture may be empty) */
+               strcpy (filename + len - 4, ".exe");
+               if (try_load_from (&result, *path, local_culture, name, filename, refonly))
+                       break;
+       }
+
+       g_free (filename);
+       return result;
+}
+
+/*
+ * Try to load referenced assemblies from assemblies_path.
+ */
+static MonoAssembly *
+monodis_preload (MonoAssemblyName *aname,
+                                gchar **assemblies_path,
+                                gpointer user_data)
+{
+       MonoAssembly *result = NULL;
+       gboolean refonly = GPOINTER_TO_UINT (user_data);
+
+       if (assemblies_path && assemblies_path [0] != NULL) {
+               result = real_load (assemblies_path, aname->culture, aname->name, refonly);
+       }
+
+       return result;
+}
+
+static GList *loaded_assemblies = NULL;
+
+static void
+monodis_assembly_load_hook (MonoAssembly *assembly, gpointer user_data)
+{
+       loaded_assemblies = g_list_prepend (loaded_assemblies, assembly);
+}
+
+static MonoAssembly *
+monodis_assembly_search_hook (MonoAssemblyName *aname, gpointer user_data)
+{
+        GList *tmp;
+
+       for (tmp = loaded_assemblies; tmp; tmp = tmp->next) {
+               MonoAssembly *ass = tmp->data;
+               if (mono_assembly_names_equal (aname, &ass->aname))
+                      return ass;
+       }
+       return NULL;
+}
+
 static void
 usage (void)
 {
@@ -1615,9 +1927,9 @@ usage (void)
                if (((i-2) % 5) == 0)
                        g_string_append_c (args, '\n');
        }
-       g_string_append (args, "[--forward-decls]\n[--mresources]");
+       g_string_append (args, "[--forward-decls]");
        fprintf (stderr,
-                "monodis -- Mono Common Intermediate Language Dissassembler\n" 
+                "monodis -- Mono Common Intermediate Language Disassembler\n" 
                 "Usage is: monodis %s file ..\n", args->str);
        exit (1);
 }
@@ -1652,6 +1964,7 @@ main (int argc, char *argv [])
                                                 argv [i]+9, strerror (errno));
                                        exit (1);
                                }
+                               dump_managed_resources = TRUE;
                                continue;
                        } else if (strncmp (argv [i], "--filter=", 9) == 0) {
                                load_filter (argv [i]+9);
@@ -1659,9 +1972,6 @@ main (int argc, char *argv [])
                        } else if (strcmp (argv [i], "--forward-decls") == 0) {
                                dump_forward_decls = TRUE;
                                continue;
-                       } else if (strcmp (argv [i], "--mresources") == 0) {
-                               dump_managed_resources = TRUE;
-                               continue;
                        } else if (strcmp (argv [i], "--help") == 0)
                                usage ();
                        for (j = 0; table_list [j].name != NULL; j++) {
@@ -1677,6 +1987,9 @@ main (int argc, char *argv [])
        if (input_files == NULL)
                usage ();
 
+       mono_install_assembly_load_hook (monodis_assembly_load_hook, NULL);
+       mono_install_assembly_search_hook (monodis_assembly_search_hook, NULL);
+
        /*
         * If we just have one file, use the corlib version it requires.
         */
@@ -1684,6 +1997,9 @@ main (int argc, char *argv [])
                char *filename = input_files->data;
 
                mono_init_from_assembly (argv [0], filename);
+
+               mono_install_assembly_preload_hook (monodis_preload, GUINT_TO_POINTER (FALSE));
+
                disassemble_file (filename);
        } else {
                mono_init (argv [0]);