void mono_gc_base_init (void) { MonoThreadInfoCallbacks cb; int dummy; if (gc_initialized) return; mono_counters_init (); corgc_init (); memset (&cb, 0, sizeof (cb)); cb.thread_register = corgc_thread_register; cb.thread_unregister = corgc_thread_unregister; cb.mono_method_is_critical = (gboolean(*)(void*))mono_runtime_is_critical_method; #ifndef HOST_WIN32 cb.thread_exit = mono_gc_pthread_exit; cb.mono_gc_pthread_create = mono_gc_pthread_create; #endif mono_threads_init (&cb, sizeof (CorgcThreadInfo)); mono_thread_info_attach (&dummy); mono_gc_enable_events (); gc_initialized = TRUE; }
void mono_gc_base_init (void) { MonoThreadInfoCallbacks cb; int dummy; mono_counters_init (); memset (&cb, 0, sizeof (cb)); /* TODO: This casts away an incompatible pointer type warning in the same manner that boehm-gc does it. This is probably worth investigating more carefully. */ cb.mono_method_is_critical = (gpointer)mono_runtime_is_critical_method; mono_threads_init (&cb, sizeof (MonoThreadInfo)); mono_thread_info_attach (&dummy); }
int main (int argc, char *argv []) { int image_result = 0; MonoImage *image; char *file = NULL; char *flags = NULL; MiniVerifierMode verifier_mode = MONO_VERIFIER_MODE_VERIFIABLE; const char *flag_desc [] = {"error", "warn", "cls", "all", "code", "fail-on-verifiable", "non-strict", "valid-only", "metadata", "partial-md", NULL}; guint flag_vals [] = {MONO_VERIFY_ERROR, MONO_VERIFY_WARNING, MONO_VERIFY_CLS, MONO_VERIFY_ALL, VERIFY_CODE_ONLY, MONO_VERIFY_FAIL_FAST, MONO_VERIFY_NON_STRICT, VALID_ONLY_FLAG, VERIFY_METADATA_ONLY, VERIFY_PARTIAL_METADATA, 0}; int i, verify_flags = MONO_VERIFY_REPORT_ALL_ERRORS, run_new_metadata_verifier = 0; for (i = 1; i < argc; i++){ if (argv [i][0] != '-'){ file = argv [i]; continue; } if (strcmp (argv [i], "--help") == 0) usage (); else if (strcmp (argv [i], "--verify") == 0) { verify_pe = 1; dump_data = 0; ++i; flags = argv [i]; } else { usage (); } } if (!file) usage (); #ifndef DISABLE_PERFCOUNTERS mono_perfcounters_init (); #endif mono_counters_init (); mono_metadata_init (); mono_images_init (); mono_assemblies_init (); mono_loader_init (); if (verify_pe) { char *tok = strtok (flags, ","); verify_metadata = 1; verify_code = 0; while (tok) { for (i = 0; flag_desc [i]; ++i) { if (strcmp (tok, flag_desc [i]) == 0) { if (flag_vals [i] == VERIFY_CODE_ONLY) { verify_metadata = 0; verify_code = 1; } else if(flag_vals [i] == MONO_VERIFY_ALL) { verify_code = 1; } else if(flag_vals [i] == VERIFY_METADATA_ONLY) { verify_metadata = 0; run_new_metadata_verifier = 1; } else if(flag_vals [i] == VERIFY_PARTIAL_METADATA) { verify_partial_md = 1; } if (flag_vals [i] == VALID_ONLY_FLAG) verifier_mode = MONO_VERIFIER_MODE_VALID; else verify_flags |= flag_vals [i]; break; } } if (!flag_desc [i]) g_print ("Unknown verify flag %s\n", tok); tok = strtok (NULL, ","); } mono_verifier_set_mode (verifier_mode); /**/ } if (verify_pe || run_new_metadata_verifier) { run_new_metadata_verifier = 1; } if (run_new_metadata_verifier) { mono_verifier_set_mode (verifier_mode); image_result = verify_image_file (file); if (image_result == 1 || !verify_code) return image_result; } image = mono_image_open (file, NULL); if (!image){ fprintf (stderr, "Cannot open image %s\n", file); exit (1); } if (dump_data) dump_dotnet_iinfo (image); if (verify_pe) { MonoAssembly *assembly; MonoImage *image; MonoImageOpenStatus status; int code_result; mono_verifier_set_mode (verifier_mode); assembly = mono_assembly_open (file, NULL); /*fake an assembly for netmodules so the verifier works*/ if (!assembly && (image = mono_image_open (file, &status)) && image->tables [MONO_TABLE_ASSEMBLY].rows == 0) { assembly = g_new0 (MonoAssembly, 1); assembly->in_gac = FALSE; assembly->image = image; image->assembly = assembly; } if (!assembly) { g_print ("Could not open assembly %s\n", file); return 4; } code_result = dump_verify_info (assembly->image, verify_flags); return code_result ? code_result : image_result; } else mono_image_close (image); return 0; }
void mono_gc_base_init (void) { MonoThreadInfoCallbacks cb; const char *env; int dummy; if (gc_initialized) return; mono_counters_init (); /* * Handle the case when we are called from a thread different from the main thread, * confusing libgc. * FIXME: Move this to libgc where it belongs. * * we used to do this only when running on valgrind, * but it happens also in other setups. */ #if defined(HAVE_PTHREAD_GETATTR_NP) && defined(HAVE_PTHREAD_ATTR_GETSTACK) && !defined(__native_client__) { size_t size; void *sstart; pthread_attr_t attr; pthread_getattr_np (pthread_self (), &attr); pthread_attr_getstack (&attr, &sstart, &size); pthread_attr_destroy (&attr); /*g_print ("stackbottom pth is: %p\n", (char*)sstart + size);*/ #ifdef __ia64__ /* * The calculation above doesn't seem to work on ia64, also we need to set * GC_register_stackbottom as well, but don't know how. */ #else /* apparently with some linuxthreads implementations sstart can be NULL, * fallback to the more imprecise method (bug# 78096). */ if (sstart) { GC_stackbottom = (char*)sstart + size; } else { int dummy; gsize stack_bottom = (gsize)&dummy; stack_bottom += 4095; stack_bottom &= ~4095; GC_stackbottom = (char*)stack_bottom; } #endif } #elif defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP) GC_stackbottom = (char*)pthread_get_stackaddr_np (pthread_self ()); #elif defined(__OpenBSD__) # include <pthread_np.h> { stack_t ss; int rslt; rslt = pthread_stackseg_np(pthread_self(), &ss); g_assert (rslt == 0); GC_stackbottom = (char*)ss.ss_sp; } #elif defined(__native_client__) /* Do nothing, GC_stackbottom is set correctly in libgc */ #else { int dummy; gsize stack_bottom = (gsize)&dummy; stack_bottom += 4095; stack_bottom &= ~4095; /*g_print ("stackbottom is: %p\n", (char*)stack_bottom);*/ GC_stackbottom = (char*)stack_bottom; } #endif #if !defined(PLATFORM_ANDROID) /* If GC_no_dls is set to true, GC_find_limit is not called. This causes a seg fault on Android. */ GC_no_dls = TRUE; #endif { if ((env = g_getenv ("MONO_GC_DEBUG"))) { char **opts = g_strsplit (env, ",", -1); for (char **ptr = opts; ptr && *ptr; ptr ++) { char *opt = *ptr; if (!strcmp (opt, "do-not-finalize")) { mono_do_not_finalize = 1; } else if (!strcmp (opt, "log-finalizers")) { log_finalizers = 1; } } } } GC_init (); GC_oom_fn = mono_gc_out_of_memory; GC_set_warn_proc (mono_gc_warning); GC_finalize_on_demand = 1; GC_finalizer_notifier = mono_gc_finalize_notify; GC_init_gcj_malloc (5, NULL); if ((env = g_getenv ("MONO_GC_PARAMS"))) { char **ptr, **opts = g_strsplit (env, ",", -1); for (ptr = opts; *ptr; ++ptr) { char *opt = *ptr; if (g_str_has_prefix (opt, "max-heap-size=")) { size_t max_heap; opt = strchr (opt, '=') + 1; if (*opt && mono_gc_parse_environment_string_extract_number (opt, &max_heap)) { if (max_heap < MIN_BOEHM_MAX_HEAP_SIZE) { fprintf (stderr, "max-heap-size must be at least %dMb.\n", MIN_BOEHM_MAX_HEAP_SIZE_IN_MB); exit (1); } GC_set_max_heap_size (max_heap); } else { fprintf (stderr, "max-heap-size must be an integer.\n"); exit (1); } continue; } else if (g_str_has_prefix (opt, "toggleref-test")) { register_test_toggleref_callback (); continue; } else { /* Could be a parameter for sgen */ /* fprintf (stderr, "MONO_GC_PARAMS must be a comma-delimited list of one or more of the following:\n"); fprintf (stderr, " max-heap-size=N (where N is an integer, possibly with a k, m or a g suffix)\n"); exit (1); */ } } g_strfreev (opts); } memset (&cb, 0, sizeof (cb)); cb.thread_register = boehm_thread_register; cb.thread_unregister = boehm_thread_unregister; cb.mono_method_is_critical = (gpointer)mono_runtime_is_critical_method; mono_threads_init (&cb, sizeof (MonoThreadInfo)); mono_mutex_init (&mono_gc_lock); mono_mutex_init_recursive (&handle_section); mono_thread_info_attach (&dummy); mono_gc_enable_events (); MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_NORMAL].entries, MONO_ROOT_SOURCE_GC_HANDLE, "gc handles table"); MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_PINNED].entries, MONO_ROOT_SOURCE_GC_HANDLE, "gc handles table"); gc_initialized = TRUE; }
int main (int argc, char *argv []) { int image_result = 0; MonoImage *image; char *file = NULL; char *flags = NULL; MiniVerifierMode verifier_mode = MONO_VERIFIER_MODE_VERIFIABLE; const char *flag_desc [] = {"error", "warn", "cls", "all", "code", "fail-on-verifiable", "non-strict", "valid-only", "metadata", "partial-md", NULL}; guint flag_vals [] = {MONO_VERIFY_ERROR, MONO_VERIFY_WARNING, MONO_VERIFY_CLS, MONO_VERIFY_ALL, VERIFY_CODE_ONLY, MONO_VERIFY_FAIL_FAST, MONO_VERIFY_NON_STRICT, VALID_ONLY_FLAG, VERIFY_METADATA_ONLY, VERIFY_PARTIAL_METADATA, 0}; int i, verify_flags = MONO_VERIFY_REPORT_ALL_ERRORS, run_new_metadata_verifier = 0; MonoThreadInfoRuntimeCallbacks ticallbacks; for (i = 1; i < argc; i++){ if (argv [i][0] != '-'){ file = argv [i]; continue; } if (strcmp (argv [i], "--help") == 0) usage (); else if (strcmp (argv [i], "--verify") == 0) { verify_pe = 1; dump_data = 0; ++i; flags = argv [i]; } else { usage (); } } if (!file) usage (); //We have to force the runtime to load the corlib under verification as its own corlib so core types are properly populated in mono_defaults. if (strstr (file, "mscorlib.dll")) g_setenv ("MONO_PATH", g_path_get_dirname (file), 1); assembly_directory [0] = g_path_get_dirname (file); assembly_directory [1] = NULL; #ifndef DISABLE_PERFCOUNTERS mono_perfcounters_init (); #endif mono_counters_init (); mono_tls_init_runtime_keys (); memset (&ticallbacks, 0, sizeof (ticallbacks)); ticallbacks.thread_state_init = thread_state_init; #ifndef HOST_WIN32 mono_w32handle_init (); #endif mono_thread_info_runtime_init (&ticallbacks); mono_metadata_init (); mono_images_init (); mono_assemblies_init (); mono_loader_init (); if (verify_pe) { char *tok = strtok (flags, ","); verify_metadata = 1; verify_code = 0; while (tok) { for (i = 0; flag_desc [i]; ++i) { if (strcmp (tok, flag_desc [i]) == 0) { if (flag_vals [i] == VERIFY_CODE_ONLY) { verify_metadata = 0; verify_code = 1; } else if(flag_vals [i] == MONO_VERIFY_ALL) { verify_code = 1; } else if(flag_vals [i] == VERIFY_METADATA_ONLY) { verify_metadata = 0; run_new_metadata_verifier = 1; } else if(flag_vals [i] == VERIFY_PARTIAL_METADATA) { verify_partial_md = 1; } if (flag_vals [i] == VALID_ONLY_FLAG) verifier_mode = MONO_VERIFIER_MODE_VALID; else verify_flags |= flag_vals [i]; break; } } if (!flag_desc [i]) g_print ("Unknown verify flag %s\n", tok); tok = strtok (NULL, ","); } mono_verifier_set_mode (verifier_mode); /**/ } if (verify_pe || run_new_metadata_verifier) { run_new_metadata_verifier = 1; } if (run_new_metadata_verifier) { mono_verifier_set_mode (verifier_mode); image_result = verify_image_file (file); if (image_result == 1 || !verify_code) return image_result; } image = mono_image_open (file, NULL); if (!image){ fprintf (stderr, "Cannot open image %s\n", file); exit (1); } if (dump_data) dump_dotnet_iinfo (image); if (verify_pe) { MonoAssemblyOpenRequest req; MonoAssembly *assembly; MonoImage *image; MonoImageOpenStatus status; int code_result; mono_verifier_set_mode (verifier_mode); mono_assembly_request_prepare (&req.request, sizeof (req), MONO_ASMCTX_DEFAULT); assembly = mono_assembly_request_open (file, &req, NULL); /*fake an assembly for netmodules so the verifier works*/ if (!assembly && (image = mono_image_open (file, &status)) && image->tables [MONO_TABLE_ASSEMBLY].rows == 0) { assembly = g_new0 (MonoAssembly, 1); assembly->in_gac = FALSE; assembly->image = image; image->assembly = assembly; } if (!assembly) { g_print ("Could not open assembly %s\n", file); return 4; } code_result = dump_verify_info (assembly->image, verify_flags, verifier_mode == MONO_VERIFIER_MODE_VALID); return code_result ? code_result : image_result; } else mono_image_close (image); return 0; }