static void process_image (MonoImage *image, gboolean all) { int i; const MonoTableInfo *t; MonoClass *klass; MonoMethod *entry; guint32 eptoken; if (verbose) g_print ("#processing image: %s\n", mono_image_get_name (image)); eptoken = mono_image_get_entry_point (image); if (eptoken) { entry = mono_get_method (image, eptoken, NULL); add_types_from_method (entry); } /* we always add the <Module> type */ klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1); handle_type (klass, all? TYPE_ALL: TYPE_BASIC); if (all) { t = mono_image_get_table_info (image, MONO_TABLE_TYPEDEF); for (i = 1; i < mono_table_info_get_rows (t); ++i) { klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | (i + 1)); handle_type (klass, all? TYPE_ALL: TYPE_BASIC); } } }
int mini_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv) { MainThreadArgs main_args; MonoImage *image; MonoMethod *main_method; /* * Get and compile the main function. */ image = mono_assembly_get_image (assembly); main_method = mono_get_method (image, mono_image_get_entry_point (image), NULL); /* * Initialize managed code. */ mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, (guint64) (gssize) main_method, 0); /* * Start the main thread and wait until it's ready. */ main_args.domain = domain; main_args.method = main_method; main_args.argc = argc; main_args.argv = argv; #if RUN_IN_SUBTHREAD mono_thread_create (domain, main_thread_handler, &main_args); #else main_thread_handler (&main_args); #endif mono_thread_manage (); /* * This will never return. */ mono_debugger_event (MONO_DEBUGGER_EVENT_WRAPPER_MAIN, 0, 0); return 0; }
MonoMethod* mono_method_desc_search_in_image (MonoMethodDesc *desc, MonoImage *image) { MonoClass *klass; const MonoTableInfo *methods; MonoMethod *method; int i; /* Handle short names for system classes */ if (!desc->name_space && image == mono_defaults.corlib) { klass = find_system_class (desc->klass); if (klass) return mono_method_desc_search_in_class (desc, klass); } if (desc->name_space && desc->klass) { klass = mono_class_from_name (image, desc->name_space, desc->klass); if (!klass) return NULL; return mono_method_desc_search_in_class (desc, klass); } /* FIXME: Is this call necessary? We don't use its result. */ mono_image_get_table_info (image, MONO_TABLE_TYPEDEF); methods = mono_image_get_table_info (image, MONO_TABLE_METHOD); for (i = 0; i < mono_table_info_get_rows (methods); ++i) { guint32 token = mono_metadata_decode_row_col (methods, i, MONO_METHOD_NAME); const char *n = mono_metadata_string_heap (image, token); if (strcmp (n, desc->name)) continue; method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL); if (mono_method_desc_full_match (desc, method)) return method; } return NULL; }
/* Called by ntdll.dll reagardless of entry point after _CorValidateImage. */ __int32 STDMETHODCALLTYPE _CorExeMain(void) { MonoDomain* domain; MonoAssembly* assembly; MonoImage* image; MonoMethod* method; guint32 entry; gchar* file_name; gchar* error; int argc; gunichar2** argvw; gchar** argv; int i; file_name = mono_get_module_file_name (NULL); init_from_coree = TRUE; domain = mono_runtime_load (file_name, NULL); error = (gchar*) mono_check_corlib_version (); if (error) { g_free (error); g_free (file_name); MessageBox (NULL, L"Corlib not in sync with this runtime.", NULL, MB_ICONERROR); mono_runtime_quit (); ExitProcess (1); } assembly = mono_assembly_open (file_name, NULL); mono_close_exe_image (); if (!assembly) { g_free (file_name); MessageBox (NULL, L"Cannot open assembly.", NULL, MB_ICONERROR); mono_runtime_quit (); ExitProcess (1); } image = assembly->image; entry = mono_image_get_entry_point (image); if (!entry) { g_free (file_name); MessageBox (NULL, L"Assembly doesn't have an entry point.", NULL, MB_ICONERROR); mono_runtime_quit (); ExitProcess (1); } method = mono_get_method (image, entry, NULL); if (method == NULL) { g_free (file_name); MessageBox (NULL, L"The entry point method could not be loaded.", NULL, MB_ICONERROR); mono_runtime_quit (); ExitProcess (1); } argvw = CommandLineToArgvW (GetCommandLine (), &argc); argv = g_new0 (gchar*, argc); argv [0] = file_name; for (i = 1; i < argc; ++i) argv [i] = g_utf16_to_utf8 (argvw [i], -1, NULL, NULL, NULL); LocalFree (argvw); mono_runtime_run_main (method, argc, argv, NULL); mono_thread_manage (); mono_runtime_quit (); /* return does not terminate the process. */ ExitProcess (mono_environment_exitcode_get ()); }
static void add_types_from_method (MonoMethod *method) { const MonoOpcode *opcode; MonoMethodHeader *header; const unsigned char *ip, *il_code_end; gpointer val = NULL, oldkey = NULL; int i, n; guint32 token; MonoClass *klass; MonoClassField *field; MonoCustomAttrInfo* cattrs; MonoType** locals; gpointer exc_iter; MonoExceptionClause clause; if (g_hash_table_lookup_extended (method_table, method, &oldkey, &val)) return; g_hash_table_insert (method_table, method, NULL); g_assert (method->klass); if (verbose > 1) g_print ("#processing method: %s\n", mono_method_full_name (method, TRUE)); mono_class_init (method->klass); cattrs = mono_custom_attrs_from_method (method); handle_cattrs (cattrs); add_type (method->klass); add_types_from_signature (mono_method_signature (method)); for (i = 0; i < mono_method_signature (method)->param_count + 1; ++i) { cattrs = mono_custom_attrs_from_param (method, i); handle_cattrs (cattrs); } if (method->flags & METHOD_ATTRIBUTE_VIRTUAL) virtual_methods = g_list_prepend (virtual_methods, method); /* if no IL code to parse, return */ if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) return; if (method->flags & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT)) return; header = mono_method_get_header (method); locals = mono_method_header_get_locals (header, &n, NULL); for (i = 0; i < n; ++i) { klass = mono_class_from_mono_type (locals [i]); add_type (klass); } for (exc_iter = NULL; mono_method_header_get_clauses (header, method, &exc_iter, &clause);) { if (clause.flags == MONO_EXCEPTION_CLAUSE_NONE) add_type (clause.data.catch_class); } ip = mono_method_header_get_code (header, &n, NULL); il_code_end = ip + n; while (ip < il_code_end) { if (verbose > 2) g_print ("#%s", mono_disasm_code_one (NULL, method, ip, NULL)); if (*ip == 0xfe) { ++ip; i = *ip + 256; } else { i = *ip; } opcode = &mono_opcodes [i]; switch (opcode->argument) { case MonoInlineNone: ip++; break; case MonoInlineType: token = read32 (ip + 1); add_type (mono_class_get (method->klass->image, token)); ip += 5; break; case MonoInlineField: { token = read32 (ip + 1); field = mono_field_from_token (method->klass->image, token, &klass, NULL); add_field (field); add_type (klass); ip += 5; break; } case MonoInlineTok: case MonoInlineSig: /* FIXME */ case MonoInlineString: case MonoShortInlineR: case MonoInlineBrTarget: case MonoInlineI: ip += 5; break; case MonoInlineVar: ip += 3; break; case MonoShortInlineVar: case MonoShortInlineI: case MonoShortInlineBrTarget: ip += 2; break; case MonoInlineSwitch: ++ip; n = read32 (ip); ip += 4; ip += 4 * n; break; case MonoInlineI8: case MonoInlineR: ip += 9; break; case MonoInlineMethod: { MonoMethod *cm = mono_get_method (method->klass->image, read32 (ip + 1), NULL); add_type (cm->klass); add_types_from_method (cm); } ip += 5; break; default: g_assert_not_reached (); } } }