Merge pull request #4453 from lambdageek/bug-49721
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Thu, 16 Mar 2017 23:09:00 +0000 (19:09 -0400)
committerGitHub <noreply@github.com>
Thu, 16 Mar 2017 23:09:00 +0000 (19:09 -0400)
[loader] Check strong name when loading from application base. (Fixes #49721)

28 files changed:
configure.ac
mono/dis/main.c
mono/metadata/appdomain.c
mono/metadata/assembly-internals.h
mono/metadata/assembly.c
mono/metadata/assembly.h
mono/metadata/attach.c
mono/metadata/coree.c
mono/metadata/domain-internals.h
mono/metadata/domain.c
mono/metadata/mono-security.c
mono/metadata/w32socket.c
mono/mini/driver.c
mono/mini/interp/interp.c
mono/tests/Makefile.am
mono/tests/bug-30085.cs
mono/tests/test-runner.cs
mono/tests/testing_gac/.gitattributes [new file with mode: 0644]
mono/tests/testing_gac/.gitignore [new file with mode: 0644]
mono/tests/testing_gac/Makefile.am [new file with mode: 0644]
mono/tests/testing_gac/README [new file with mode: 0644]
mono/tests/testing_gac/testkey.snk [new file with mode: 0644]
mono/tests/testing_gac/v1/app-refl-load.cs [new file with mode: 0644]
mono/tests/testing_gac/v1/app.cs [new file with mode: 0644]
mono/tests/testing_gac/v1/gactestlib.cs [new file with mode: 0644]
mono/tests/testing_gac/v2/gactestlib.cs [new file with mode: 0644]
mono/tests/w32message.cs
tools/pedump/pedump.c

index cf871f8e485e0e2e6417a29b6d7d0085a09fba21..433ff566fd7d69a1ce7475421f6914d99e4aae4a 100644 (file)
@@ -4443,6 +4443,7 @@ mono/tests/Makefile
 mono/tests/tests-config
 mono/tests/assemblyresolve/Makefile
 mono/tests/gc-descriptors/Makefile
+mono/tests/testing_gac/Makefile
 mono/unit-tests/Makefile
 mono/benchmark/Makefile
 mono/mini/Makefile
index 599651b1368b78f6c6770ff5742d1c6d83495c81..4c29af97bc9773c514f7a3886fd6ceff755ec6d5 100644 (file)
@@ -29,7 +29,7 @@
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/loader.h>
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/w32handle.h>
 #include <mono/utils/bsearch.h>
@@ -1844,22 +1844,25 @@ load_filter (const char* filename)
 
 
 static gboolean
-try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2,
-                                       const gchar *path3, const gchar *path4, gboolean refonly)
+try_load_from (MonoAssembly **assembly,
+              const gchar *path1, const gchar *path2,
+              const gchar *path3, const gchar *path4, gboolean refonly,
+              MonoAssemblyCandidatePredicate predicate, gpointer user_data)
 {
        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);
+               *assembly = mono_assembly_open_predicate (fullpath, refonly, FALSE, predicate, user_data, NULL);
 
        g_free (fullpath);
        return (*assembly != NULL);
 }
 
 static MonoAssembly *
-real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolean refonly)
+real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolean refonly,
+          MonoAssemblyCandidatePredicate predicate, gpointer user_data)
 {
        MonoAssembly *result = NULL;
        gchar **path;
@@ -1883,22 +1886,22 @@ real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolea
                /* 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))
+               if (try_load_from (&result, *path, local_culture, "", filename, refonly, predicate, user_data))
                        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))
+               if (try_load_from (&result, *path, local_culture, "", filename, refonly, predicate, user_data))
                        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))
+               if (try_load_from (&result, *path, local_culture, name, filename, refonly, predicate, user_data))
                        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))
+               if (try_load_from (&result, *path, local_culture, name, filename, refonly, predicate, user_data))
                        break;
        }
 
@@ -1918,7 +1921,7 @@ monodis_preload (MonoAssemblyName *aname,
        gboolean refonly = GPOINTER_TO_UINT (user_data);
 
        if (assemblies_path && assemblies_path [0] != NULL) {
-               result = real_load (assemblies_path, aname->culture, aname->name, refonly);
+               result = real_load (assemblies_path, aname->culture, aname->name, refonly, NULL, NULL);
        }
 
        return result;
index 77f2c7d123397b532506d8c7fe91cfd03e048579..81a92adc2e1a3ceb6b36797384d078e8770b7666 100644 (file)
@@ -38,7 +38,6 @@
 #include <mono/metadata/appdomain-icalls.h>
 #include <mono/metadata/domain-internals.h>
 #include "mono/metadata/metadata-internals.h"
-#include <mono/metadata/assembly.h>
 #include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/exception-internals.h>
@@ -1889,9 +1888,11 @@ leave:
 
 
 static gboolean
-try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2,
-                                       const gchar *path3, const gchar *path4,
-                                       gboolean refonly, gboolean is_private)
+try_load_from (MonoAssembly **assembly,
+              const gchar *path1, const gchar *path2,
+              const gchar *path3, const gchar *path4,
+              gboolean refonly, gboolean is_private,
+              MonoAssemblyCandidatePredicate predicate, gpointer user_data)
 {
        gchar *fullpath;
        gboolean found = FALSE;
@@ -1910,14 +1911,14 @@ try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2,
                found = g_file_test (fullpath, G_FILE_TEST_IS_REGULAR);
        
        if (found)
-               *assembly = mono_assembly_open_full (fullpath, NULL, refonly);
+               *assembly = mono_assembly_open_predicate (fullpath, refonly, FALSE, predicate, user_data, NULL);
 
        g_free (fullpath);
        return (*assembly != NULL);
 }
 
 static MonoAssembly *
-real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolean refonly)
+real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolean refonly, MonoAssemblyCandidatePredicate predicate, gpointer user_data)
 {
        MonoAssembly *result = NULL;
        gchar **path;
@@ -1944,22 +1945,22 @@ real_load (gchar **search_path, const gchar *culture, const gchar *name, gboolea
                /* 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, is_private))
+               if (try_load_from (&result, *path, local_culture, "", filename, refonly, is_private, predicate, user_data))
                        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, is_private))
+               if (try_load_from (&result, *path, local_culture, "", filename, refonly, is_private, predicate, user_data))
                        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, is_private))
+               if (try_load_from (&result, *path, local_culture, name, filename, refonly, is_private, predicate, user_data))
                        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, is_private))
+               if (try_load_from (&result, *path, local_culture, name, filename, refonly, is_private, predicate, user_data))
                        break;
        }
 
@@ -1985,11 +1986,19 @@ mono_domain_assembly_preload (MonoAssemblyName *aname,
        set_domain_search_path (domain);
 
        if (domain->search_path && domain->search_path [0] != NULL) {
-               result = real_load (domain->search_path, aname->culture, aname->name, refonly);
+               if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Domain %s search path is:", domain->friendly_name);
+                       for (int i = 0; domain->search_path [i]; i++) {
+                               const char *p = domain->search_path[i];
+                               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "\tpath[%d] = '%s'", i, p);
+                       }
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "End of domain %s search path.", domain->friendly_name);                    
+               }
+               result = real_load (domain->search_path, aname->culture, aname->name, refonly, &mono_assembly_candidate_predicate_sn_same_name, aname);
        }
 
        if (result == NULL && assemblies_path && assemblies_path [0] != NULL) {
-               result = real_load (assemblies_path, aname->culture, aname->name, refonly);
+               result = real_load (assemblies_path, aname->culture, aname->name, refonly, &mono_assembly_candidate_predicate_sn_same_name, aname);
        }
 
        return result;
@@ -2043,7 +2052,7 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoStringHandle fname, MonoBoole
        if (!is_ok (error))
                goto leave;
        
-       MonoAssembly *ass = mono_assembly_open_a_lot (filename, &status, refOnly, TRUE);
+       MonoAssembly *ass = mono_assembly_open_predicate (filename, refOnly, TRUE, NULL, NULL, &status);
        
        if (!ass) {
                if (status == MONO_IMAGE_IMAGE_INVALID)
index c24e328f33083ff1c3beb8da8736aefe9be59bf7..01cd44d5aacfc41978002266dd6ff6448790cdd2 100644 (file)
@@ -5,10 +5,36 @@
 #ifndef __MONO_METADATA_ASSEMBLY_INTERNALS_H__
 #define __MONO_METADATA_ASSEMBLY_INTERNALS_H__
 
+#include <glib.h>
+
 #include <mono/metadata/assembly.h>
 
 MONO_API MonoImage*    mono_assembly_load_module_checked (MonoAssembly *assembly, uint32_t idx, MonoError *error);
 
 MonoAssembly * mono_assembly_open_a_lot (const char *filename, MonoImageOpenStatus *status, gboolean refonly, gboolean load_from_context);
 
+/* If predicate returns true assembly should be loaded, if false ignore it. */
+typedef gboolean (*MonoAssemblyCandidatePredicate)(MonoAssembly *, gpointer);
+
+MonoAssembly*          mono_assembly_open_predicate (const char *filename,
+                                                    gboolean refonly,
+                                                    gboolean load_from_context,
+                                                    MonoAssemblyCandidatePredicate pred,
+                                                    gpointer user_data,
+                                                    MonoImageOpenStatus *status);
+
+MonoAssembly*          mono_assembly_load_from_predicate (MonoImage *image, const char *fname,
+                                                         gboolean refonly,
+                                                         MonoAssemblyCandidatePredicate pred,
+                                                         gpointer user_data,
+                                                         MonoImageOpenStatus *status);
+
+/* MonoAssemblyCandidatePredicate that compares the assembly name (name, version,
+ * culture, public key token) of the candidate with the wanted name, if the
+ * wanted name has a public key token (if not present, always return true).
+ * Pass the wanted MonoAssemblyName* as the user_data.
+ */
+gboolean
+mono_assembly_candidate_predicate_sn_same_name (MonoAssembly *candidate, gpointer wanted_name);
+
 #endif /* __MONO_METADATA_ASSEMBLY_INTERNALS_H__ */
index fa765bbe5f1d58fb93ac473f664583296442ab6b..aa900409470e52ba1c0b1d51e3ed2ca1608d7215 100644 (file)
@@ -528,7 +528,7 @@ mono_assembly_names_equal (MonoAssemblyName *l, MonoAssemblyName *r)
 }
 
 static MonoAssembly *
