Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / tools / pedump / pedump.c
index 4bbcc699335a9bc8bd75a9e8e5376de774b74580..b75a8fed5bed87dc07e631fadb9fac3063039a14 100644 (file)
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/tokentype.h>
 #include <mono/metadata/appdomain.h>
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/verify-internals.h>
 #include <mono/metadata/marshal.h>
+#include <mono/metadata/w32handle.h>
 #include "mono/utils/mono-digest.h"
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-counters.h>
@@ -41,6 +42,8 @@ gboolean verify_metadata = FALSE;
 gboolean verify_code = FALSE;
 gboolean verify_partial_md = FALSE;
 
+static char *assembly_directory[2];
+
 static MonoAssembly *pedump_preload (MonoAssemblyName *aname, gchar **assemblies_path, gpointer user_data);
 static void pedump_assembly_load_hook (MonoAssembly *assembly, gpointer user_data);
 static MonoAssembly *pedump_assembly_search_hook (MonoAssemblyName *aname, gpointer user_data);
@@ -347,7 +350,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;
@@ -386,6 +389,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++;
@@ -425,51 +431,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);
+
+               /*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);
+
+               mono_init_version ("pedump", image->version);
+
+               mono_install_assembly_preload_hook (pedump_preload, GUINT_TO_POINTER (FALSE));
 
-       mono_image_load_names (image);
+               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);
 
-       /*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);
+               mono_install_assembly_preload_hook (pedump_preload, GUINT_TO_POINTER (FALSE));
 
-       /*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_icall_init ();
+               mono_marshal_init ();
+               image = mono_get_corlib ();
 
-       mono_init_version ("pedump", image->version);
+               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;
+               }
 
-       mono_install_assembly_preload_hook (pedump_preload, GUINT_TO_POINTER (FALSE));
+               if (!mono_verifier_verify_cli_data (image, &errors))
+                       goto invalid_image;
 
-       mono_icall_init ();
-       mono_marshal_init ();
+               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;
@@ -487,13 +525,21 @@ verify_image_file (const char *fname)
                }
                mono_class_init (klass);
                if (mono_class_has_failure (klass)) {
-                       printf ("Error verifying class(0x%08x) %s.%s a type load error happened\n", token, klass->name_space, klass->name);
+                       MonoError type_load_error;
+                       error_init (&type_load_error);
+                       mono_error_set_for_class_failure (&type_load_error, klass);
+                       printf ("Could not initialize class(0x%08x) %s.%s due to %s\n", token, klass->name_space, klass->name, mono_error_get_message (&type_load_error));
+                       mono_error_cleanup (&type_load_error);
                        ++count;
                }
 
                mono_class_setup_vtable (klass);
                if (mono_class_has_failure (klass)) {
-                       printf ("Error verifying class(0x%08x) %s.%s a type load error happened\n", token, klass->name_space, klass->name);
+                       MonoError type_load_error;
+                       error_init (&type_load_error);
+                       mono_error_set_for_class_failure (&type_load_error, klass);
+                       printf ("Could not initialize vtable of class(0x%08x) %s.%s due to %s\n", token, klass->name_space, klass->name, mono_error_get_message (&type_load_error));
+                       mono_error_cleanup (&type_load_error);
                        ++count;
                }
        }
@@ -523,7 +569,7 @@ try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2,
        *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);
+               *assembly = mono_assembly_open_predicate (fullpath, refonly, FALSE, NULL, NULL, NULL);
 
        g_free (fullpath);
        return (*assembly != NULL);
@@ -591,6 +637,8 @@ pedump_preload (MonoAssemblyName *aname,
        if (assemblies_path && assemblies_path [0] != NULL) {
                result = real_load (assemblies_path, aname->culture, aname->name, refonly);
        }
+       if (!result)
+               result = real_load (assembly_directory, aname->culture, aname->name, refonly);
 
        return result;
 }
@@ -616,6 +664,11 @@ pedump_assembly_search_hook (MonoAssemblyName *aname, gpointer user_data)
        return NULL;
 }
 
+static void
+thread_state_init (MonoThreadUnwindState *ctx)
+{
+}
+
 #define VALID_ONLY_FLAG 0x08000000
 #define VERIFY_CODE_ONLY MONO_VERIFY_ALL + 1 
 #define VERIFY_METADATA_ONLY VERIFY_CODE_ONLY + 1
@@ -632,6 +685,7 @@ main (int argc, char *argv [])
        const char *flag_desc [] = {"error", "warn", "cls", "all", "code", "fail-on-verifiable", "non-strict", "valid-only", "metadata", "partial-md", NULL};
        guint flag_vals [] = {MONO_VERIFY_ERROR, MONO_VERIFY_WARNING, MONO_VERIFY_CLS, MONO_VERIFY_ALL, VERIFY_CODE_ONLY, MONO_VERIFY_FAIL_FAST, MONO_VERIFY_NON_STRICT, VALID_ONLY_FLAG, VERIFY_METADATA_ONLY, VERIFY_PARTIAL_METADATA, 0};
        int i, verify_flags = MONO_VERIFY_REPORT_ALL_ERRORS, run_new_metadata_verifier = 0;
+       MonoThreadInfoRuntimeCallbacks ticallbacks;
        
        for (i = 1; i < argc; i++){
                if (argv [i][0] != '-'){
@@ -654,15 +708,30 @@ 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);
+       assembly_directory [0] = g_path_get_dirname (file);
+       assembly_directory [1] = NULL;
+
 #ifndef DISABLE_PERFCOUNTERS
        mono_perfcounters_init ();
 #endif
        mono_counters_init ();
+       mono_tls_init_runtime_keys ();
+       memset (&ticallbacks, 0, sizeof (ticallbacks));
+       ticallbacks.thread_state_init = thread_state_init;
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
+       mono_thread_info_runtime_init (&ticallbacks);
+
        mono_metadata_init ();
        mono_images_init ();
        mono_assemblies_init ();
        mono_loader_init ();
  
+
        if (verify_pe) {
                char *tok = strtok (flags, ",");
 
@@ -701,7 +770,7 @@ main (int argc, char *argv [])
        if (verify_pe || run_new_metadata_verifier) {
                run_new_metadata_verifier = 1;
        }
-       
+
        if (run_new_metadata_verifier) {
                mono_verifier_set_mode (verifier_mode);
 
@@ -726,7 +795,7 @@ main (int argc, char *argv [])
 
                mono_verifier_set_mode (verifier_mode);
 
-               assembly = mono_assembly_open (file, NULL);
+               assembly = mono_assembly_open_predicate (file, FALSE, FALSE, NULL, NULL, NULL);
                /*fake an assembly for netmodules so the verifier works*/
                if (!assembly && (image = mono_image_open (file, &status)) && image->tables [MONO_TABLE_ASSEMBLY].rows == 0) {
                        assembly = g_new0 (MonoAssembly, 1);
@@ -740,7 +809,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);