[corlib] When parsing the ECMA key, don't produce a public key. Fixes #58637
[mono.git] / mono / metadata / assembly.c
index c592c202eec071e4fde61ff2a33ef6258edfbc78..6f1de9964a328304d5b4601c1e94125caf62d731 100644 (file)
@@ -50,7 +50,7 @@
 #include <sys/stat.h>
 #endif
 
-#ifdef PLATFORM_MACOSX
+#ifdef HOST_DARWIN
 #include <mach-o/dyld.h>
 #endif
 
@@ -60,6 +60,7 @@ typedef struct  {
        guint8 version_set_index;
        const char* new_assembly_name;
        gboolean only_lower_versions;
+       gboolean framework_facade_assembly;
 } AssemblyVersionMap;
 
 /* Flag bits for assembly_names_equal_flags (). */
@@ -68,8 +69,10 @@ typedef enum {
        ANAME_EQ_NONE = 0x0,
        /* Don't compare public key token */
        ANAME_EQ_IGNORE_PUBKEY = 0x1,
+       /* Don't compare the versions */
+       ANAME_EQ_IGNORE_VERSION = 0x2,
 
-       ANAME_EQ_MASK = 0x1
+       ANAME_EQ_MASK = 0x3
 } AssemblyNameEqFlags;
 
 /* the default search path is empty, the first slot is replaced with the computed value */
@@ -86,7 +89,9 @@ static char **assemblies_path = NULL;
 /* Contains the list of directories that point to auxiliary GACs */
 static char **extra_gac_paths = NULL;
 
