#include "loader.h"
#include <mono/io-layer/io-layer.h>
#include <mono/utils/mono-logger.h>
+#include <mono/utils/mono-path.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
return NULL;
}
-static gchar *
-canonicalize_path (const char *path)
-{
- gchar *abspath, *pos, *lastpos, *dest;
- int backc;
-
- if (g_path_is_absolute (path)) {
- abspath = g_strdup (path);
- } else {
- gchar *tmpdir = g_get_current_dir ();
- abspath = g_build_filename (tmpdir, path, NULL);
- g_free (tmpdir);
- }
-
- abspath = g_strreverse (abspath);
-
- backc = 0;
- dest = lastpos = abspath;
- pos = strchr (lastpos, G_DIR_SEPARATOR);
-
- while (pos != NULL) {
- int len = pos - lastpos;
- if (len == 1 && lastpos [0] == '.') {
- // nop
- } else if (len == 2 && lastpos [0] == '.' && lastpos [1] == '.') {
- backc++;
- } else if (len > 0) {
- if (backc > 0) {
- backc--;
- } else {
- if (dest != lastpos)
- /* The two strings can overlap */
- memmove (dest, lastpos, len + 1);
- dest += len + 1;
- }
- }
- lastpos = pos + 1;
- pos = strchr (lastpos, G_DIR_SEPARATOR);
- }
-
- if (dest != lastpos) strcpy (dest, lastpos);
- return g_strreverse (abspath);
-}
-
/**
* mono_images_init:
*
return load_tables (image);
}
-void
-mono_image_add_to_name_cache (MonoImage *image, const char *nspace,
- const char *name, guint32 index)
-{
- GHashTable *nspace_table;
- GHashTable *name_cache = image->name_cache;
-
- if (!(nspace_table = g_hash_table_lookup (name_cache, nspace))) {
- nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (name_cache, (char *)nspace, (char *)nspace_table);
- }
- g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (index));
-}
-
static void
load_modules (MonoImage *image, MonoImageOpenStatus *status)
{
MonoTableInfo *t;
+ MonoTableInfo *file_table;
int i;
char *base_dir;
gboolean refonly = image->ref_only;
+ GList *list_iter, *valid_modules = NULL;
if (image->modules)
return;
+ file_table = &image->tables [MONO_TABLE_FILE];
+ for (i = 0; i < file_table->rows; i++) {
+ guint32 cols [MONO_FILE_SIZE];
+ mono_metadata_decode_row (file_table, i, cols, MONO_FILE_SIZE);
+ if (cols [MONO_FILE_FLAGS] == FILE_CONTAINS_NO_METADATA)
+ continue;
+ valid_modules = g_list_prepend (valid_modules, (char*)mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
+ }
+
t = &image->tables [MONO_TABLE_MODULEREF];
image->modules = g_new0 (MonoImage *, t->rows);
image->module_count = t->rows;
char *module_ref;
const char *name;
guint32 cols [MONO_MODULEREF_SIZE];
+ int valid = 0;
mono_metadata_decode_row (t, i, cols, MONO_MODULEREF_SIZE);
name = mono_metadata_string_heap (image, cols [MONO_MODULEREF_NAME]);
+ for (list_iter = valid_modules; list_iter; list_iter = list_iter->next) {
+ /* be safe with string dups, but we could just compare string indexes */
+ if (strcmp (list_iter->data, name) == 0) {
+ valid = TRUE;
+ break;
+ }
+ }
+ if (!valid)
+ continue;
module_ref = g_build_filename (base_dir, name, NULL);
image->modules [i] = mono_image_open_full (module_ref, status, refonly);
if (image->modules [i]) {
/* g_print ("loaded module %s from %s (%p)\n", module_ref, image->name, image->assembly); */
}
/*
- * FIXME: what do we do here? it could be a native dll...
- * We should probably do lazy-loading of modules.
+ * FIXME: We should probably do lazy-loading of modules.
*/
if (status)
*status = MONO_IMAGE_OK;
}
g_free (base_dir);
-}
-
-static void
-load_class_names (MonoImage *image)
-{
- MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEDEF];
- guint32 cols [MONO_TYPEDEF_SIZE];
- const char *name;
- const char *nspace;
- guint32 i, visib, nspace_index;
- GHashTable *name_cache2, *nspace_table;
-
- /* Temporary hash table to avoid lookups in the nspace_table */
- name_cache2 = g_hash_table_new (NULL, NULL);
-
- for (i = 1; i <= t->rows; ++i) {
- mono_metadata_decode_row (t, i - 1, cols, MONO_TYPEDEF_SIZE);
- /* nested types are accessed from the nesting name */
- visib = cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK;
- if (visib > TYPE_ATTRIBUTE_PUBLIC && visib <= TYPE_ATTRIBUTE_NESTED_ASSEMBLY)
- continue;
- name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
- nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
-
- nspace_index = cols [MONO_TYPEDEF_NAMESPACE];
- nspace_table = g_hash_table_lookup (name_cache2, GUINT_TO_POINTER (nspace_index));
- if (!nspace_table) {
- nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (image->name_cache, (char*)nspace, nspace_table);
- g_hash_table_insert (name_cache2, GUINT_TO_POINTER (nspace_index),
- nspace_table);
- }
- g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (i));
- }
-
- /* Load type names from EXPORTEDTYPES table */
- {
- MonoTableInfo *t = &image->tables [MONO_TABLE_EXPORTEDTYPE];
- guint32 cols [MONO_EXP_TYPE_SIZE];
- int i;
-
- for (i = 0; i < t->rows; ++i) {
- mono_metadata_decode_row (t, i, cols, MONO_EXP_TYPE_SIZE);
- name = mono_metadata_string_heap (image, cols [MONO_EXP_TYPE_NAME]);
- nspace = mono_metadata_string_heap (image, cols [MONO_EXP_TYPE_NAMESPACE]);
-
- nspace_index = cols [MONO_EXP_TYPE_NAMESPACE];
- nspace_table = g_hash_table_lookup (name_cache2, GUINT_TO_POINTER (nspace_index));
- if (!nspace_table) {
- nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (image->name_cache, (char*)nspace, nspace_table);
- g_hash_table_insert (name_cache2, GUINT_TO_POINTER (nspace_index),
- nspace_table);
- }
- g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (mono_metadata_make_token (MONO_TABLE_EXPORTEDTYPE, i + 1)));
- }
- }
-
- g_hash_table_destroy (name_cache2);
+ g_list_free (valid_modules);
}
static void
image->method_cache = g_hash_table_new (NULL, NULL);
image->class_cache = g_hash_table_new (NULL, NULL);
image->field_cache = g_hash_table_new (NULL, NULL);
- image->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
image->delegate_begin_invoke_cache =
g_hash_table_new ((GHashFunc)mono_signature_hash,
image->managed_wrapper_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
image->native_wrapper_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
image->remoting_invoke_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
+ image->cominterop_invoke_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
+ image->cominterop_wrapper_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
image->synchronized_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
image->unbox_wrapper_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
if (!load_metadata (image, iinfo))
goto invalid_image;
- load_class_names (image);
-
/* modules don't have an assembly table row */
if (image->tables [MONO_TABLE_ASSEMBLY].rows)
image->assembly_name = mono_metadata_string_heap (image,
image->raw_data = mono_raw_buffer_load (fileno (filed), FALSE, 0, stat_buf.st_size);
iinfo = g_new0 (MonoCLIImageInfo, 1);
image->image_info = iinfo;
- image->name = canonicalize_path (fname);
+ image->name = mono_path_resolve_symlinks (fname);
image->ref_only = refonly;
image->ref_count = 1;
g_return_val_if_fail (fname != NULL, NULL);
- absfname = canonicalize_path (fname);
+ absfname = mono_path_canonicalize (fname);
/*
* The easiest solution would be to do all the loading inside the mutex,
}
if (image->ptr_cache)
g_hash_table_destroy (image->ptr_cache);
- g_hash_table_foreach (image->name_cache, free_hash_table, NULL);
- g_hash_table_destroy (image->name_cache);
+ if (image->name_cache) {
+ g_hash_table_foreach (image->name_cache, free_hash_table, NULL);
+ g_hash_table_destroy (image->name_cache);
+ }
g_hash_table_destroy (image->native_wrapper_cache);
g_hash_table_destroy (image->managed_wrapper_cache);
g_hash_table_destroy (image->delegate_begin_invoke_cache);
g_hash_table_destroy (image->runtime_invoke_cache);
g_hash_table_destroy (image->synchronized_cache);
g_hash_table_destroy (image->unbox_wrapper_cache);
+ g_hash_table_destroy (image->cominterop_invoke_cache);
+ g_hash_table_destroy (image->cominterop_wrapper_cache);
g_hash_table_destroy (image->typespec_cache);
g_hash_table_destroy (image->ldfld_wrapper_cache);
g_hash_table_destroy (image->ldflda_wrapper_cache);