#include <mono/metadata/assembly.h>
#include <mono/metadata/loader.h>
-#include <mono/metadata/cil-coff.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/class.h>
#include <mono/metadata/object.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/environment.h>
#include <mono/metadata/verify.h>
+#include <mono/metadata/verify-internals.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/security-manager.h>
-#include <mono/os/gc_wrapper.h>
+#include <mono/metadata/security-core-clr.h>
+#include <mono/metadata/gc-internal.h>
+#include <mono/metadata/coree.h>
#include "mono/utils/mono-counters.h"
+#include <mono/os/gc_wrapper.h>
#include "mini.h"
#include "jit.h"
static void mini_usage (void);
-/* This turns off command line globbing under win32 */
#ifdef PLATFORM_WIN32
+/* Need this to determine whether to detach console */
+#include <mono/metadata/cil-coff.h>
+/* This turns off command line globbing under win32 */
int _CRT_glob = 0;
#endif
MONO_OPT_INTRINS | \
MONO_OPT_LOOP | \
MONO_OPT_EXCEPTION | \
+ MONO_OPT_CMOV | \
+ MONO_OPT_GSHARED | \
MONO_OPT_AOT)
#define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP)
return opt;
}
+static gboolean
+parse_debug_options (const char* p)
+{
+ MonoDebugOptions *opt = mini_get_debug_options ();
+
+ do {
+ if (!*p) {
+ fprintf (stderr, "Syntax error; expected debug option name\n");
+ return FALSE;
+ }
+
+ if (!strncmp (p, "casts", 5)) {
+ opt->better_cast_details = TRUE;
+ p += 5;
+ } else if (!strncmp (p, "mdb-optimizations", 17)) {
+ opt->mdb_optimizations = TRUE;
+ p += 17;
+ } else {
+ fprintf (stderr, "Invalid debug option `%s', use --help-debug for details\n", p);
+ return FALSE;
+ }
+
+ if (*p == ',') {
+ p++;
+ if (!*p) {
+ fprintf (stderr, "Syntax error; expected debug option name\n");
+ return FALSE;
+ }
+ }
+ } while (*p);
+
+ return TRUE;
+}
+
typedef struct {
const char name [6];
const char desc [18];
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS,
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_SSA,
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION,
+ MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_CMOV,
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_ABCREM,
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_ABCREM | MONO_OPT_SSAPRE,
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_ABCREM,
return total;
}
+#ifdef MONO_JIT_INFO_TABLE_TEST
+typedef struct _JitInfoData
+{
+ guint start;
+ guint length;
+ MonoJitInfo *ji;
+ struct _JitInfoData *next;
+} JitInfoData;
+
+typedef struct
+{
+ guint start;
+ guint length;
+ int num_datas;
+ JitInfoData *data;
+} Region;
+
+typedef struct
+{
+ int num_datas;
+ int num_regions;
+ Region *regions;
+ int num_frees;
+ JitInfoData *frees;
+} ThreadData;
+
+static int num_threads;
+static ThreadData *thread_datas;
+static MonoDomain *test_domain;
+
+static JitInfoData*
+alloc_random_data (Region *region)
+{
+ JitInfoData **data;
+ JitInfoData *prev;
+ guint prev_end;
+ guint next_start;
+ guint max_len;
+ JitInfoData *d;
+ int num_retries = 0;
+ int pos, i;
+
+ restart:
+ prev = NULL;
+ data = ®ion->data;
+ pos = random () % (region->num_datas + 1);
+ i = 0;
+ while (*data != NULL) {
+ if (i++ == pos)
+ break;
+ prev = *data;
+ data = &(*data)->next;
+ }
+
+ if (prev == NULL)
+ g_assert (*data == region->data);
+ else
+ g_assert (prev->next == *data);
+
+ if (prev == NULL)
+ prev_end = region->start;
+ else
+ prev_end = prev->start + prev->length;
+
+ if (*data == NULL)
+ next_start = region->start + region->length;
+ else
+ next_start = (*data)->start;
+
+ g_assert (prev_end <= next_start);
+
+ max_len = next_start - prev_end;
+ if (max_len < 128) {
+ if (++num_retries >= 10)
+ return NULL;
+ goto restart;
+ }
+ if (max_len > 1024)
+ max_len = 1024;
+
+ d = g_new0 (JitInfoData, 1);
+ d->start = prev_end + random () % (max_len / 2);
+ d->length = random () % MIN (max_len, next_start - d->start) + 1;
+
+ g_assert (d->start >= prev_end && d->start + d->length <= next_start);
+
+ d->ji = g_new0 (MonoJitInfo, 1);
+ d->ji->method = (MonoMethod*) 0xABadBabe;
+ d->ji->code_start = (gpointer)(gulong) d->start;
+ d->ji->code_size = d->length;
+ d->ji->cas_inited = 1; /* marks an allocated jit info */
+
+ d->next = *data;
+ *data = d;
+
+ ++region->num_datas;
+
+ return d;
+}
+
+static JitInfoData**
+choose_random_data (Region *region)
+{
+ int n;
+ int i;
+ JitInfoData **d;
+
+ g_assert (region->num_datas > 0);
+
+ n = random () % region->num_datas;
+
+ for (d = ®ion->data, i = 0;
+ i < n;
+ d = &(*d)->next, ++i)
+ ;
+
+ return d;
+}
+
+static Region*
+choose_random_region (ThreadData *td)
+{
+ return &td->regions [random () % td->num_regions];
+}
+
+static ThreadData*
+choose_random_thread (void)
+{
+ return &thread_datas [random () % num_threads];
+}
+
+static void
+free_jit_info_data (ThreadData *td, JitInfoData *free)
+{
+ free->next = td->frees;
+ td->frees = free;
+
+ if (++td->num_frees >= 1000) {
+ int i;
+
+ for (i = 0; i < 500; ++i)
+ free = free->next;
+
+ while (free->next != NULL) {
+ JitInfoData *next = free->next->next;
+
+ //g_free (free->next->ji);
+ g_free (free->next);
+ free->next = next;
+
+ --td->num_frees;
+ }
+ }
+}
+
+#define NUM_THREADS 8
+#define REGIONS_PER_THREAD 10
+#define REGION_SIZE 0x10000
+
+#define MAX_ADDR (REGION_SIZE * REGIONS_PER_THREAD * NUM_THREADS)
+
+#define MODE_ALLOC 1
+#define MODE_FREE 2
+
+static void
+test_thread_func (ThreadData *td)
+{
+ int mode = MODE_ALLOC;
+ int i = 0;
+ gulong lookup_successes = 0, lookup_failures = 0;
+ MonoDomain *domain = test_domain;
+ int thread_num = (int)(td - thread_datas);
+ gboolean modify_thread = thread_num < NUM_THREADS / 2; /* only half of the threads modify the table */
+
+ for (;;) {
+ int alloc;
+ int lookup = 1;
+
+ if (td->num_datas == 0) {
+ lookup = 0;
+ alloc = 1;
+ } else if (modify_thread && random () % 1000 < 5) {
+ lookup = 0;
+ if (mode == MODE_ALLOC)
+ alloc = (random () % 100) < 70;
+ else if (mode == MODE_FREE)
+ alloc = (random () % 100) < 30;
+ }
+
+ if (lookup) {
+ /* modify threads sometimes look up their own jit infos */
+ if (modify_thread && random () % 10 < 5) {
+ Region *region = choose_random_region (td);
+
+ if (region->num_datas > 0) {
+ JitInfoData **data = choose_random_data (region);
+ guint pos = (*data)->start + random () % (*data)->length;
+ MonoJitInfo *ji;
+
+ ji = mono_jit_info_table_find (domain, (char*)(gulong) pos);
+
+ g_assert (ji->cas_inited);
+ g_assert ((*data)->ji == ji);
+ }
+ } else {
+ int pos = random () % MAX_ADDR;
+ char *addr = (char*)(gulong) pos;
+ MonoJitInfo *ji;
+
+ ji = mono_jit_info_table_find (domain, addr);
+
+ /*
+ * FIXME: We are actually not allowed
+ * to do this. By the time we examine
+ * the ji another thread might already
+ * have removed it.
+ */
+ if (ji != NULL) {
+ g_assert (addr >= (char*)ji->code_start && addr < (char*)ji->code_start + ji->code_size);
+ ++lookup_successes;
+ } else
+ ++lookup_failures;
+ }
+ } else if (alloc) {
+ JitInfoData *data = alloc_random_data (choose_random_region (td));
+
+ if (data != NULL) {
+ mono_jit_info_table_add (domain, data->ji);
+
+ ++td->num_datas;
+ }
+ } else {
+ Region *region = choose_random_region (td);
+
+ if (region->num_datas > 0) {
+ JitInfoData **data = choose_random_data (region);
+ JitInfoData *free;
+
+ mono_jit_info_table_remove (domain, (*data)->ji);
+
+ //(*data)->ji->cas_inited = 0; /* marks a free jit info */
+
+ free = *data;
+ *data = (*data)->next;
+
+ free_jit_info_data (td, free);
+
+ --region->num_datas;
+ --td->num_datas;
+ }
+ }
+
+ if (++i % 100000 == 0) {
+ int j;
+ g_print ("num datas %d (%ld - %ld): %d", (int)(td - thread_datas),
+ lookup_successes, lookup_failures, td->num_datas);
+ for (j = 0; j < td->num_regions; ++j)
+ g_print (" %d", td->regions [j].num_datas);
+ g_print ("\n");
+ }
+
+ if (td->num_datas < 100)
+ mode = MODE_ALLOC;
+ else if (td->num_datas > 2000)
+ mode = MODE_FREE;
+ }
+}
+
+/*
+static void
+small_id_thread_func (gpointer arg)
+{
+ MonoThread *thread = mono_thread_current ();
+ MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
+
+ g_print ("my small id is %d\n", (int)thread->small_id);
+ mono_hazard_pointer_clear (hp, 1);
+ sleep (3);
+ g_print ("done %d\n", (int)thread->small_id);
+}
+*/
+
+static void
+jit_info_table_test (MonoDomain *domain)
+{
+ int i;
+
+ g_print ("testing jit_info_table\n");
+
+ num_threads = NUM_THREADS;
+ thread_datas = g_new0 (ThreadData, num_threads);
+
+ for (i = 0; i < num_threads; ++i) {
+ int j;
+
+ thread_datas [i].num_regions = REGIONS_PER_THREAD;
+ thread_datas [i].regions = g_new0 (Region, REGIONS_PER_THREAD);
+
+ for (j = 0; j < REGIONS_PER_THREAD; ++j) {
+ thread_datas [i].regions [j].start = (num_threads * j + i) * REGION_SIZE;
+ thread_datas [i].regions [j].length = REGION_SIZE;
+ }
+ }
+
+ test_domain = domain;
+
+ /*
+ for (i = 0; i < 72; ++i)
+ mono_thread_create (domain, small_id_thread_func, NULL);
+
+ sleep (2);
+ */
+
+ for (i = 0; i < num_threads; ++i)
+ mono_thread_create (domain, test_thread_func, &thread_datas [i]);
+}
+#endif
+
enum {
DO_BENCH,
DO_REGRESSION,
MonoImage *image = mono_assembly_get_image (ass);
MonoMethod *method;
MonoCompile *cfg;
- int i, count = 0;
+ int i, count = 0, fail_count = 0;
for (i = 0; i < mono_image_get_table_rows (image, MONO_TABLE_METHOD); ++i) {
guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
g_free (desc);
}
cfg = mini_method_compile (method, args->opts, mono_get_root_domain (), FALSE, FALSE, 0);
+ if (cfg->exception_type != MONO_EXCEPTION_NONE) {
+ printf ("Compilation of %s failed with exception '%s':\n", mono_method_full_name (cfg->method, TRUE), cfg->exception_message);
+ fail_count ++;
+ }
mono_destroy_compile (cfg);
}
+ if (fail_count)
+ exit (1);
}
static void
MainThreadArgs *main_args = user_data;
MonoAssembly *assembly;
- assembly = mono_domain_assembly_open (main_args->domain, main_args->file);
- if (!assembly){
- fprintf (stderr, "Can not open image %s\n", main_args->file);
- exit (1);
- }
-
if (mono_compile_aot) {
- int res = mono_compile_assembly (assembly, main_args->opts, main_args->aot_options);
- printf ("AOT RESULT %d\n", res);
+ int i, res;
+
+ /* Treat the other arguments as assemblies to compile too */
+ for (i = 0; i < main_args->argc; ++i) {
+ assembly = mono_domain_assembly_open (main_args->domain, main_args->argv [i]);
+ if (!assembly) {
+ fprintf (stderr, "Can not open image %s\n", main_args->argv [i]);
+ exit (1);
+ }
+ res = mono_compile_assembly (assembly, main_args->opts, main_args->aot_options);
+ if (res != 0) {
+ fprintf (stderr, "AOT of image %s failed.\n", main_args->argv [i]);
+ exit (1);
+ }
+ }
} else {
+ assembly = mono_domain_assembly_open (main_args->domain, main_args->file);
+ if (!assembly){
+ fprintf (stderr, "Can not open image %s\n", main_args->file);
+ exit (1);
+ }
+
/*
* This must be done in a thread managed by mono since it can invoke
* managed code.
"Runtime and JIT debugging options:\n"
" --breakonex Inserts a breakpoint on exceptions\n"
" --break METHOD Inserts a breakpoint at METHOD entry\n"
+ " --break-at-bb METHOD N Inserts a breakpoint in METHOD at BB N\n"
" --compile METHOD Just compile METHOD in assembly\n"
" --compile-all Compiles all the methods in the assembly\n"
" --ncompile N Number of times to compile METHOD (default: 1)\n"
" --regression Runs the regression test contained in the assembly\n"
" --statfile FILE Sets the stat file to FILE\n"
" --stats Print statistics about the JIT operations\n"
- " --wapi=hps|semdel IO-layer maintenance\n"
+ " --wapi=hps|semdel|seminfo IO-layer maintenance\n"
+ " --inject-async-exc METHOD OFFSET Inject an asynchronous exception at METHOD\n"
+ " --verify-all Run the verifier on all methods\n"
+ " --full-aot Avoid JITting any code\n"
"\n"
"Other options:\n"
" --graph[=TYPE] METHOD Draws a graph of the specified method:\n");
"\n"
"Development:\n"
" --aot Compiles the assembly to native code\n"
- " --debug Enable debugging support\n"
+ " --debug[=<options>] Enable debugging support, use --help-debug for details\n"
" --profile[=profiler] Runs in profiling mode with the specified profiler module\n"
" --trace[=EXPR] Enable tracing, use --help-trace for details\n"
" --help-devel Shows more options available to developers\n"
" --runtime=VERSION Use the VERSION runtime, instead of autodetecting\n"
" --optimize=OPT Turns on or off a specific optimization\n"
" Use --list-opt to get a list of optimizations\n"
- " --security Turns on the security manager (unsupported, default is off)\n");
+ " --security[=mode] Turns on the unsupported security manager (off by default)\n"
+ " mode is one of cas, core-clr, verifiable or validil\n");
}
static void
" disabled Don't print any output until toggled via SIGUSR2\n");
}
+static void
+mini_debug_usage (void)
+{
+ fprintf (stdout,
+ "Debugging options:\n"
+ " --debug[=OPTIONS] Enable debugging support, optional OPTIONS is a comma\n"
+ " separated list of options\n"
+ "\n"
+ "OPTIONS is composed of:\n"
+ " casts Enable more detailed InvalidCastException messages.\n"
+ " mdb-optimizations Disable some JIT optimizations which are normally\n"
+ " disabled when running inside the debugger.\n"
+ " This is useful if you plan to attach to the running\n"
+ " process with the debugger.\n");
+}
+
+#if defined(__arm__) && defined(__ARM_EABI__)
+/* Redefine ARCHITECTURE to include more information */
+#undef ARCHITECTURE
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define ARCHITECTURE "armel"
+#else
+#define ARCHITECTURE "armeb"
+#endif
+#endif
+
static const char info[] =
#ifdef HAVE_KW_THREAD
"\tTLS: __thread\n"
"\tSIGSEGV: altstack\n"
#else
"\tSIGSEGV: normal\n"
+#endif
+#ifdef HAVE_EPOLL
+ "\tNotifications: epoll\n"
+#else
+ "\tNotification: Thread + polling\n"
#endif
"\tArchitecture: " ARCHITECTURE "\n"
"\tDisabled: " DISABLED_FEATURES "\n"
#define error_if_aot_unsupported()
#endif
+#ifdef PLATFORM_WIN32
+BOOL APIENTRY DllMain (HMODULE module_handle, DWORD reason, LPVOID reserved)
+{
+ if (!GC_DllMain (module_handle, reason, reserved))
+ return FALSE;
+
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ mono_install_runtime_load (mini_init);
+ break;
+ case DLL_PROCESS_DETACH:
+ if (coree_module_handle)
+ FreeLibrary (coree_module_handle);
+ break;
+ }
+ return TRUE;
+}
+#endif
+
int
mono_main (int argc, char* argv[])
{
MonoMethod *method;
MonoCompile *cfg;
MonoDomain *domain;
+ MonoImageOpenStatus open_status;
const char* aname, *mname = NULL;
char *config_file = NULL;
int i, count = 1;
char *profile_options = NULL;
char *aot_options = NULL;
char *forced_version = NULL;
+#ifdef MONO_JIT_INFO_TABLE_TEST
+ int test_jit_info_table = FALSE;
+#endif
setlocale (LC_ALL, "");
#if HAVE_SCHED_SETAFFINITY
if (getenv ("MONO_NO_SMP")) {
unsigned long proc_mask = 1;
- sched_setaffinity (getpid(), sizeof (unsigned long), &proc_mask);
+ sched_setaffinity (getpid(), sizeof (unsigned long), (gpointer)&proc_mask);
}
#endif
if (!g_thread_supported ())
} else if (strcmp (argv [i], "--verbose") == 0 || strcmp (argv [i], "-v") == 0) {
mini_verbose++;
} else if (strcmp (argv [i], "--version") == 0 || strcmp (argv [i], "-V") == 0) {
- g_print ("Mono JIT compiler version %s (%s)\nCopyright (C) 2002-2007 Novell, Inc and Contributors. www.mono-project.com\n", VERSION, FULL_VERSION);
+ g_print ("Mono JIT compiler version %s (%s)\nCopyright (C) 2002-2008 Novell, Inc and Contributors. www.mono-project.com\n", VERSION, FULL_VERSION);
g_print (info);
if (mini_verbose) {
const char *cerror;
} else if (strcmp (argv [i], "--help-devel") == 0){
mini_usage_jitdeveloper ();
return 0;
+ } else if (strcmp (argv [i], "--help-debug") == 0){
+ mini_debug_usage ();
+ return 0;
} else if (strcmp (argv [i], "--list-opt") == 0){
mini_usage_list_opt ();
return 0;
if (!mono_debugger_insert_breakpoint (argv [++i], FALSE))
fprintf (stderr, "Error: invalid method name '%s'\n", argv [i]);
+ } else if (strcmp (argv [i], "--break-at-bb") == 0) {
+ if (i + 2 >= argc) {
+ fprintf (stderr, "Missing method name or bb num in --break-at-bb command line option.");
+ return 1;
+ }
+ mono_break_at_bb_method = mono_method_desc_new (argv [++i], TRUE);
+ if (mono_break_at_bb_method == NULL) {
+ fprintf (stderr, "Method name is in a bad format in --break-at-bb command line option.");
+ return 1;
+ }
+ mono_break_at_bb_bb_num = atoi (argv [++i]);
+ } else if (strcmp (argv [i], "--inject-async-exc") == 0) {
+ if (i + 2 >= argc) {
+ fprintf (stderr, "Missing method name or position in --inject-async-exc command line option\n");
+ return 1;
+ }
+ mono_inject_async_exc_method = mono_method_desc_new (argv [++i], TRUE);
+ if (mono_inject_async_exc_method == NULL) {
+ fprintf (stderr, "Method name is in a bad format in --inject-async-exc command line option\n");
+ return 1;
+ }
+ mono_inject_async_exc_pos = atoi (argv [++i]);
+ } else if (strcmp (argv [i], "--verify-all") == 0) {
+ mono_verifier_enable_verify_all ();
+ } else if (strcmp (argv [i], "--full-aot") == 0) {
+ mono_aot_only = TRUE;
} else if (strcmp (argv [i], "--print-vtable") == 0) {
mono_print_vtable = TRUE;
} else if (strcmp (argv [i], "--stats") == 0) {
action = DO_DRAW;
} else if (strcmp (argv [i], "--debug") == 0) {
enable_debugging = TRUE;
+ } else if (strncmp (argv [i], "--debug=", 8) == 0) {
+ enable_debugging = TRUE;
+ if (!parse_debug_options (argv [i] + 8))
+ return 1;
} else if (strcmp (argv [i], "--security") == 0) {
- mono_use_security_manager = TRUE;
+ /* fixme enable verifiable code when the verifier works with 2.0
+ * mini_verifier_set_mode (MINI_VERIFIER_MODE_VERIFIABLE);
+ */
+ mono_security_set_mode (MONO_SECURITY_MODE_CAS);
mono_activate_security_manager ();
} else if (strncmp (argv [i], "--security=", 11) == 0) {
if (strcmp (argv [i] + 11, "temporary-smcs-hack") == 0) {
- mono_security_smcs_hack = TRUE;
- } else {
- fprintf (stderr, "error: --security= option has invalid argument\n");
+ mono_security_set_mode (MONO_SECURITY_MODE_SMCS_HACK);
+ } else if (strcmp (argv [i] + 11, "core-clr") == 0) {
+ /* fixme enable verifiable code when the verifier works with 2.0
+ * mini_verifier_set_mode (MINI_VERIFIER_MODE_VERIFIABLE);
+ */
+ mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
+ } else if (strcmp (argv [i] + 11, "core-clr-test") == 0) {
+ /* fixme should we enable verifiable code here?*/
+ mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
+ mono_security_core_clr_test = TRUE;
+ } else if (strcmp (argv [i] + 11, "cas") == 0){
+ /* fixme enable verifiable code when the verifier works with 2.0
+ * mini_verifier_set_mode (MINI_VERIFIER_MODE_VERIFIABLE);
+ */
+ mono_security_set_mode (MONO_SECURITY_MODE_CAS);
+ mono_activate_security_manager ();
+ } else if (strcmp (argv [i] + 11, "validil") == 0) {
+ mono_verifier_set_mode (MONO_VERIFIER_MODE_VALID);
+ } else if (strcmp (argv [i] + 11, "verifiable") == 0) {
+ mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
+ } else {
+ fprintf (stderr, "error: --security= option has invalid argument (cas, core-clr, verifiable or validil)\n");
return 1;
}
} else if (strcmp (argv [i], "--desktop") == 0) {
fprintf (stderr, "Invalid --wapi suboption: '%s'\n", argv [i]);
return 1;
}
+#ifdef MONO_JIT_INFO_TABLE_TEST
+ } else if (strcmp (argv [i], "--test-jit-info-table") == 0) {
+ test_jit_info_table = TRUE;
+#endif
} else {
fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
return 1;
return 1;
}
- if ((action == DO_EXEC) && g_getenv ("MONO_INSIDE_MDB"))
+ if ((action == DO_EXEC) && mono_debug_using_mono_debugger ())
action = DO_DEBUGGER;
if (mono_compile_aot || action == DO_EXEC || action == DO_DEBUGGER) {
if (enable_profile) {
/* Needed because of TLS accesses in mono_profiler_load () */
- MONO_GC_PRE_INIT ();
+ mono_gc_base_init ();
mono_profiler_load (profile_options);
}
}
if (action == DO_DEBUGGER) {
- opt |= MONO_OPT_SHARED;
- opt &= ~MONO_OPT_INLINE;
- opt &= ~MONO_OPT_COPYPROP;
- opt &= ~MONO_OPT_CONSPROP;
enable_debugging = TRUE;
#ifdef MONO_DEBUGGER_SUPPORTED
g_print ("The Mono Debugger is not supported on this platform.\n");
return 1;
#endif
- }
+ } else if (enable_debugging)
+ mono_debug_init (MONO_DEBUG_FORMAT_MONO);
mono_set_defaults (mini_verbose, opt);
+ mono_setup_vtable_in_class_init = FALSE;
domain = mini_init (argv [i], forced_version);
switch (action) {
break;
}
- if (action == DO_DEBUGGER)
- mono_debug_init_1 (domain);
- else if (enable_debugging) {
- mono_debug_init (MONO_DEBUG_FORMAT_MONO);
- mono_debug_init_1 (domain);
- }
-
/* Parse gac loading options before loading assemblies. */
if (mono_compile_aot || action == DO_EXEC || action == DO_DEBUGGER) {
mono_config_parse (config_file);
}
- assembly = mono_assembly_open (aname, NULL);
+#ifdef MONO_JIT_INFO_TABLE_TEST
+ if (test_jit_info_table)
+ jit_info_table_test (domain);
+#endif
+
+ assembly = mono_assembly_open (aname, &open_status);
if (!assembly) {
- fprintf (stderr, "Cannot open assembly %s.\n", aname);
+ fprintf (stderr, "Cannot open assembly '%s': %s.\n", aname, mono_image_strerror (open_status));
mini_cleanup (domain);
return 2;
}
if (trace_options != NULL)
mono_trace_set_assembly (assembly);
- if (enable_debugging)
- mono_debug_init_2 (assembly);
-
if (mono_compile_aot || action == DO_EXEC) {
const char *error;
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
MonoMethod *nm;
- nm = mono_marshal_get_native_wrapper (method);
+ nm = mono_marshal_get_native_wrapper (method, TRUE, FALSE);
cfg = mini_method_compile (nm, opt, mono_get_root_domain (), FALSE, FALSE, part);
}
else
for (i = 0; i < count; ++i) {
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
- method = mono_marshal_get_native_wrapper (method);
+ method = mono_marshal_get_native_wrapper (method, TRUE, FALSE);
cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, FALSE, 0);
mono_destroy_compile (cfg);
return mini_init (file, NULL);
}
+/**
+ * mono_jit_init_version:
+ * @domain_name: the name of the root domain
+ * @runtime_version: the version of the runtime to load
+ *
+ * Use this version when you want to force a particular runtime
+ * version to be used. By default Mono will pick the runtime that is
+ * referenced by the initial assembly (specified in @file), this
+ * routine allows programmers to specify the actual runtime to be used
+ * as the initial runtime is inherited by all future assemblies loaded
+ * (since Mono does not support having more than one mscorlib runtime
+ * loaded at once).
+ *
+ * The @runtime_version can be one of these strings: "v1.1.4322" for
+ * the 1.1 runtime or "v2.0.50727" for the 2.0 runtime.
+ *
+ * Returns: the MonoDomain representing the domain where the assembly
+ * was loaded.
+ */
MonoDomain *
-mono_jit_init_version (const char *file, const char *runtime_version)
+mono_jit_init_version (const char *domain_name, const char *runtime_version)
{
- return mini_init (file, runtime_version);
+ return mini_init (domain_name, runtime_version);
}
void
{
mini_cleanup (domain);
}
+
+/**
+ * mono_jit_set_trace_options:
+ * @options: string representing the trace options
+ *
+ * Set the options of the tracing engine. This function can be called before initializing
+ * the mono runtime. See the --trace mono(1) manpage for the options format.
+ *
+ * Returns: #TRUE if the options where parsed and set correctly, #FALSE otherwise.
+ */
+gboolean
+mono_jit_set_trace_options (const char* options)
+{
+ MonoTraceSpec *trace_opt = mono_trace_parse_options (options);
+ if (trace_opt == NULL)
+ return FALSE;
+ mono_jit_trace_calls = trace_opt;
+ return TRUE;
+}
+