X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmetadata.c;h=da6ba91e1ac6b1d2872880dcba685d83be84ab60;hb=87f4f81d52ee965d3a242517300cf74e0c3810b8;hp=4f1cfaf04154bc596df2b0c9703b7516a08239ec;hpb=0717f141b92db56481cc09af70c026d7ffad8921;p=mono.git diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index 4f1cfaf0415..da6ba91e1ac 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -10,9 +10,6 @@ */ #include -#ifdef HAVE_ALLOCA_H -#include -#endif #include #include #include @@ -27,7 +24,7 @@ #include "verify-internals.h" #include "class.h" #include "marshal.h" -#include "gc-internal.h" +#include "debug-helpers.h" #include /* Auxiliary structure used for caching inflated signatures */ @@ -36,7 +33,7 @@ typedef struct { MonoGenericContext context; } MonoInflatedMethodSignature; -static gboolean do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container, +static gboolean do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container, gboolean transient, const char *ptr, const char **rptr); static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only); @@ -44,9 +41,7 @@ static gboolean mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolea static gboolean mono_metadata_fnptr_equal (MonoMethodSignature *s1, MonoMethodSignature *s2, gboolean signature_only); static gboolean _mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2, gboolean signature_only); -static GSList* free_generic_inst_dependents (MonoGenericInst *ginst); static void free_generic_inst (MonoGenericInst *ginst); -static GSList* free_generic_class_dependents (MonoGenericClass *ginst); static void free_generic_class (MonoGenericClass *ginst); static void free_inflated_method (MonoMethodInflated *method); static void free_inflated_signature (MonoInflatedMethodSignature *sig); @@ -963,6 +958,7 @@ mono_metadata_decode_row (const MonoTableInfo *t, int idx, guint32 *res, int res const char *data; g_assert (idx < t->rows); + g_assert (idx >= 0); data = t->base + idx * t->row_size; g_assert (res_size == count); @@ -1245,27 +1241,29 @@ mono_metadata_parse_custom_mod (MonoImage *m, MonoCustomMod *dest, const char *p } /* - * mono_metadata_parse_array_full: + * mono_metadata_parse_array_internal: * @m: a metadata context. + * @transient: whenever to allocate data from the heap * @ptr: a pointer to an encoded array description. * @rptr: pointer updated to match the end of the decoded stream * * Decodes the compressed array description found in the metadata @m at @ptr. * * Returns: a #MonoArrayType structure describing the array type - * and dimensions. Memory is allocated from the image mempool. + * and dimensions. Memory is allocated from the heap or from the image mempool, depending + * on the value of @transient. * * LOCKING: Acquires the loader lock */ -MonoArrayType * -mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, - const char *ptr, const char **rptr) +static MonoArrayType * +mono_metadata_parse_array_internal (MonoImage *m, MonoGenericContainer *container, + gboolean transient, const char *ptr, const char **rptr) { int i; MonoArrayType *array; MonoType *etype; - array = mono_image_alloc0 (m, sizeof (MonoArrayType)); + array = transient ? g_malloc0 (sizeof (MonoArrayType)) : mono_image_alloc0 (m, sizeof (MonoArrayType)); etype = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, ptr, &ptr); if (!etype) return NULL; @@ -1274,13 +1272,13 @@ mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, array->numsizes = mono_metadata_decode_value (ptr, &ptr); if (array->numsizes) - array->sizes = mono_image_alloc0 (m, sizeof (int) * array->numsizes); + array->sizes = transient ? g_malloc0 (sizeof (int) * array->numsizes) : mono_image_alloc0 (m, sizeof (int) * array->numsizes); for (i = 0; i < array->numsizes; ++i) array->sizes [i] = mono_metadata_decode_value (ptr, &ptr); array->numlobounds = mono_metadata_decode_value (ptr, &ptr); if (array->numlobounds) - array->lobounds = mono_image_alloc0 (m, sizeof (int) * array->numlobounds); + array->lobounds = transient ? g_malloc0 (sizeof (int) * array->numlobounds) : mono_image_alloc0 (m, sizeof (int) * array->numlobounds); for (i = 0; i < array->numlobounds; ++i) array->lobounds [i] = mono_metadata_decode_signed_value (ptr, &ptr); @@ -1289,6 +1287,13 @@ mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, return array; } +MonoArrayType * +mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, + const char *ptr, const char **rptr) +{ + return mono_metadata_parse_array_internal (m, container, FALSE, ptr, rptr); +} + MonoArrayType * mono_metadata_parse_array (MonoImage *m, const char *ptr, const char **rptr) { @@ -1362,6 +1367,9 @@ builtin_types[] = { static GHashTable *type_cache = NULL; static int next_generic_inst_id = 0; +static MonoImageSet *mscorlib_image_set; +static GPtrArray *image_sets; + static guint mono_generic_class_hash (gconstpointer data); /* @@ -1486,6 +1494,8 @@ mono_metadata_cleanup (void) { g_hash_table_destroy (type_cache); type_cache = NULL; + g_ptr_array_free (image_sets, TRUE); + image_sets = NULL; } /** @@ -1495,6 +1505,7 @@ mono_metadata_cleanup (void) * @opt_attrs: optional attributes to store in the returned type * @ptr: pointer to the type representation * @rptr: pointer updated to match the end of the decoded stream + * @transient: whenever to allocate the result from the heap or from a mempool * * Decode a compressed type description found at @ptr in @m. * @mode can be one of MONO_PARSE_MOD_TYPE, MONO_PARSE_PARAM, MONO_PARSE_RET, @@ -1507,15 +1518,14 @@ mono_metadata_cleanup (void) * (stored in image->property_hash) generic container. * When we encounter any MONO_TYPE_VAR or MONO_TYPE_MVAR's, they're looked up in * this MonoGenericContainer. - * This is a Mono runtime internal function. * * LOCKING: Acquires the loader lock. * * Returns: a #MonoType structure representing the decoded type. */ -MonoType* -mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, MonoParseTypeMode mode, - short opt_attrs, const char *ptr, const char **rptr) +static MonoType* +mono_metadata_parse_type_internal (MonoImage *m, MonoGenericContainer *container, MonoParseTypeMode mode, + short opt_attrs, gboolean transient, const char *ptr, const char **rptr) { MonoType *type, *cached; MonoType stype; @@ -1557,7 +1567,10 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo } if (count) { - type = mono_image_alloc0 (m, MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod)); + int size; + + size = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod); + type = transient ? g_malloc0 (size) : mono_image_alloc0 (m, size); type->num_mods = count; if (count > 64) g_warning ("got more than 64 modifiers in type"); @@ -1593,14 +1606,14 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo type->byref = byref; type->pinned = pinned ? 1 : 0; - if (!do_mono_metadata_parse_type (type, m, container, ptr, &ptr)) { + if (!do_mono_metadata_parse_type (type, m, container, transient, ptr, &ptr)) { return NULL; } if (rptr) *rptr = ptr; - if (!type->num_mods) { + if (!type->num_mods && !transient) { /* no need to free type here, because it is on the stack */ if ((type->type == MONO_TYPE_CLASS || type->type == MONO_TYPE_VALUETYPE) && !type->pinned && !type->attrs) { MonoType *ret = type->byref ? &type->data.klass->this_arg : &type->data.klass->byval_arg; @@ -1636,12 +1649,19 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo /* printf ("%x %x %c %s\n", type->attrs, type->num_mods, type->pinned ? 'p' : ' ', mono_type_full_name (type)); */ if (type == &stype) { - type = mono_image_alloc (m, MONO_SIZEOF_TYPE); + type = transient ? g_malloc (MONO_SIZEOF_TYPE) : mono_image_alloc (m, MONO_SIZEOF_TYPE); memcpy (type, &stype, MONO_SIZEOF_TYPE); } return type; } +MonoType* +mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, MonoParseTypeMode mode, + short opt_attrs, const char *ptr, const char **rptr) +{ + return mono_metadata_parse_type_internal (m, container, mode, opt_attrs, FALSE, ptr, rptr); +} + /* * LOCKING: Acquires the loader lock. */ @@ -2158,9 +2178,6 @@ retry: } } -static MonoImageSet *mscorlib_image_set; -static GPtrArray *image_sets; - /* * get_image_set: * @@ -2257,6 +2274,60 @@ delete_image_set (MonoImageSet *set) g_free (set); } +static void +mono_image_set_lock (MonoImageSet *set) +{ + EnterCriticalSection (&set->lock); +} + +static void +mono_image_set_unlock (MonoImageSet *set) +{ + LeaveCriticalSection (&set->lock); +} + +gpointer +mono_image_set_alloc (MonoImageSet *set, guint size) +{ + gpointer res; + + mono_image_set_lock (set); + if (!set->mempool) + set->mempool = mono_mempool_new_size (1024); + res = mono_mempool_alloc (set->mempool, size); + mono_image_set_unlock (set); + + return res; +} + +gpointer +mono_image_set_alloc0 (MonoImageSet *set, guint size) +{ + gpointer res; + + mono_image_set_lock (set); + if (!set->mempool) + set->mempool = mono_mempool_new_size (1024); + res = mono_mempool_alloc0 (set->mempool, size); + mono_image_set_unlock (set); + + return res; +} + +char* +mono_image_set_strdup (MonoImageSet *set, const char *s) +{ + char *res; + + mono_image_set_lock (set); + if (!set->mempool) + set->mempool = mono_mempool_new_size (1024); + res = mono_mempool_strdup (set->mempool, s); + mono_image_set_unlock (set); + + return res; +} + /* * Structure used by the collect_..._images functions to store the image list. */ @@ -2540,7 +2611,10 @@ mono_metadata_clean_for_image (MonoImage *image) //check_image_sets (image); - /* The data structures could reference each other so we delete them in two phases */ + /* + * The data structures could reference each other so we delete them in two phases. + * This is required because of the hashing functions in gclass/ginst_cache. + */ ginst_data.image = gclass_data.image = image; ginst_data.list = gclass_data.list = NULL; mono_loader_lock (); @@ -2558,9 +2632,9 @@ mono_metadata_clean_for_image (MonoImage *image) /* Delete the removed items */ for (l = ginst_data.list; l; l = l->next) - free_list = g_slist_concat (free_generic_inst_dependents (l->data), free_list); + free_generic_inst (l->data); for (l = gclass_data.list; l; l = l->next) - free_list = g_slist_concat (free_generic_class_dependents (l->data), free_list); + free_generic_class (l->data); g_slist_free (ginst_data.list); g_slist_free (gclass_data.list); /* delete_image_set () modifies the lists so make a copy */ @@ -2604,74 +2678,23 @@ free_inflated_method (MonoMethodInflated *imethod) } static void -free_list_with_data (GSList *l) -{ - while (l) { - g_free (l->data); - l = g_slist_delete_link (l, l); - } -} - -static GSList* -free_generic_inst_dependents (MonoGenericInst *ginst) +free_generic_inst (MonoGenericInst *ginst) { int i; + /* The ginst itself is allocated from the image set mempool */ for (i = 0; i < ginst->type_argc; ++i) mono_metadata_free_type (ginst->type_argv [i]); - return g_slist_prepend (NULL, ginst); -} - -static void -free_generic_inst (MonoGenericInst *ginst) -{ - free_list_with_data (free_generic_inst_dependents (ginst)); -} - -static GSList* -free_generic_class_dependents (MonoGenericClass *gclass) -{ - GSList *l = NULL; - int i; - - /* FIXME: The dynamic case */ - if (gclass->cached_class && !gclass->cached_class->image->dynamic && !mono_generic_class_is_generic_type_definition (gclass)) { - MonoClass *class = gclass->cached_class; - - /* Allocated in mono_class_init () */ - g_free (class->methods); - if (class->ext) - g_free (class->ext->properties); - /* Allocated in mono_generic_class_get_class () */ - g_free (class->interfaces); - l = g_slist_prepend (l, class); - } else if (gclass->is_dynamic) { - MonoDynamicGenericClass *dgclass = (MonoDynamicGenericClass *)gclass; - - for (i = 0; i < dgclass->count_fields; ++i) { - MonoClassField *field = dgclass->fields + i; - mono_metadata_free_type (field->type); - g_free ((char*)field->name); -#if HAVE_SGEN_GC - MONO_GC_UNREGISTER_ROOT (dgclass->field_objects [i]); -#endif - } - - g_free (dgclass->methods); - g_free (dgclass->ctors); - g_free (dgclass->fields); - g_free (dgclass->field_objects); - g_free (dgclass->field_generic_types); - if (!mono_generic_class_is_generic_type_definition (gclass)) - l = g_slist_prepend (l, gclass->cached_class); - } - return g_slist_prepend (l, gclass); } static void free_generic_class (MonoGenericClass *gclass) { - free_list_with_data (free_generic_class_dependents (gclass)); + /* The gclass itself is allocated from the image set mempool */ + if (gclass->is_dynamic) + mono_reflection_free_dynamic_generic_class (gclass); + if (gclass->cached_class && gclass->cached_class->interface_id) + mono_unload_interface_id (gclass->cached_class); } static void @@ -2771,10 +2794,8 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv) break; is_open = (i < type_argc); - ginst = alloca (size); -#ifndef MONO_SMALL_CONFIG - ginst->id = 0; -#endif + ginst = g_alloca (size); + memset (ginst, 0, sizeof (MonoGenericInst)); ginst->is_open = is_open; ginst->type_argc = type_argc; memcpy (ginst->type_argv, type_argv, type_argc * sizeof (MonoType *)); @@ -2791,7 +2812,7 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv) ginst = g_hash_table_lookup (set->ginst_cache, ginst); if (!ginst) { - ginst = g_malloc (size); + ginst = mono_image_set_alloc0 (set, size); #ifndef MONO_SMALL_CONFIG ginst->id = ++next_generic_inst_id; #endif @@ -2861,17 +2882,18 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst } if (is_dynamic) { - MonoDynamicGenericClass *dgclass = g_new0 (MonoDynamicGenericClass, 1); + MonoDynamicGenericClass *dgclass = mono_image_set_new0 (set, MonoDynamicGenericClass, 1); gclass = &dgclass->generic_class; gclass->is_dynamic = 1; } else { - gclass = g_new0 (MonoGenericClass, 1); + gclass = mono_image_set_new0 (set, MonoGenericClass, 1); } gclass->is_tb_open = is_tb_open; gclass->container_class = container_class; gclass->context.class_inst = inst; gclass->context.method_inst = NULL; + gclass->owner = set; if (inst == container_class->generic_container->context.class_inst && !is_tb_open) gclass->cached_class = container_class; @@ -3070,11 +3092,29 @@ mono_metadata_get_shared_type (MonoType *type) return NULL; } +static gboolean +compare_type_literals (int class_type, int type_type) +{ + /* byval_arg.type can be zero if we're decoding a type that references a class been loading. + * See mcs/test/gtest-440. and #650936. + * FIXME This better be moved to the metadata verifier as it can catch more cases. + */ + if (!class_type) + return TRUE; + /* NET 1.1 assemblies might encode string and object in a denormalized way. + * See #675464. + */ + if (type_type == MONO_TYPE_CLASS && (class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT)) + return TRUE; + return class_type == type_type; +} + /* * do_mono_metadata_parse_type: * @type: MonoType to be filled in with the return value * @m: image context * @generic_context: generics_context + * @transient: whenever to allocate data from the heap * @ptr: pointer to the encoded type * @rptr: pointer where the end of the encoded type is saved * @@ -3092,7 +3132,7 @@ mono_metadata_get_shared_type (MonoType *type) */ static gboolean do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container, - const char *ptr, const char **rptr) + gboolean transient, const char *ptr, const char **rptr) { gboolean ok = TRUE; type->type = mono_metadata_decode_value (ptr, &ptr); @@ -3120,9 +3160,13 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer case MONO_TYPE_VALUETYPE: case MONO_TYPE_CLASS: { guint32 token; + MonoClass *class; token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr); - type->data.klass = mono_class_get (m, token); - if (!type->data.klass) + class = mono_class_get (m, token); + type->data.klass = class; + if (!class) + return FALSE; + if (!compare_type_literals (class->byval_arg.type, type->type)) return FALSE; break; } @@ -3136,7 +3180,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer break; } case MONO_TYPE_PTR: - type->data.type = mono_metadata_parse_type_full (m, container, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr); + type->data.type = mono_metadata_parse_type_internal (m, container, MONO_PARSE_MOD_TYPE, 0, transient, ptr, &ptr); if (!type->data.type) return FALSE; break; @@ -3146,7 +3190,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer return FALSE; break; case MONO_TYPE_ARRAY: - type->data.array = mono_metadata_parse_array_full (m, container, ptr, &ptr); + type->data.array = mono_metadata_parse_array_internal (m, container, transient, ptr, &ptr); if (!type->data.array) return FALSE; break; @@ -3392,7 +3436,7 @@ mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *sum * * LOCKING: Acquires the loader lock. * - * Returns: a MonoMethodHeader allocated from the image mempool. + * Returns: a transient MonoMethodHeader allocated from the heap. */ MonoMethodHeader * mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, const char *ptr) @@ -3452,7 +3496,7 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons if (local_var_sig_tok) { int idx = (local_var_sig_tok & 0xffffff)-1; - if (idx >= t->rows) + if (idx >= t->rows || idx < 0) return NULL; mono_metadata_decode_row (t, idx, cols, 1); @@ -3474,10 +3518,11 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons mh = g_malloc0 (MONO_SIZEOF_METHOD_HEADER + len * sizeof (MonoType*) + num_clauses * sizeof (MonoExceptionClause)); mh->num_locals = len; for (i = 0; i < len; ++i) { - mh->locals [i] = mono_metadata_parse_type_full ( - m, container, MONO_PARSE_LOCAL, 0, locals_ptr, &locals_ptr); + mh->locals [i] = mono_metadata_parse_type_internal (m, container, + MONO_PARSE_LOCAL, 0, TRUE, locals_ptr, &locals_ptr); if (!mh->locals [i]) { g_free (clauses); + g_free (mh); return NULL; } } @@ -3533,12 +3578,17 @@ mono_metadata_parse_mh (MonoImage *m, const char *ptr) void mono_metadata_free_mh (MonoMethodHeader *mh) { + int i; + /* If it is not transient it means it's part of a wrapper method, * or a SRE-generated method, so the lifetime in that case is * dictated by the method's own lifetime */ - if (mh->is_transient) + if (mh->is_transient) { + for (i = 0; i < mh->num_locals; ++i) + mono_metadata_free_type (mh->locals [i]); g_free (mh); + } } /* @@ -4516,9 +4566,20 @@ mono_metadata_type_hash (MonoType *t1) switch (t1->type) { case MONO_TYPE_VALUETYPE: case MONO_TYPE_CLASS: - case MONO_TYPE_SZARRAY: - /* check if the distribution is good enough */ - return ((hash << 5) - hash) ^ mono_metadata_str_hash (t1->data.klass->name); + case MONO_TYPE_SZARRAY: { + MonoClass *class = t1->data.klass; + /* + * Dynamic classes must not be hashed on their type since it can change + * during runtime. For example, if we hash a reference type that is + * later made into a valuetype. + * + * This is specially problematic with generic instances since they are + * inserted in a bunch of hash tables before been finished. + */ + if (class->image->dynamic) + return (t1->byref << 6) | mono_metadata_str_hash (class->name); + return ((hash << 5) - hash) ^ mono_metadata_str_hash (class->name); + } case MONO_TYPE_PTR: return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type); case MONO_TYPE_ARRAY: @@ -5164,7 +5225,6 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec) const char *ptr; guint32 len; MonoType *type, *type2; - MonoType stack_type; mono_loader_lock (); @@ -5186,15 +5246,8 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec) len = mono_metadata_decode_value (ptr, &ptr); - type = &stack_type; - memset (type, 0, MONO_SIZEOF_TYPE); - - if (*ptr == MONO_TYPE_BYREF) { - type->byref = 1; - ptr++; - } - - if (!do_mono_metadata_parse_type (type, image, NULL, ptr, &ptr)) { + type = mono_metadata_parse_type_internal (image, NULL, MONO_PARSE_TYPE, 0, TRUE, ptr, &ptr); + if (!type) { mono_loader_unlock (); return NULL; } @@ -5206,9 +5259,9 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec) return type2; } - type2 = mono_image_alloc (image, MONO_SIZEOF_TYPE); - memcpy (type2, type, MONO_SIZEOF_TYPE); + type2 = mono_metadata_type_dup (image, type); g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER (type_spec), type2); + mono_metadata_free_type (type); mono_loader_unlock (); @@ -5368,7 +5421,17 @@ handle_enum: } *conv = MONO_MARSHAL_CONV_BOOL_I4; return MONO_NATIVE_BOOLEAN; - case MONO_TYPE_CHAR: return MONO_NATIVE_U2; + case MONO_TYPE_CHAR: + if (mspec) { + switch (mspec->native) { + case MONO_NATIVE_U2: + case MONO_NATIVE_U1: + return mspec->native; + default: + g_error ("cant marshal char to native type %02x", mspec->native); + } + } + return unicode ? MONO_NATIVE_U2 : MONO_NATIVE_U1; case MONO_TYPE_I1: return MONO_NATIVE_I1; case MONO_TYPE_U1: return MONO_NATIVE_U1; case MONO_TYPE_I2: return MONO_NATIVE_I2; @@ -5530,7 +5593,7 @@ mono_metadata_get_marshal_info (MonoImage *meta, guint32 idx, gboolean is_field) return mono_metadata_blob_heap (meta, mono_metadata_decode_row_col (tdef, loc.result, MONO_FIELD_MARSHAL_NATIVE_TYPE)); } -static MonoMethod* +MonoMethod* method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context) { guint32 idx = tok >> MONO_METHODDEFORREF_BITS; @@ -5557,6 +5620,7 @@ gboolean mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod ***overrides, gint32 *num_overrides, MonoGenericContext *generic_context) { + MonoError error; locator_t loc; MonoTableInfo *tdef = &image->tables [MONO_TABLE_METHODIMPL]; guint32 start, end; @@ -5601,6 +5665,12 @@ mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod for (i = 0; i < num; ++i) { MonoMethod *method; + if (!mono_verifier_verify_methodimpl_row (image, start + i, &error)) { + mono_error_cleanup (&error); + ok = FALSE; + break; + } + mono_metadata_decode_row (tdef, start + i, cols, MONO_METHODIMPL_SIZE); method = method_from_method_def_or_ref ( image, cols [MONO_METHODIMPL_DECLARATION], generic_context); @@ -5667,7 +5737,7 @@ get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGene } if (!found) return TRUE; - res = g_new0 (MonoClass*, found + 1); + res = mono_image_alloc0 (image, sizeof (MonoClass*) * (found + 1)); for (i = 0, tmp = cons; i < found; ++i, tmp = tmp->next) { res [i] = tmp->data; } @@ -5727,6 +5797,9 @@ mono_metadata_has_generic_params (MonoImage *image, guint32 token) return mono_metadata_get_generic_param_row (image, token, &owner); } +/* + * Memory is allocated from IMAGE's mempool. + */ gboolean mono_metadata_load_generic_param_constraints_full (MonoImage *image, guint32 token, MonoGenericContainer *container) @@ -5752,6 +5825,7 @@ mono_metadata_load_generic_param_constraints_full (MonoImage *image, guint32 tok * Load the generic parameter constraints for the newly created generic type or method * represented by @token and @container. The @container is the new container which has * been returned by a call to mono_metadata_load_generic_params() with this @token. + * Memory is allocated from IMAGE's mempool. */ void mono_metadata_load_generic_param_constraints (MonoImage *image, guint32 token,