New test.
[mono.git] / mono / metadata / assembly.c
index 29ef8580add944c3bf2f4eab668bda3b01a1623a..69187a39eee43cdad5389575dbc8c619bc5fbbc7 100644 (file)
@@ -29,6 +29,7 @@
 #include <mono/metadata/mono-config.h>
 #include <mono/utils/mono-digest.h>
 #include <mono/utils/mono-logger-internal.h>
+#include <mono/utils/mono-path.h>
 #include <mono/metadata/reflection.h>
 #include <mono/metadata/coree.h>
 
@@ -61,6 +62,7 @@ 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
 /* The list of system assemblies what will be remapped to the running
  * runtime version. WARNING: this list must be sorted.
  */
@@ -92,6 +94,7 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"PEAPI", 0},
        {"System", 0},
        {"System.ComponentModel.DataAnnotations", 2},
+       {"System.Configuration", 0},
        {"System.Configuration.Install", 0},
        {"System.Core", 2},
        {"System.Data", 0},
@@ -111,7 +114,6 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"System.ServiceProcess", 0},
        {"System.Web", 0},
        {"System.Web.Abstractions", 2},
-       {"System.Web.Extensions", 2},
        {"System.Web.Mobile", 0},
        {"System.Web.Routing", 2},
        {"System.Web.Services", 0},
@@ -119,6 +121,7 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"System.Xml", 0},
        {"mscorlib", 0}
 };
+#endif
 
 /*
  * keeps track of loaded assemblies
@@ -126,6 +129,27 @@ 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
+
 /* This protects loaded_assemblies and image->references */
 #define mono_assemblies_lock() EnterCriticalSection (&assemblies_mutex)
 #define mono_assemblies_unlock() LeaveCriticalSection (&assemblies_mutex)
@@ -567,7 +591,7 @@ void
 mono_set_rootdir (void)
 {
 #if defined(HOST_WIN32) || (defined(PLATFORM_MACOSX) && !defined(TARGET_ARM))
-       gchar *bindir, *installdir, *root, *name, *config;
+       gchar *bindir, *installdir, *root, *name, *resolvedname, *config;
 
 #ifdef HOST_WIN32
        name = mono_get_module_file_name ((HMODULE) &__ImageBase);
@@ -590,10 +614,14 @@ mono_set_rootdir (void)
                        fallback ();
                        return;
                }
+
+               name = mono_path_resolve_symlinks (name);
        }
 #endif
 
-       bindir = g_path_get_dirname (name);
+       resolvedname = mono_path_resolve_symlinks (name);
+
+       bindir = g_path_get_dirname (resolvedname);
        installdir = g_path_get_dirname (bindir);
        root = g_build_path (G_DIR_SEPARATOR_S, installdir, "lib", NULL);
 
@@ -612,6 +640,7 @@ mono_set_rootdir (void)
        g_free (installdir);
        g_free (bindir);
        g_free (name);
+       g_free (resolvedname);
 #elif defined(DISABLE_MONO_AUTODETECTION)
        fallback ();
 #else
@@ -727,9 +756,11 @@ mono_assembly_fill_assembly_name (MonoImage *image, MonoAssemblyName *aname)
 char*
 mono_stringify_assembly_name (MonoAssemblyName *aname)
 {
+       const char *quote = (aname->name && g_ascii_isspace (aname->name [0])) ? "\"" : "";
+
        return g_strdup_printf (
-               "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
-               aname->name,
+               "%s%s%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
+               quote, aname->name, quote,
                aname->major, aname->minor, aname->build, aname->revision,
                aname->culture && *aname->culture? aname->culture: "neutral",
                aname->public_key_token [0] ? (char *)aname->public_key_token : "null",
@@ -768,6 +799,7 @@ mono_assembly_addref (MonoAssembly *assembly)
        InterlockedIncrement (&assembly->ref_count);
 }
 
+#ifndef DISABLE_ASSEMBLY_REMAPPING
 static MonoAssemblyName *
 mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_aname)
 {
@@ -816,6 +848,7 @@ mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_ana
        }
        return aname;
 }
