Merge pull request #2274 from esdrubal/udpclientreceive
[mono.git] / mono / metadata / assembly.c
index bd887b84f22b620cec97e9db216d7e5708d8cd99..a3916463b691522ce18b0f11b87e17c1d5195102 100644 (file)
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/mono-config-dirs.h>
 #include <mono/utils/mono-digest.h>
-#include <mono/utils/mono-logger-internal.h>
+#include <mono/utils/mono-logger-internals.h>
 #include <mono/utils/mono-path.h>
 #include <mono/metadata/reflection.h>
 #include <mono/metadata/coree.h>
 #include <mono/metadata/cil-coff.h>
 #include <mono/utils/mono-io-portability.h>
 #include <mono/utils/atomic.h>
-#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-os-mutex.h>
 
 #ifndef HOST_WIN32
 #include <sys/types.h>
@@ -88,6 +88,8 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"I18N.Other", 0},
        {"I18N.Rare", 0},
        {"I18N.West", 0},
+       {"Microsoft.Build.Engine", 2},
+       {"Microsoft.Build.Framework", 2},
        {"Microsoft.VisualBasic", 1},
        {"Microsoft.VisualC", 1},
        {"Mono.Cairo", 0},
@@ -177,9 +179,11 @@ mono_set_corlib_data (void *data, size_t size)
 
 #endif
 
+static char* unquote (const char *str);
+
 /* This protects loaded_assemblies and image->references */
-#define mono_assemblies_lock() mono_mutex_lock (&assemblies_mutex)
-#define mono_assemblies_unlock() mono_mutex_unlock (&assemblies_mutex)
+#define mono_assemblies_lock() mono_os_mutex_lock (&assemblies_mutex)
+#define mono_assemblies_unlock() mono_os_mutex_unlock (&assemblies_mutex)
 static mono_mutex_t assemblies_mutex;
 
 /* If defined, points to the bundled assembly information */
@@ -204,7 +208,7 @@ encode_public_tok (const guchar *token, gint32 len)
        gchar *res;
        int i;
 
-       res = g_malloc (len * 2 + 1);
+       res = (gchar *)g_malloc (len * 2 + 1);
        for (i = 0; i < len; i++) {
                res [i * 2] = allowed [token [i] >> 4];
                res [i * 2 + 1] = allowed [token [i] & 0xF];
@@ -748,20 +752,20 @@ mono_assemblies_init (void)
        check_path_env ();
        check_extra_gac_path_env ();
 
-       mono_mutex_init_recursive (&assemblies_mutex);
-       mono_mutex_init (&assembly_binding_mutex);
+       mono_os_mutex_init_recursive (&assemblies_mutex);
+       mono_os_mutex_init (&assembly_binding_mutex);
 }
 
 static void
 mono_assembly_binding_lock (void)
 {
-       mono_locks_mutex_acquire (&assembly_binding_mutex, AssemblyBindingLock);
+       mono_locks_os_acquire (&assembly_binding_mutex, AssemblyBindingLock);
 }
 
 static void
 mono_assembly_binding_unlock (void)
 {
-       mono_locks_mutex_release (&assembly_binding_mutex, AssemblyBindingLock);
+       mono_locks_os_release (&assembly_binding_mutex, AssemblyBindingLock);
 }
 
 gboolean
