X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Floader.c;h=f9b83480b52262a3647136ce9aeb5ebf96025386;hb=ef0ddf45c3081e799edcb4e95770186514b80cf1;hp=be83f8f68d3589c58e2828c4320bc5e171e913ea;hpb=4e4013721304d8da777f3137a9857e387c7cf548;p=mono.git diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index be83f8f68d3..f9b83480b52 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -17,6 +17,7 @@ * TODO: * This should keep track of the assembly versions that we are loading. * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include @@ -461,7 +462,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, MonoTableInfo *tables = image->tables; MonoType *sig_type; guint32 cols[6]; - guint32 nindex, class; + guint32 nindex, class_index; const char *fname; const char *ptr; guint32 idx = mono_metadata_token_index (token); @@ -470,16 +471,16 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE); nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS; - class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; + class_index = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]); if (!mono_verifier_verify_memberref_field_signature (image, cols [MONO_MEMBERREF_SIGNATURE], NULL)) { - mono_error_set_bad_image (error, image, "Bad field '%s' signature 0x%08x", class, token); + mono_error_set_bad_image (error, image, "Bad field '%s' signature 0x%08x", class_index, token); return NULL; } - switch (class) { + switch (class_index) { case MONO_MEMBERREF_PARENT_TYPEDEF: klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | nindex, error); break; @@ -490,7 +491,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, klass = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_SPEC | nindex, context, error); break; default: - mono_error_set_bad_image (error, image, "Bad field field '%s' signature 0x%08x", class, token); + mono_error_set_bad_image (error, image, "Bad field field '%s' signature 0x%08x", class_index, token); } if (!klass) @@ -501,21 +502,25 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, /* we may want to check the signature here... */ if (*ptr++ != 0x6) { - mono_error_set_field_load (error, klass, fname, "Bad field signature class token %08x field name %s token %08x", class, fname, token); + mono_error_set_field_load (error, klass, fname, "Bad field signature class token %08x field name %s token %08x", class_index, fname, token); return NULL; } /* FIXME: This needs a cache, especially for generic instances, since - * mono_metadata_parse_type () allocates everything from a mempool. + * we ask mono_metadata_parse_type_checked () to allocates everything from a mempool. + * FIXME part2, mono_metadata_parse_type_checked actually allows for a transient type instead. + * FIXME part3, transient types are not 100% transient, so we need to take care of that first. */ - sig_type = find_cached_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE]); + sig_type = (MonoType *)find_cached_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE]); if (!sig_type) { - sig_type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr); + MonoError inner_error; + sig_type = mono_metadata_parse_type_checked (image, NULL, 0, FALSE, ptr, &ptr, &inner_error); if (sig_type == NULL) { - mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x", fname, token); + mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x due to: %s", fname, token, mono_error_get_message (&inner_error)); + mono_error_cleanup (&inner_error); return NULL; } - sig_type = cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type); + sig_type = (MonoType *)cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type); } mono_class_init (klass); /*FIXME is this really necessary?*/ @@ -534,17 +539,14 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, /* * mono_field_from_token: * @deprecated use the _checked variant + * Notes: runtime code MUST not use this function */ MonoClassField* mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, MonoGenericContext *context) { MonoError error; MonoClassField *res = mono_field_from_token_checked (image, token, retklass, context, &error); - mono_loader_assert_no_error (); - if (!mono_error_ok (&error)) { - mono_loader_set_error_from_mono_error (&error); - mono_error_cleanup (&error); - } + g_assert (mono_error_ok (&error)); return res; } @@ -562,7 +564,7 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk MonoClass *handle_class; *retklass = NULL; - result = mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context); + result = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context); // This checks the memberref type as well if (!result || handle_class != mono_defaults.fieldhandle_class) { mono_error_set_bad_image (error, image, "Bad field token 0x%08x", token); @@ -572,7 +574,7 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk return result; } - if ((field = mono_conc_hashtable_lookup (image->field_cache, GUINT_TO_POINTER (token)))) { + if ((field = (MonoClassField *)mono_conc_hashtable_lookup (image->field_cache, GUINT_TO_POINTER (token)))) { *retklass = field->parent; return field; } @@ -682,7 +684,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con See mono/tests/generic-type-load-exception.2.il FIXME we should better report this error to the caller */ - if (!klass->methods || klass->exception_type) { + if (!klass->methods || mono_class_has_failure (klass)) { mono_error_set_type_load_class (error, klass, "Could not find method due to a type load error"); //FIXME get the error from the class return NULL; @@ -815,7 +817,7 @@ inflate_generic_signature_checked (MonoImage *image, MonoMethodSignature *sig, M if (!context) return sig; - res = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + ((gint32)sig->param_count) * sizeof (MonoType*)); + res = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + ((gint32)sig->param_count) * sizeof (MonoType*)); res->param_count = sig->param_count; res->sentinelpos = -1; res->ret = mono_class_inflate_generic_type_checked (sig->ret, context, error); @@ -871,11 +873,11 @@ mono_inflate_generic_signature (MonoMethodSignature *sig, MonoGenericContext *co } static MonoMethodHeader* -inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context) +inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context, MonoError *error) { MonoMethodHeader *res; int i; - res = g_malloc0 (MONO_SIZEOF_METHOD_HEADER + sizeof (gpointer) * header->num_locals); + res = (MonoMethodHeader *)g_malloc0 (MONO_SIZEOF_METHOD_HEADER + sizeof (gpointer) * header->num_locals); res->code = header->code; res->code_size = header->code_size; res->max_stack = header->max_stack; @@ -883,36 +885,42 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context) res->init_locals = header->init_locals; res->num_locals = header->num_locals; res->clauses = header->clauses; - for (i = 0; i < header->num_locals; ++i) - res->locals [i] = mono_class_inflate_generic_type (header->locals [i], context); + + mono_error_init (error); + + for (i = 0; i < header->num_locals; ++i) { + res->locals [i] = mono_class_inflate_generic_type_checked (header->locals [i], context, error); + if (!is_ok (error)) + goto fail; + } if (res->num_clauses) { - res->clauses = g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses); + res->clauses = (MonoExceptionClause *)g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses); for (i = 0; i < header->num_clauses; ++i) { MonoExceptionClause *clause = &res->clauses [i]; if (clause->flags != MONO_EXCEPTION_CLAUSE_NONE) continue; - clause->data.catch_class = mono_class_inflate_generic_class (clause->data.catch_class, context); + clause->data.catch_class = mono_class_inflate_generic_class_checked (clause->data.catch_class, context, error); + if (!is_ok (error)) + goto fail; } } return res; +fail: + g_free (res); + return NULL; } /* * token is the method_ref/def/spec token used in a call IL instruction. + * @deprecated use the _checked variant + * Notes: runtime code MUST not use this function */ MonoMethodSignature* mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context) { MonoError error; MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, context, &error); - - mono_loader_assert_no_error (); - - if (!res) { - g_assert (!mono_error_ok (&error)); - mono_loader_set_error_from_mono_error (&error); - mono_error_cleanup (&error); /* FIXME Don't swallow the error */ - } + mono_error_cleanup (&error); return res; } @@ -934,8 +942,10 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32 if (table == MONO_TABLE_METHODSPEC) { /* the verifier (do_invoke_method) will turn the NULL into a verifier error */ - if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated) + if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated) { + mono_error_set_bad_image (error, image, "Method is a pinvoke or open generic"); return NULL; + } return mono_method_signature_checked (method, error); } @@ -951,14 +961,14 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE); sig_idx = cols [MONO_MEMBERREF_SIGNATURE]; - sig = find_cached_memberref_sig (image, sig_idx); + sig = (MonoMethodSignature *)find_cached_memberref_sig (image, sig_idx); if (!sig) { if (!mono_verifier_verify_memberref_method_signature (image, sig_idx, NULL)) { - guint32 class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; + guint32 klass = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; const char *fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]); //FIXME include the verification error - mono_error_set_bad_image (error, image, "Bad method signature class token 0x%08x field name %s token 0x%08x", class, fname, token); + mono_error_set_bad_image (error, image, "Bad method signature class token 0x%08x field name %s token 0x%08x", klass, fname, token); return NULL; } @@ -969,14 +979,14 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32 if (!sig) return NULL; - sig = cache_memberref_sig (image, sig_idx, sig); + sig = (MonoMethodSignature *)cache_memberref_sig (image, sig_idx, sig); } /* FIXME: we probably should verify signature compat in the dynamic case too*/ if (!mono_verifier_is_sig_compatible (image, method, sig)) { - guint32 class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; + guint32 klass = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; const char *fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]); - mono_error_set_bad_image (error, image, "Incompatible method signature class token 0x%08x field name %s token 0x%08x", class, fname, token); + mono_error_set_bad_image (error, image, "Incompatible method signature class token 0x%08x field name %s token 0x%08x", klass, fname, token); return NULL; } } @@ -1001,19 +1011,17 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32 return sig; } +/* + * token is the method_ref/def/spec token used in a call IL instruction. + * @deprecated use the _checked variant + * Notes: runtime code MUST not use this function + */ MonoMethodSignature* mono_method_get_signature (MonoMethod *method, MonoImage *image, guint32 token) { MonoError error; MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, NULL, &error); - - mono_loader_assert_no_error (); - - if (!res) { - g_assert (!mono_error_ok (&error)); - mono_loader_set_error_from_mono_error (&error); - mono_error_cleanup (&error); /* FIXME Don't swallow the error */ - } + mono_error_cleanup (&error); return res; } @@ -1024,7 +1032,7 @@ mono_method_search_in_array_class (MonoClass *klass, const char *name, MonoMetho int i; mono_class_setup_methods (klass); - g_assert (!klass->exception_type); /*FIXME this should not fail, right?*/ + g_assert (!mono_class_has_failure (klass)); /*FIXME this should not fail, right?*/ for (i = 0; i < klass->method.count; ++i) { MonoMethod *method = klass->methods [i]; if (strcmp (method->name, name) == 0 && sig->param_count == method->signature->param_count) @@ -1041,7 +1049,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp MonoMethod *method = NULL; MonoTableInfo *tables = image->tables; guint32 cols[6]; - guint32 nindex, class, sig_idx; + guint32 nindex, class_index, sig_idx; const char *mname; MonoMethodSignature *sig; const char *ptr; @@ -1050,7 +1058,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, 3); nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS; - class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; + class_index = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK; /*g_print ("methodref: 0x%x 0x%x %s\n", class, nindex, mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]));*/ @@ -1062,9 +1070,9 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp * method into a cache. */ if (used_context) - *used_context = class == MONO_MEMBERREF_PARENT_TYPESPEC; + *used_context = class_index == MONO_MEMBERREF_PARENT_TYPESPEC; - switch (class) { + switch (class_index) { case MONO_MEMBERREF_PARENT_TYPEREF: klass = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | nindex, error); if (!klass) @@ -1090,7 +1098,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp return method; } default: - mono_error_set_bad_image (error, image, "Memberref parent unknown: class: %d, index %d", class, nindex); + mono_error_set_bad_image (error, image, "Memberref parent unknown: class: %d, index %d", class_index, nindex); goto fail; } @@ -1107,16 +1115,16 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp ptr = mono_metadata_blob_heap (image, sig_idx); mono_metadata_decode_blob_size (ptr, &ptr); - sig = find_cached_memberref_sig (image, sig_idx); + sig = (MonoMethodSignature *)find_cached_memberref_sig (image, sig_idx); if (!sig) { sig = mono_metadata_parse_method_signature_full (image, NULL, 0, ptr, NULL, error); if (sig == NULL) goto fail; - sig = cache_memberref_sig (image, sig_idx, sig); + sig = (MonoMethodSignature *)cache_memberref_sig (image, sig_idx, sig); } - switch (class) { + switch (class_index) { case MONO_MEMBERREF_PARENT_TYPEREF: case MONO_MEMBERREF_PARENT_TYPEDEF: method = find_method (klass, NULL, mname, sig, klass, error); @@ -1138,7 +1146,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp break; } default: - mono_error_set_bad_image (error, image,"Memberref parent unknown: class: %d, index %d", class, nindex); + mono_error_set_bad_image (error, image,"Memberref parent unknown: class: %d, index %d", class_index, nindex); goto fail; } @@ -1332,7 +1340,7 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons mono_loader_init (); if (!assembly) { - entry = g_malloc0 (sizeof (MonoDllMap)); + entry = (MonoDllMap *)g_malloc0 (sizeof (MonoDllMap)); entry->dll = dll? g_strdup (dll): NULL; entry->target = tdll? g_strdup (tdll): NULL; entry->func = func? g_strdup (func): NULL; @@ -1343,7 +1351,7 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons global_dll_map = entry; global_loader_data_unlock (); } else { - entry = mono_image_alloc0 (assembly, sizeof (MonoDllMap)); + entry = (MonoDllMap *)mono_image_alloc0 (assembly, sizeof (MonoDllMap)); entry->dll = dll? mono_image_strdup (assembly, dll): NULL; entry->target = tdll? mono_image_strdup (assembly, tdll): NULL; entry->func = func? mono_image_strdup (assembly, func): NULL; @@ -1390,7 +1398,7 @@ cached_module_load (const char *name, int flags, char **err) global_loader_data_lock (); if (!global_module_map) global_module_map = g_hash_table_new (g_str_hash, g_str_equal); - res = g_hash_table_lookup (global_module_map, name); + res = (MonoDl *)g_hash_table_lookup (global_module_map, name); if (res) { global_loader_data_unlock (); return res; @@ -1446,7 +1454,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char if (image_is_dynamic (method->klass->image)) { MonoReflectionMethodAux *method_aux = - g_hash_table_lookup ( + (MonoReflectionMethodAux *)g_hash_table_lookup ( ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method); if (!method_aux) return NULL; @@ -1477,8 +1485,8 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char image->pinvoke_scopes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); image->pinvoke_scope_filenames = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } - module = g_hash_table_lookup (image->pinvoke_scopes, new_scope); - found_name = g_hash_table_lookup (image->pinvoke_scope_filenames, new_scope); + module = (MonoDl *)g_hash_table_lookup (image->pinvoke_scopes, new_scope); + found_name = (char *)g_hash_table_lookup (image->pinvoke_scope_filenames, new_scope); mono_image_unlock (image); if (module) cached = TRUE; @@ -1866,7 +1874,7 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, if (image_is_dynamic (image)) { MonoClass *handle_class; - result = mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context); + result = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context); mono_loader_assert_no_error (); // This checks the memberref type as well @@ -1943,6 +1951,7 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, if (generic_container) { result->is_generic = TRUE; generic_container->owner.method = result; + generic_container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous /*FIXME put this before the image alloc*/ if (!mono_metadata_load_generic_param_constraints_checked (image, token, generic_container, error)) return NULL; @@ -1979,7 +1988,10 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, MonoMethod * mono_get_method (MonoImage *image, guint32 token, MonoClass *klass) { - return mono_get_method_full (image, token, klass, NULL); + MonoError error; + MonoMethod *result = mono_get_method_checked (image, token, klass, NULL, &error); + mono_error_cleanup (&error); + return result; } MonoMethod * @@ -1988,11 +2000,7 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass, { MonoError error; MonoMethod *result = mono_get_method_checked (image, token, klass, context, &error); - mono_loader_assert_no_error (); - if (!mono_error_ok (&error)) { - mono_loader_set_error_from_mono_error (&error); - mono_error_cleanup (&error); - } + mono_error_cleanup (&error); return result; } @@ -2011,11 +2019,11 @@ mono_get_method_checked (MonoImage *image, guint32 token, MonoClass *klass, Mono if (mono_metadata_token_table (token) == MONO_TABLE_METHOD) { if (!image->method_cache) image->method_cache = g_hash_table_new (NULL, NULL); - result = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token))); + result = (MonoMethod *)g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token))); } else if (!image_is_dynamic (image)) { if (!image->methodref_cache) image->methodref_cache = g_hash_table_new (NULL, NULL); - result = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token)); + result = (MonoMethod *)g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token)); } mono_image_unlock (image); @@ -2032,9 +2040,9 @@ mono_get_method_checked (MonoImage *image, guint32 token, MonoClass *klass, Mono MonoMethod *result2 = NULL; if (mono_metadata_token_table (token) == MONO_TABLE_METHOD) - result2 = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token))); + result2 = (MonoMethod *)g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token))); else if (!image_is_dynamic (image)) - result2 = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token)); + result2 = (MonoMethod *)g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token)); if (result2) { mono_image_unlock (image); @@ -2135,12 +2143,7 @@ mono_get_method_constrained (MonoImage *image, guint32 token, MonoClass *constra { MonoError error; MonoMethod *result = mono_get_method_constrained_checked (image, token, constrained_class, context, cil_method, &error); - - mono_loader_assert_no_error (); - if (!mono_error_ok (&error)) { - mono_loader_set_error_from_mono_error (&error); - mono_error_cleanup (&error); - } + mono_error_cleanup (&error); return result; } @@ -2230,7 +2233,7 @@ mono_method_get_param_names (MonoMethod *method, const char **names) if (image_is_dynamic (klass->image)) { MonoReflectionMethodAux *method_aux = - g_hash_table_lookup ( + (MonoReflectionMethodAux *)g_hash_table_lookup ( ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method); if (method_aux && method_aux->param_names) { for (i = 0; i < mono_method_signature (method)->param_count; ++i) @@ -2245,7 +2248,7 @@ mono_method_get_param_names (MonoMethod *method, const char **names) mono_image_lock (klass->image); if (klass->image->wrapper_param_names) - pnames = g_hash_table_lookup (klass->image->wrapper_param_names, method); + pnames = (char **)g_hash_table_lookup (klass->image->wrapper_param_names, method); mono_image_unlock (klass->image); if (pnames) { @@ -2321,7 +2324,7 @@ mono_method_get_marshal_info (MonoMethod *method, MonoMarshalSpec **mspecs) if (image_is_dynamic (method->klass->image)) { MonoReflectionMethodAux *method_aux = - g_hash_table_lookup ( + (MonoReflectionMethodAux *)g_hash_table_lookup ( ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method); if (method_aux && method_aux->param_marshall) { MonoMarshalSpec **dyn_specs = method_aux->param_marshall; @@ -2376,7 +2379,7 @@ mono_method_has_marshal_info (MonoMethod *method) if (image_is_dynamic (method->klass->image)) { MonoReflectionMethodAux *method_aux = - g_hash_table_lookup ( + (MonoReflectionMethodAux *)g_hash_table_lookup ( ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method); MonoMarshalSpec **dyn_specs = method_aux->param_marshall; if (dyn_specs) { @@ -2421,7 +2424,7 @@ mono_method_get_wrapper_data (MonoMethod *method, guint32 id) if (method->is_inflated) method = ((MonoMethodInflated *) method)->declaring; - data = ((MonoMethodWrapper *)method)->method_data; + data = (void **)((MonoMethodWrapper *)method)->method_data; g_assert (data != NULL); g_assert (id <= GPOINTER_TO_UINT (*data)); return data [id]; @@ -2435,7 +2438,7 @@ typedef struct { static gboolean stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data) { - StackWalkUserData *d = data; + StackWalkUserData *d = (StackWalkUserData *)data; switch (frame->type) { case FRAME_TYPE_DEBUGGER_INVOKE: @@ -2475,7 +2478,7 @@ typedef struct { static gboolean async_stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data) { - AsyncStackWalkUserData *d = data; + AsyncStackWalkUserData *d = (AsyncStackWalkUserData *)data; switch (frame->type) { case FRAME_TYPE_DEBUGGER_INVOKE: @@ -2516,7 +2519,7 @@ mono_stack_walk_async_safe (MonoStackWalkAsyncSafe func, void *initial_sig_conte static gboolean last_managed (MonoMethod *m, gint no, gint ilo, gboolean managed, gpointer data) { - MonoMethod **dest = data; + MonoMethod **dest = (MonoMethod **)data; *dest = m; /*g_print ("In %s::%s [%d] [%d]\n", m->klass->name, m->name, no, ilo);*/ @@ -2669,7 +2672,7 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) if (can_cache_signature) { mono_image_lock (img); - signature = g_hash_table_lookup (img->method_signatures, sig); + signature = (MonoMethodSignature *)g_hash_table_lookup (img->method_signatures, sig); mono_image_unlock (img); } @@ -2687,7 +2690,7 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) if (can_cache_signature) { mono_image_lock (img); - sig2 = g_hash_table_lookup (img->method_signatures, sig); + sig2 = (MonoMethodSignature *)g_hash_table_lookup (img->method_signatures, sig); if (!sig2) g_hash_table_insert (img->method_signatures, (gpointer)sig, signature); mono_image_unlock (img); @@ -2713,7 +2716,7 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) signature->pinvoke = 1; else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) { - MonoCallConvention conv = 0; + MonoCallConvention conv = (MonoCallConvention)0; MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)m; signature->pinvoke = 1; @@ -2795,30 +2798,35 @@ mono_method_get_token (MonoMethod *method) } MonoMethodHeader* -mono_method_get_header (MonoMethod *method) +mono_method_get_header_checked (MonoMethod *method, MonoError *error) { int idx; guint32 rva; MonoImage* img; gpointer loc; - MonoMethodHeader *header; MonoGenericContainer *container; - if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) - return NULL; - + mono_error_init (error); img = method->klass->image; + if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) { + mono_error_set_bad_image (error, img, "Method has no body"); + return NULL; + } + if (method->is_inflated) { MonoMethodInflated *imethod = (MonoMethodInflated *) method; MonoMethodHeader *header, *iheader; - header = mono_method_get_header (imethod->declaring); + header = mono_method_get_header_checked (imethod->declaring, error); if (!header) return NULL; - iheader = inflate_generic_header (header, mono_method_get_context (method)); + iheader = inflate_generic_header (header, mono_method_get_context (method), error); mono_metadata_free_mh (header); + if (!iheader) { + return NULL; + } mono_image_lock (img); @@ -2850,12 +2858,16 @@ mono_method_get_header (MonoMethod *method) idx = mono_metadata_token_index (method->token); rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA); - if (!mono_verifier_verify_method_header (img, rva, NULL)) + if (!mono_verifier_verify_method_header (img, rva, NULL)) { + mono_error_set_bad_image (error, img, "Invalid method header, failed verification"); return NULL; + } loc = mono_image_rva_map (img, rva); - if (!loc) + if (!loc) { + mono_error_set_bad_image (error, img, "Method has zero rva"); return NULL; + } /* * When parsing the types of local variables, we must pass any container available @@ -2864,11 +2876,19 @@ mono_method_get_header (MonoMethod *method) container = mono_method_get_generic_container (method); if (!container) container = method->klass->generic_container; - header = mono_metadata_parse_mh_full (img, container, loc); + return mono_metadata_parse_mh_full (img, container, (const char *)loc, error); +} +MonoMethodHeader* +mono_method_get_header (MonoMethod *method) +{ + MonoError error; + MonoMethodHeader *header = mono_method_get_header_checked (method, &error); + mono_error_cleanup (&error); return header; } + guint32 mono_method_get_flags (MonoMethod *method, guint32 *iflags) { @@ -2894,7 +2914,7 @@ mono_method_get_index (MonoMethod *method) return mono_metadata_token_index (method->token); mono_class_setup_methods (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) return 0; for (i = 0; i < klass->method.count; ++i) { if (method == klass->methods [i]) {