Merge pull request #5382 from kumpera/pedump_fix
authorRodrigo Kumpera <kumpera@users.noreply.github.com>
Wed, 16 Aug 2017 04:58:17 +0000 (21:58 -0700)
committerGitHub <noreply@github.com>
Wed, 16 Aug 2017 04:58:17 +0000 (21:58 -0700)
Address pedump issues from https://bugzilla.xamarin.com/show_bug.cgi?id=58168

mono/metadata/metadata-verify.c
mono/metadata/metadata.c
mono/metadata/tabledefs.h
mono/metadata/verify.h
tools/pedump/pedump.c

index f31983c303f3a9b039fb44ba970437689a3a7114..f0299605583b7a7686f78031422521334b25ee4f 100644 (file)
@@ -1894,8 +1894,13 @@ handle_enum:
                FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid boxed object type %x", sub_type));
        }
 
-
        case MONO_TYPE_CLASS:
+               if (klass && klass->enumtype) {
+                       klass = klass->element_class;
+                       type = klass->byval_arg.type;
+                       goto handle_enum;
+               }
+
                if (klass != mono_defaults.systemtype_class)
                        FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid class parameter type %s:%s ",klass->name_space, klass->name));
                *_ptr = ptr;
@@ -2413,7 +2418,7 @@ verify_typedef_table (VerifyContext *ctx)
        for (i = 0; i < table->rows; ++i) {
                mono_metadata_decode_row (table, i, data, MONO_TYPEDEF_SIZE);
                if (data [MONO_TYPEDEF_FLAGS] & INVALID_TYPEDEF_FLAG_BITS)
-                       ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d invalid flags field 0x%08x", i, data [MONO_TYPEDEF_FLAGS]));
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d invalid flags field 0x%08x rejected bits: 0x%08x", i, data [MONO_TYPEDEF_FLAGS], data [MONO_TYPEDEF_FLAGS] & INVALID_TYPEDEF_FLAG_BITS));
 
                if ((data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_LAYOUT_MASK) == 0x18)
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d invalid class layout 0x18", i));
@@ -2962,8 +2967,11 @@ verify_cattr_table_full (VerifyContext *ctx)
                /*This can't fail since this is checked in is_valid_cattr_blob*/
                g_assert (decode_signature_header (ctx, data [MONO_CUSTOM_ATTR_VALUE], &size, &ptr));
 
-               if (!is_valid_cattr_content (ctx, ctor, ptr, size))
-                       ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute content row %d Value field 0x%08x", i, data [MONO_CUSTOM_ATTR_VALUE]));
+               if (!is_valid_cattr_content (ctx, ctor, ptr, size)) {
+                       char *ctor_name =  mono_method_full_name (ctor, TRUE);
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute content row %d Value field 0x%08x ctor: %s", i, data [MONO_CUSTOM_ATTR_VALUE], ctor_name));
+                       g_free (ctor_name);
+               }
        }
 }
 
