2 * assembly.c: Routines for loading assemblies.
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc. http://www.ximian.com
10 * Implement big-endian versions of the reading routines.
20 #include "rawbuffer.h"
22 #define CSIZE(x) (sizeof (x) / 4)
25 * g_concat_dir_and_file:
26 * @dir: directory name
29 * returns a new allocated string that is the concatenation of dir and file,
30 * takes care of the exact details for concatenating them.
33 g_concat_dir_and_file (const char *dir, const char *file)
35 g_return_val_if_fail (dir != NULL, NULL);
36 g_return_val_if_fail (file != NULL, NULL);
39 * If the directory name doesn't have a / on the end, we need
40 * to add one so we get a proper path to the file
42 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
43 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
45 return g_strconcat (dir, file, NULL);
49 default_assembly_name_resolver (const char *name)
53 if (strcmp (name, "mscorlib") == 0)
54 return g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
56 file = g_strconcat (name, ".dll", NULL);
57 path = g_concat_dir_and_file (MONO_ASSEMBLIES, file);
65 * @filename: Opens the assembly pointed out by this name
66 * @resolver: A user provided function to resolve assembly references
67 * @status: where a status code can be returned
69 * mono_assembly_open opens the PE-image pointed by @filename, and
70 * loads any external assemblies referenced by it.
72 * NOTE: we could do lazy loading of the assemblies. Or maybe not worth
76 mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
77 enum MonoImageOpenStatus *status)
83 const char *basename = strrchr (filename, '/');
84 static MonoAssembly *corlib;
86 g_return_val_if_fail (filename != NULL, NULL);
95 * Temporary hack until we have a complete corlib.dll
97 if (strcmp (basename, CORLIB_NAME) == 0) {
102 fullname = g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
103 image = mono_image_open (fullname, status);
106 image = mono_image_open (filename, status);
110 *status = MONO_IMAGE_ERROR_ERRNO;
114 if (resolver == NULL)
115 resolver = default_assembly_name_resolver;
117 t = &image->tables [MONO_TABLE_ASSEMBLYREF];
119 image->references = g_new0 (MonoAssembly *, t->rows + 1);
121 ass = g_new (MonoAssembly, 1);
125 * Load any assemblies this image references
127 for (i = 0; i < t->rows; i++){
130 guint32 cols [MONO_ASSEMBLYREF_SIZE];
132 mono_metadata_decode_row (t, i, cols, CSIZE (cols));
133 name = mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME]);
136 * Special case until we have a passable corlib:
138 * ie, references to mscorlib from corlib.dll are ignored
139 * and we do not load corlib twice.
141 if (strcmp (basename, CORLIB_NAME) == 0){
145 if (strcmp (name, "mscorlib") == 0)
149 assembly_ref = (*resolver) (name);
151 image->references [i] = mono_assembly_open (assembly_ref, resolver, status);
153 if (image->references [i] == NULL){
156 for (j = 0; j < i; j++)
157 mono_assembly_close (image->references [j]);
158 g_free (image->references);
159 mono_image_close (image);
161 g_warning ("Could not find assembly %s %s", name, assembly_ref);
162 g_free (assembly_ref);
164 *status = MONO_IMAGE_MISSING_ASSEMBLYREF;
168 g_free (assembly_ref);
170 image->references [i] = NULL;
176 mono_assembly_close (MonoAssembly *assembly)
181 g_return_if_fail (assembly != NULL);
183 image = assembly->image;
184 for (i = 0; image->references [i] != NULL; i++)
185 mono_image_close (image->references [i]->image);
186 g_free (image->references);
188 mono_image_close (assembly->image);