@@ -787,7 +791,7 @@ mono_assembly_fill_assembly_name (MonoImage *image, MonoAssemblyName *aname)
        aname->revision = cols [MONO_ASSEMBLY_REV_NUMBER];
        aname->hash_alg = cols [MONO_ASSEMBLY_HASH_ALG];
        if (cols [MONO_ASSEMBLY_PUBLIC_KEY]) {
-               guchar* token = g_malloc (8);
+               guchar* token = (guchar *)g_malloc (8);
                gchar* encoded;
                const gchar* pkey;
                int len;
@@ -1112,7 +1116,7 @@ mono_assembly_load_reference (MonoImage *image, int index)
                 * a non loaded reference using the ReflectionOnly api
                */
                if (!reference)
-                       reference = REFERENCE_MISSING;
+                       reference = (MonoAssembly *)REFERENCE_MISSING;
        } else {
                /* we first try without setting the basedir: this can eventually result in a ResolveAssembly
                 * event which is the MS .net compatible behaviour (the assemblyresolve_event3.cs test has been fixed
@@ -1153,7 +1157,7 @@ mono_assembly_load_reference (MonoImage *image, int index)
        mono_assemblies_lock ();
        if (reference == NULL) {
                /* Flag as not found */
-               reference = REFERENCE_MISSING;
+               reference = (MonoAssembly *)REFERENCE_MISSING;
        }       
 
        if (!image->references [index]) {
@@ -1584,6 +1588,7 @@ mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboo
        
        image = NULL;
 
+       // If VM built with mkbundle
        loaded_from_bundle = FALSE;
        if (bundles != NULL) {
                image = mono_assembly_open_from_bundle (fname, status, refonly);
@@ -1932,10 +1937,10 @@ parse_public_key (const gchar *key, gchar** pubkey, gboolean *is_ecma)
        /* Encode the size of the blob */
        offset = 0;
        if (keylen <= 127) {
-               arr = g_malloc (keylen + 1);
+               arr = (gchar *)g_malloc (keylen + 1);
                arr [offset++] = keylen;
        } else {
-               arr = g_malloc (keylen + 2);
+               arr = (gchar *)g_malloc (keylen + 2);
                arr [offset++] = 0x80; /* 10bs */
                arr [offset++] = keylen;
        }
@@ -2076,11 +2081,19 @@ gboolean
 mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboolean save_public_key, gboolean *is_version_defined, gboolean *is_token_defined)
 {
        gchar *dllname;
+       gchar *dllname_uq;
        gchar *version = NULL;
+       gchar *version_uq;
        gchar *culture = NULL;
+       gchar *culture_uq;
        gchar *token = NULL;
+       gchar *token_uq;
        gchar *key = NULL;
+       gchar *key_uq;
        gchar *retargetable = NULL;
+       gchar *retargetable_uq;
+       gchar *procarch;
+       gchar *procarch_uq;
        gboolean res;
        gchar *value, *part_name;
        guint32 part_name_len;
@@ -2152,29 +2165,42 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole
 
                if (part_name_len == 12 && !g_ascii_strncasecmp (part_name, "Retargetable", part_name_len)) {
                        retargetable = value;
-                       if (strlen (retargetable) == 0) {
-                               goto cleanup_and_fail;
-                       }
+                       retargetable_uq = unquote (retargetable);
+                       if (retargetable_uq != NULL)
+                               retargetable = retargetable_uq;
+
                        if (!g_ascii_strcasecmp (retargetable, "yes")) {
                                flags |= ASSEMBLYREF_RETARGETABLE_FLAG;
                        } else if (g_ascii_strcasecmp (retargetable, "no")) {
+                               free (retargetable_uq);
                                goto cleanup_and_fail;
                        }
+
+                       free (retargetable_uq);
                        tmp++;
                        continue;
                }
 
                if (part_name_len == 21 && !g_ascii_strncasecmp (part_name, "ProcessorArchitecture", part_name_len)) {
-                       if (!g_ascii_strcasecmp (value, "MSIL"))
+                       procarch = value;
+                       procarch_uq = unquote (procarch);
+                       if (procarch_uq != NULL)
+                               procarch = procarch_uq;
+
+                       if (!g_ascii_strcasecmp (procarch, "MSIL"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_MSIL;
-                       else if (!g_ascii_strcasecmp (value, "X86"))
+                       else if (!g_ascii_strcasecmp (procarch, "X86"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_X86;
-                       else if (!g_ascii_strcasecmp (value, "IA64"))
+                       else if (!g_ascii_strcasecmp (procarch, "IA64"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_IA64;
-                       else if (!g_ascii_strcasecmp (value, "AMD64"))
+                       else if (!g_ascii_strcasecmp (procarch, "AMD64"))
                                arch = MONO_PROCESSOR_ARCHITECTURE_AMD64;
-                       else
+                       else {
+                               free (procarch_uq);
                                goto cleanup_and_fail;
+                       }
+
+                       free (procarch_uq);
                        tmp++;
                        continue;
                }
@@ -2188,8 +2214,26 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole
                goto cleanup_and_fail;
        }
 
-       res = build_assembly_name (dllname, version, culture, token, key, flags, arch,
-               aname, save_public_key);
+       dllname_uq = unquote (dllname);
+       version_uq = unquote (version);
+       culture_uq = unquote (culture);
+       token_uq = unquote (token);
+       key_uq = unquote (key);
+
+       res = build_assembly_name (
+               dllname_uq == NULL ? dllname : dllname_uq,
+               version_uq == NULL ? version : version_uq,
+               culture_uq == NULL ? culture : culture_uq,
+               token_uq == NULL ? token : token_uq,
+               key_uq == NULL ? key : key_uq,
+               flags, arch, aname, save_public_key);
+
+       free (dllname_uq);
+       free (version_uq);
+       free (culture_uq);
+       free (token_uq);
+       free (key_uq);
+
        g_strfreev (parts);
        return res;
 
@@ -2198,6 +2242,29 @@ cleanup_and_fail:
        return FALSE;
 }
 
+static char*
+unquote (const char *str)
+{
+       gint slen;
+       const char *end;
+
+       if (str == NULL)
+               return NULL;
+
+       slen = strlen (str);
+       if (slen < 2)
+               return NULL;
+
+       if (*str != '\'' && *str != '\"')
+               return NULL;
+
+       end = str + slen - 1;
+       if (*str != *end)
+               return NULL;
+
+       return g_strndup (str + 1, slen - 2);
+}
+
 /**
  * mono_assembly_name_parse:
  * @name: name to parse
@@ -2480,7 +2547,7 @@ mono_assembly_load_publisher_policy (MonoAssemblyName *aname)
 
        if (strstr (aname->name, ".dll")) {
                len = strlen (aname->name) - 4;
-               name = g_malloc (len);
+               name = (gchar *)g_malloc (len);
                strncpy (name, aname->name, len);
        } else
                name = g_strdup (aname->name);
@@ -2546,7 +2613,7 @@ search_binding_loaded (MonoAssemblyName *aname)
        GSList *tmp;
 
        for (tmp = loaded_assembly_bindings; tmp; tmp = tmp->next) {
-               MonoAssemblyBindingInfo *info = tmp->data;
+               MonoAssemblyBindingInfo *info = (MonoAssemblyBindingInfo *)tmp->data;
                if (assembly_binding_maps_name (info, aname))
                        return info;
        }
@@ -2601,12 +2668,12 @@ assembly_binding_info_parsed (MonoAssemblyBindingInfo *info, void *user_data)
                return;
 
        for (tmp = domain->assembly_bindings; tmp; tmp = tmp->next) {
-               info_tmp = tmp->data;
+               info_tmp = (MonoAssemblyBindingInfo *)tmp->data;
                if (strcmp (info->name, info_tmp->name) == 0 && info_versions_equal (info, info_tmp))
                        return;
        }
 
-       info_copy = mono_mempool_alloc0 (domain->mp, sizeof (MonoAssemblyBindingInfo));
+       info_copy = (MonoAssemblyBindingInfo *)mono_mempool_alloc0 (domain->mp, sizeof (MonoAssemblyBindingInfo));
        memcpy (info_copy, info, sizeof (MonoAssemblyBindingInfo));
        if (info->name)
                info_copy->name = mono_mempool_strdup (domain->mp, info->name);
@@ -2654,7 +2721,7 @@ get_per_domain_assembly_binding_info (MonoDomain *domain, MonoAssemblyName *anam
 
        info = NULL;
        for (list = domain->assembly_bindings; list; list = list->next) {
-               info = list->data;
+               info = (MonoAssemblyBindingInfo *)list->data;
                if (info && !strcmp (aname->name, info->name) && info_major_minor_in_range (info, aname))
                        break;
                info = NULL;
@@ -2720,7 +2787,7 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
                info2 = get_per_domain_assembly_binding_info (domain, aname);
 
                if (info2) {
-                       info = g_memdup (info2, sizeof (MonoAssemblyBindingInfo));
+                       info = (MonoAssemblyBindingInfo *)g_memdup (info2, sizeof (MonoAssemblyBindingInfo));
                        info->name = g_strdup (info2->name);
                        info->culture = g_strdup (info2->culture);
                        info->domain_id = domain->domain_id;
@@ -2791,7 +2858,7 @@ mono_assembly_load_from_gac (MonoAssemblyName *aname,  gchar *filename, MonoImag
 
        if (strstr (aname->name, ".dll")) {
                len = strlen (filename) - 4;
-               name = g_malloc (len);
+               name = (gchar *)g_malloc (len);
                strncpy (name, aname->name, len);
        } else {
                name = g_strdup (aname->name);
@@ -2854,6 +2921,7 @@ 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;
@@ -2870,6 +2938,7 @@ mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *
        }
 #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);
        mono_assembly_name_free (aname);
@@ -2877,16 +2946,16 @@ mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *
        if (corlib != NULL)
                return corlib;
 
-       if (assemblies_path) {
+       // 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);
                if (corlib)
                        return corlib;
        }
 
-       /* Load corlib from mono/<version> */
-       
+       /* Normal case: Load corlib from mono/<version> */
        corlib_file = g_build_filename ("mono", runtime->framework_version, "mscorlib.dll", NULL);
-       if (assemblies_path) {
+       if (assemblies_path) { // Custom assemblies path
                corlib = load_in_path (corlib_file, (const char**)assemblies_path, status, FALSE);
                if (corlib) {
                        g_free (corlib_file);
@@ -3104,7 +3173,7 @@ mono_assembly_close_except_image_pools (MonoAssembly *assembly)
                assembly->image = NULL;
 
        for (tmp = assembly->friend_assembly_names; tmp; tmp = tmp->next) {
-               MonoAssemblyName *fname = tmp->data;
+               MonoAssemblyName *fname = (MonoAssemblyName *)tmp->data;
                mono_assembly_name_free (fname);
                g_free (fname);
        }
@@ -3179,11 +3248,11 @@ mono_assemblies_cleanup (void)
 {
        GSList *l;
 
-       mono_mutex_destroy (&assemblies_mutex);
-       mono_mutex_destroy (&assembly_binding_mutex);
+       mono_os_mutex_destroy (&assemblies_mutex);
+       mono_os_mutex_destroy (&assembly_binding_mutex);
 
        for (l = loaded_assembly_bindings; l; l = l->next) {
-               MonoAssemblyBindingInfo *info = l->data;
+               MonoAssemblyBindingInfo *info = (MonoAssemblyBindingInfo *)l->data;
 
                mono_assembly_binding_info_free (info);
                g_free (info);
@@ -3205,7 +3274,7 @@ mono_assembly_cleanup_domain_bindings (guint32 domain_id)
        iter = &loaded_assembly_bindings;
        while (*iter) {
                GSList *l = *iter;
-               MonoAssemblyBindingInfo *info = l->data;
+               MonoAssemblyBindingInfo *info = (MonoAssemblyBindingInfo *)l->data;
 
                if (info->domain_id == domain_id) {
                        *iter = l->next;