-load_in_path (const char *basename, const char** search_path, MonoImageOpenStatus *status, MonoBoolean refonly)
+load_in_path (const char *basename, const char** search_path, MonoImageOpenStatus *status, MonoBoolean refonly, MonoAssemblyCandidatePredicate predicate, gpointer user_data)
 {
        int i;
        char *fullpath;
@@ -536,7 +536,7 @@ load_in_path (const char *basename, const char** search_path, MonoImageOpenStatu
 
        for (i = 0; search_path [i]; ++i) {
                fullpath = g_build_filename (search_path [i], basename, NULL);
-               result = mono_assembly_open_full (fullpath, status, refonly);
+               result = mono_assembly_open_predicate (fullpath, refonly, FALSE, predicate, user_data, status);
                g_free (fullpath);
                if (result)
                        return result;
@@ -1125,6 +1125,16 @@ mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_ana
                dest_aname->minor = vset->minor;
                dest_aname->build = vset->build;
                dest_aname->revision = vset->revision;
+               if (current_runtime->public_key_token != NULL &&
+                   dest_aname->public_key_token [0] != 0 &&
+                   !mono_public_tokens_are_equal (dest_aname->public_key_token, (const mono_byte *)current_runtime->public_key_token)) {
+                       mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+                                   "The request for assembly name '%s' with PublicKeyToken=%s was remapped to PublicKeyToken=%s",
+                                   dest_aname->name,
+                                   dest_aname->public_key_token,
+                                   current_runtime->public_key_token);
+                       memcpy (dest_aname->public_key_token, current_runtime->public_key_token, MONO_PUBLIC_KEY_TOKEN_LENGTH);
+               }
                if (vmap->new_assembly_name != NULL) {
                        dest_aname->name = vmap->new_assembly_name;
                        mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
@@ -1677,7 +1687,16 @@ mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboo
 MonoAssembly *
 mono_assembly_open_a_lot (const char *filename, MonoImageOpenStatus *status, gboolean refonly, gboolean load_from_context)
 {
+       return mono_assembly_open_predicate (filename, refonly, load_from_context, NULL, NULL, status);
+}
 
+MonoAssembly *
+mono_assembly_open_predicate (const char *filename, gboolean refonly,
+                             gboolean load_from_context,
+                             MonoAssemblyCandidatePredicate predicate,
+                             gpointer user_data,
+                             MonoImageOpenStatus *status)
+{
        MonoImage *image;
        MonoAssembly *ass;
        MonoImageOpenStatus def_status;
@@ -1770,7 +1789,7 @@ mono_assembly_open_a_lot (const char *filename, MonoImageOpenStatus *status, gbo
                return image->assembly;
        }
 
-       ass = mono_assembly_load_from_full (image, fname, status, refonly);
+       ass = mono_assembly_load_from_predicate (image, fname, refonly, predicate, user_data, status);
 
        if (ass) {
                if (!loaded_from_bundle)
@@ -1948,7 +1967,7 @@ mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoErro
 MonoAssembly *
 mono_assembly_open (const char *filename, MonoImageOpenStatus *status)
 {
-       return mono_assembly_open_full (filename, status, FALSE);
+       return mono_assembly_open_predicate (filename, FALSE, FALSE, NULL, NULL, status);
 }
 
 /**
@@ -1973,6 +1992,16 @@ mono_assembly_open (const char *filename, MonoImageOpenStatus *status)
 MonoAssembly *
 mono_assembly_load_from_full (MonoImage *image, const char*fname, 
                              MonoImageOpenStatus *status, gboolean refonly)
+{
+       return mono_assembly_load_from_predicate (image, fname, refonly, NULL, NULL, status);
+}
+
+MonoAssembly *
+mono_assembly_load_from_predicate (MonoImage *image, const char *fname,
+                                  gboolean refonly,
+                                  MonoAssemblyCandidatePredicate predicate,
+                                  gpointer user_data,
+                                  MonoImageOpenStatus *status)
 {
        MonoAssembly *ass, *ass2;
        char *base_dir;
@@ -2062,6 +2091,15 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
                mono_error_cleanup (&refasm_error);
        }
 
+       if (predicate && !predicate (ass, user_data)) {
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate returned FALSE, skipping '%s' (%s)\n", ass->aname.name, image->name);
+               g_free (ass);
+               g_free (base_dir);
+               mono_image_close (image);
+               *status = MONO_IMAGE_IMAGE_INVALID;
+               return NULL;
+       }
+
        mono_assemblies_lock ();
 
        if (image->assembly) {
@@ -2673,7 +2711,7 @@ probe_for_partial_name (const char *basepath, const char *fullname, MonoAssembly
        if (fullpath == NULL)
                return NULL;
        else {
-               MonoAssembly *res = mono_assembly_open (fullpath, status);
+               MonoAssembly *res = mono_assembly_open_predicate (fullpath, FALSE, FALSE, NULL, NULL, status);
                g_free (fullpath);
                return res;
        }
@@ -3196,7 +3234,7 @@ mono_assembly_load_from_gac (MonoAssemblyName *aname,  gchar *filename, MonoImag
                paths = extra_gac_paths;
                while (!result && *paths) {
                        fullpath = g_build_path (G_DIR_SEPARATOR_S, *paths, "lib", "mono", "gac", subpath, NULL);
-                       result = mono_assembly_open_full (fullpath, status, refonly);
+                       result = mono_assembly_open_predicate (fullpath, refonly, FALSE, NULL, NULL, status);
                        g_free (fullpath);
                        paths++;
                }
@@ -3210,7 +3248,7 @@ mono_assembly_load_from_gac (MonoAssemblyName *aname,  gchar *filename, MonoImag
 
        fullpath = g_build_path (G_DIR_SEPARATOR_S, mono_assembly_getrootdir (),
                        "mono", "gac", subpath, NULL);
-       result = mono_assembly_open_full (fullpath, status, refonly);
+       result = mono_assembly_open_predicate (fullpath, refonly, FALSE, NULL, NULL, status);
        g_free (fullpath);
 
        if (result)
@@ -3259,7 +3297,7 @@ mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *
 
        // This unusual directory layout can occur if mono is being built and run out of its own source repo
        if (assemblies_path) { // Custom assemblies path set via MONO_PATH or mono_set_assemblies_path
-               corlib = load_in_path ("mscorlib.dll", (const char**)assemblies_path, status, FALSE);
+               corlib = load_in_path ("mscorlib.dll", (const char**)assemblies_path, status, FALSE, NULL, NULL);
                if (corlib)
                        goto return_corlib_and_facades;
        }
@@ -3267,13 +3305,13 @@ mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *
        /* Normal case: Load corlib from mono/<version> */
        corlib_file = g_build_filename ("mono", runtime->framework_version, "mscorlib.dll", NULL);
        if (assemblies_path) { // Custom assemblies path
-               corlib = load_in_path (corlib_file, (const char**)assemblies_path, status, FALSE);
+               corlib = load_in_path (corlib_file, (const char**)assemblies_path, status, FALSE, NULL, NULL);
                if (corlib) {
                        g_free (corlib_file);
                        goto return_corlib_and_facades;
                }
        }
-       corlib = load_in_path (corlib_file, default_path, status, FALSE);
+       corlib = load_in_path (corlib_file, default_path, status, FALSE, NULL, NULL);
        g_free (corlib_file);
 
 return_corlib_and_facades:
@@ -3295,6 +3333,44 @@ prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refon
        return candidate;
 }
 
+gboolean
+mono_assembly_candidate_predicate_sn_same_name (MonoAssembly *candidate, gpointer ud)
+{
+       MonoAssemblyName *wanted_name = (MonoAssemblyName*)ud;
+       MonoAssemblyName *candidate_name = &candidate->aname;
+
+       g_assert (wanted_name != NULL);
+       g_assert (candidate_name != NULL);
+
+       if (mono_trace_is_traced (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY)) {
+               char * s = mono_stringify_assembly_name (wanted_name);
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: wanted = %s\n", s);
+               g_free (s);
+               s = mono_stringify_assembly_name (candidate_name);
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate = %s\n", s);
+               g_free (s);
+       }
+
+       /* No wanted token, bail. */
+       if (0 == wanted_name->public_key_token [0]) {
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: wanted has no token, returning TRUE\n");
+               return TRUE;
+       }
+
+       if (0 == candidate_name->public_key_token [0]) {
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate has no token, returning FALSE\n");
+               return FALSE;
+       }
+
+
+       gboolean result = mono_assembly_names_equal (wanted_name, candidate_name);
+
+       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s\n",
+                   result ? "match, returning TRUE" : "don't match, returning FALSE");
+       return result;
+
+}
+
 
 MonoAssembly*
 mono_assembly_load_full_nosearch (MonoAssemblyName *aname, 
@@ -3352,7 +3428,7 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
 
                if (basedir) {
                        fullpath = g_build_filename (basedir, filename, NULL);
-                       result = mono_assembly_open_full (fullpath, status, refonly);
+                       result = mono_assembly_open_predicate (fullpath, refonly, FALSE, NULL, NULL, status);
                        g_free (fullpath);
                        if (result) {
                                result->in_gac = FALSE;
@@ -3361,7 +3437,7 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
                        }
                }
 
-               result = load_in_path (filename, default_path, status, refonly);
+               result = load_in_path (filename, default_path, status, refonly, NULL, NULL);
                if (result)
                        result->in_gac = FALSE;
                g_free (filename);
index 0cde65a2b5b1d244f5ae0e5818ee303180332e75..9b12cafdf66f4d4cc0e9e1c339ed49833ef06917 100644 (file)
@@ -8,8 +8,10 @@ MONO_BEGIN_DECLS
 
 MONO_API void          mono_assemblies_init     (void);
 MONO_API void          mono_assemblies_cleanup  (void);
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoAssembly *mono_assembly_open       (const char *filename,
                                        MonoImageOpenStatus *status);
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoAssembly *mono_assembly_open_full (const char *filename,
                                        MonoImageOpenStatus *status,
                                        mono_bool refonly);
index 72330bbc4fbac5b967452135f960a34d304fab52..6aba8e215b47e5d4acfb51f594c7b384dd1cb0cb 100644 (file)
@@ -31,7 +31,7 @@
 #include <netdb.h>
 #include <unistd.h>
 
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/metadata.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/object-internals.h>
@@ -275,7 +275,7 @@ mono_attach_load_agent (MonoDomain *domain, char *agent, char *args, MonoObject
        gpointer pa [1];
        MonoImageOpenStatus open_status;
 
-       agent_assembly = mono_assembly_open (agent, &open_status);
+       agent_assembly = mono_assembly_open_predicate (agent, FALSE, FALSE, NULL, NULL, &open_status);
        if (!agent_assembly) {
                fprintf (stderr, "Cannot open agent assembly '%s': %s.\n", agent, mono_image_strerror (open_status));
                g_free (agent);
index 0ce8810d4c224354306cb72cd01cf6d64f573da1..295ab4e928cae0412972d5491bb1de4b5bbb47d4 100644 (file)
@@ -19,7 +19,7 @@
 #include "cil-coff.h"
 #include "metadata-internals.h"
 #include "image.h"
-#include "assembly.h"
+#include "assembly-internals.h"
 #include "domain-internals.h"
 #include "appdomain.h"
 #include "object.h"
@@ -119,7 +119,7 @@ BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpRes
                 * probably be delayed until the first call to an exported function.
                 */
                if (image->tables [MONO_TABLE_ASSEMBLY].rows && ((MonoCLIImageInfo*) image->image_info)->cli_cli_header.ch_vtable_fixups.rva)
-                       assembly = mono_assembly_open (file_name, NULL);
+                       assembly = mono_assembly_open_predicate (file_name, FALSE, FALSE, NULL, NULL, NULL);
 
                g_free (file_name);
                break;
@@ -170,7 +170,7 @@ __int32 STDMETHODCALLTYPE _CorExeMain(void)
                ExitProcess (1);
        }
 
-       assembly = mono_assembly_open (file_name, NULL);
+       assembly = mono_assembly_open_predicate (file_name, FALSE, FALSE, NULL, NULL, NULL);
        mono_close_exe_image ();
        if (!assembly) {
                g_free (file_name);
index 10347f109004e75c4eab58ae6bcb5cb7be6a7aeb..ecd89bef1e0415862979b32882fabb486a3ee642 100644 (file)
@@ -427,6 +427,7 @@ typedef struct  {
 typedef struct  {
        const char runtime_version [12];
        const char framework_version [4];
+       const char *public_key_token;
        const AssemblyVersionSet version_sets [5];
 } MonoRuntimeInfo;
 
index b3fc90a4be5737989eaf6716982e7a4dbd19bc9f..a35350dc9a99c1f83c9c418df48d126125b0c578 100644 (file)
@@ -32,7 +32,7 @@
 #include <mono/metadata/domain-internals.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/debug-internals.h>
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/appdomain.h>
@@ -98,9 +98,9 @@ static const MonoRuntimeInfo *current_runtime = NULL;
 /* This is the list of runtime versions supported by this JIT.
  */
 static const MonoRuntimeInfo supported_runtimes[] = {
-       {"v4.0.30319","4.5", { {4,0,0,0}, {10,0,0,0}, {4,0,0,0}, {4,0,0,0}, {4,0,0,0} } },
-       {"mobile",    "2.1", { {2,0,5,0}, {10,0,0,0}, {2,0,5,0}, {2,0,5,0}, {4,0,0,0} } },
-       {"moonlight", "2.1", { {2,0,5,0}, { 9,0,0,0}, {3,5,0,0}, {3,0,0,0}, NOT_AVAIL } },
+       {"v4.0.30319","4.5",               NULL, { {4,0,0,0}, {10,0,0,0}, {4,0,0,0}, {4,0,0,0}, {4,0,0,0} } },
+       {"mobile",    "2.1", "7cec85d7bea7798e", { {2,0,5,0}, {10,0,0,0}, {2,0,5,0}, {2,0,5,0}, {4,0,0,0} } },
+       {"moonlight", "2.1",               NULL, { {2,0,5,0}, { 9,0,0,0}, {3,5,0,0}, {3,0,0,0}, NOT_AVAIL } },
 };
 
 #undef NOT_AVAIL
@@ -992,10 +992,10 @@ mono_domain_assembly_open (MonoDomain *domain, const char *name)
                current = mono_domain_get ();
 
                mono_domain_set (domain, FALSE);
-               ass = mono_assembly_open (name, NULL);
+               ass = mono_assembly_open_predicate (name, FALSE, FALSE, NULL, NULL, NULL);
                mono_domain_set (current, FALSE);
        } else {
-               ass = mono_assembly_open (name, NULL);
+               ass = mono_assembly_open_predicate (name, FALSE, FALSE, NULL, NULL, NULL);
        }
 
        return ass;
index 0d770f70cdc0906290840eeb398892843cfcdfb4..28b209d4f31249ccde284e54c4d9715c7f35eabc 100644 (file)
@@ -12,7 +12,7 @@
 #include <config.h>
 #endif
 
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/image.h>
 #include <mono/metadata/exception.h>
@@ -592,7 +592,7 @@ void invoke_protected_memory_method (MonoArray *data, MonoObject *scope, gboolea
        if (system_security_assembly == NULL) {
                system_security_assembly = mono_image_loaded ("System.Security");
                if (!system_security_assembly) {
-                       MonoAssembly *sa = mono_assembly_open ("System.Security.dll", NULL);
+                       MonoAssembly *sa = mono_assembly_open_predicate ("System.Security.dll", FALSE, FALSE, NULL, NULL, NULL);
                        if (!sa)
                                g_assert_not_reached ();
                        system_security_assembly = mono_assembly_get_image (sa);
index 8bc8b49a8c5b70bb2043829c7bb12797141bf069..bd221429641102adfe0c73ebc4a61029cc75e08a 100644 (file)
@@ -47,7 +47,7 @@
 
 #include <mono/metadata/object.h>
 #include <mono/metadata/exception.h>
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/w32file.h>
 #include <mono/metadata/threads.h>
@@ -641,7 +641,7 @@ get_socket_assembly (void)
 
                socket_assembly = mono_image_loaded ("System");
                if (!socket_assembly) {
-                       MonoAssembly *sa = mono_assembly_open ("System.dll", NULL);
+                       MonoAssembly *sa = mono_assembly_open_predicate ("System.dll", FALSE, FALSE, NULL, NULL, NULL);
                
                        if (!sa) {
                                g_assert_not_reached ();
@@ -1973,7 +1973,7 @@ ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal (gsize sock, gi
                if (mono_posix_image == NULL) {
                        mono_posix_image = mono_image_loaded ("Mono.Posix");
                        if (!mono_posix_image) {
-                               MonoAssembly *sa = mono_assembly_open ("Mono.Posix.dll", NULL);
+                               MonoAssembly *sa = mono_assembly_open_predicate ("Mono.Posix.dll", FALSE, FALSE, NULL, NULL, NULL);
                                if (!sa) {
                                        *werror = WSAENOPROTOOPT;
                                        return;
index 9674a350f904aa1434741540ab3db5f58c94ab10..7a64689897785245979c39f23330243fe86d3ee5 100644 (file)
@@ -21,7 +21,7 @@
 #include <unistd.h>
 #endif
 
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/loader.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/class.h>
@@ -536,7 +536,7 @@ mini_regression_list (int verbose, int count, char *images [])
        
        total_run =  total = 0;
        for (i = 0; i < count; ++i) {
-               ass = mono_assembly_open (images [i], NULL);
+               ass = mono_assembly_open_predicate (images [i], FALSE, FALSE, NULL, NULL, NULL);
                if (!ass) {
                        g_warning ("failed to load assembly: %s", images [i]);
                        continue;
@@ -1122,7 +1122,7 @@ load_agent (MonoDomain *domain, char *desc)
                args = NULL;
        }
 
-       agent_assembly = mono_assembly_open (agent, &open_status);
+       agent_assembly = mono_assembly_open_predicate (agent, FALSE, FALSE, NULL, NULL, &open_status);
        if (!agent_assembly) {
                fprintf (stderr, "Cannot open agent assembly '%s': %s.\n", agent, mono_image_strerror (open_status));
                g_free (agent);
@@ -2121,7 +2121,7 @@ mono_main (int argc, char* argv[])
                jit_info_table_test (domain);
 #endif
 
-       assembly = mono_assembly_open (aname, &open_status);
+       assembly = mono_assembly_open_predicate (aname, FALSE, FALSE, NULL, NULL, &open_status);
        if (!assembly) {
                fprintf (stderr, "Cannot open assembly '%s': %s.\n", aname, mono_image_strerror (open_status));
                mini_cleanup (domain);
index 72fcf9f131116d31561b06333ca06a5a7948cd09..9207195fa150f38a485c56a18452185a48d94888 100644 (file)
@@ -36,7 +36,7 @@
 
 /* trim excessive headers */
 #include <mono/metadata/image.h>
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/cil-coff.h>
 #include <mono/metadata/mono-endian.h>
 #include <mono/metadata/tabledefs.h>
@@ -4535,7 +4535,7 @@ mono_interp_regression_list (int verbose, int count, char *images [])
        
        total_run = total = 0;
        for (i = 0; i < count; ++i) {
-               MonoAssembly *ass = mono_assembly_open (images [i], NULL);
+               MonoAssembly *ass = mono_assembly_open_predicate (images [i], FALSE, FALSE, NULL, NULL, NULL);
                if (!ass) {
                        g_warning ("failed to load assembly: %s", images [i]);
                        continue;
index 3ced39a0cdd0326ebe3e6f19fa126bf0f12c676b..cbef28ab7249edbfda165289c5f62966b01661e7 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = assemblyresolve gc-descriptors
+SUBDIRS = assemblyresolve gc-descriptors . testing_gac
 
 if FULL_AOT_TESTS
 FEATUREFUL_RUNTIME_TEST =  
@@ -7,7 +7,7 @@ FEATUREFUL_RUNTIME_TEST = test-appdomain-unload
 endif
 
 check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-multi-netmodule test-cattr-type-load test-reflection-load-with-context test_platform        \
-                test-console-output test-messages test-env-options test-unhandled-exception-2 $(FEATUREFUL_RUNTIME_TEST) test-process-stress test-pedump rm-empty-logs
+                test-console-output test-env-options test-unhandled-exception-2 $(FEATUREFUL_RUNTIME_TEST) test-process-stress test-pedump rm-empty-logs runtest-gac-loading
 check-full: test-sgen check-local
 check-parallel: compile-tests check-full
 
@@ -481,7 +481,8 @@ BASE_TEST_CS_SRC=           \
        thread6.cs      \
        appdomain-threadpool-unload.cs  \
        process-unref-race.cs   \
-       bug-46661.cs
+       bug-46661.cs    \
+       w32message.cs
 
 TEST_CS_SRC_DIST=      \
        $(BASE_TEST_CS_SRC)     \
@@ -580,6 +581,11 @@ TEST_IL_SRC=                       \
 if AMD64
 # #651684
 PLATFORM_DISABLED_TESTS = finally_guard.exe
+
+if HOST_WIN32
+PLATFORM_DISABLED_TESTS += w32message.exe
+endif
+
 endif
 
 if IA64
@@ -592,7 +598,7 @@ if X86
 
 if HOST_WIN32
 PLATFORM_DISABLED_TESTS=async-exc-compilation.exe finally_guard.exe finally_block_ending_in_dead_bb.exe \
-       bug-18026.exe monitor.exe threadpool-exceptions5.exe process-unref-race.exe
+       bug-18026.exe monitor.exe threadpool-exceptions5.exe process-unref-race.exe w32message.exe
 endif
 
 endif
@@ -643,6 +649,8 @@ PLATFORM_DISABLED_TESTS= abort-stress-1.exe \
                          threadpool-exceptions5.exe \
                          threadpool-exceptions6.exe
 
+PLATFORM_DISABLED_TESTS+= w32message.exe
+
 # Tests that rely on AppDomain.Unload
 PLATFORM_DISABLED_TESTS+= appdomain-async-invoke.exe \
                           appdomain-exit.exe \
@@ -1188,22 +1196,6 @@ test-eglib-remap:
        @if which nm > /dev/null; then if nm $(top_builddir)/mono/mini/mono | grep -v $(OK_G_SYMBOLS) | grep 't g_'; then exit 1; else exit 0; fi; fi
 endif
 
-#
-# Tests that the internals in mono/io-layer/messages.c are ok by triggering the 
-# code that checks that the table is properly sorted
-#
-if NACL_CODEGEN
-test-messages:
-else
-if HOST_WIN32
-test-messages:
-else
-test-messages: w32message.exe
-       > test_messages.zero
-       $(with_mono_path) $(JITTEST_PROG_RUN) w32message.exe > w32message.allout 2>&1 && cmp test_messages.zero w32message.allout
-endif
-endif
-
 test-env-options:
        MONO_ENV_OPTIONS="--version" $(RUNTIME) array-init.exe | grep -q Architecture:
 
@@ -1211,7 +1203,7 @@ test-sgen : sgen-tests
 
 # Precompile the test assemblies in parallel
 compile-tests:
-       $(MAKE) -j4 $(TESTSI_CS) $(TESTSI_IL) $(TESTBS) libtest.la $(PREREQSI_IL) $(PREREQSI_CS)
+       $(MAKE) -j4 $(TESTSI_CS) $(TESTSI_IL) $(TESTBS) libtest.la $(PREREQSI_IL) $(PREREQSI_CS) compile-gac-loading
 if FULL_AOT_TESTS
        $(MAKE) $(PREREQSI_IL_AOT) $(PREREQSI_CS_AOT) $(AOT_EXTRA_LIBS)
 endif
@@ -1731,9 +1723,15 @@ EXTRA_DIST += bug-17537-helper.cs
 bug-17537-helper.exe: bug-17537-helper.cs
        $(MCS) -out:$@ $(srcdir)/bug-17537-helper.cs
        chmod -x $@
+if FULL_AOT_TESTS
+       $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
+if HYBRID_AOT_TESTS
+       $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
 
 bug-17537.exe: bug-17537.cs bug-17537-helper.exe
-       $(MCS) -r:System.dll -out:$@ $(srcdir)/bug-17537.cs
+       $(MCS) -r:$(CLASS)/System.dll -out:$@ $(srcdir)/bug-17537.cs
 
 EXTRA_DIST += coreclr-security.cs
 
@@ -1785,7 +1783,7 @@ generic-delegate2.2.exe : generic-delegate2.2.cs generic-delegate2-lib.2.dll
        $(MCS) -r:generic-delegate2-lib.2.dll -out:$@ $(srcdir)/generic-delegate2.2.cs
 
 bug-3903.exe: bug-3903.cs
-       $(MCS_NO_LIB)  $(srcdir)/bug-3903.cs -r:$(srcdir)/../../external/binary-reference-assemblies/v2.0/System.Core.dll -out:$@
+       $(MCS_NO_LIB)  $(srcdir)/bug-3903.cs -nostdlib -r:$(srcdir)/../../external/binary-reference-assemblies/v2.0/mscorlib.dll -r:$(srcdir)/../../external/binary-reference-assemblies/v2.0/System.Core.dll -out:$@
 
 gshared: test-generic-sharing
 
@@ -1972,6 +1970,14 @@ test-console-output: console-output.exe
 test-pedump: test-runner.exe
        $(with_mono_path) $(mono_build_root)/tools/pedump/pedump --verify error test-runner.exe
 
+.PHONY: test-gac-loading
+
+runtest-gac-loading: test-runner.exe
+       $(MAKE) -C testing_gac runtest
+
+compile-gac-loading:
+       $(MAKE) -C testing_gac compile-tests
+
 PROCESS_STRESS_TESTS=  \
                process-stress-1.exe    \
                process-stress-2.exe    \
index 9fc03ba6ff7e1321b30f782bda7ca2cf02a6fb10..494c5ecc1acbcd82b000a50546e940c347e68e04 100644 (file)
@@ -17,8 +17,14 @@ class Program
 
        static void ProbeCorlib ()
        {
-               Type good = System.Type.GetType("System.Nullable`1[[System.Int32, mscorlib]]"); 
-               Type bad = System.Type.GetType("System.Nullable`1[[System.IO.MemoryMappedFiles.MemoryMappedFile, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");
+               Type good = System.Type.GetType("System.Nullable`1[[System.Int32, mscorlib]]");
+#if MOBILE
+               string pubKeyToken = "7cec85d7bea7798e";
+#else
+               string pubKeyToken = "b77a5c561934e089";
+#endif
+               string t = String.Format ("System.Nullable`1[[System.IO.MemoryMappedFiles.MemoryMappedFile, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken={0}]]", pubKeyToken);
+               Type bad = System.Type.GetType(t);
 
                if (good.Assembly.FullName.Split (',') [0] != "mscorlib")
                        throw new Exception ("Wrong assembly name");
index 9975440147cfad259371d8e54bc8980a57464ff0..648a899c5e35b08fa809d17dc271d50c056a6b58 100644 (file)
@@ -31,6 +31,7 @@ public class TestRunner
        const string TEST_TIME_FORMAT = "mm\\:ss\\.fff";
        const string ENV_TIMEOUT = "TEST_DRIVER_TIMEOUT_SEC";
        const string MONO_PATH = "MONO_PATH";
+       const string MONO_GAC_PREFIX = "MONO_GAC_PREFIX";
 
        class ProcessData {
                public string test;
@@ -57,6 +58,7 @@ public class TestRunner
                string config = null;
                string mono_path = null;
                string runtime_args = null;
+               string mono_gac_prefix = null;
                var opt_sets = new List<string> ();
 
                string aot_run_flags = null;
@@ -147,6 +149,13 @@ public class TestRunner
                                        }
                                        mono_path = args [i + 1].Substring(0, args [i + 1].Length);
 
+                                       i += 2;
+                               } else if (args [i] == "--mono-gac-prefix") {
+                                       if (i + 1 >= args.Length) {
+                                               Console.WriteLine ("Missing argument to --mono-gac-prefix command line option.");
+                                               return 1;
+                                       }
+                                       mono_gac_prefix = args[i + 1];
                                        i += 2;
                                } else if (args [i] == "--aot-run-flags") {
                                        if (i + 1 >= args.Length) {
@@ -251,7 +260,10 @@ public class TestRunner
                                                ProcessStartInfo job = new ProcessStartInfo (runtime, aot_args);
                                                job.UseShellExecute = false;
                                                job.EnvironmentVariables[ENV_TIMEOUT] = timeout.ToString();
-                                               job.EnvironmentVariables[MONO_PATH] = mono_path;
+                                               if (mono_path != null)
+                                                       job.EnvironmentVariables[MONO_PATH] = mono_path;
+                                               if (mono_gac_prefix != null)
+                                                       job.EnvironmentVariables[MONO_GAC_PREFIX] = mono_gac_prefix;
                                                Process compiler = new Process ();
                                                compiler.StartInfo = job;
 
@@ -331,6 +343,8 @@ public class TestRunner
                                                info.EnvironmentVariables["MONO_CONFIG"] = config;
                                        if (mono_path != null)
                                                info.EnvironmentVariables[MONO_PATH] = mono_path;
+                                       if (mono_gac_prefix != null)
+                                               info.EnvironmentVariables[MONO_GAC_PREFIX] = mono_gac_prefix;
                                        Process p = new Process ();
                                        p.StartInfo = info;
 
diff --git a/mono/tests/testing_gac/.gitattributes b/mono/tests/testing_gac/.gitattributes
new file mode 100644 (file)
index 0000000..18dffd1
--- /dev/null
@@ -0,0 +1 @@
+testkey.snk binary
\ No newline at end of file
diff --git a/mono/tests/testing_gac/.gitignore b/mono/tests/testing_gac/.gitignore
new file mode 100644 (file)
index 0000000..fea7aaf
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/lib/mono/
diff --git a/mono/tests/testing_gac/Makefile.am b/mono/tests/testing_gac/Makefile.am
new file mode 100644 (file)
index 0000000..c22260a
--- /dev/null
@@ -0,0 +1,180 @@
+
+### buildtree stuff
+
+CLASS=$(mcs_topdir)/class/lib/$(DEFAULT_PROFILE)
+
+if FULL_AOT_TESTS
+PROFILE_MCS_FLAGS = -d:MOBILE,MOBILE_LEGACY,FULL_AOT_DESKTOP 
+endif
+
+if HYBRID_AOT_TESTS
+PROFILE_MCS_FLAGS = -d:MOBILE,MOBILE_LEGACY 
+endif
+
+### test runner stuff
+
+if HOST_WIN32
+PLATFORM_PATH_SEPARATOR=;
+else
+PLATFORM_PATH_SEPARATOR=:
+endif
+
+RUNTIME= $(top_builddir)/runtime/mono-wrapper
+TEST_RUNTIME = MONO_PATH=$(CLASS) $(RUNTIME)
+TOOLS_RUNTIME= MONO_PATH=$(mcs_topdir)/class/lib/build $(RUNTIME)
+
+TEST_RUNNER = ../test-runner.exe --runtime $(RUNTIME)
+
+if HOST_WIN32
+TEST_RUNNER_ARGS=--runtime $(if $(MONO_EXECUTABLE),$(shell cygpath -w -a $(MONO_EXECUTABLE) | sed 's/\\/\\\\/g'),mono)
+else
+TEST_RUNNER_ARGS=--runtime $(if $(MONO_EXECUTABLE),$(MONO_EXECUTABLE),mono)
+endif
+
+TEST_RUNNER_ARGS += $(if $(V), --verbose,)
+
+CLASS=$(mcs_topdir)/class/lib/$(DEFAULT_PROFILE)
+
+if FULL_AOT_TESTS
+TEST_RUNNER += --aot-run-flags "$(AOT_RUN_FLAGS)" --aot-build-flags "$(AOT_BUILD_FLAGS)"
+endif
+
+if HYBRID_AOT_TESTS
+TEST_RUNNER += --aot-run-flags "$(AOT_RUN_FLAGS)" --aot-build-flags "$(AOT_BUILD_FLAGS)"
+endif
+
+### tools
+
+GACUTIL= $(mcs_topdir)/class/lib/build/gacutil.exe
+SN= $(mcs_topdir)/class/lib/build/sn.exe
+
+MCS= $(TOOLS_RUNTIME) $(CSC) -noconfig -nologo -debug:portable -target:library $(PROFILE_MCS_FLAGS)
+
+### testcase stuff
+
+BASE_MONO_PATH=$(CLASS)
+
+V1_SRC= v1/gactestlib.cs
+V2_SRC= v2/gactestlib.cs
+APP_V1_SRC = v1/app.cs v1/app-refl-load.cs
+
+APP_SIGNED_V1_EXE = app-v1.exe app-refl-load-v1.exe
+
+UNSIGNED_V1_DLL= unsigned_v1/gactestlib.dll
+UNSIGNED_V2_DLL= unsigned_v2/gactestlib.dll
+
+SIGNED_V1_DLL= signed_v1/gactestlib.dll
+SIGNED_V2_DLL= signed_v2/gactestlib.dll
+
+GACTESTLIB_SRCS= $(V1_SRC) $(V2_SRC)
+GACTESTLIB_DLLS= $(SIGNED_V1_DLL) $(SIGNED_V2_DLL) $(UNSIGNED_V1_DLL) $(UNSIGNED_V2_DLL)
+
+if FULL_AOT_TESTS
+GACTESTLIB_DLLS_AOT=$(GACTESTLIB_DLLS:.dll=.dll$(PLATFORM_AOT_SUFFIX))
+APP_SIGNED_V1_AOT=$(APP_SIGNED_V1_EXE:.exe=.exe$(PLATFORM_AOT_SUFFIX))
+endif
+
+if HYBRID_AOT_TESTS
+GACTESTLIB_DLLS_AOT=$(GACTESTLIB_DLLS:.dll=.dll$(PLATFORM_AOT_SUFFIX))
+APP_SIGNED_V1_AOT=$(APP_SIGNED_V1_EXE:.exe=.exe$(PLATFORM_AOT_SUFFIX))
+endif
+
+
+SIGNING_KEY= testkey.snk
+
+# prefix for the testing gac.  gacutil will add lib/mono/gac directories
+GACDIR=.
+
+SIGN= -delaysign -keyfile:$(SIGNING_KEY)
+
+
+### autotools stuff
+
+EXTRA_DIST= README $(SIGNING_KEY) $(GACTESTLIB_SRCS) 
+
+### Test cases
+
+# MONO_GAC_PREFIX tests
+if FULL_AOT_TESTS
+GAC_TESTS=
+else
+if HYBRID_AOT_TESTS
+GAC_TESTS=
+else
+GAC_TESTS= test-signed-v1-app-gac
+endif
+endif
+
+# MONO_PATH tests
+MP_TESTS= test-signed-v1-app-mp-unsigned-v1 \
+       test-signed-v1-app-mp-signed-v1 \
+       test-signed-v1-app-mp-unsigned-v2-signed-v1 \
+       test-signed-v1-app-mp-signed-v2-signed-v1
+
+###
+
+.PHONY: runtest compile-tests prereqs
+
+runtest: $(MP_TESTS) $(GAC_TESTS)
+
+compile-tests: prereqs $(APP_SIGNED_V1_EXE) $(APP_SIGNED_V1_AOT)
+
+prereqs: $(GACTESTLIB_DLLS) $(GACTESTLIB_DLLS_AOT) gacinstall
+
+$(UNSIGNED_V1_DLL): $(V1_SRC)
+       -mkdir -p $(@D)
+       $(MCS) -out:$@ $<
+
+$(UNSIGNED_V2_DLL): $(V2_SRC)
+       -mkdir -p $(@D)
+       $(MCS) -out:$@ $<
+
+$(SIGNED_V1_DLL): $(V1_SRC) $(SIGNING_KEY)
+       -mkdir -p $(@D)
+       $(MCS) -out:$@ $(SIGN) $< && $(TOOLS_RUNTIME) $(SN) -R $@ $(SIGNING_KEY)
+
+$(SIGNED_V2_DLL): $(V2_SRC) $(SIGNING_KEY)
+       -mkdir -p $(@D)
+       $(MCS) -out:$@ $(SIGN) $< && $(TOOLS_RUNTIME) $(SN) -R $@ $(SIGNING_KEY)
+
+%-v1.exe: v1/%.cs $(SIGNED_V1_DLL)
+       $(MCS) -target:exe -out:$@ -r:$(SIGNED_V1_DLL) $<
+
+%.exe$(PLATFORM_AOT_SUFFIX): %.exe 
+       $(TEST_RUNTIME) $(AOT_BUILD_FLAGS) $<
+
+%.dll$(PLATFORM_AOT_SUFFIX): %.dll 
+       $(TEST_RUNTIME) $(AOT_BUILD_FLAGS) $<
+
+test-signed-v1-app-mp-unsigned-v1: $(APP_SIGNED_V1_EXE) prereqs
+       $(TOOLS_RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name "testing_gac_$@" --mono-path "unsigned_v1$(PLATFORM_PATH_SEPARATOR)$(BASE_MONO_PATH)" --expected-exit-code 1 $(APP_SIGNED_V1_EXE)
+
+test-signed-v1-app-mp-signed-v1: $(APP_SIGNED_V1_EXE) prereqs
+       $(TOOLS_RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name "testing_gac_$@" --mono-path "signed_v1$(PLATFORM_PATH_SEPARATOR)$(BASE_MONO_PATH)"  $(APP_SIGNED_V1_EXE)
+
+test-signed-v1-app-gac: $(APP_SIGNED_V1_EXE) gacinstall prereqs
+       $(TOOLS_RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name "testing_gac_$@" --mono-gac-prefix $(GACDIR) $(APP_SIGNED_V1_EXE)
+
+test-signed-v1-app-mp-unsigned-v2-signed-v1: $(APP_SIGNED_V1_EXE) prereqs
+       $(TOOLS_RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name "testing_gac_$@" --mono-path "unsigned_v2$(PLATFORM_PATH_SEPARATOR)signed_v1$(PLATFORM_PATH_SEPARATOR)$(BASE_MONO_PATH)" $(APP_SIGNED_V1_EXE)
+
+test-signed-v1-app-mp-signed-v2-signed-v1: $(APP_SIGNED_V1_EXE) prereqs
+       $(TOOLS_RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name "testing_gac_$@" --mono-path "signed_v2$(PLATFORM_PATH_SEPARATOR)signed_v1$(PLATFORM_PATH_SEPARATOR)$(BASE_MONO_PATH)" $(APP_SIGNED_V1_EXE)
+
+.PHONY: gacinstall
+
+gacinstall: $(SIGNED_V1_DLL) $(GACTESTLIB_DLLS_AOT)
+       $(TOOLS_RUNTIME) $(GACUTIL) -i $< -gacdir $(GACDIR) 
+
+mostlyclean-local: clean-gac-subdir clean-gactestlib-dll
+       -rm -f TestResult-*.xml
+
+.PHONY: clean-gac-subdir clean-gactestlib-dll
+
+clean-gac-subdir:
+       -rm -rf $(GACDIR)/lib/mono/gac/
+
+clean-gactestlib-dll:
+       -rm -f $(GACTESTLIB_DLLS)
+       -rm -f $(GACTESTLIB_DLLS_AOT)
+       -rm -f $(APP_SIGNED_V1_EXE) $(APP_SIGNED_V1_AOT)
diff --git a/mono/tests/testing_gac/README b/mono/tests/testing_gac/README
new file mode 100644 (file)
index 0000000..5087911
--- /dev/null
@@ -0,0 +1,7 @@
+This directory is used by some tests in <root>/mono/tests that require a GAC (set via MONO_GAC_PREFIX).
+
+The gac will be in this directory, under lib/mono/gac/
+
+
+
+When clean, this directory should have no files other than this README and Makefile
\ No newline at end of file
diff --git a/mono/tests/testing_gac/testkey.snk b/mono/tests/testing_gac/testkey.snk
new file mode 100644 (file)
index 0000000..b76369a
Binary files /dev/null and b/mono/tests/testing_gac/testkey.snk differ
diff --git a/mono/tests/testing_gac/v1/app-refl-load.cs b/mono/tests/testing_gac/v1/app-refl-load.cs
new file mode 100644 (file)
index 0000000..4170aa0
--- /dev/null
@@ -0,0 +1,45 @@
+using System;
+using System.Reflection;
+
+public class App {
+       const string assemblyName = "gactestlib";
+       const string assemblyVersion = "1.0.0.0";
+       const string assemblyPublicKeyToken = "537eab56aa911cb7"; /* see testkey.snk */
+       public static int Main (string[] args)
+       {
+               TestAssemblyLoad ();
+
+               TestReflectionOnlyLoad ();
+
+               return 0;
+       }
+
+       public static void TestAssemblyLoad ()
+       {
+               var expectedVersion = new Version (assemblyVersion);
+
+               var s = String.Format ("{0}, Version={1}, Culture=\"\", PublicKeyToken={2}",
+                                      assemblyName, assemblyVersion, assemblyPublicKeyToken);
+               var n = new AssemblyName (s);
+               var a = AppDomain.CurrentDomain.Load (n);
+
+               if (a == null)
+                       Environment.Exit (1);
+               if (a.GetName ().Version != expectedVersion)
+                       Environment.Exit (2);
+       }
+
+       public static void TestReflectionOnlyLoad ()
+       {
+               var expectedVersion = new Version (assemblyVersion);
+
+               var s = String.Format ("{0}, Version={1}, Culture=\"\", PublicKeyToken={2}",
+                                      assemblyName, assemblyVersion, assemblyPublicKeyToken);
+               var a = Assembly.ReflectionOnlyLoad (s);
+
+               if (a == null)
+                       Environment.Exit (3);
+               if (a.GetName ().Version != expectedVersion)
+                       Environment.Exit (4);
+       }
+}
diff --git a/mono/tests/testing_gac/v1/app.cs b/mono/tests/testing_gac/v1/app.cs
new file mode 100644 (file)
index 0000000..523668a
--- /dev/null
@@ -0,0 +1,8 @@
+using System;
+
+public class App {
+       public static void Main () {
+               X.N1 ();
+               X.N2 ();
+       }
+}
diff --git a/mono/tests/testing_gac/v1/gactestlib.cs b/mono/tests/testing_gac/v1/gactestlib.cs
new file mode 100644 (file)
index 0000000..1ced863
--- /dev/null
@@ -0,0 +1,15 @@
+
+[assembly: System.Reflection.AssemblyVersion ("1.0.0.0")]
+
+public class X
+{
+       public static void N1 ()
+       {
+               
+       }
+
+       public static void N2 ()
+       {
+       }
+
+}
diff --git a/mono/tests/testing_gac/v2/gactestlib.cs b/mono/tests/testing_gac/v2/gactestlib.cs
new file mode 100644 (file)
index 0000000..85ae296
--- /dev/null
@@ -0,0 +1,15 @@
+
+[assembly: System.Reflection.AssemblyVersion ("1.1.0.0")]
+
+public class X
+{
+       public static void N1 ()
+       {
+               
+       }
+
+       // In the "v2" version, let's make this method missing.
+       // public static void N2 ()
+       // {
+       // }
+}
index 5ff5d3a1e727fe7cb697368fc1b98ef4e510cbb1..cacfa691420864741284489786e263d82fa93501 100644 (file)
@@ -2,9 +2,6 @@
 // This test merely creates a Win32Exception that triggers the
 // code in mono/io-layer/message.c that validates that the
 // error table is propertly sorted
-//
-// If there is output on stderr, we have an error
-//
 using System;
 using System.ComponentModel;
 
@@ -14,13 +11,16 @@ class X {
                return new Win32Exception (c).Message;
        }
 
-       static void check (int c, string s)
+       static bool check (int c, string s)
        {
-               if (msg (c) != s)
-                       Console.WriteLine ("For {0} expected {1} got {2}", c, s, msg (c));
+               if (msg (c) != s) {
+                       Console.Error.WriteLine ("For {0} expected {1} got {2}", c, s, msg (c));
+                       return false;
+               }
+               return true;
        }
        
-       static void Main ()
+       static int Main ()
        {
                //
                // All this test does is instantiate two Win32Exceptions
@@ -33,8 +33,11 @@ class X {
                Exception a = new Win32Exception (99999);
                a = new Win32Exception (9805);
 
-               check (2, "Cannot find the specified file");
+               if (!check (2, "Cannot find the specified file"))
+                       return 1;
+
 
+               return 0;
        }
        
-}
\ No newline at end of file
+}
index 6ae2a1e1e497e30b768c728687a773408f3d1997..072b535f299e50eeb30e684b19c3ca1dd5c81e90 100644 (file)
@@ -21,7 +21,7 @@
 #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>
@@ -523,7 +523,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);
@@ -727,7 +727,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);