-#ifndef DISABLE_ASSEMBLY_REMAPPING
+#ifndef DISABLE_DESKTOP_LOADER
+
+#define FACADE_ASSEMBLY(str) {str, 0, NULL, FALSE, TRUE}
 
 static GHashTable* assembly_remapping_table;
 /* The list of system assemblies what will be remapped to the running
@@ -118,6 +123,9 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"Microsoft.Build.Utilities.v3.5", 2, "Microsoft.Build.Utilities.v4.0"},
        {"Microsoft.VisualBasic", 1},
        {"Microsoft.VisualC", 1},
+       FACADE_ASSEMBLY ("Microsoft.Win32.Primitives"),
+       FACADE_ASSEMBLY ("Microsoft.Win32.Registry"),
+       FACADE_ASSEMBLY ("Microsoft.Win32.Registry.AccessControl"),
        {"Mono.Cairo", 0},
        {"Mono.CompilerServices.SymbolWriter", 0},
        {"Mono.Data", 0},
@@ -133,46 +141,165 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"Novell.Directory.Ldap", 0},
        {"PEAPI", 0},
        {"System", 0},
+       FACADE_ASSEMBLY ("System.AppContext"),
+       FACADE_ASSEMBLY ("System.Collections"),
+       FACADE_ASSEMBLY ("System.Collections.Concurrent"),
+       FACADE_ASSEMBLY ("System.Collections.NonGeneric"),
+       FACADE_ASSEMBLY ("System.Collections.Specialized"),
+       FACADE_ASSEMBLY ("System.ComponentModel"),
+       FACADE_ASSEMBLY ("System.ComponentModel.Annotations"),
        {"System.ComponentModel.Composition", 2},
        {"System.ComponentModel.DataAnnotations", 2},
+       FACADE_ASSEMBLY ("System.ComponentModel.EventBasedAsync"),
+       FACADE_ASSEMBLY ("System.ComponentModel.Primitives"),
+       FACADE_ASSEMBLY ("System.ComponentModel.TypeConverter"),
        {"System.Configuration", 0},
        {"System.Configuration.Install", 0},
+       FACADE_ASSEMBLY ("System.Console"),
        {"System.Core", 2},
        {"System.Data", 0},
+       FACADE_ASSEMBLY ("System.Data.Common"),
        {"System.Data.Linq", 2},
        {"System.Data.OracleClient", 0},
        {"System.Data.Services", 2},
        {"System.Data.Services.Client", 2},
+       FACADE_ASSEMBLY ("System.Data.SqlClient"),
        {"System.Data.SqlXml", 0},
        {"System.Design", 0},
+       FACADE_ASSEMBLY ("System.Diagnostics.Contracts"),
+       FACADE_ASSEMBLY ("System.Diagnostics.Debug"),
+       FACADE_ASSEMBLY ("System.Diagnostics.FileVersionInfo"),
+       FACADE_ASSEMBLY ("System.Diagnostics.Process"),
+       FACADE_ASSEMBLY ("System.Diagnostics.StackTrace"),
+       FACADE_ASSEMBLY ("System.Diagnostics.TextWriterTraceListener"),
+       FACADE_ASSEMBLY ("System.Diagnostics.Tools"),
+       FACADE_ASSEMBLY ("System.Diagnostics.TraceEvent"),
+       FACADE_ASSEMBLY ("System.Diagnostics.TraceSource"),
+       FACADE_ASSEMBLY ("System.Diagnostics.Tracing"),
        {"System.DirectoryServices", 0},
        {"System.Drawing", 0},
        {"System.Drawing.Design", 0},
+       FACADE_ASSEMBLY ("System.Drawing.Primitives"),
+       FACADE_ASSEMBLY ("System.Dynamic.Runtime"),
        {"System.EnterpriseServices", 0},
-       {"System.IO.Compression", 2},
+       FACADE_ASSEMBLY ("System.Globalization"),
+       FACADE_ASSEMBLY ("System.Globalization.Calendars"),
+       FACADE_ASSEMBLY ("System.Globalization.Extensions"),
        {"System.IdentityModel", 3},
        {"System.IdentityModel.Selectors", 3},
+       FACADE_ASSEMBLY ("System.IO"),
+       {"System.IO.Compression", 2},
+       FACADE_ASSEMBLY ("System.IO.Compression.ZipFile"),
+       FACADE_ASSEMBLY ("System.IO.FileSystem"),
+       FACADE_ASSEMBLY ("System.IO.FileSystem.AccessControl"),
+       FACADE_ASSEMBLY ("System.IO.FileSystem.DriveInfo"),
+       FACADE_ASSEMBLY ("System.IO.FileSystem.Primitives"),
+       FACADE_ASSEMBLY ("System.IO.FileSystem.Watcher"),
+       FACADE_ASSEMBLY ("System.IO.IsolatedStorage"),
+       FACADE_ASSEMBLY ("System.IO.MemoryMappedFiles"),
+       FACADE_ASSEMBLY ("System.IO.Packaging"),
+       FACADE_ASSEMBLY ("System.IO.Pipes"),
+       FACADE_ASSEMBLY ("System.IO.UnmanagedMemoryStream"),
+       FACADE_ASSEMBLY ("System.Linq"),
+       FACADE_ASSEMBLY ("System.Linq.Expressions"),
+       FACADE_ASSEMBLY ("System.Linq.Parallel"),
+       FACADE_ASSEMBLY ("System.Linq.Queryable"),
        {"System.Management", 0},
        {"System.Messaging", 0},
        {"System.Net", 2},
+       FACADE_ASSEMBLY ("System.Net.AuthenticationManager"),
+       FACADE_ASSEMBLY ("System.Net.Cache"),
        {"System.Net.Http", 4},
+       {"System.Net.Http.Rtc", 0},
+       FACADE_ASSEMBLY ("System.Net.HttpListener"),
+       FACADE_ASSEMBLY ("System.Net.Mail"),
+       FACADE_ASSEMBLY ("System.Net.NameResolution"),
+       FACADE_ASSEMBLY ("System.Net.NetworkInformation"),
+       FACADE_ASSEMBLY ("System.Net.Ping"),
+       FACADE_ASSEMBLY ("System.Net.Primitives"),
+       FACADE_ASSEMBLY ("System.Net.Requests"),
+       FACADE_ASSEMBLY ("System.Net.Security"),
+       FACADE_ASSEMBLY ("System.Net.ServicePoint"),
+       FACADE_ASSEMBLY ("System.Net.Sockets"),
+       FACADE_ASSEMBLY ("System.Net.Utilities"),
+       FACADE_ASSEMBLY ("System.Net.WebHeaderCollection"),
+       FACADE_ASSEMBLY ("System.Net.WebSockets"),
+       FACADE_ASSEMBLY ("System.Net.WebSockets.Client"),
        {"System.Numerics.Vectors", 3},
-       {"System.Runtime.InteropServices.RuntimeInformation", 2},
+       FACADE_ASSEMBLY ("System.ObjectModel"),
+       FACADE_ASSEMBLY ("System.Reflection"),
+       FACADE_ASSEMBLY ("System.Reflection.DispatchProxy"),
+       FACADE_ASSEMBLY ("System.Reflection.Emit"),
+       FACADE_ASSEMBLY ("System.Reflection.Emit.ILGeneration"),
+       FACADE_ASSEMBLY ("System.Reflection.Emit.Lightweight"),
+       FACADE_ASSEMBLY ("System.Reflection.Extensions"),
+       FACADE_ASSEMBLY ("System.Reflection.Primitives"),
+       FACADE_ASSEMBLY ("System.Reflection.TypeExtensions"),
+       FACADE_ASSEMBLY ("System.Resources.ReaderWriter"),
+       FACADE_ASSEMBLY ("System.Resources.ResourceManager"),
+       FACADE_ASSEMBLY ("System.Runtime"),
+       FACADE_ASSEMBLY ("System.Runtime.CompilerServices.VisualC"),
+       FACADE_ASSEMBLY ("System.Runtime.Extensions"),
+       FACADE_ASSEMBLY ("System.Runtime.Handles"),
+       FACADE_ASSEMBLY ("System.Runtime.InteropServices"),
+       FACADE_ASSEMBLY ("System.Runtime.InteropServices.RuntimeInformation"),
+       FACADE_ASSEMBLY ("System.Runtime.InteropServices.WindowsRuntime"),
+       FACADE_ASSEMBLY ("System.Runtime.Loader"),
+       FACADE_ASSEMBLY ("System.Runtime.Numerics"),
        {"System.Runtime.Remoting", 0},
        {"System.Runtime.Serialization", 3},
-       {"System.Runtime.Serialization.Formatters", 3},
+       FACADE_ASSEMBLY ("System.Runtime.Serialization.Formatters"),
        {"System.Runtime.Serialization.Formatters.Soap", 0},
+       FACADE_ASSEMBLY ("System.Runtime.Serialization.Json"),
+       FACADE_ASSEMBLY ("System.Runtime.Serialization.Primitives"),
+       FACADE_ASSEMBLY ("System.Runtime.Serialization.Xml"),
        {"System.Security", 0},
+       FACADE_ASSEMBLY ("System.Security.AccessControl"),
+       FACADE_ASSEMBLY ("System.Security.Claims"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Algorithms"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Cng"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Csp"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.DeriveBytes"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Encoding"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.Aes"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.ECDiffieHellman"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.ECDsa"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.Hashing"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Encryption.Hashing.Algorithms"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.OpenSsl"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Pkcs"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.Primitives"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.ProtectedData"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.RSA"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.RandomNumberGenerator"),
+       FACADE_ASSEMBLY ("System.Security.Cryptography.X509Certificates"),
+       FACADE_ASSEMBLY ("System.Security.Principal"),
+       FACADE_ASSEMBLY ("System.Security.Principal.Windows"),
+       FACADE_ASSEMBLY ("System.Security.SecureString"),
        {"System.ServiceModel", 3},
-       {"System.ServiceModel.Duplex", 3},
-       {"System.ServiceModel.Http", 3},
-       {"System.ServiceModel.NetTcp", 3},
-       {"System.ServiceModel.Primitives", 3},
-       {"System.ServiceModel.Security", 3},
+       FACADE_ASSEMBLY ("System.ServiceModel.Duplex"),
+       FACADE_ASSEMBLY ("System.ServiceModel.Http"),
+       FACADE_ASSEMBLY ("System.ServiceModel.NetTcp"),
+       FACADE_ASSEMBLY ("System.ServiceModel.Primitives"),
+       FACADE_ASSEMBLY ("System.ServiceModel.Security"),
        {"System.ServiceModel.Web", 2},
        {"System.ServiceProcess", 0},
-       {"System.Text.Encoding.CodePages", 3},
+       FACADE_ASSEMBLY ("System.ServiceProcess.ServiceController"),
+       FACADE_ASSEMBLY ("System.Text.Encoding"),
+       FACADE_ASSEMBLY ("System.Text.Encoding.CodePages"),
+       FACADE_ASSEMBLY ("System.Text.Encoding.Extensions"),
+       FACADE_ASSEMBLY ("System.Text.RegularExpressions"),
+       FACADE_ASSEMBLY ("System.Threading"),
+       FACADE_ASSEMBLY ("System.Threading.AccessControl"),
+       FACADE_ASSEMBLY ("System.Threading.Overlapped"),
+       FACADE_ASSEMBLY ("System.Threading.Tasks"),
+       FACADE_ASSEMBLY ("System.Threading.Tasks.Parallel"),
+       FACADE_ASSEMBLY ("System.Threading.Thread"),
+       FACADE_ASSEMBLY ("System.Threading.ThreadPool"),
+       FACADE_ASSEMBLY ("System.Threading.Timer"),
        {"System.Transactions", 0},
+       FACADE_ASSEMBLY ("System.ValueTuple"),
        {"System.Web", 0},
        {"System.Web.Abstractions", 2},
        {"System.Web.DynamicData", 2},
@@ -180,13 +307,22 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"System.Web.Mobile", 0},
        {"System.Web.Routing", 2},
        {"System.Web.Services", 0},
+       {"System.Windows", 0},
        {"System.Windows.Forms", 0},
        {"System.Xml", 0},
        {"System.Xml.Linq", 2},
-       {"System.Xml.ReaderWriter", 3},
-       {"System.Xml.XPath.XmlDocument", 3},
+       FACADE_ASSEMBLY ("System.Xml.ReaderWriter"),
+       {"System.Xml.Serialization", 0},
+       FACADE_ASSEMBLY ("System.Xml.XDocument"),
+       FACADE_ASSEMBLY ("System.Xml.XPath"),
+       FACADE_ASSEMBLY ("System.Xml.XPath.XmlDocument"),
+       FACADE_ASSEMBLY ("System.Xml.XPath.XDocument"),
+       FACADE_ASSEMBLY ("System.Xml.XmlDocument"),
+       FACADE_ASSEMBLY ("System.Xml.XmlSerializer"),
+       FACADE_ASSEMBLY ("System.Xml.Xsl.Primitives"),
        {"WindowsBase", 3},
-       {"mscorlib", 0}
+       {"mscorlib", 0},
+       FACADE_ASSEMBLY ("netstandard"),
 };
 #endif
 
@@ -196,27 +332,6 @@ static const AssemblyVersionMap framework_assemblies [] = {
 static GList *loaded_assemblies = NULL;
 static MonoAssembly *corlib;
 
-#if defined(__native_client__)
-
-/* On Native Client, allow mscorlib to be loaded from memory  */
-/* instead of loaded off disk.  If these are not set, default */
-/* mscorlib loading will take place                           */
-
-/* NOTE: If mscorlib data is passed to mono in this way then */
-/* it needs to remain allocated during the use of mono.      */
-
-static void *corlibData = NULL;
-static size_t corlibSize = 0;
-
-void
-mono_set_corlib_data (void *data, size_t size)
-{
-  corlibData = data;
-  corlibSize = size;
-}
-
-#endif
-
 static char* unquote (const char *str);
 
 /* This protects loaded_assemblies and image->references */
