Wed Aug 29 18:37:37 CEST 2007 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / assembly.c
index 10dbacfd70d12d4a01c83c08c8e879f9d3f92331..8c48fe7d241676e683927ff83e67b361770102be 100644 (file)
@@ -23,6 +23,7 @@
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/domain-internals.h>
 #include <mono/metadata/mono-endian.h>
+#include <mono/metadata/mono-debug.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/mono-uri.h>
 #include <mono/metadata/mono-config.h>
@@ -72,7 +73,6 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"Mono.Cairo", 0},
        {"Mono.CompilerServices.SymbolWriter", 0},
        {"Mono.Data", 0},
-       {"Mono.Data.SqliteClient", 0},
        {"Mono.Data.SybaseClient", 0},
        {"Mono.Data.Tds", 0},
        {"Mono.Data.TdsClient", 0},
@@ -674,16 +674,18 @@ 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]) {
-               gchar* token = g_malloc (8);
+               guchar* token = g_malloc (8);
                gchar* encoded;
+               const gchar* pkey;
                int len;
 
-               aname->public_key = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
-               len = mono_metadata_decode_blob_size (aname->public_key, (const char**)&aname->public_key);
+               pkey = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
+               len = mono_metadata_decode_blob_size (pkey, &pkey);
+               aname->public_key = (guchar*)pkey;
 
                mono_digest_get_public_token (token, aname->public_key, len);
                encoded = encode_public_tok (token, 8);
-               g_strlcpy (aname->public_key_token, encoded, MONO_PUBLIC_KEY_TOKEN_LENGTH);
+               g_strlcpy ((char*)aname->public_key_token, encoded, MONO_PUBLIC_KEY_TOKEN_LENGTH);
 
                g_free (encoded);
                g_free (token);
@@ -694,7 +696,7 @@ mono_assembly_fill_assembly_name (MonoImage *image, MonoAssemblyName *aname)
        }
 
        if (cols [MONO_ASSEMBLY_PUBLIC_KEY]) {
-               aname->public_key = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
+               aname->public_key = (guchar*)mono_metadata_blob_heap (image, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
        }
        else
                aname->public_key = 0;
@@ -734,12 +736,12 @@ assemblyref_public_tok (MonoImage *image, guint32 key_index, guint32 flags)
        len = mono_metadata_decode_blob_size (public_tok, &public_tok);
 
        if (flags & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG) {
-               gchar token [8];
-               mono_digest_get_public_token (token, public_tok, len);
+               guchar token [8];
+               mono_digest_get_public_token (token, (guchar*)public_tok, len);
                return encode_public_tok (token, 8);
        }
 
-       return encode_public_tok (public_tok, len);
+       return encode_public_tok ((guchar*)public_tok, len);
 }
 
 /**
@@ -834,7 +836,7 @@ mono_assembly_get_assemblyref (MonoImage *image, int index, MonoAssemblyName *an
 
        if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
                gchar *token = assemblyref_public_tok (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY], aname->flags);
-               g_strlcpy (aname->public_key_token, token, MONO_PUBLIC_KEY_TOKEN_LENGTH);
+               g_strlcpy ((char*)aname->public_key_token, token, MONO_PUBLIC_KEY_TOKEN_LENGTH);
                g_free (token);
        } else {
                memset (aname->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH);
@@ -853,6 +855,8 @@ mono_assembly_load_reference (MonoImage *image, int index)
         * it inside a critical section.
         */
        mono_assemblies_lock ();
+       if (!image->references)
+               mono_assembly_load_references (image, &status);
        reference = image->references [index];
        mono_assemblies_unlock ();
        if (reference)
@@ -860,7 +864,7 @@ mono_assembly_load_reference (MonoImage *image, int index)
 
        mono_assembly_get_assemblyref (image, index, &aname);
 