+#endif
 
 /*
  * mono_assembly_get_assemblyref:
@@ -932,7 +965,7 @@ mono_assembly_load_reference (MonoImage *image, int index)
                if (reference != REFERENCE_MISSING){
                        mono_assembly_addref (reference);
                        if (image->assembly)
-                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Ref addref %s %p -> %s %p: %d\n",
+                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Ref addref %s %p -> %s %p: %d",
                                    image->assembly->aname.name, image->assembly, reference->aname.name, reference, reference->ref_count);
                } else {
                        if (image->assembly)
@@ -1531,7 +1564,7 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
        /* Add a non-temporary reference because of ass->image */
        mono_image_addref (image);
 
-       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Image addref %s %p -> %s %p: %d\n", ass->aname.name, ass, image->name, image, image->ref_count);
+       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Image addref %s %p -> %s %p: %d", ass->aname.name, ass, image->name, image, image->ref_count);
 
        /* 
         * The load hooks might take locks so we can't call them while holding the
@@ -2031,7 +2064,10 @@ MonoAssembly*
 mono_assembly_load_with_partial_name (const char *name, MonoImageOpenStatus *status)
 {
        MonoAssembly *res;
-       MonoAssemblyName *aname, base_name, maped_aname;
+       MonoAssemblyName *aname, base_name;
+#ifndef DISABLE_ASSEMBLY_REMAPPING
+       MonoAssemblyName maped_aname;
+#endif
        gchar *fullname, *gacpath;
        gchar **paths;
 
@@ -2041,12 +2077,14 @@ mono_assembly_load_with_partial_name (const char *name, MonoImageOpenStatus *sta
        if (!mono_assembly_name_parse (name, aname))
                return NULL;
 
+#ifndef DISABLE_ASSEMBLY_REMAPPING
        /* 
         * If no specific version has been requested, make sure we load the
         * correct version for system assemblies.
         */ 
        if ((aname->major | aname->minor | aname->build | aname->revision) == 0)
                aname = mono_assembly_remap_version (aname, &maped_aname);
+#endif
        
        res = mono_assembly_loaded (aname);
        if (res) {
@@ -2514,17 +2552,39 @@ mono_assembly_load_from_gac (MonoAssemblyName *aname,  gchar *filename, MonoImag
        return result;
 }
 
-
 MonoAssembly*
 mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *status)
 {
        char *corlib_file;
+       MonoAssemblyName *aname;
 
        if (corlib) {
                /* g_print ("corlib already loaded\n"); */
                return corlib;
        }
-       
+
+#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
+
+       aname = mono_assembly_name_new ("mscorlib.dll");
+       corlib = invoke_assembly_preload_hook (aname, assemblies_path);
+       mono_assembly_name_free (aname);
+       if (corlib != NULL)
+               return corlib;
+
        if (assemblies_path) {
                corlib = load_in_path ("mscorlib.dll", (const char**)assemblies_path, status, FALSE);
                if (corlib)
@@ -2555,12 +2615,17 @@ mono_assembly_load_full_nosearch (MonoAssemblyName *aname,
 {
        MonoAssembly *result;
        char *fullpath, *filename;
-       MonoAssemblyName maped_aname, maped_name_pp;
+#ifndef DISABLE_ASSEMBLY_REMAPPING
+       MonoAssemblyName maped_aname;
+#endif
+       MonoAssemblyName maped_name_pp;
        int ext_index;
        const char *ext;
        int len;
 
+#ifndef DISABLE_ASSEMBLY_REMAPPING
        aname = mono_assembly_remap_version (aname, &maped_aname);
+#endif
        
        /* Reflection only assemblies don't get assembly binding */
        if (!refonly)
@@ -2671,9 +2736,11 @@ MonoAssembly*
 mono_assembly_loaded_full (MonoAssemblyName *aname, gboolean refonly)
 {
        MonoAssembly *res;
+#ifndef DISABLE_ASSEMBLY_REMAPPING
        MonoAssemblyName maped_aname;
 
        aname = mono_assembly_remap_version (aname, &maped_aname);
+#endif
 
        res = mono_assembly_invoke_search_hook_internal (aname, refonly, FALSE);