@@ -326,12 +441,6 @@ mono_set_assemblies_path (const char* path)
        }
 }
 
-/* Native Client can't get this info from an environment variable so */
-/* it's passed in to the runtime, or set manually by embedding code. */
-#ifdef __native_client__
-char* nacl_mono_path = NULL;
-#endif
-
 static void
 check_path_env (void)
 {
@@ -339,10 +448,6 @@ check_path_env (void)
                return;
 
        char* path = g_getenv ("MONO_PATH");
-#ifdef __native_client__
-       if (!path)
-               path = strdup (nacl_mono_path);
-#endif
        if (!path)
                return;
 
@@ -545,8 +650,9 @@ assembly_names_equal_flags (MonoAssemblyName *l, MonoAssemblyName *r, AssemblyNa
        if (l->culture && r->culture && strcmp (l->culture, r->culture))
                return FALSE;
 
-       if (l->major != r->major || l->minor != r->minor ||
-                       l->build != r->build || l->revision != r->revision)
+       if ((l->major != r->major || l->minor != r->minor ||
+            l->build != r->build || l->revision != r->revision) &&
+           (flags & ANAME_EQ_IGNORE_VERSION) == 0)
                if (! ((l->major == 0 && l->minor == 0 && l->build == 0 && l->revision == 0) || (r->major == 0 && r->minor == 0 && r->build == 0 && r->revision == 0)))
                        return FALSE;
 
@@ -734,7 +840,7 @@ set_dirs (char *exe)
 void
 mono_set_rootdir (void)
 {
-#if defined(HOST_WIN32) || (defined(PLATFORM_MACOSX) && !defined(TARGET_ARM))
+#if defined(HOST_WIN32) || (defined(HOST_DARWIN) && !defined(TARGET_ARM))
        gchar *bindir, *installdir, *root, *name, *resolvedname, *config;
 
 #ifdef HOST_WIN32
@@ -834,7 +940,7 @@ mono_assemblies_init (void)
        mono_os_mutex_init_recursive (&assemblies_mutex);
        mono_os_mutex_init (&assembly_binding_mutex);
 
-#ifndef DISABLE_ASSEMBLY_REMAPPING
+#ifndef DISABLE_DESKTOP_LOADER
        assembly_remapping_table = g_hash_table_new (g_str_hash, g_str_equal);
 
        int i;
@@ -1124,7 +1230,7 @@ mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_ana
                return dest_aname;
        }
        
-#ifndef DISABLE_ASSEMBLY_REMAPPING
+#ifndef DISABLE_DESKTOP_LOADER
        const AssemblyVersionMap *vmap = (AssemblyVersionMap *)g_hash_table_lookup (assembly_remapping_table, aname->name);
        if (vmap) {
                const AssemblyVersionSet* vset;
@@ -1132,6 +1238,12 @@ mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_ana
                g_assert (index < G_N_ELEMENTS (current_runtime->version_sets));
                vset = &current_runtime->version_sets [index];
 
+               if (vmap->framework_facade_assembly) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Assembly %s is a framework Facade asseembly",
+                                   aname->name);
+                       return aname;
+               }
+
                if (aname->major == vset->major && aname->minor == vset->minor &&
                        aname->build == vset->build && aname->revision == vset->revision) {
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Found assembly remapping for %s and was for the same version %d.%d.%d.%d",
@@ -1837,11 +1949,24 @@ mono_assembly_open_predicate (const char *filename, gboolean refonly,
        }
 
        if (image->assembly) {
-               /* Already loaded by another appdomain */
-               mono_assembly_invoke_load_hook (image->assembly);
-               mono_image_close (image);
-               g_free (fname);
-               return image->assembly;
+               /* We want to return the MonoAssembly that's already loaded,
+                * but if we're using the strict assembly loader, we also need
+                * to check that the previously loaded assembly matches the
+                * predicate.  It could be that we previously loaded a
+                * different version that happens to have the filename that
+                * we're currently probing. */
+               if (mono_loader_get_strict_strong_names () &&
+                   predicate && !predicate (image->assembly, user_data)) {
+                       mono_image_close (image);
+                       g_free (fname);
+                       return NULL;
+               } else {
+                       /* Already loaded by another appdomain */
+                       mono_assembly_invoke_load_hook (image->assembly);
+                       mono_image_close (image);
+                       g_free (fname);
+                       return image->assembly;
+               }
        }
 
        ass = mono_assembly_load_from_predicate (image, fname, refonly, predicate, user_data, status);
@@ -1983,6 +2108,10 @@ has_reference_assembly_attribute_iterator (MonoImage *image, guint32 typeref_sco
 gboolean
 mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error)
 {
+       g_assert (assembly && assembly->image);
+       /* .NET Framework appears to ignore the attribute on dynamic
+        * assemblies, so don't call this function for dynamic assemblies. */
+       g_assert (!image_is_dynamic (assembly->image));
        error_init (error);
 
        /*
@@ -2093,7 +2222,7 @@ mono_assembly_load_from_predicate (MonoImage *image, const char *fname,
        ass->ref_only = refonly;
        ass->image = image;
 
-       mono_profiler_assembly_event (ass, MONO_PROFILE_START_LOAD);
+       MONO_PROFILER_RAISE (assembly_loading, (ass));
 
        mono_assembly_fill_assembly_name (image, &ass->aname);
 
@@ -2185,7 +2314,7 @@ mono_assembly_load_from_predicate (MonoImage *image, const char *fname,
 
        mono_assembly_invoke_load_hook (ass);
 
-       mono_profiler_assembly_loaded (ass, MONO_PROFILE_OK);
+       MONO_PROFILER_RAISE (assembly_loaded, (ass));
        
        return ass;
 }
@@ -2241,19 +2370,20 @@ static gboolean
 parse_public_key (const gchar *key, gchar** pubkey, gboolean *is_ecma)
 {
        const gchar *pkey;
-       gchar header [16], val, *arr;
+       gchar header [16], val, *arr, *endp;
        gint i, j, offset, bitlen, keylen, pkeylen;
-       
+
+       //both pubkey and is_ecma are required arguments
+       g_assert (pubkey && is_ecma);
+
        keylen = strlen (key) >> 1;
        if (keylen < 1)
                return FALSE;
 
        /* allow the ECMA standard key */
        if (strcmp (key, "00000000000000000400000000000000") == 0) {
-               if (pubkey) {
-                       *pubkey = g_strdup (key);
-                       *is_ecma = TRUE;
-               }
+               *pubkey = g_strdup (key);
+               *is_ecma = TRUE;
                return TRUE;
        }
        *is_ecma = FALSE;
@@ -2298,21 +2428,11 @@ parse_public_key (const gchar *key, gchar** pubkey, gboolean *is_ecma)
        bitlen = read32 (header + 12) >> 3;
        if ((bitlen + 16 + 4) != pkeylen)
                return FALSE;
-
-       /* parsing is OK and the public key itself is not requested back */
-       if (!pubkey)
-               return TRUE;
                
+       arr = (gchar *)g_malloc (keylen + 4);
        /* Encode the size of the blob */
-       offset = 0;
-       if (keylen <= 127) {
-               arr = (gchar *)g_malloc (keylen + 1);
-               arr [offset++] = keylen;
-       } else {
-               arr = (gchar *)g_malloc (keylen + 2);
-               arr [offset++] = 0x80; /* 10bs */
-               arr [offset++] = keylen;
-       }
+       mono_metadata_encode_value (keylen, &arr[0], &endp);
+       offset = (gint)(endp-arr);
                
        for (i = offset, j = 0; i < keylen + offset; i++) {
                arr [i] = g_ascii_xdigit_value (key [j++]) << 4;
@@ -2386,10 +2506,8 @@ build_assembly_name (const char *name, const char *version, const char *culture,
                }
 
                if (is_ecma) {
-                       if (save_public_key)
-                               aname->public_key = (guint8*)pkey;
-                       else
-                               g_free (pkey);
+                       aname->public_key = NULL;
+                       g_free (pkey);
                        g_strlcpy ((gchar*)aname->public_key_token, "b77a5c561934e089", MONO_PUBLIC_KEY_TOKEN_LENGTH);
                        return TRUE;
                }
@@ -3148,6 +3266,28 @@ get_per_domain_assembly_binding_info (MonoDomain *domain, MonoAssemblyName *anam
        return info;
 }
 
+void
+mono_domain_parse_assembly_bindings (MonoDomain *domain, int amajor, int aminor, gchar *domain_config_file_name)
+{
+       if (domain->assembly_bindings_parsed)
+               return;
+       mono_domain_lock (domain);
+       if (!domain->assembly_bindings_parsed) {
+
+               gchar *domain_config_file_path = mono_portability_find_file (domain_config_file_name, TRUE);
+
+               if (!domain_config_file_path)
+                       domain_config_file_path = domain_config_file_name;
+
+               mono_config_parse_assembly_bindings (domain_config_file_path, amajor, aminor, domain, assembly_binding_info_parsed);
+               domain->assembly_bindings_parsed = TRUE;
+               if (domain_config_file_name != domain_config_file_path)
+                       g_free (domain_config_file_path);
+       }
+
+       mono_domain_unlock (domain);
+}
+
 static MonoAssemblyName*
 mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_name)
 {
@@ -3180,25 +3320,14 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
        }
 
        if (domain && domain->setup && domain->setup->configuration_file) {
-               mono_domain_lock (domain);
-               if (!domain->assembly_bindings_parsed) {
-                       gchar *domain_config_file_name = mono_string_to_utf8_checked (domain->setup->configuration_file, &error);
-                       /* expect this to succeed because mono_domain_set_options_from_config () did
-                        * the same thing when the domain was created. */
-                       mono_error_assert_ok (&error);
-
-                       gchar *domain_config_file_path = mono_portability_find_file (domain_config_file_name, TRUE);
-
-                       if (!domain_config_file_path)
-                               domain_config_file_path = domain_config_file_name;
-                       
-                       mono_config_parse_assembly_bindings (domain_config_file_path, aname->major, aname->minor, domain, assembly_binding_info_parsed);
-                       domain->assembly_bindings_parsed = TRUE;
-                       if (domain_config_file_name != domain_config_file_path)
-                               g_free (domain_config_file_name);
-                       g_free (domain_config_file_path);
-               }
+               gchar *domain_config_file_name = mono_string_to_utf8_checked (domain->setup->configuration_file, &error);
+               /* expect this to succeed because mono_domain_set_options_from_config () did
+                * the same thing when the domain was created. */
+               mono_error_assert_ok (&error);
+               mono_domain_parse_assembly_bindings (domain, aname->major, aname->minor, domain_config_file_name);
+               g_free (domain_config_file_name);
 
+               mono_domain_lock (domain);
                info2 = get_per_domain_assembly_binding_info (domain, aname);
 
                if (info2) {
@@ -3209,6 +3338,7 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
                }
 
                mono_domain_unlock (domain);
+
        }
 
        if (!info) {
@@ -3337,23 +3467,6 @@ mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *
                return corlib;
        }
 
-       // In native client, Corlib is embedded in the executable as static variable corlibData
-#if defined(__native_client__)
-       if (corlibData != NULL && corlibSize != 0) {
-               int status = 0;
-               /* First "FALSE" instructs mono not to make a copy. */
-               /* Second "FALSE" says this is not just a ref.      */
-               MonoImage* image = mono_image_open_from_data_full (corlibData, corlibSize, FALSE, &status, FALSE);
-               if (image == NULL || status != 0)
-                       g_print("mono_image_open_from_data_full failed: %d\n", status);
-               corlib = mono_assembly_load_from_full (image, "mscorlib", &status, FALSE);
-               if (corlib == NULL || status != 0)
-                       g_print ("mono_assembly_load_from_full failed: %d\n", status);
-               if (corlib)
-                       return corlib;
-       }
-#endif
-
        // A nonstandard preload hook may provide a special mscorlib assembly
        aname = mono_assembly_name_new ("mscorlib.dll");
        corlib = invoke_assembly_preload_hook (aname, assemblies_path);
@@ -3393,8 +3506,11 @@ prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refon
 {
        MonoError refasm_error;
        error_init (&refasm_error);
-       if (candidate && !refonly && mono_assembly_has_reference_assembly_attribute (candidate, &refasm_error)) {
-               candidate = NULL;
+       if (candidate && !refonly) {
+               /* .NET Framework seems to not check for ReferenceAssemblyAttribute on dynamic assemblies */
+               if (!image_is_dynamic (candidate->image) &&
+                   mono_assembly_has_reference_assembly_attribute (candidate, &refasm_error))
+                       candidate = NULL;
        }
        mono_error_cleanup (&refasm_error);
        return candidate;
@@ -3449,13 +3565,21 @@ exact_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *candidate_name)
 gboolean
 framework_assembly_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *candidate_name)
 {
-#ifndef DISABLE_ASSEMBLY_REMAPPING
+#ifndef DISABLE_DESKTOP_LOADER
        const AssemblyVersionMap *vmap = (AssemblyVersionMap *)g_hash_table_lookup (assembly_remapping_table, wanted_name->name);
        if (vmap) {
-               /* If the wanted name is a framework assembly, it's enough for the name/version/culture to match.  If the assembly was remapped, the public key token is likely unrelated. */
-               gboolean result = assembly_names_equal_flags (wanted_name, candidate_name, ANAME_EQ_IGNORE_PUBKEY);
-               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s (ignoring the public key token)", result ? "match, returning TRUE" : "don't match, returning FALSE");
-               return result;
+               if (!vmap->framework_facade_assembly) {
+                       /* If the wanted name is a framework assembly, it's enough for the name/version/culture to match.  If the assembly was remapped, the public key token is likely unrelated. */
+                       gboolean result = assembly_names_equal_flags (wanted_name, candidate_name, ANAME_EQ_IGNORE_PUBKEY);
+                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s (ignoring the public key token)", result ? "match, returning TRUE" : "don't match, returning FALSE");
+                       return result;
+               } else {
+                       /* For facades, the name and public key token should
+                        * match, but the version doesn't matter. */
+                       gboolean result = assembly_names_equal_flags (wanted_name, candidate_name, ANAME_EQ_IGNORE_VERSION);
+                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s (ignoring version)", result ? "match, returning TRUE" : "don't match, returning FALSE");
+                       return result;
+               }
        }
 #endif
        return FALSE;
@@ -3498,6 +3622,15 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
                return mono_assembly_load_corlib (mono_get_runtime_info (), status);
        }
 
+       MonoAssemblyCandidatePredicate predicate = NULL;
+       void* predicate_ud = NULL;
+#if !defined(DISABLE_DESKTOP_LOADER)
+       if (G_LIKELY (mono_loader_get_strict_strong_names ())) {
+               predicate = &mono_assembly_candidate_predicate_sn_same_name;
+               predicate_ud = aname;
+       }
+#endif
+
        len = strlen (aname->name);
        for (ext_index = 0; ext_index < 2; ext_index ++) {
                ext = ext_index == 0 ? ".dll" : ".exe";
@@ -3517,7 +3650,7 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
 
                if (basedir) {
                        fullpath = g_build_filename (basedir, filename, NULL);
-                       result = mono_assembly_open_predicate (fullpath, refonly, FALSE, &mono_assembly_candidate_predicate_sn_same_name, aname, status);
+                       result = mono_assembly_open_predicate (fullpath, refonly, FALSE, predicate, predicate_ud, status);
                        g_free (fullpath);
                        if (result) {
                                result->in_gac = FALSE;
@@ -3526,7 +3659,7 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
                        }
                }
 
-               result = load_in_path (filename, default_path, status, refonly, &mono_assembly_candidate_predicate_sn_same_name, aname);
+               result = load_in_path (filename, default_path, status, refonly, predicate, predicate_ud);
                if (result)
                        result->in_gac = FALSE;
                g_free (filename);
@@ -3660,7 +3793,7 @@ mono_assembly_close_except_image_pools (MonoAssembly *assembly)
        if (InterlockedDecrement (&assembly->ref_count) > 0)
                return FALSE;
 
-       mono_profiler_assembly_event (assembly, MONO_PROFILE_START_UNLOAD);
+       MONO_PROFILER_RAISE (assembly_unloading, (assembly));
 
        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Unloading assembly %s [%p].", assembly->aname.name, assembly);
 
@@ -3683,7 +3816,7 @@ mono_assembly_close_except_image_pools (MonoAssembly *assembly)
        g_slist_free (assembly->friend_assembly_names);
        g_free (assembly->basedir);
 
-       mono_profiler_assembly_event (assembly, MONO_PROFILE_END_UNLOAD);
+       MONO_PROFILER_RAISE (assembly_unloaded, (assembly));
 
        return TRUE;
 }