static char **extra_gac_paths = NULL;
#ifndef DISABLE_ASSEMBLY_REMAPPING
+
+static GHashTable* assembly_remapping_table;
/* The list of system assemblies what will be remapped to the running
- * runtime version. WARNING: this list must be sorted.
+ * runtime version.
+ * This list is stored in @assembly_remapping_table during initialization.
+ * Keep it sorted just to make maintenance easier.
+ *
* The integer number is an index in the MonoRuntimeInfo structure, whose
* values can be found in domain.c - supported_runtimes. Look there
* to understand what remapping will be made.
{"System.Drawing", 0},
{"System.Drawing.Design", 0},
{"System.EnterpriseServices", 0},
+ {"System.IO.Compression", 2},
{"System.IdentityModel", 3},
{"System.IdentityModel.Selectors", 3},
- {"System.IO.Compression", 2},
{"System.Management", 0},
{"System.Messaging", 0},
{"System.Net", 2},
- {"System.Net.Http", 3},
+ {"System.Net.Http", 4},
{"System.Numerics.Vectors", 3},
{"System.Runtime.InteropServices.RuntimeInformation", 2},
{"System.Runtime.Remoting", 0},
}
*dest = *splitted;
- if (g_getenv ("MONO_DEBUG") == NULL)
+ if (g_hasenv ("MONO_DEBUG"))
return;
splitted = assemblies_path;
static void
check_path_env (void)
{
- const char* path;
- path = g_getenv ("MONO_PATH");
+ if (assemblies_path != NULL)
+ return;
+
+ char* path = g_getenv ("MONO_PATH");
#ifdef __native_client__
if (!path)
- path = nacl_mono_path;
+ path = strdup (nacl_mono_path);
#endif
- if (!path || assemblies_path != NULL)
+ if (!path)
return;
mono_set_assemblies_path(path);
+ g_free (path);
}
static void
-check_extra_gac_path_env (void) {
- const char *path;
+check_extra_gac_path_env (void)
+{
+ char *path;
char **splitted, **dest;
path = g_getenv ("MONO_GAC_PREFIX");
return;
splitted = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 1000);
+ g_free (path);
+
if (extra_gac_paths)
g_strfreev (extra_gac_paths);
extra_gac_paths = dest = splitted;
}
*dest = *splitted;
- if (g_getenv ("MONO_DEBUG") == NULL)
+ if (!g_hasenv ("MONO_DEBUG"))
return;
while (*splitted) {
mono_os_mutex_init_recursive (&assemblies_mutex);
mono_os_mutex_init (&assembly_binding_mutex);
+
+#ifndef DISABLE_ASSEMBLY_REMAPPING
+ assembly_remapping_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ int i;
+ for (i = 0; i < G_N_ELEMENTS (framework_assemblies) - 1; ++i)
+ g_hash_table_insert (assembly_remapping_table, (void*)framework_assemblies [i].assembly_name, (void*)&framework_assemblies [i]);
+
+#endif
}
static void
mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_aname)
{
const MonoRuntimeInfo *current_runtime;
- int pos, first, last;
if (aname->name == NULL) return aname;
}
#ifndef DISABLE_ASSEMBLY_REMAPPING
- first = 0;
- last = G_N_ELEMENTS (framework_assemblies) - 1;
-
- while (first <= last) {
- int res;
- pos = first + (last - first) / 2;
- res = strcmp (aname->name, framework_assemblies[pos].assembly_name);
- if (res == 0) {
- const AssemblyVersionSet* vset;
- int index = framework_assemblies[pos].version_set_index;
- g_assert (index < G_N_ELEMENTS (current_runtime->version_sets));
- vset = ¤t_runtime->version_sets [index];
-
- if (aname->major == vset->major && aname->minor == vset->minor &&
- aname->build == vset->build && aname->revision == vset->revision)
- return aname;
-
- if (framework_assemblies[pos].only_lower_versions && compare_versions ((AssemblyVersionSet*)vset, aname) < 0)
- return aname;
-
- if ((aname->major | aname->minor | aname->build | aname->revision) != 0)
- mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
- "The request to load the assembly %s v%d.%d.%d.%d was remapped to v%d.%d.%d.%d",
- aname->name,
- aname->major, aname->minor, aname->build, aname->revision,
- vset->major, vset->minor, vset->build, vset->revision
- );
-
- memcpy (dest_aname, aname, sizeof(MonoAssemblyName));
- dest_aname->major = vset->major;
- dest_aname->minor = vset->minor;
- dest_aname->build = vset->build;
- dest_aname->revision = vset->revision;
- if (framework_assemblies[pos].new_assembly_name != NULL) {
- dest_aname->name = framework_assemblies[pos].new_assembly_name;
- mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
- "The assembly name %s was remapped to %s",
- aname->name,
- dest_aname->name);
- }
- return dest_aname;
- } else if (res < 0) {
- last = pos - 1;
- } else {
- first = pos + 1;
+ const AssemblyVersionMap *vmap = (AssemblyVersionMap *)g_hash_table_lookup (assembly_remapping_table, aname->name);
+ if (vmap) {
+ const AssemblyVersionSet* vset;
+ int index = vmap->version_set_index;
+ g_assert (index < G_N_ELEMENTS (current_runtime->version_sets));
+ vset = ¤t_runtime->version_sets [index];
+
+ if (aname->major == vset->major && aname->minor == vset->minor &&
+ aname->build == vset->build && aname->revision == vset->revision) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Found assembly remapping for %s and was for the same version %d.%d.%d.%d",
+ aname->name,
+ aname->major, aname->minor, aname->build, aname->revision);
+ return aname;
+ }
+
+ if (vmap->only_lower_versions && compare_versions ((AssemblyVersionSet*)vset, aname) < 0) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY,
+ "Found lower-versions-only assembly remaping to load %s %d.%d.%d.%d but mapping has %d.%d.%d.%d",
+ aname->name,
+ aname->major, aname->minor, aname->build, aname->revision,
+ vset->major, vset->minor, vset->build, vset->revision
+ );
+ return aname;
}
+
+ if ((aname->major | aname->minor | aname->build | aname->revision) != 0)
+ mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+ "The request to load the assembly %s v%d.%d.%d.%d was remapped to v%d.%d.%d.%d",
+ aname->name,
+ aname->major, aname->minor, aname->build, aname->revision,
+ vset->major, vset->minor, vset->build, vset->revision
+ );
+
+ memcpy (dest_aname, aname, sizeof(MonoAssemblyName));
+ dest_aname->major = vset->major;
+ dest_aname->minor = vset->minor;
+ dest_aname->build = vset->build;
+ dest_aname->revision = vset->revision;
+ if (vmap->new_assembly_name != NULL) {
+ dest_aname->name = vmap->new_assembly_name;
+ mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+ "The assembly name %s was remapped to %s",
+ aname->name,
+ dest_aname->name);
+ }
+ return dest_aname;
}
#endif
MonoAssembly *
mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboolean refonly)
{
+ return mono_assembly_open_a_lot (filename, status, refonly, FALSE);
+}
+
+MonoAssembly *
+mono_assembly_open_a_lot (const char *filename, MonoImageOpenStatus *status, gboolean refonly, gboolean load_from_context)
+{
+
MonoImage *image;
MonoAssembly *ass;
MonoImageOpenStatus def_status;
}
if (!image)
- image = mono_image_open_full (fname, status, refonly);
+ image = mono_image_open_a_lot (fname, status, refonly, load_from_context);
if (!image){
if (*status == MONO_IMAGE_OK)
gboolean
mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
/*
* This might be called during assembly loading, so do everything using the low-level
prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refonly)
{
MonoError refasm_error;
- mono_error_init (&refasm_error);
+ error_init (&refasm_error);
if (candidate && !refonly && mono_assembly_has_reference_assembly_attribute (candidate, &refasm_error)) {
candidate = NULL;
}