X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fverify.c;h=4c8a8ed54614739d1bccf35c80197d38d044b60d;hb=f33e2fece0b056ea82643f7c3074aaadf07c67a4;hp=3aa838f915b85bbdcea67f91b96f7eef4b824566;hpb=6a35737bdb5d3365c2e4cccc0174e244b6dc63ff;p=mono.git diff --git a/mono/metadata/verify.c b/mono/metadata/verify.c index 3aa838f915b..4c8a8ed5461 100644 --- a/mono/metadata/verify.c +++ b/mono/metadata/verify.c @@ -1,11 +1,15 @@ -#include +#include #include #include #include #include #include #include +#include +#include +#include +#include #include #include #include @@ -52,8 +56,8 @@ mono_free_verify_list (GSList *list) (list) = g_slist_prepend ((list), vinfo); \ } while (0) -static const char* const -valid_cultures[] = { +static const char +valid_cultures[][9] = { "ar-SA", "ar-IQ", "ar-EG", "ar-LY", "ar-DZ", "ar-MA", "ar-TN", "ar-OM", "ar-YE", "ar-SY", "ar-JO", "ar-LB", @@ -88,8 +92,7 @@ valid_cultures[] = { "Lt-uz-UZ", "Cy-uz-UZ", "tt-TA", "pa-IN", "gu-IN", "ta-IN", "te-IN", "kn-IN", "mr-IN", "sa-IN", "mn-MN", "gl-ES", - "kok-IN", "syr-SY", "div-MV", - NULL + "kok-IN", "syr-SY", "div-MV" }; static int @@ -99,9 +102,11 @@ is_valid_culture (const char *cname) int found; found = *cname == 0; - for (i = 0; !found && valid_cultures [i]; ++i) { - if (g_strcasecmp (valid_cultures [i], cname)) + for (i = 0; i < G_N_ELEMENTS (valid_cultures); ++i) { + if (g_strcasecmp (valid_cultures [i], cname)) { found = 1; + break; + } } return found; } @@ -318,7 +323,7 @@ verify_constant_table (MonoImage *image, GSList *list, int level) MonoTableInfo *t = &image->tables [MONO_TABLE_CONSTANT]; guint32 cols [MONO_CONSTANT_SIZE]; guint32 value, i; - GHashTable *dups = g_hash_table_new (g_direct_hash, g_direct_equal); + GHashTable *dups = g_hash_table_new (NULL, NULL); for (i = 0; i < t->rows; ++i) { mono_metadata_decode_row (t, i, cols, MONO_CONSTANT_SIZE); @@ -352,17 +357,17 @@ verify_constant_table (MonoImage *image, GSList *list, int level) ADD_ERROR (list, g_strdup_printf ("Type 0x%x is invalid in Constant row %d", cols [MONO_CONSTANT_TYPE], i + 1)); } if (level & MONO_VERIFY_ERROR) { - value = cols [MONO_CONSTANT_PARENT] >> HASCONSTANT_BITS; - switch (cols [MONO_CONSTANT_PARENT] & HASCONSTANT_MASK) { - case HASCONSTANT_FIEDDEF: + value = cols [MONO_CONSTANT_PARENT] >> MONO_HASCONSTANT_BITS; + switch (cols [MONO_CONSTANT_PARENT] & MONO_HASCONSTANT_MASK) { + case MONO_HASCONSTANT_FIEDDEF: if (value > image->tables [MONO_TABLE_FIELD].rows) ADD_ERROR (list, g_strdup_printf ("Parent (field) is invalid in Constant row %d", i + 1)); break; - case HASCONSTANT_PARAM: + case MONO_HASCONSTANT_PARAM: if (value > image->tables [MONO_TABLE_PARAM].rows) ADD_ERROR (list, g_strdup_printf ("Parent (param) is invalid in Constant row %d", i + 1)); break; - case HASCONSTANT_PROPERTY: + case MONO_HASCONSTANT_PROPERTY: if (value > image->tables [MONO_TABLE_PROPERTY].rows) ADD_ERROR (list, g_strdup_printf ("Parent (property) is invalid in Constant row %d", i + 1)); break; @@ -388,7 +393,7 @@ verify_event_map_table (MonoImage *image, GSList *list, int level) MonoTableInfo *t = &image->tables [MONO_TABLE_EVENTMAP]; guint32 cols [MONO_EVENT_MAP_SIZE]; guint32 i, last_event; - GHashTable *dups = g_hash_table_new (g_direct_hash, g_direct_equal); + GHashTable *dups = g_hash_table_new (NULL, NULL); last_event = 0; @@ -441,17 +446,17 @@ verify_event_table (MonoImage *image, GSList *list, int level) } if (level & MONO_VERIFY_ERROR && cols [MONO_EVENT_TYPE]) { - value = cols [MONO_EVENT_TYPE] >> TYPEDEFORREF_BITS; - switch (cols [MONO_EVENT_TYPE] & TYPEDEFORREF_MASK) { - case TYPEDEFORREF_TYPEDEF: + value = cols [MONO_EVENT_TYPE] >> MONO_TYPEDEFORREF_BITS; + switch (cols [MONO_EVENT_TYPE] & MONO_TYPEDEFORREF_MASK) { + case MONO_TYPEDEFORREF_TYPEDEF: if (!value || value > image->tables [MONO_TABLE_TYPEDEF].rows) ADD_ERROR (list, g_strdup_printf ("Type invalid in Event row %d", i + 1)); break; - case TYPEDEFORREF_TYPEREF: + case MONO_TYPEDEFORREF_TYPEREF: if (!value || value > image->tables [MONO_TABLE_TYPEREF].rows) ADD_ERROR (list, g_strdup_printf ("Type invalid in Event row %d", i + 1)); break; - case TYPEDEFORREF_TYPESPEC: + case MONO_TYPEDEFORREF_TYPESPEC: if (!value || value > image->tables [MONO_TABLE_TYPESPEC].rows) ADD_ERROR (list, g_strdup_printf ("Type invalid in Event row %d", i + 1)); break; @@ -682,7 +687,7 @@ enum { TYPE_MAX = 8 }; -static const char* +static const char* const arg_name [TYPE_MAX] = { "Invalid", "Int32", @@ -1132,6 +1137,7 @@ mono_method_verify (MonoMethod *method, int level) { MonoMethodHeader *header; MonoMethodSignature *signature, *csig; + MonoGenericContext *generic_context = NULL; MonoMethod *cmethod; MonoClassField *field; MonoClass *klass; @@ -1140,9 +1146,9 @@ mono_method_verify (MonoMethod *method, int level) ILStackDesc *stack; register const unsigned char *ip; register const unsigned char *end; - const unsigned char *target; /* branch target */ + const unsigned char *target = NULL; /* branch target */ int max_args, max_stack, cur_stack, i, n, need_merge, start; - guint32 token, ip_offset; + guint32 token, ip_offset = 0; char *local_state = NULL; GSList *list = NULL; guint prefix = 0; @@ -1152,8 +1158,8 @@ mono_method_verify (MonoMethod *method, int level) (method->flags & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT))) { return NULL; } - signature = method->signature; - header = ((MonoMethodNormal *)method)->header; + signature = mono_method_signature (method); + header = mono_method_get_header (method); ip = header->code; end = ip + header->code_size; max_args = signature->param_count + signature->hasthis; @@ -1171,6 +1177,9 @@ mono_method_verify (MonoMethod *method, int level) params = signature->params; } + if (signature->is_inflated) + generic_context = ((MonoMethodInflated *) method)->context; + if (header->num_locals) { local_state = g_new (char, header->num_locals); memset (local_state, header->init_locals, header->num_locals); @@ -1385,10 +1394,15 @@ mono_method_verify (MonoMethod *method, int level) /* * FIXME: we could just load the signature ... */ - cmethod = mono_get_method (image, token, NULL); + cmethod = mono_get_method_full (image, token, NULL, generic_context); if (!cmethod) ADD_INVALID (list, g_strdup_printf ("Method 0x%08x not found at 0x%04x", token, ip_offset)); - csig = cmethod->signature; + if (mono_method_signature (cmethod)) { + csig = mono_method_signature (cmethod); + } else { + csig = mono_method_get_signature (cmethod, image, token); + } + CHECK_STACK_UNDERFLOW (csig->param_count + csig->hasthis); cur_stack -= csig->param_count + csig->hasthis; if (csig->ret->type != MONO_TYPE_VOID) { @@ -1600,7 +1614,7 @@ mono_method_verify (MonoMethod *method, int level) CHECK_STACK_UNDERFLOW (1); if (stack [cur_stack - 1].stype != TYPE_MP) ADD_INVALID (list, g_strdup_printf ("Invalid argument to ldobj at 0x%04x", ip_offset)); - klass = mono_class_get (image, token); + klass = mono_class_get_full (image, token, generic_context); if (!klass) ADD_INVALID (list, g_strdup_printf ("Cannot load class from token 0x%08x at 0x%04x", token, ip_offset)); if (!klass->valuetype) @@ -1622,10 +1636,10 @@ mono_method_verify (MonoMethod *method, int level) /* * FIXME: we could just load the signature ... */ - cmethod = mono_get_method (image, token, NULL); + cmethod = mono_get_method_full (image, token, NULL, generic_context); if (!cmethod) ADD_INVALID (list, g_strdup_printf ("Constructor 0x%08x not found at 0x%04x", token, ip_offset)); - csig = cmethod->signature; + csig = mono_method_signature (cmethod); CHECK_STACK_UNDERFLOW (csig->param_count); cur_stack -= csig->param_count; CHECK_STACK_OVERFLOW (); @@ -1668,7 +1682,7 @@ mono_method_verify (MonoMethod *method, int level) if (stack [cur_stack - 1].stype != TYPE_OBJ && stack [cur_stack - 1].stype != TYPE_MP) ADD_INVALID (list, g_strdup_printf ("Invalid argument %s to ldfld at 0x%04x", arg_name [stack [cur_stack].stype], ip_offset)); token = read32 (ip + 1); - field = mono_field_from_token (image, token, &klass); + field = mono_field_from_token (image, token, &klass, generic_context); if (!field) ADD_INVALID (list, g_strdup_printf ("Cannot load field from token 0x%08x at 0x%04x", token, ip_offset)); type_to_eval_stack_type (field->type, stack + cur_stack - 1, FALSE); @@ -1679,7 +1693,7 @@ mono_method_verify (MonoMethod *method, int level) if (stack [cur_stack - 1].stype != TYPE_OBJ && stack [cur_stack - 1].stype != TYPE_MP) ADD_INVALID (list, g_strdup_printf ("Invalid argument to ldflda at 0x%04x", ip_offset)); token = read32 (ip + 1); - field = mono_field_from_token (image, token, &klass); + field = mono_field_from_token (image, token, &klass, generic_context); if (!field) ADD_INVALID (list, g_strdup_printf ("Cannot load field from token 0x%08x at 0x%04x", token, ip_offset)); type_to_eval_stack_type (field->type, stack + cur_stack - 1, TRUE); @@ -1691,7 +1705,7 @@ mono_method_verify (MonoMethod *method, int level) if (stack [cur_stack].stype != TYPE_OBJ && stack [cur_stack].stype != TYPE_MP) ADD_INVALID (list, g_strdup_printf ("Invalid argument to stfld at 0x%04x", ip_offset)); token = read32 (ip + 1); - field = mono_field_from_token (image, token, &klass); + field = mono_field_from_token (image, token, &klass, generic_context); if (!field) ADD_INVALID (list, g_strdup_printf ("Cannot load field from token 0x%08x at 0x%04x", token, ip_offset)); /* can_store */ @@ -1700,7 +1714,7 @@ mono_method_verify (MonoMethod *method, int level) case CEE_LDSFLD: CHECK_STACK_OVERFLOW (); token = read32 (ip + 1); - field = mono_field_from_token (image, token, &klass); + field = mono_field_from_token (image, token, &klass, generic_context); if (!field) ADD_INVALID (list, g_strdup_printf ("Cannot load field from token 0x%08x at 0x%04x", token, ip_offset)); type_to_eval_stack_type (field->type, stack + cur_stack, FALSE); @@ -1710,7 +1724,7 @@ mono_method_verify (MonoMethod *method, int level) case CEE_LDSFLDA: CHECK_STACK_OVERFLOW (); token = read32 (ip + 1); - field = mono_field_from_token (image, token, &klass); + field = mono_field_from_token (image, token, &klass, generic_context); if (!field) ADD_INVALID (list, g_strdup_printf ("Cannot load field from token 0x%08x at 0x%04x", token, ip_offset)); type_to_eval_stack_type (field->type, stack + cur_stack, TRUE); @@ -1721,7 +1735,7 @@ mono_method_verify (MonoMethod *method, int level) CHECK_STACK_UNDERFLOW (1); --cur_stack; token = read32 (ip + 1); - field = mono_field_from_token (image, token, &klass); + field = mono_field_from_token (image, token, &klass, generic_context); if (!field) ADD_INVALID (list, g_strdup_printf ("Cannot load field from token 0x%08x at 0x%04x", token, ip_offset)); /* can store */ @@ -1813,9 +1827,9 @@ mono_method_verify (MonoMethod *method, int level) cur_stack -= 3; ++ip; break; - case CEE_UNUSED2: - case CEE_UNUSED3: - case CEE_UNUSED4: + case CEE_LDELEM_ANY: + case CEE_STELEM_ANY: + case CEE_UNBOX_ANY: case CEE_UNUSED5: case CEE_UNUSED6: case CEE_UNUSED7: @@ -2083,8 +2097,9 @@ mono_method_verify (MonoMethod *method, int level) ip += 5; --cur_stack; break; - case CEE_UNUSED68: - ++ip; + case CEE_CONSTRAINED_: + token = read32 (ip + 1); + ip += 5; break; case CEE_CPBLK: CHECK_STACK_UNDERFLOW (3); @@ -2094,8 +2109,8 @@ mono_method_verify (MonoMethod *method, int level) CHECK_STACK_UNDERFLOW (3); ip++; break; - case CEE_UNUSED69: - ++ip; + case CEE_NO_: + ip += 2; break; case CEE_RETHROW: ++ip; @@ -2115,7 +2130,6 @@ mono_method_verify (MonoMethod *method, int level) CHECK_STACK_UNDERFLOW (1); ++ip; break; - case CEE_UNUSED52: case CEE_UNUSED53: case CEE_UNUSED54: case CEE_UNUSED55: @@ -2212,7 +2226,8 @@ methodbuilder_fields[] = { {"pinfo", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, pinfo)}, {"pi_dll", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, dll)}, {"pi_entry", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, dllentry)}, - {"ncharset", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, charset)}, + {"charset", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, charset)}, + {"extra_flags", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, extra_flags)}, {"native_cc", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, native_cc)}, {"call_conv", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, call_conv)}, {NULL, 0} @@ -2245,7 +2260,6 @@ propertybuilder_fields[] = { static const FieldDesc ilgenerator_fields[] = { {"code", G_STRUCT_OFFSET (MonoReflectionILGen, code)}, - {"mbuilder", G_STRUCT_OFFSET (MonoReflectionILGen, mbuilder)}, {"code_len", G_STRUCT_OFFSET (MonoReflectionILGen, code_len)}, {"max_stack", G_STRUCT_OFFSET (MonoReflectionILGen, max_stack)}, {"cur_stack", G_STRUCT_OFFSET (MonoReflectionILGen, cur_stack)}, @@ -2328,15 +2342,6 @@ monopropertyinfo_fields[] = { {NULL, 0} }; -static const FieldDesc -monofieldinfo_fields[] = { - {"parent", G_STRUCT_OFFSET (MonoFieldInfo, parent)}, - {"type", G_STRUCT_OFFSET (MonoFieldInfo, type)}, - {"name", G_STRUCT_OFFSET (MonoFieldInfo, name)}, - {"attrs", G_STRUCT_OFFSET (MonoFieldInfo, attrs)}, - {NULL, 0} -}; - static const FieldDesc monomethod_fields[] = { {"mhandle", G_STRUCT_OFFSET (MonoReflectionMethod, method)}, @@ -2367,7 +2372,6 @@ reflection_classes_to_check [] = { {"MonoField", monofield_fields}, {"MonoMethodInfo", monomethodinfo_fields}, {"MonoPropertyInfo", monopropertyinfo_fields}, - {"MonoFieldInfo", monofieldinfo_fields}, {"MonoMethod", monomethod_fields}, {"MonoCMethod", monocmethod_fields}, {"ParameterInfo", pinfo_fields}, @@ -2408,6 +2412,7 @@ async_result_fields[] = { {"sync_completed", G_STRUCT_OFFSET (MonoAsyncResult, sync_completed)}, {"completed", G_STRUCT_OFFSET (MonoAsyncResult, completed)}, {"endinvoke_called", G_STRUCT_OFFSET (MonoAsyncResult, endinvoke_called)}, + {"async_callback", G_STRUCT_OFFSET (MonoAsyncResult, async_callback)}, {NULL, 0} }; @@ -2474,7 +2479,7 @@ messaging_classes_to_check [] = { static FieldDesc transparent_proxy_fields[] = { {"_rp", G_STRUCT_OFFSET (MonoTransparentProxy, rp)}, - {"_class", G_STRUCT_OFFSET (MonoTransparentProxy, klass)}, + {"_class", G_STRUCT_OFFSET (MonoTransparentProxy, remote_class)}, {NULL, 0} }; @@ -2501,7 +2506,6 @@ wait_handle_fields[] = { static FieldDesc thread_fields[] = { {"system_thread_handle", G_STRUCT_OFFSET (MonoThread, handle)}, - {"current_culture", G_STRUCT_OFFSET (MonoThread, culture_info)}, {"threadpool_thread", G_STRUCT_OFFSET (MonoThread, threadpool_thread)}, {"state", G_STRUCT_OFFSET (MonoThread, state)}, {"abort_exc", G_STRUCT_OFFSET (MonoThread, abort_exc)}, @@ -2517,6 +2521,67 @@ threading_classes_to_check [] = { {NULL, NULL} }; +static const FieldDesc +cinfo_fields[] = { + {"datetime_format", G_STRUCT_OFFSET (MonoCultureInfo, datetime_format)}, + {"number_format", G_STRUCT_OFFSET (MonoCultureInfo, number_format)}, + {"textinfo", G_STRUCT_OFFSET (MonoCultureInfo, textinfo)}, + {"name", G_STRUCT_OFFSET (MonoCultureInfo, name)}, + {"displayname", G_STRUCT_OFFSET (MonoCultureInfo, displayname)}, + {"englishname", G_STRUCT_OFFSET (MonoCultureInfo, englishname)}, + {"nativename", G_STRUCT_OFFSET (MonoCultureInfo, nativename)}, + {"iso3lang", G_STRUCT_OFFSET (MonoCultureInfo, iso3lang)}, + {"iso2lang", G_STRUCT_OFFSET (MonoCultureInfo, iso2lang)}, + {"icu_name", G_STRUCT_OFFSET (MonoCultureInfo, icu_name)}, + {"win3lang", G_STRUCT_OFFSET (MonoCultureInfo, win3lang)}, + {"compareinfo", G_STRUCT_OFFSET (MonoCultureInfo, compareinfo)}, + {NULL, 0} +}; + +static const FieldDesc +dtfinfo_fields[] = { + {"amDesignator", G_STRUCT_OFFSET (MonoDateTimeFormatInfo, AMDesignator)}, + {"pmDesignator", G_STRUCT_OFFSET (MonoDateTimeFormatInfo, PMDesignator)}, + {"dayNames", G_STRUCT_OFFSET (MonoDateTimeFormatInfo, DayNames)}, + {"monthNames", G_STRUCT_OFFSET (MonoDateTimeFormatInfo, MonthNames)}, + {NULL, 0} +}; + +static const FieldDesc +nfinfo_fields[] = { + {"decimalFormats", G_STRUCT_OFFSET (MonoNumberFormatInfo, decimalFormats)}, + {"currencySymbol", G_STRUCT_OFFSET (MonoNumberFormatInfo, currencySymbol)}, + {"percentSymbol", G_STRUCT_OFFSET (MonoNumberFormatInfo, percentSymbol)}, + {"positiveSign", G_STRUCT_OFFSET (MonoNumberFormatInfo, positiveSign)}, + {NULL, 0} +}; + +static const FieldDesc +compinfo_fields[] = { + {"lcid", G_STRUCT_OFFSET (MonoCompareInfo, lcid)}, + {"ICU_collator", G_STRUCT_OFFSET (MonoCompareInfo, ICU_collator)}, + {NULL, 0} +}; + +static const FieldDesc +sortkey_fields[] = { + {"str", G_STRUCT_OFFSET (MonoSortKey, str)}, + {"options", G_STRUCT_OFFSET (MonoSortKey, options)}, + {"key", G_STRUCT_OFFSET (MonoSortKey, key)}, + {"lcid", G_STRUCT_OFFSET (MonoSortKey, lcid)}, + {NULL, 0} +}; + +static const ClassDesc +globalization_classes_to_check [] = { + {"CultureInfo", cinfo_fields}, + {"DateTimeFormatInfo", dtfinfo_fields}, + {"NumberFormatInfo", nfinfo_fields}, + {"CompareInfo", compinfo_fields}, + {"SortKey", sortkey_fields}, + {NULL, NULL} +}; + typedef struct { const char *name; const ClassDesc *types; @@ -2531,6 +2596,7 @@ namespaces_to_check[] = { {"System.Threading", threading_classes_to_check}, {"System.Diagnostics", system_diagnostics_classes_to_check}, {"System", system_classes_to_check}, + {"System.Globalization", globalization_classes_to_check}, {NULL, NULL} }; @@ -2543,28 +2609,38 @@ check_corlib (MonoImage *corlib) const ClassDesc *cdesc; const NameSpaceDesc *ndesc; gint struct_offset; + GString *result = NULL; for (ndesc = namespaces_to_check; ndesc->name; ++ndesc) { for (cdesc = ndesc->types; cdesc->name; ++cdesc) { klass = mono_class_from_name (corlib, ndesc->name, cdesc->name); - if (!klass) - return g_strdup_printf ("Cannot find class %s", cdesc->name); + if (!klass) { + if (!result) + result = g_string_new (""); + g_string_append_printf (result, "Cannot find class %s\n", cdesc->name); + continue; + } mono_class_init (klass); /* * FIXME: we should also check the size of valuetypes, or * we're going to have trouble when we access them in arrays. */ if (klass->valuetype) - struct_offset = 8; + struct_offset = sizeof (MonoObject); else struct_offset = 0; for (fdesc = cdesc->fields; fdesc->name; ++fdesc) { field = mono_class_get_field_from_name (klass, fdesc->name); - if (!field || (field->offset != (fdesc->offset + struct_offset))) - return g_strdup_printf ("field `%s' mismatch in class %s (%ld != %ld)", fdesc->name, cdesc->name, (long) fdesc->offset, (long) (field?field->offset:-1)); + if (!field || (field->offset != (fdesc->offset + struct_offset))) { + if (!result) + result = g_string_new (""); + g_string_append_printf (result, "field `%s' mismatch in class %s (%ld + %ld != %ld)\n", fdesc->name, cdesc->name, (long) fdesc->offset, (long)struct_offset, (long) (field?field->offset:-1)); + } } } } + if (result) + return g_string_free (result, FALSE); return NULL; } @@ -2573,3 +2649,4 @@ mono_verify_corlib () { return check_corlib (mono_defaults.corlib); } +