#include <config.h>
#include <glib.h>
#include <string.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <mono/os/gc_wrapper.h>
-
+#include <mono/metadata/gc-internal.h>
#include <mono/metadata/object.h>
#include <mono/metadata/domain-internals.h>
#include "mono/metadata/metadata-internals.h"
#include <mono/utils/mono-logger.h>
#include <mono/utils/mono-path.h>
#include <mono/utils/mono-stdlib.h>
+#include <mono/utils/mono-io-portability.h>
#ifdef PLATFORM_WIN32
#include <direct.h>
#endif
-#define MONO_CORLIB_VERSION 56
+/*
+ * This is the version number of the corlib-runtime interface. When
+ * making changes to this interface (by changing the layout
+ * of classes the runtime knows about, changing icall signature or
+ * semantics etc), increment this variable. Also increment the
+ * pair of this variable in mscorlib in:
+ * mcs/class/mscorlib/System/Environment.cs
+ *
+ * Changes which are already detected at runtime, like the addition
+ * of icalls, do not require an increment.
+ */
+#define MONO_CORLIB_VERSION 65
+
+typedef struct
+{
+ int runtime_count;
+ int assemblybinding_count;
+ MonoDomain *domain;
+} RuntimeConfig;
CRITICAL_SECTION mono_delegate_section;
MonoAppDomain *ad;
MonoClass *class;
MonoString *arg;
+
+ mono_portability_helpers_init ();
- MONO_GC_PRE_INIT ();
+ mono_gc_base_init ();
mono_monitor_init ();
mono_thread_pool_init ();
mono_marshal_init ();
/* mscorlib is loaded before we install the load hook */
mono_domain_fire_assembly_load (mono_defaults.corlib->assembly, NULL);
-
+
return;
}
mono_type_initialization_cleanup ();
mono_monitor_cleanup ();
+
+#ifndef PLATFORM_WIN32
+ _wapi_cleanup ();
+#endif
}
static MonoDomainFunc quit_function = NULL;
return root->domain;
}
+static char*
+get_attribute_value (const gchar **attribute_names,
+ const gchar **attribute_values,
+ const char *att_name)
+{
+ int n;
+ for (n = 0; attribute_names [n] != NULL; n++) {
+ if (strcmp (attribute_names [n], att_name) == 0)
+ return g_strdup (attribute_values [n]);
+ }
+ return NULL;
+}
+
+static void
+start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ RuntimeConfig *runtime_config = user_data;
+
+ if (strcmp (element_name, "runtime") == 0) {
+ runtime_config->runtime_count++;
+ return;
+ }
+
+ if (strcmp (element_name, "assemblyBinding") == 0) {
+ runtime_config->assemblybinding_count++;
+ return;
+ }
+
+ if (runtime_config->runtime_count != 1 || runtime_config->assemblybinding_count != 1)
+ return;
+
+ if (strcmp (element_name, "probing") != 0)
+ return;
+
+ g_free (runtime_config->domain->private_bin_path);
+ runtime_config->domain->private_bin_path = get_attribute_value (attribute_names, attribute_values, "privatePath");
+ if (runtime_config->domain->private_bin_path && !runtime_config->domain->private_bin_path [0]) {
+ g_free (runtime_config->domain->private_bin_path);
+ runtime_config->domain->private_bin_path = NULL;
+ return;
+ }
+}
+
+static void
+end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ RuntimeConfig *runtime_config = user_data;
+ if (strcmp (element_name, "runtime") == 0)
+ runtime_config->runtime_count--;
+ else if (strcmp (element_name, "assemblyBinding") == 0)
+ runtime_config->assemblybinding_count--;
+}
+
+static const GMarkupParser
+mono_parser = {
+ start_element,
+ end_element,
+ NULL,
+ NULL,
+ NULL
+};
+
+static void
+mono_set_private_bin_path_from_config (MonoDomain *domain)
+{
+ gchar *config_file, *text;
+ gsize len;
+ struct stat sbuf;
+ GMarkupParseContext *context;
+ RuntimeConfig runtime_config;
+
+ if (!domain || !domain->setup || !domain->setup->configuration_file)
+ return;
+
+ config_file = mono_string_to_utf8 (domain->setup->configuration_file);
+ if (stat (config_file, &sbuf) != 0) {
+ g_free (config_file);
+ return;
+ }
+
+ if (!g_file_get_contents (config_file, &text, &len, NULL)) {
+ g_free (config_file);
+ return;
+ }
+ g_free (config_file);
+
+ runtime_config.runtime_count = 0;
+ runtime_config.assemblybinding_count = 0;
+ runtime_config.domain = domain;
+
+ context = g_markup_parse_context_new (&mono_parser, 0, &runtime_config, NULL);
+ if (g_markup_parse_context_parse (context, text, len, NULL))
+ g_markup_parse_context_end_parse (context, NULL);
+ g_markup_parse_context_free (context);
+ g_free (text);
+}
+
MonoAppDomain *
ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
{
MONO_OBJECT_SETREF (setup, application_base, mono_string_new_utf16 (data, mono_string_chars (root->setup->application_base), mono_string_length (root->setup->application_base)));
}
+ mono_set_private_bin_path_from_config (data);
+
mono_context_init (data);
add_assemblies_to_domain (data, mono_defaults.corlib->assembly, NULL);
return res;
}
-static MonoReflectionAssembly *
-try_assembly_resolve (MonoDomain *domain, MonoString *fname, gboolean refonly)
+MonoReflectionAssembly *
+mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, gboolean refonly)
{
MonoClass *klass;
MonoMethod *method;
aname_str = mono_stringify_assembly_name (aname);
/* FIXME: We invoke managed code here, so there is a potential for deadlocks */
- assembly = try_assembly_resolve (domain, mono_string_new (domain, aname_str), refonly);
+ assembly = mono_try_assembly_resolve (domain, mono_string_new (domain, aname_str), refonly);
g_free (aname_str);
if (ass->image->references) {
for (i = 0; ass->image->references [i] != NULL; i++) {
- if (!g_hash_table_lookup (ht, ass->image->references [i])) {
- add_assemblies_to_domain (domain, ass->image->references [i], ht);
- }
+ if (ass->image->references [i] != REFERENCE_MISSING)
+ if (!g_hash_table_lookup (ht, ass->image->references [i])) {
+ add_assemblies_to_domain (domain, ass->image->references [i], ht);
+ }
}
}
if (destroy_ht)
{
MonoAppDomainSetup *setup;
gchar **tmp;
- gchar *utf8;
+ gchar *search_path = NULL;
gint i;
gint npaths = 0;
gchar **pvt_split = NULL;
return; /* Must set application base to get private path working */
npaths++;
- if (setup->private_bin_path) {
- utf8 = mono_string_to_utf8 (setup->private_bin_path);
- pvt_split = g_strsplit (utf8, G_SEARCHPATH_SEPARATOR_S, 1000);
- g_free (utf8);
+
+ if (setup->private_bin_path)
+ search_path = mono_string_to_utf8 (setup->private_bin_path);
+
+ if (domain->private_bin_path) {
+ if (search_path == NULL)
+ search_path = domain->private_bin_path;
+ else {
+ gchar *tmp2 = search_path;
+ search_path = g_strjoin (";", search_path, domain->private_bin_path, NULL);
+ g_free (tmp2);
+ }
+ }
+
+ if (search_path) {
+ /*
+ * As per MSDN documentation, AppDomainSetup.PrivateBinPath contains a list of
+ * directories relative to ApplicationBase separated by semicolons (see
+ * http://msdn2.microsoft.com/en-us/library/system.appdomainsetup.privatebinpath.aspx)
+ * The loop below copes with the fact that some Unix applications may use ':' (or
+ * System.IO.Path.PathSeparator) as the path search separator. We replace it with
+ * ';' for the subsequent split.
+ *
+ * The issue was reported in bug #81446
+ */
+
+#ifndef PLATFORM_WIN32
+ gint slen;
+
+ slen = strlen (search_path);
+ for (i = 0; i < slen; i++)
+ if (search_path [i] == ':')
+ search_path [i] = ';';
+#endif
+
+ pvt_split = g_strsplit (search_path, ";", 1000);
+ g_free (search_path);
for (tmp = pvt_split; *tmp; tmp++, npaths++);
}
strcpy (target + targetlen - tail_len, extension);
dest = g_utf8_to_utf16 (target, strlen (target), NULL, NULL, NULL);
+ DeleteFile (dest);
copy_result = CopyFile (orig, dest, FALSE);
g_free (orig);
g_free (dest);
{
gint32 hash = 0, hash2 = 0;
char name_hash [9];
- char path_hash [19];
+ char path_hash [30];
char *bname = g_path_get_basename (filename);
+ char *dirname = g_path_get_dirname (filename);
+ char *location, *dyn_base;
MonoDomain *domain = mono_domain_get ();
hash = get_cstring_hash (bname);
- hash2 = get_cstring_hash (g_path_get_dirname (filename));
+ hash2 = get_cstring_hash (dirname);
g_snprintf (name_hash, sizeof (name_hash), "%08x", hash);
- g_snprintf (path_hash, sizeof (path_hash), "%08x_%08x", hash ^ hash2, hash2);
- return g_build_filename (mono_string_to_utf8 (domain->setup->dynamic_base),
- "assembly",
- "shadow",
- name_hash,
- path_hash,
- bname,
- NULL);
+ g_snprintf (path_hash, sizeof (path_hash), "%08x_%08x_%08x", hash ^ hash2, hash2, domain->shadow_serial);
+ dyn_base = mono_string_to_utf8 (domain->setup->dynamic_base);
+ location = g_build_filename (dyn_base, "assembly", "shadow", name_hash, path_hash, bname, NULL);
+ g_free (dyn_base);
+ g_free (bname);
+ g_free (dirname);
+ return location;
}
static gboolean
orig = g_utf8_to_utf16 (filename, strlen (filename), NULL, NULL, NULL);
dest = g_utf8_to_utf16 (shadow, strlen (shadow), NULL, NULL, NULL);
+ DeleteFile (dest);
copy_result = CopyFile (orig, dest, FALSE);
g_free (dest);
g_free (orig);
MonoReflectionAssembly *
ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomain *ad,
- MonoArray *raw_assembly,
- MonoArray *raw_symbol_store, MonoObject *evidence,
- MonoBoolean refonly)
+ MonoArray *raw_assembly,
+ MonoArray *raw_symbol_store, MonoObject *evidence,
+ MonoBoolean refonly)
{
MonoAssembly *ass;
MonoReflectionAssembly *refass = NULL;
}
if (raw_symbol_store != NULL)
- mono_debug_init_2_memory (image, mono_array_addr (raw_symbol_store, guint8, 0), mono_array_length (raw_symbol_store));
+ mono_debug_open_image_from_memory (image, mono_array_addr (raw_symbol_store, guint8, 0), mono_array_length (raw_symbol_store));
ass = mono_assembly_load_from_full (image, "", &status, refonly);
mono_raise_exception (exc);
}
- ass = mono_assembly_load_full (&aname, NULL, &status, refOnly);
+ ass = mono_assembly_load_full_nosearch (&aname, NULL, &status, refOnly);
mono_assembly_name_free (&aname);
- if (!ass && (refass = try_assembly_resolve (domain, assRef, refOnly)) == NULL){
- /* FIXME: it doesn't make much sense since we really don't have a filename ... */
- MonoException *exc = mono_get_exception_file_not_found2 (NULL, assRef);
- mono_raise_exception (exc);
+ if (!ass) {
+ /* MS.NET doesn't seem to call the assembly resolve handler for refonly assemblies */
+ if (!refOnly)
+ refass = mono_try_assembly_resolve (domain, assRef, refOnly);
+ else
+ refass = NULL;
+ if (!refass) {
+ /* FIXME: it doesn't make much sense since we really don't have a filename ... */
+ MonoException *exc = mono_get_exception_file_not_found2 (NULL, assRef);
+ mono_raise_exception (exc);
+ }
}
if (refass == NULL)
}
gint32
-ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad, MonoString *file,
- MonoObject *evidence, MonoArray *args)
+ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad,
+ MonoReflectionAssembly *refass, MonoArray *args)
{
- MonoAssembly *assembly;
MonoImage *image;
MonoMethod *method;
- char *filename;
- gint32 res;
- MonoReflectionAssembly *refass;
MONO_ARCH_SAVE_REGS;
- filename = mono_string_to_utf8 (file);
- assembly = mono_assembly_open (filename, NULL);
- g_free (filename);
-
- if (!assembly)
- mono_raise_exception (mono_get_exception_file_not_found2 (NULL, file));
-
- image = assembly->image;
+ g_assert (refass);
+ image = refass->assembly->image;
+ g_assert (image);
method = mono_get_method (image, mono_image_get_entry_point (image), NULL);
if (!args)
args = (MonoArray *) mono_array_new (ad->data, mono_defaults.string_class, 0);
- refass = mono_assembly_get_object (ad->data, assembly);
- MONO_OBJECT_SETREF (refass, evidence, evidence);
-
- res = mono_runtime_exec_main (method, (MonoArray *)args, NULL);
-
- return res;
+ return mono_runtime_exec_main (method, (MonoArray *)args, NULL);
}
gint32