-       if (image->assembly->ref_only) {
+       if (image->assembly && image->assembly->ref_only) {
                /* We use the loaded corlib */
                if (!strcmp (aname.name, "mscorlib"))
                        reference = mono_assembly_load_full (&aname, image->assembly->basedir, &status, FALSE);
@@ -873,7 +877,7 @@ mono_assembly_load_reference (MonoImage *image, int index)
                if (!reference)
                        reference = REFERENCE_MISSING;
        } else
-               reference = mono_assembly_load (&aname, image->assembly->basedir, &status);
+               reference = mono_assembly_load (&aname, image->assembly? image->assembly->basedir: NULL, &status);
 
        if (reference == NULL){
                char *extra_msg = g_strdup ("");
@@ -894,7 +898,7 @@ mono_assembly_load_reference (MonoImage *image, int index)
                                   "     Public Key: %s\n%s",
                                   image->name, aname.name, index,
                                   aname.major, aname.minor, aname.build, aname.revision,
-                                  strlen(aname.public_key_token) == 0 ? "(none)" : (char*)aname.public_key_token, extra_msg);
+                                  strlen ((char*)aname.public_key_token) == 0 ? "(none)" : (char*)aname.public_key_token, extra_msg);
                g_free (extra_msg);
        }
 
@@ -907,10 +911,12 @@ mono_assembly_load_reference (MonoImage *image, int index)
        if (!image->references [index]) {
                if (reference != REFERENCE_MISSING){
                        mono_assembly_addref (reference);
-                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Ref addref %s %p -> %s %p: %d\n",
+                       if (image->assembly)
+                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Ref addref %s %p -> %s %p: %d\n",
                                    image->assembly->aname.name, image->assembly, reference->aname.name, reference, reference->ref_count);
                } else {
-                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Failed to load assembly %s %p\n",
+                       if (image->assembly)
+                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Failed to load assembly %s %p\n",
                                    image->assembly->aname.name, image->assembly);
                }
                
@@ -928,21 +934,12 @@ void
 mono_assembly_load_references (MonoImage *image, MonoImageOpenStatus *status)
 {
        MonoTableInfo *t;
-       int i;
 
        *status = MONO_IMAGE_OK;
 
        t = &image->tables [MONO_TABLE_ASSEMBLYREF];
        
        image->references = g_new0 (MonoAssembly *, t->rows + 1);
-
-       /* resolve assembly references for modules */
-       for (i = 0; i < image->module_count; i++){
-               if (image->modules [i]) {
-                       image->modules [i]->assembly = image->assembly;
-                       mono_assembly_load_references (image->modules [i], status);
-               }
-       }
 }
 
 typedef struct AssemblyLoadHook AssemblyLoadHook;
@@ -1222,17 +1219,23 @@ absolute_dir (const gchar *filename)
  * defined bundles, if found, returns the MonoImage for it, if not found
  * returns NULL
  */
