}
char *
-mono_cli_rva_map (MonoCLIImageInfo *iinfo, guint32 addr)
+mono_image_rva_map (MonoImage *image, guint32 addr)
{
+ MonoCLIImageInfo *iinfo = image->image_info;
const int top = iinfo->cli_section_count;
MonoSectionTable *tables = iinfo->cli_section_tables;
int i;
for (i = 0; i < top; i++){
if ((addr >= tables->st_virtual_address) &&
(addr < tables->st_virtual_address + tables->st_raw_data_size)){
+ if (!iinfo->cli_sections [i]) {
+ if (!mono_image_ensure_section_idx (image, i))
+ return NULL;
+ }
return (char*)iinfo->cli_sections [i] +
(addr - tables->st_virtual_address);
}
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) strncpy (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:
*
/* consistency checks here */
}
- for (i = 0; i < top; i++)
- if (!mono_image_ensure_section_idx (image, i))
- return FALSE;
-
return TRUE;
}
t = &image->tables [MONO_TABLE_MODULEREF];
image->modules = g_new0 (MonoImage *, t->rows);
+ image->module_count = t->rows;
base_dir = g_path_get_dirname (image->name);
for (i = 0; i < t->rows; i++){
char *module_ref;
image->native_wrapper_cache = g_hash_table_new (NULL, NULL);
image->remoting_invoke_cache = g_hash_table_new (NULL, NULL);
image->synchronized_cache = g_hash_table_new (NULL, NULL);
+ image->unbox_wrapper_cache = g_hash_table_new (NULL, NULL);
image->typespec_cache = g_hash_table_new (NULL, NULL);
image->memberref_signatures = g_hash_table_new (NULL, NULL);
-
- image->generic_inst_cache =
- g_hash_table_new ((GHashFunc)mono_metadata_generic_inst_hash,
- (GCompareFunc)mono_metadata_generic_inst_equal);
+ image->helper_signatures = g_hash_table_new (g_str_hash, g_str_equal);
}
static MonoImage *
image->f = filed;
iinfo = g_new0 (MonoCLIImageInfo, 1);
image->image_info = iinfo;
-
- if (g_path_is_absolute (fname))
- image->name = g_strdup (fname);
- else {
- gchar *path = g_get_current_dir ();
- image->name = g_build_filename (path, fname, NULL);
- g_free (path);
- }
+ image->name = canonicalize_path (fname);
return do_mono_image_load (image, status);
}
mono_image_open (const char *fname, MonoImageOpenStatus *status)
{
MonoImage *image, *image2;
- const char *absfname;
+ char *absfname;
g_return_val_if_fail (fname != NULL, NULL);
- if (g_path_is_absolute (fname))
- absfname = fname;
- else {
- gchar *path = g_get_current_dir ();
- absfname = g_build_filename (path, fname, NULL);
- g_free (path);
- }
+ absfname = canonicalize_path (fname);
/*
* The easiest solution would be to do all the loading inside the mutex,
*/
EnterCriticalSection (&images_mutex);
image = g_hash_table_lookup (loaded_images_hash, absfname);
-
- if (absfname != fname)
- g_free (absfname);
+ g_free (absfname);
if (image){
image->ref_count++;
return NULL;
EnterCriticalSection (&images_mutex);
- image2 = g_hash_table_lookup (loaded_images_hash, fname);
+ image2 = g_hash_table_lookup (loaded_images_hash, image->name);
+
if (image2) {
/* Somebody else beat us to it */
image2->ref_count ++;
LeaveCriticalSection (&images_mutex);
mono_image_close (image);
-
return image2;
}
g_hash_table_insert (loaded_images_hash, image->name, image);
- if (image->assembly_name)
+ if (image->assembly_name && (g_hash_table_lookup (loaded_images_hash, image->assembly_name) == NULL))
g_hash_table_insert (loaded_images_hash, (char *) image->assembly_name, image);
g_hash_table_insert (loaded_images_guid_hash, image->guid, image);
LeaveCriticalSection (&images_mutex);
mono_metadata_free_method_signature ((MonoMethodSignature*)val);
}
+static void
+free_remoting_wrappers (gpointer key, gpointer val, gpointer user_data)
+{
+ g_free (val);
+}
+
/**
- * mono_image_close:
+ * mono_image_addref:
* @image: The image file we wish to add a reference to
*
* Increases the reference count of an image.
if (image == image2) {
/* This is not true if we are called from mono_image_open () */
g_hash_table_remove (loaded_images_hash, image->name);
- if (image->assembly_name)
- g_hash_table_remove (loaded_images_hash, (char *) image->assembly_name);
g_hash_table_remove (loaded_images_guid_hash, image->guid);
/* Multiple images might have the same guid */
build_guid_table ();
- }
+ }
+ if (image->assembly_name && (g_hash_table_lookup (loaded_images_hash, image->assembly_name) == image))
+ g_hash_table_remove (loaded_images_hash, (char *) image->assembly_name);
LeaveCriticalSection (&images_mutex);
if (image->f)
fclose (image->f);
- if (image->raw_data_allocated)
- g_free (image->raw_data);
+ if (image->raw_data_allocated) {
+ /* image->raw_metadata and cli_sections might lie inside image->raw_data */
+ MonoCLIImageInfo *ii = image->image_info;
+ int i;
+
+ if ((image->raw_metadata > image->raw_data) &&
+ (image->raw_metadata <= (image->raw_data + image->raw_data_len)))
+ image->raw_metadata = NULL;
+ for (i = 0; i < ii->cli_section_count; i++)
+ if (((char*)(ii->cli_sections [i]) > image->raw_data) &&
+ ((char*)(ii->cli_sections [i]) <= ((char*)image->raw_data + image->raw_data_len)))
+ ii->cli_sections [i] = NULL;
+
+ g_free (image->raw_data);
+ }
g_free (image->name);
+ g_free (image->guid);
g_free (image->files);
g_hash_table_destroy (image->method_cache);
g_hash_table_destroy (image->delegate_begin_invoke_cache);
g_hash_table_destroy (image->delegate_end_invoke_cache);
g_hash_table_destroy (image->delegate_invoke_cache);
+ g_hash_table_foreach (image->remoting_invoke_cache, free_remoting_wrappers, NULL);
g_hash_table_destroy (image->remoting_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->typespec_cache);
- g_hash_table_destroy (image->generic_inst_cache);
g_hash_table_foreach (image->memberref_signatures, free_mr_signatures, NULL);
g_hash_table_destroy (image->memberref_signatures);
+ g_hash_table_foreach (image->helper_signatures, free_mr_signatures, NULL);
+ g_hash_table_destroy (image->helper_signatures);
if (image->raw_metadata != NULL)
mono_raw_buffer_free (image->raw_metadata);
g_free (image->image_info);
}
- g_free (image);
+ if (!image->dynamic)
+ /* Dynamic images are GC_MALLOCed */
+ g_free (image);
}
/**
return(NULL);
}
- resource_dir=(MonoPEResourceDir *)mono_cli_rva_map (info, rsrc->rva);
+ resource_dir=(MonoPEResourceDir *)mono_image_rva_map (image, rsrc->rva);
if(resource_dir==NULL) {
return(NULL);
}
if (!ch->ch_resources.rva || offset + 4 > ch->ch_resources.size)
return NULL;
- data = mono_cli_rva_map (iinfo, ch->ch_resources.rva);
+ data = mono_image_rva_map (image, ch->ch_resources.rva);
if (!data)
return NULL;
data += offset;
res = mono_image_open (name, NULL);
if (res) {
int i;
- t = &res->tables [MONO_TABLE_MODULEREF];
/* g_print ("loaded file %s from %s (%p)\n", name, image->name, image->assembly); */
res->assembly = image->assembly;
- for (i = 0; i < t->rows; ++i) {
+ for (i = 0; i < res->module_count; ++i) {
if (res->modules [i] && !res->modules [i]->assembly)
res->modules [i]->assembly = image->assembly;
}
if (!de->size || !de->rva)
return NULL;
- data = mono_cli_rva_map (iinfo, de->rva);
+ data = mono_image_rva_map (image, de->rva);
if (!data)
return NULL;
if (size)
}
int
-mono_table_info_get_rows (MonoTableInfo *table)
+mono_table_info_get_rows (const MonoTableInfo *table)
{
return table->rows;
}
return image->dynamic;
}
-char*
-mono_image_rva_map (MonoImage *image, guint32 rva)
+gboolean
+mono_image_has_authenticode_entry (MonoImage *image)
{
- return mono_cli_rva_map (image->image_info, rva);
+ MonoCLIImageInfo *iinfo = image->image_info;
+ MonoDotNetHeader *header = &iinfo->cli_header;
+ MonoPEDirEntry *de = &header->datadir.pe_certificate_table;
+ // the Authenticode "pre" (non ASN.1) header is 8 bytes long
+ return ((de->rva != 0) && (de->size > 8));
}
-