static void check_vmethods (MonoClass *klass, MonoMethod *method) { MonoMethod **vtable; if (method->klass == klass) return; mono_class_init (klass); mono_class_init (method->klass); vtable = klass->vtable; /* iface */ if (!vtable) return; if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { if (MONO_CLASS_IMPLEMENTS_INTERFACE (klass, method->klass->interface_id)) { int iface_offset = mono_class_interface_offset (klass, method->klass); g_assert (method->slot != -1); if (vtable [iface_offset + method->slot]) add_types_from_method (vtable [iface_offset + method->slot]); } } else { if (mono_class_has_parent (klass, method->klass)) { g_assert (method->slot != -1); if (vtable [method->slot]) add_types_from_method (vtable [method->slot]); } } }
/** * mono_get_exception_type_initialization: * @type_name: the name of the type that failed to initialize. * @inner: the inner exception. * * Returns: a new instance of the System.TypeInitializationException */ MonoException * mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner) { MonoClass *klass; gpointer args [2]; MonoObject *exc; MonoMethod *method; gpointer iter; klass = mono_class_from_name (mono_get_corlib (), "System", "TypeInitializationException"); g_assert (klass); mono_class_init (klass); /* TypeInitializationException only has 1 ctor with 2 args */ iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method)) && mono_method_signature (method)->param_count == 2) break; method = NULL; } g_assert (method); args [0] = mono_string_new (mono_domain_get (), type_name); args [1] = inner; exc = mono_object_new (mono_domain_get (), klass); mono_runtime_invoke (method, exc, args, NULL); return (MonoException *) exc; }
static inline void print_report (const gchar *format, ...) { MonoError error; MonoClass *klass; MonoProperty *prop; MonoString *str; char *stack_trace; va_list ap; fprintf (stdout, "-=-=-=-=-=-=- MONO_IOMAP REPORT -=-=-=-=-=-=-\n"); va_start (ap, format); vfprintf (stdout, format, ap); fprintf (stdout, "\n"); va_end (ap); klass = mono_class_load_from_name (mono_get_corlib (), "System", "Environment"); mono_class_init (klass); prop = mono_class_get_property_from_name (klass, "StackTrace"); str = (MonoString*)mono_property_get_value_checked (prop, NULL, NULL, &error); mono_error_assert_ok (&error); stack_trace = mono_string_to_utf8_checked (str, &error); mono_error_assert_ok (&error); fprintf (stdout, "-= Stack Trace =-\n%s\n\n", stack_trace); g_free (stack_trace); fflush (stdout); }
static gint64 debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2, gchar *full_name) { MonoImage *image = (MonoImage *) GUINT_TO_POINTER ((gsize) image_argument); gchar *name_space, *name, *pos; MonoClass *klass; pos = strrchr (full_name, '.'); if (pos) { name_space = full_name; *pos = 0; name = pos + 1; } else { name = full_name; name_space = NULL; } klass = mono_class_from_name (image, name_space ? name_space : "", name); if (!klass) return -1; mono_class_init (klass); mono_class_setup_methods (klass); return (gint64) (gssize) klass; }
static void handle_type (MonoClass *klass, guint32 flags) { int i; guint32 missing; MonoCustomAttrInfo* cattrs; gpointer val = NULL, oldkey = NULL; MonoProperty* prop; MonoEvent* event; MonoMethod* method; MonoClassField* field; gpointer iter; if (g_hash_table_lookup_extended (type_table, klass, &oldkey, &val)) { missing = flags & ~(GPOINTER_TO_UINT (val)); } else { missing = flags; } if (!missing) return; g_hash_table_insert (type_table, klass, GUINT_TO_POINTER (missing)); if (verbose) g_print ("#processing klass: %s.%s\n", klass->name_space, klass->name); mono_class_init (klass); if (klass->parent) add_type (klass->parent); if (klass->nested_in) add_type (klass->nested_in); iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if ((missing & TYPE_METHODS) || strcmp (method->name, ".cctor") == 0) add_types_from_method (method); } if (klass->enumtype) { add_field (mono_class_get_field_from_name (klass, "value__")); } if (force_enums || (missing & TYPE_FIELDS)) { iter = NULL; while ((field = mono_class_get_fields (klass, &iter))) add_field (field); } iter = NULL; while ((prop = mono_class_get_properties (klass, &iter))) { cattrs = mono_custom_attrs_from_property (klass, prop); handle_cattrs (cattrs); } iter = NULL; while ((event = mono_class_get_events (klass, &iter))) { cattrs = mono_custom_attrs_from_event (klass, event); handle_cattrs (cattrs); } for (i = 0; i < klass->interface_count; ++i) add_type (klass->interfaces [i]); cattrs = mono_custom_attrs_from_class (klass); handle_cattrs (cattrs); }
MonoSecurityManager* mono_security_manager_get_methods (void) { /* Already initialized ? */ if (secman.securitymanager) return &secman; /* Initialize */ secman.securitymanager = mono_class_get_security_manager_class (); if (!secman.securitymanager->inited) mono_class_init (secman.securitymanager); return &secman; }
/* * Context propagation is required when: * (a) the security manager is active (1.x and later) * (b) other contexts needs to be propagated (2.x and later) * * returns NULL if no context propagation is required, else the returns the * MonoMethod to call to Capture the ExecutionContext. */ MonoMethod* mono_get_context_capture_method (void) { static MonoMethod *method = NULL; if (mono_image_get_assembly (mono_defaults.corlib)->aname.major < 2) return NULL; /* older corlib revisions won't have the class (nor the method) */ MonoClass *execution_context = mono_class_try_get_execution_context_class (); if (execution_context && !method) { mono_class_init (execution_context); method = mono_class_get_method_from_name (execution_context, "Capture", 0); } return method; }
void mono_debug_open_method (MonoCompile *cfg) { MiniDebugMethodInfo *info; MonoDebugMethodJitInfo *jit; MonoMethodHeader *header; info = (MiniDebugMethodInfo *) cfg->debug_info; if (!info) return; mono_class_init (cfg->method->klass); header = cfg->header; g_assert (header); info->jit = jit = g_new0 (MonoDebugMethodJitInfo, 1); info->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry)); jit->num_locals = header->num_locals; jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals); }
/** * mono_get_exception_reflection_type_load: * @types: an array of types that were defined in the moduled loaded. * @exceptions: an array of exceptions that were thrown during the type loading. * * Returns: a new instance of the `System.Reflection.ReflectionTypeLoadException` */ MonoException * mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions) { MonoError error; MonoClass *klass; gpointer args [2]; MonoObject *exc; MonoMethod *method; gpointer iter; klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException"); mono_class_init (klass); /* Find the Type[], Exception[] ctor */ iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method))) { MonoMethodSignature *sig = mono_method_signature (method); if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY) break; } method = NULL; } g_assert (method); args [0] = types; args [1] = exceptions; exc = mono_object_new_checked (mono_domain_get (), klass, &error); mono_error_assert_ok (&error); mono_runtime_invoke_checked (method, exc, args, &error); mono_error_raise_exception (&error); /* FIXME don't raise here */ return (MonoException *) exc; }
/** * mono_get_exception_reflection_type_load: * @types: an array of types that were defined in the moduled loaded. * @exceptions: an array of exceptions that were thrown during the type loading. * * Returns: a new instance of the System.Reflection.ReflectionTypeLoadException */ MonoException * mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions) { MonoClass *klass; gpointer args [2]; MonoObject *exc; MonoMethod *method; klass = mono_class_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException"); g_assert (klass); mono_class_init (klass); method = mono_class_get_method_from_name (klass, ".ctor", 2); g_assert (method); args [0] = types; args [1] = exceptions; exc = mono_object_new (mono_domain_get (), klass); mono_runtime_invoke (method, exc, args, NULL); return (MonoException *) exc; }
/** * mono_get_exception_type_initialization: * @type_name: the name of the type that failed to initialize. * @inner: the inner exception. * * Returns: a new instance of the `System.TypeInitializationException` */ MonoException * mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner) { MonoError error; MonoClass *klass; gpointer args [2]; MonoObject *exc; MonoMethod *method; gpointer iter; klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException"); mono_class_init (klass); iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method))) { MonoMethodSignature *sig = mono_method_signature (method); if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type (sig->params [1]) == mono_defaults.exception_class) break; } method = NULL; } g_assert (method); args [0] = mono_string_new (mono_domain_get (), type_name); args [1] = inner; exc = mono_object_new_checked (mono_domain_get (), klass, &error); mono_error_assert_ok (&error); mono_runtime_invoke_checked (method, exc, args, &error); mono_error_raise_exception (&error); /* FIXME don't raise here */ return (MonoException *) exc; }
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 (); } } }
static int verify_image_file (const char *fname) { GSList *errors = NULL, *tmp; MonoImage *image; MonoTableInfo *table; MonoAssembly *assembly; MonoImageOpenStatus status; int i, count = 0; const char* desc [] = { "Ok", "Error", "Warning", NULL, "CLS", NULL, NULL, NULL, "Not Verifiable" }; image = mono_image_open_raw (fname, &status); if (!image) { printf ("Could not open %s\n", fname); return 1; } if (!mono_verifier_verify_pe_data (image, &errors)) goto invalid_image; if (!mono_image_load_pe_data (image)) { printf ("Could not load pe data for assembly %s\n", fname); return 1; } if (!mono_verifier_verify_cli_data (image, &errors)) goto invalid_image; if (!mono_image_load_cli_data (image)) { printf ("Could not load cli data for assembly %s\n", fname); return 1; } if (!mono_verifier_verify_table_data (image, &errors)) goto invalid_image; mono_image_load_names (image); /*fake an assembly for class loading to work*/ assembly = g_new0 (MonoAssembly, 1); assembly->in_gac = FALSE; assembly->image = image; image->assembly = assembly; mono_assembly_fill_assembly_name (image, &assembly->aname); /*Finish initializing the runtime*/ mono_install_assembly_load_hook (pedump_assembly_load_hook, NULL); mono_install_assembly_search_hook (pedump_assembly_search_hook, NULL); mono_init_version ("pedump", image->version); mono_install_assembly_preload_hook (pedump_preload, GUINT_TO_POINTER (FALSE)); mono_icall_init (); mono_marshal_init (); if (!verify_partial_md && !mono_verifier_verify_full_table_data (image, &errors)) goto invalid_image; table = &image->tables [MONO_TABLE_TYPEDEF]; for (i = 1; i <= table->rows; ++i) { MonoError error; guint32 token = i | MONO_TOKEN_TYPE_DEF; MonoClass *klass = mono_class_get_checked (image, token, &error); if (!klass) { printf ("Could not load class with token %x due to %s\n", token, mono_error_get_message (&error)); mono_error_cleanup (&error); continue; } mono_class_init (klass); if (mono_class_has_failure (klass)) { printf ("Error verifying class(0x%08x) %s.%s a type load error happened\n", token, klass->name_space, klass->name); ++count; } mono_class_setup_vtable (klass); if (mono_class_has_failure (klass)) { printf ("Error verifying class(0x%08x) %s.%s a type load error happened\n", token, klass->name_space, klass->name); ++count; } } if (count) return 5; return 0; invalid_image: for (tmp = errors; tmp; tmp = tmp->next) { MonoVerifyInfo *info = (MonoVerifyInfo *)tmp->data; g_print ("%s: %s\n", desc [info->status], info->message); if (info->status == MONO_VERIFY_ERROR) count++; } mono_free_verify_list (errors); if (count) g_print ("Error count: %d\n", count); return 1; }