-static MonoImage *
+MonoImage *
 mono_assembly_open_from_bundle (const char *filename, MonoImageOpenStatus *status, gboolean refonly)
 {
        int i;
-       char *name = g_path_get_basename (filename);
+       char *name;
        MonoImage *image = NULL;
 
        /*
         * we do a very simple search for bundled assemblies: it's not a general 
         * purpose assembly loading mechanism.
         */
+
+       if (!bundles)
+               return NULL;
+
+       name = g_path_get_basename (filename);
+
        mono_assemblies_lock ();
        for (i = 0; !image && bundles [i]; ++i) {
                if (strcmp (bundles [i]->name, name) == 0) {
@@ -1338,15 +1341,19 @@ mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboo
 }
 
 /*
- * load_friend_assemblies:
+ * mono_load_friend_assemblies:
  * @ass: an assembly
  *
  * Load the list of friend assemblies that are allowed to access
  * the assembly's internal types and members. They are stored as assembly
  * names in custom attributes.
+ *
+ * This is an internal method, we need this because when we load mscorlib
+ * we do not have the mono_defaults.internals_visible_class loaded yet,
+ * so we need to load these after we initialize the runtime. 
  */
-static void
-load_friend_assemblies (MonoAssembly* ass)
+void
+mono_assembly_load_friends (MonoAssembly* ass)
 {
        int i;
        MonoCustomAttrInfo* attrs = mono_custom_attrs_from_assembly (ass);
@@ -1355,16 +1362,16 @@ load_friend_assemblies (MonoAssembly* ass)
        for (i = 0; i < attrs->num_attrs; ++i) {
                MonoCustomAttrEntry *attr = &attrs->attrs [i];
                MonoAssemblyName *aname;
-               const guchar *data;
+               const gchar *data;
                guint slen;
                /* Do some sanity checking */
                if (!attr->ctor || attr->ctor->klass != mono_defaults.internals_visible_class)
                        continue;
                if (attr->data_size < 4)
                        continue;
-               data = attr->data;
+               data = (const char*)attr->data;
                /* 0xFF means null string, see custom attr format */
-               if (data [0] != 1 || data [1] != 0 || data [2] == 0xFF)
+               if (data [0] != 1 || data [1] != 0 || (data [2] & 0xFF) == 0xFF)
                        continue;
                slen = mono_metadata_decode_value (data + 2, &data);
                aname = g_new0 (MonoAssemblyName, 1);
@@ -1461,11 +1468,11 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
                /* avoid loading the same assembly twice for now... */
                ass2 = search_loaded (&ass->aname, refonly);
                if (ass2) {
+                       mono_assemblies_unlock ();
                        g_free (ass);
                        g_free (base_dir);
                        mono_image_close (image);
                        *status = MONO_IMAGE_OK;
-                       mono_assemblies_unlock ();
                        return ass2;
                }
        }
@@ -1507,7 +1514,7 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
 
        loaded_assemblies = g_list_prepend (loaded_assemblies, ass);
        if (mono_defaults.internals_visible_class)
-               load_friend_assemblies (ass);
+               mono_assembly_load_friends (ass);
        mono_assemblies_unlock ();
 
        mono_assembly_invoke_load_hook (ass);
@@ -1752,7 +1759,13 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole
                        tmp++;
                        continue;
                }
-               
+
+               if (!g_ascii_strncasecmp (value, "ProcessorArchitecture=", 22)) {
+                       /* this is ignored for now, until we can change MonoAssemblyName */
+                       tmp++;
+                       continue;
+               }
+
                g_strfreev (parts);
                return FALSE;
        }
@@ -1797,7 +1810,8 @@ probe_for_partial_name (const char *basepath, const char *fullname, MonoAssembly
        while ((direntry = g_dir_read_name (dirhandle))) {
                gboolean match = TRUE;
                
-               parse_assembly_directory_name (aname->name, direntry, &gac_aname);
+               if(!parse_assembly_directory_name (aname->name, direntry, &gac_aname))
+                       continue;
                
                if (aname->culture != NULL && strcmp (aname->culture, gac_aname.culture) != 0)
                        match = FALSE;
@@ -2319,22 +2333,12 @@ mono_assembly_close (MonoAssembly *assembly)
 
        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Unloading assembly %s [%p].", assembly->aname.name, assembly);
 
+       mono_debug_close_image (assembly->image);
+
        mono_assemblies_lock ();
        loaded_assemblies = g_list_remove (loaded_assemblies, assembly);
        mono_assemblies_unlock ();
 
-       if (assembly->image->references) {
-               int i;
-
-               for (i = 0; assembly->image->references [i]; i++) {
-                       if (assembly->image->references [i])
-                               mono_assembly_close (assembly->image->references [i]);
-               }
-
-               g_free (assembly->image->references);
-               assembly->image->references = NULL;
-       }
-
        assembly->image->assembly = NULL;
 
        mono_image_close (assembly->image);