index b41dbf4e8186eff36f490f2a4d4844b032c73295..0ba52ce0b7359d578d94ed18991d85ce6a2cbb15 100644 (file)
@@ -1641,6 +1641,16 @@ mono_metadata_init (void)
 {
        int i;
 
+       /* We guard against double initialization due to how pedump in verification mode works.
+       Until runtime initialization is properly factored to work with what it needs we need workarounds like this.
+       FIXME: https://bugzilla.xamarin.com/show_bug.cgi?id=58793
+       */
+       static gboolean inited;
+
+       if (inited)
+               return;
+       inited = TRUE;
+
        type_cache = g_hash_table_new (mono_type_hash, mono_type_equal);
 
        for (i = 0; i < NBUILTIN_TYPES (); ++i)
index 90cb93e050c3f4391107e77567d1c3667d00c5b7..e3aa51b4cf5f8673bf6f9980648eb88d48084698 100644 (file)
@@ -127,6 +127,8 @@ enum {
 
 #define TYPE_ATTRIBUTE_IMPORT                0x00001000
 #define TYPE_ATTRIBUTE_SERIALIZABLE          0x00002000
+#define TYPE_ATTRIBUTE_WINDOWS_RUNTIME       0x00004000
+
 
 #define TYPE_ATTRIBUTE_STRING_FORMAT_MASK    0x00030000
 #define TYPE_ATTRIBUTE_ANSI_CLASS            0x00000000
index ed7920e69f9346ecadb255199f81b9529eee6fc2..162ef4434e6829119b29a2b82ed5d11936788dc5 100644 (file)
@@ -8,7 +8,6 @@
 #include <mono/metadata/metadata.h>
 #include <mono/metadata/image.h>
 #include <mono/metadata/loader.h>
-#include <mono/metadata/class-internals.h>
 #include <glib.h> /* GSList dep */
 
 MONO_BEGIN_DECLS
@@ -53,7 +52,7 @@ typedef struct {
 
 typedef struct {
        MonoVerifyInfo info;
-       MonoExceptionType exception_type : 8; /*should be one of MONO_EXCEPTION_* */
+       int8_t exception_type; /*should be one of MONO_EXCEPTION_* */
 } MonoVerifyInfoExtended;
 
 
index 322185faaf7dfd8049a94c213c41a76be9beb4b7..722d42f9828ab161d75a8d757594b4ae090f7bf1 100644 (file)
@@ -348,7 +348,7 @@ dump_dotnet_iinfo (MonoImage *image)
 }
 
 static int
-dump_verify_info (MonoImage *image, int flags)
+dump_verify_info (MonoImage *image, int flags, gboolean valid_only)
 {
        GSList *errors, *tmp;
        int count = 0, verifiable = 0;
@@ -387,6 +387,9 @@ dump_verify_info (MonoImage *image, int flags)
 
                        for (tmp = errors; tmp; tmp = tmp->next) {
                                MonoVerifyInfo *info = (MonoVerifyInfo *)tmp->data;
+                               if (info->status == MONO_VERIFY_NOT_VERIFIABLE && valid_only)
+                                       continue;
+
                                g_print ("%s: %s\n", desc [info->status], info->message);
                                if (info->status == MONO_VERIFY_ERROR) {
                                        count++;
@@ -426,51 +429,83 @@ verify_image_file (const char *fname)
                "Ok", "Error", "Warning", NULL, "CLS", NULL, NULL, NULL, "Not Verifiable"
        };
 
-       image = mono_image_open_raw (fname, &status);
-       if (!image) {
-               printf ("Could not open %s\n", fname);
-               return 1;
-       }
+       if (!strstr (fname, "mscorlib.dll")) {
+               image = mono_image_open_raw (fname, &status);
+               if (!image) {
+                       printf ("Could not open %s\n", fname);
+                       return 1;
+               }
 
-       if (!mono_verifier_verify_pe_data (image, &errors))
-               goto invalid_image;
+               if (!mono_verifier_verify_pe_data (image, &errors))
+                       goto invalid_image;
 
-       if (!mono_image_load_pe_data (image)) {
-               printf ("Could not load pe data for assembly %s\n", fname);
-               return 1;
-       }
+               if (!mono_image_load_pe_data (image)) {
+                       printf ("Could not load pe data for assembly %s\n", fname);
+                       return 1;
+               }
 
-       if (!mono_verifier_verify_cli_data (image, &errors))
-               goto invalid_image;
+               if (!mono_verifier_verify_cli_data (image, &errors))
+                       goto invalid_image;
 
-       if (!mono_image_load_cli_data (image)) {
-               printf ("Could not load cli data for assembly %s\n", fname);
-               return 1;
-       }
+               if (!mono_image_load_cli_data (image)) {
+                       printf ("Could not load cli data for assembly %s\n", fname);
+                       return 1;
+               }
 
-       if (!mono_verifier_verify_table_data (image, &errors))
-               goto invalid_image;
+               if (!mono_verifier_verify_table_data (image, &errors))
+                       goto invalid_image;
+
+               mono_image_load_names (image);
 
-       mono_image_load_names (image);
+               /*fake an assembly for class loading to work*/
+               assembly = g_new0 (MonoAssembly, 1);
+               assembly->in_gac = FALSE;
+               assembly->image = image;
+               image->assembly = assembly;
+               mono_assembly_fill_assembly_name (image, &assembly->aname);
 
-       /*fake an assembly for class loading to work*/
-       assembly = g_new0 (MonoAssembly, 1);
-       assembly->in_gac = FALSE;
-       assembly->image = image;
-       image->assembly = assembly;
-       mono_assembly_fill_assembly_name (image, &assembly->aname);
+               /*Finish initializing the runtime*/
+               mono_install_assembly_load_hook (pedump_assembly_load_hook, NULL);
+               mono_install_assembly_search_hook (pedump_assembly_search_hook, NULL);
 
-       /*Finish initializing the runtime*/
-       mono_install_assembly_load_hook (pedump_assembly_load_hook, NULL);
-       mono_install_assembly_search_hook (pedump_assembly_search_hook, NULL);
+               mono_init_version ("pedump", image->version);
 
-       mono_init_version ("pedump", image->version);
+               mono_install_assembly_preload_hook (pedump_preload, GUINT_TO_POINTER (FALSE));
 
-       mono_install_assembly_preload_hook (pedump_preload, GUINT_TO_POINTER (FALSE));
+               mono_icall_init ();
+               mono_marshal_init ();
+       } else {
+               /*Finish initializing the runtime*/
+               mono_install_assembly_load_hook (pedump_assembly_load_hook, NULL);
+               mono_install_assembly_search_hook (pedump_assembly_search_hook, NULL);
+
+               mono_init_version ("pedump", NULL);
+
+               mono_install_assembly_preload_hook (pedump_preload, GUINT_TO_POINTER (FALSE));
 
-       mono_icall_init ();
-       mono_marshal_init ();
+               mono_icall_init ();
+               mono_marshal_init ();
+               image = mono_get_corlib ();
+
+               if (!mono_verifier_verify_pe_data (image, &errors))
+                       goto invalid_image;
+
+               if (!mono_image_load_pe_data (image)) {
+                       printf ("Could not load pe data for assembly %s\n", fname);
+                       return 1;
+               }
 
+               if (!mono_verifier_verify_cli_data (image, &errors))
+                       goto invalid_image;
+
+               if (!mono_image_load_cli_data (image)) {
+                       printf ("Could not load cli data for assembly %s\n", fname);
+                       return 1;
+               }
+
+               if (!mono_verifier_verify_table_data (image, &errors))
+                       goto invalid_image;
+       }
 
        if (!verify_partial_md && !mono_verifier_verify_full_table_data (image, &errors))
                goto invalid_image;
@@ -669,6 +704,10 @@ main (int argc, char *argv [])
        if (!file)
                usage ();
 
+       //We have to force the runtime to load the corlib under verification as its own corlib so core types are properly populated in mono_defaults.
+       if (strstr (file, "mscorlib.dll"))
+               g_setenv ("MONO_PATH", g_path_get_dirname (file), 1);
+
 #ifndef DISABLE_PERFCOUNTERS
        mono_perfcounters_init ();
 #endif
@@ -764,7 +803,7 @@ main (int argc, char *argv [])
                        return 4;
                }
 
-               code_result = dump_verify_info (assembly->image, verify_flags);
+               code_result = dump_verify_info (assembly->image, verify_flags, verifier_mode == MONO_VERIFIER_MODE_VALID);
                return code_result ? code_result : image_result;
        } else
                mono_image_close (image);