Merge pull request #3756 from henricm/named-pipe-alertable-on-windows
[mono.git] / mono / metadata / metadata-verify.c
index ca2a15a7e03f6f33c2758061302e3aca75b83820..c3beaa4553795cf7d9285b3b0f68c5d3c88abf7e 100644 (file)
@@ -5,6 +5,7 @@
  *     Mono Project (http://www.mono-project.com)
  *
  * Copyright (C) 2005-2008 Novell, Inc. (http://www.novell.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <mono/metadata/object-internals.h>
 #include <mono/metadata/verify.h>
@@ -24,6 +25,7 @@
 #include <mono/metadata/attrdefs.h>
 #include <mono/utils/strenc.h>
 #include <mono/utils/mono-error-internals.h>
+#include <mono/utils/bsearch.h>
 #include <string.h>
 //#include <signal.h>
 #include <ctype.h>
@@ -138,7 +140,7 @@ const static unsigned char coded_index_desc[] = {
        5, /*tables*/
        MONO_TABLE_TYPEDEF,
        MONO_TABLE_TYPEREF,
-       MONO_TABLE_MODULE,
+       MONO_TABLE_MODULEREF,
        MONO_TABLE_METHOD,
        MONO_TABLE_TYPESPEC,
 
@@ -331,7 +333,7 @@ bounds_check_virtual_address (VerifyContext *ctx, guint32 rva, guint32 size)
                return FALSE;
 
        if (ctx->stage > STAGE_PE) {
-               MonoCLIImageInfo *iinfo = ctx->image->image_info;
+               MonoCLIImageInfo *iinfo = (MonoCLIImageInfo *)ctx->image->image_info;
                const int top = iinfo->cli_section_count;
                MonoSectionTable *tables = iinfo->cli_section_tables;
                int i;
@@ -658,7 +660,7 @@ verify_resources_table (VerifyContext *ctx)
        DataDirectory it = ctx->data_directories [RESOURCE_TABLE_IDX];
        guint32 offset;
        guint16 named_entries, id_entries;
-       const char *ptr, *root, *end;
+       const char *ptr;
 
        if (it.rva == 0)
                return;
@@ -667,8 +669,7 @@ verify_resources_table (VerifyContext *ctx)
                ADD_ERROR (ctx, g_strdup_printf ("Resource section is too small, must be at least 16 bytes long but it's %d long", it.size));
 
        offset = it.translated_offset;
-       root = ptr = ctx->data + offset;
-       end = root + it.size;
+       ptr = ctx->data + offset;
 
        g_assert (offset != INVALID_OFFSET);
 
@@ -689,7 +690,7 @@ verify_resources_table (VerifyContext *ctx)
 static DataDirectory
 get_data_dir (VerifyContext *ctx, int idx)
 {
-       MonoCLIImageInfo *iinfo = ctx->image->image_info;
+       MonoCLIImageInfo *iinfo = (MonoCLIImageInfo *)ctx->image->image_info;
        MonoPEDirEntry *entry= &iinfo->cli_header.datadir.pe_export_table;
        DataDirectory res;
 
@@ -729,7 +730,7 @@ verify_cli_header (VerifyContext *ctx)
        if (!read32 (ptr + 8) || !read32 (ptr + 12))
                ADD_ERROR (ctx, g_strdup_printf ("Missing medatata section in the CLI header"));
 
-       if ((read32 (ptr + 16) & ~0x0001000B) != 0)
+       if ((read32 (ptr + 16) & ~0x0003000B) != 0)
                ADD_ERROR (ctx, g_strdup_printf ("Invalid CLI header flags"));
 
        ptr += 24;
@@ -1069,7 +1070,7 @@ search_sorted_table (VerifyContext *ctx, int table, int column, guint32 coded_to
        base = tinfo->base;
 
        VERIFIER_DEBUG ( printf ("looking token %x table %d col %d rsize %d roff %d\n", coded_token, table, column, locator.col_size, locator.col_offset) );
-       res = bsearch (&locator, base, tinfo->rows, tinfo->row_size, token_locator);
+       res = (const char *)mono_binary_search (&locator, base, tinfo->rows, tinfo->row_size, token_locator);
        if (!res)
                return -1;
 
@@ -1096,7 +1097,7 @@ string_cmp (VerifyContext *ctx, const char *str, guint offset)
 static gboolean
 mono_verifier_is_corlib (MonoImage *image)
 {
-       gboolean trusted_location = (mono_security_get_mode () != MONO_SECURITY_MODE_CORE_CLR) ? 
+       gboolean trusted_location = !mono_security_core_clr_enabled () ?
                        TRUE : mono_security_core_clr_is_platform_image (image);
 
        return trusted_location && image->module_name && !strcmp ("mscorlib.dll", image->module_name);
@@ -1230,7 +1231,7 @@ parse_custom_mods (VerifyContext *ctx, const char **_ptr, const char *end)
                if (!safe_read_cint (token, ptr, end))
                        FAIL (ctx, g_strdup ("CustomMod: Not enough room for the token"));
        
-               if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token))
+               if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
                        FAIL (ctx, g_strdup_printf ("CustomMod: invalid TypeDefOrRef token %x", token));
        }
 
@@ -1287,7 +1288,7 @@ parse_generic_inst (VerifyContext *ctx, const char **_ptr, const char *end)
        if (!safe_read_cint (token, ptr, end))
                FAIL (ctx, g_strdup ("GenericInst: Not enough room for type token"));
 
-       if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token))
+       if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
                FAIL (ctx, g_strdup_printf ("GenericInst: invalid TypeDefOrRef token %x", token));
 
        if (ctx->token) {
@@ -1303,6 +1304,9 @@ parse_generic_inst (VerifyContext *ctx, const char **_ptr, const char *end)
                FAIL (ctx, g_strdup ("GenericInst: Zero arguments generic instance"));
 
        for (i = 0; i < count; ++i) {
+               if (!parse_custom_mods (ctx, &ptr, end))
+                       FAIL (ctx, g_strdup ("Type: Failed to parse pointer custom attr"));
+
                if (!parse_type (ctx, &ptr, end))
                        FAIL (ctx, g_strdup_printf ("GenericInst: invalid generic argument %d", i + 1));
        }
@@ -1346,12 +1350,15 @@ parse_type (VerifyContext *ctx, const char **_ptr, const char *end)
                if (!safe_read_cint (token, ptr, end))
                        FAIL (ctx, g_strdup ("Type: Not enough room for the type token"));
        
-               if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token))
+               if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
                        FAIL (ctx, g_strdup_printf ("Type: invalid TypeDefOrRef token %x", token));
+
+               if (!get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
+                       FAIL (ctx, g_strdup_printf ("Type: zero TypeDefOrRef token %x", token));
                if (ctx->token) {
                        if (mono_metadata_token_index (ctx->token) == get_coded_index_token (TYPEDEF_OR_REF_DESC, token) &&
                                mono_metadata_token_table (ctx->token) == get_coded_index_table (TYPEDEF_OR_REF_DESC, token))
-                               FAIL (ctx, g_strdup_printf ("Type: Recurside type specification (%x). A type signature can't reference itself", ctx->token));
+                               FAIL (ctx, g_strdup_printf ("Type: Recursive type specification (%x). A type signature can't reference itself", ctx->token));
                }
                break;
 
@@ -1433,8 +1440,11 @@ parse_param (VerifyContext *ctx, const char **_ptr, const char *end)
        }
 
        //it's a byref, update the cursor ptr
-       if (type == MONO_TYPE_BYREF)
+       if (type == MONO_TYPE_BYREF) {
                *_ptr = ptr;
+               if (!parse_custom_mods (ctx, _ptr, end))
+                       return FALSE;
+       }
 
        return parse_type (ctx, _ptr, end);
 }
@@ -1523,6 +1533,8 @@ parse_property_signature (VerifyContext *ctx, const char **_ptr, const char *end
                FAIL (ctx, g_strdup ("PropertySig: Could not parse property type"));
 
        for (i = 0; i < param_count; ++i) {
+               if (!parse_custom_mods (ctx, &ptr, end))
+                       FAIL (ctx, g_strdup ("Type: Failed to parse pointer custom attr"));
                if (!parse_type (ctx, &ptr, end))
                        FAIL (ctx, g_strdup_printf ("PropertySig: Error parsing arg %d", i));
        }
@@ -1641,6 +1653,20 @@ is_valid_method_signature (VerifyContext *ctx, guint32 offset)
        return parse_method_signature (ctx, &ptr, end, FALSE, FALSE);
 }
 
+static gboolean
+is_valid_memberref_method_signature (VerifyContext *ctx, guint32 offset)
+{
+       guint32 size = 0;
+       const char *ptr = NULL, *end;
+
+       if (!decode_signature_header (ctx, offset, &size, &ptr))
+               FAIL (ctx, g_strdup ("MemberRefSig: Could not decode signature header"));
+       end = ptr + size;
+
+       return parse_method_signature (ctx, &ptr, end, TRUE, FALSE);
+}
+
+
 static gboolean
 is_valid_method_or_field_signature (VerifyContext *ctx, guint32 offset)
 {
@@ -1762,7 +1788,7 @@ get_enum_by_encoded_name (VerifyContext *ctx, const char **_ptr, const char *end
                return NULL;
        }
 
-       enum_name = g_memdup (str_start, str_len + 1);
+       enum_name = (char *)g_memdup (str_start, str_len + 1);
        enum_name [str_len] = 0;
        type = mono_reflection_type_from_name (enum_name, ctx->image);
        if (!type) {
@@ -1853,8 +1879,10 @@ handle_enum:
                                klass = get_enum_by_encoded_name (ctx, &ptr, end);
                                if (!klass)
                                        return FALSE;
+                       } else if (etype == 0x50 || etype == MONO_TYPE_CLASS) {
+                               klass = mono_defaults.systemtype_class;
                        } else if ((etype >= MONO_TYPE_BOOLEAN && etype <= MONO_TYPE_STRING) || etype == 0x51) {
-                               simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : etype;
+                               simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : (MonoTypeEnum)etype;
                                klass = mono_class_from_mono_type (&simple_type);
                        } else
                                FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid array element type %x", etype));
@@ -1959,7 +1987,7 @@ is_valid_cattr_content (VerifyContext *ctx, MonoMethod *ctor, const char *ptr, g
                        FAIL (ctx, g_strdup_printf ("CustomAttribute: Not enough space for named parameter %d type", i));
 
                if (kind >= MONO_TYPE_BOOLEAN && kind <= MONO_TYPE_STRING) {
-                       simple_type.type = kind;
+                       simple_type.type = (MonoTypeEnum)kind;
                        type = &simple_type;
                } else if (kind == MONO_TYPE_ENUM) {
                        MonoClass *klass = get_enum_by_encoded_name (ctx, &ptr, end);
@@ -1980,8 +2008,10 @@ is_valid_cattr_content (VerifyContext *ctx, MonoMethod *ctor, const char *ptr, g
                                klass = get_enum_by_encoded_name (ctx, &ptr, end);
                                if (!klass)
                                        return FALSE;
+                       } else if (etype == 0x50 || etype == MONO_TYPE_CLASS) {
+                               klass = mono_defaults.systemtype_class;
                        } else if ((etype >= MONO_TYPE_BOOLEAN && etype <= MONO_TYPE_STRING) || etype == 0x51) {
-                               simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : etype;
+                               simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : (MonoTypeEnum)etype;
                                klass = mono_class_from_mono_type (&simple_type);
                        } else
                                FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid array element type %x", etype));
@@ -2112,6 +2142,8 @@ is_valid_methodspec_blob (VerifyContext *ctx, guint32 offset)
                FAIL (ctx, g_strdup ("MethodSpec: Zero generic argument count"));
 
        for (i = 0; i < count; ++i) {
+               if (!parse_custom_mods (ctx, &ptr, end))
+                       return FALSE;
                if (!parse_type (ctx, &ptr, end))
                        FAIL (ctx, g_strdup_printf ("MethodSpec: Could not parse parameter %d", i + 1));
        }
@@ -2258,6 +2290,8 @@ is_valid_method_header (VerifyContext *ctx, guint32 rva, guint32 *locals_token)
                        FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature table 0x%x", ((local_vars_tok >> 24) & 0xFF)));
                if ((local_vars_tok & 0xFFFFFF) > ctx->image->tables [MONO_TABLE_STANDALONESIG].rows)   
                        FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature points to invalid row 0x%x", local_vars_tok & 0xFFFFFF));
+               if (!(local_vars_tok & 0xFFFFFF))
+                       FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature with zero index"));
                *locals_token = local_vars_tok & 0xFFFFFF;
        }
 
@@ -2401,6 +2435,9 @@ verify_typedef_table (VerifyContext *ctx)
                if (data [MONO_TYPEDEF_EXTENDS] && !is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS]))
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d extend field coded index 0x%08x", i, data [MONO_TYPEDEF_EXTENDS]));
 
+               if (data [MONO_TYPEDEF_EXTENDS] && !get_coded_index_token (TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS]))
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d zero coded extend field coded index 0x%08x", i, data [MONO_TYPEDEF_EXTENDS]));
+
                visibility = data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK;
                if ((visibility >= TYPE_ATTRIBUTE_NESTED_PUBLIC && visibility <= TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM) &&
                        search_sorted_table (ctx, MONO_TABLE_NESTEDCLASS, MONO_NESTED_CLASS_NESTED, i + 1) == -1)
@@ -2553,7 +2590,7 @@ verify_field_table_full (VerifyContext *ctx)
 }
 
 /*bits 8,9,10,11,13,14,15*/
-#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15))
+#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15))
 static void
 verify_method_table (VerifyContext *ctx)
 {
@@ -2623,8 +2660,8 @@ verify_method_table (VerifyContext *ctx)
                                ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but not Static", i));
                        if (flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_VIRTUAL))
                                ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but is Abstract or Virtual", i));
-                       if (!(access == METHOD_ATTRIBUTE_COMPILER_CONTROLLED || access == METHOD_ATTRIBUTE_PUBLIC || access == METHOD_ATTRIBUTE_PRIVATE))
-                               ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but not CompilerControled, Public or Private", i));
+                       if (access == METHOD_ATTRIBUTE_FAMILY || access == METHOD_ATTRIBUTE_FAM_AND_ASSEM || access == METHOD_ATTRIBUTE_FAM_OR_ASSEM)
+                               ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but not CompilerControled, Public, Private or Assembly", i));
                }
 
                //TODO check valuetype for synchronized
@@ -2649,8 +2686,8 @@ verify_method_table (VerifyContext *ctx)
                //TODO check signature contents
 
                if (rva) {
-                       if (flags & METHOD_ATTRIBUTE_ABSTRACT)
-                               ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is Abstract", i));
+                       if ((flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_PINVOKE_IMPL)) || (implflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
+                               ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is either Abstract, InternalCall or PinvokeImpl", i));
                        if (code_type == METHOD_IMPL_ATTRIBUTE_OPTIL)
                                ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is CodeTypeMask is neither Native, CIL or Runtime", i));
                } else {
@@ -2790,7 +2827,7 @@ verify_interfaceimpl_table (VerifyContext *ctx)
        for (i = 0; i < table->rows; ++i) {
                mono_metadata_decode_row (table, i, data, MONO_INTERFACEIMPL_SIZE);
                if (data [MONO_INTERFACEIMPL_CLASS] && data [MONO_INTERFACEIMPL_CLASS] > ctx->image->tables [MONO_TABLE_TYPEDEF].rows)
-                       ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Class field 0x%08x", i, data [MONO_TABLE_TYPEDEF]));
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Class field 0x%08x", i, data [MONO_INTERFACEIMPL_CLASS]));
 
                if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_INTERFACEIMPL_INTERFACE]))
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Inteface field coded index 0x%08x", i, data [MONO_INTERFACEIMPL_INTERFACE]));
@@ -2878,8 +2915,8 @@ verify_cattr_table (VerifyContext *ctx)
                if (!is_valid_coded_index (ctx, HAS_CATTR_DESC, data [MONO_CUSTOM_ATTR_PARENT]))
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT]));
 
-               if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]))
-                       ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT]));
+               if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]) || !get_coded_index_token (CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]))
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Type field 0x%08x", i, data [MONO_CUSTOM_ATTR_TYPE]));
 
                if (data [MONO_CUSTOM_ATTR_VALUE] && !is_valid_blob_object (ctx, data [MONO_CUSTOM_ATTR_VALUE], 0))
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d invalid value blob 0x%x", i, data [MONO_CUSTOM_ATTR_VALUE]));
@@ -2889,6 +2926,7 @@ verify_cattr_table (VerifyContext *ctx)
 static void
 verify_cattr_table_full (VerifyContext *ctx)
 {
+       MonoError error;
        MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
        MonoMethod *ctor;
        const char *ptr;
@@ -2913,7 +2951,12 @@ verify_cattr_table_full (VerifyContext *ctx)
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute constructor row %d Token 0x%08x", i, data [MONO_CUSTOM_ATTR_TYPE]));
                }
 
-               ctor = mono_get_method (ctx->image, mtoken, NULL);
+               ctor = mono_get_method_checked (ctx->image, mtoken, NULL, NULL, &error);
+
+               if (!ctor) {
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute content row %d Could not load ctor due to %s", i, mono_error_get_message (&error)));
+                       mono_error_cleanup (&error);
+               }
 
                /*This can't fail since this is checked in is_valid_cattr_blob*/
                g_assert (decode_signature_header (ctx, data [MONO_CUSTOM_ATTR_VALUE], &size, &ptr));
@@ -3156,7 +3199,7 @@ verify_event_table_full (VerifyContext *ctx)
                if (!found_add)
                        ADD_ERROR (ctx, g_strdup_printf ("Invalid Event row %d has no AddOn associated method", i));
                if (!found_remove)
-                       ADD_ERROR (ctx, g_strdup_printf ("Invalid Event row %d has no AddOn associated method", i));
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid Event row %d has no RemoveOn associated method", i));
        }
 }
 
@@ -3245,7 +3288,7 @@ verify_moduleref_table (VerifyContext *ctx)
                mono_metadata_decode_row (table, i, data, MONO_MODULEREF_SIZE);
 
                if (!is_valid_non_empty_string (ctx, data[MONO_MODULEREF_NAME]))
-                       ADD_ERROR (ctx, g_strdup_printf ("Invalid MethodImpl row %d Class field %08x", i, data [MONO_TABLE_TYPEDEF]));
+                       ADD_ERROR (ctx, g_strdup_printf ("Invalid ModuleRef row %d name field %08x", i, data [MONO_MODULEREF_NAME]));
        }
 }
 
@@ -3333,7 +3376,7 @@ verify_fieldrva_table (VerifyContext *ctx)
        }
 }
 
-#define INVALID_ASSEMBLY_FLAGS_BITS ~((1 << 0) | (1 << 4) | (1 << 8) | (1 << 14) | (1 << 15))
+#define INVALID_ASSEMBLY_FLAGS_BITS ~((1 << 0) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 14) | (1 << 15))
 static void
 verify_assembly_table (VerifyContext *ctx)
 {
@@ -3365,7 +3408,7 @@ verify_assembly_table (VerifyContext *ctx)
        }
 }
 
-#define INVALID_ASSEMBLYREF_FLAGS_BITS ~(1)
+#define INVALID_ASSEMBLYREF_FLAGS_BITS ~((1 << 0) | (1 << 8) | (1 << 14) | (1 << 15))
 static void
 verify_assemblyref_table (VerifyContext *ctx)
 {
@@ -3451,7 +3494,7 @@ verify_exportedtype_table (VerifyContext *ctx)
 static void
 verify_manifest_resource_table (VerifyContext *ctx)
 {
-       MonoCLIImageInfo *iinfo = ctx->image->image_info;
+       MonoCLIImageInfo *iinfo = (MonoCLIImageInfo *)ctx->image->image_info;
        MonoCLIHeader *ch = &iinfo->cli_cli_header;
        MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_MANIFESTRESOURCE];
        guint32 data [MONO_MANIFEST_SIZE], impl_table, token, resources_size;
@@ -3589,18 +3632,30 @@ verify_generic_param_constraint_table (VerifyContext *ctx)
        MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
        guint32 data [MONO_GENPARCONSTRAINT_SIZE];
        int i;
+       guint32 last_owner = 0, last_constraint = 0;
 
        for (i = 0; i < table->rows; ++i) {
                mono_metadata_decode_row (table, i, data, MONO_GENPARCONSTRAINT_SIZE);
 
                if (!data [MONO_GENPARCONSTRAINT_GENERICPAR] || data [MONO_GENPARCONSTRAINT_GENERICPAR] > ctx->image->tables [MONO_TABLE_GENERICPARAM].rows)
-                       ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Owner token %08x", i, data [MONO_TABLE_GENERICPARAM]));
+                       ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Owner token %08x", i, data [MONO_GENPARCONSTRAINT_GENERICPAR]));
 
                if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_GENPARCONSTRAINT_CONSTRAINT]))
                        ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Constraint token %08x", i, data [MONO_GENPARCONSTRAINT_CONSTRAINT]));
 
                if (!get_coded_index_token (TYPEDEF_OR_REF_DESC, data [MONO_GENPARCONSTRAINT_CONSTRAINT]))
                        ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has null Constraint token", i));
+
+               if (last_owner > data [MONO_GENPARCONSTRAINT_GENERICPAR])
+                       ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d is not properly sorted. Previous value of the owner column is 0x%08x current value is 0x%08x", i, last_owner, data [MONO_GENPARCONSTRAINT_GENERICPAR]));
+
+               if (last_owner == data [MONO_GENPARCONSTRAINT_GENERICPAR]) {
+                       if (last_constraint == data [MONO_GENPARCONSTRAINT_CONSTRAINT])
+                               ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has duplicate constraint 0x%08x", i, last_constraint));
+               } else {
+                       last_owner = data [MONO_GENPARCONSTRAINT_GENERICPAR];
+               }
+               last_constraint = data [MONO_GENPARCONSTRAINT_CONSTRAINT];
        }
 }
 
@@ -3614,15 +3669,15 @@ typedef struct {
 static guint
 typedef_hash (gconstpointer _key)
 {
-       const TypeDefUniqueId *key = _key;
+       const TypeDefUniqueId *key = (const TypeDefUniqueId *)_key;
        return g_str_hash (key->name) ^ g_str_hash (key->name_space) ^ key->resolution_scope; /*XXX better salt the int key*/
 }
 
 static gboolean
 typedef_equals (gconstpointer _a, gconstpointer _b)
 {
-       const TypeDefUniqueId *a = _a;
-       const TypeDefUniqueId *b = _b;
+       const TypeDefUniqueId *a = (const TypeDefUniqueId *)_a;
+       const TypeDefUniqueId *b = (const TypeDefUniqueId *)_b;
        return !strcmp (a->name, b->name) && !strcmp (a->name_space, b->name_space) && a->resolution_scope == b->resolution_scope;
 }
 
@@ -3830,7 +3885,7 @@ cleanup_context_checked (VerifyContext *ctx, MonoError *error)
 {
        g_free (ctx->sections);
        if (ctx->errors) {
-               MonoVerifyInfo *info = ctx->errors->data;
+               MonoVerifyInfo *info = (MonoVerifyInfo *)ctx->errors->data;
                mono_error_set_bad_image (error, ctx->image, "%s", info->message);
                mono_free_verify_list (ctx->errors);
        }
@@ -4014,7 +4069,22 @@ mono_verifier_verify_method_signature (MonoImage *image, guint32 offset, MonoErr
 }
 
 gboolean
-mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSList **error_list)
+mono_verifier_verify_memberref_method_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+       VerifyContext ctx;
+
+       if (!mono_verifier_is_enabled_for_image (image))
+               return TRUE;
+
+       init_verify_context (&ctx, image, error_list != NULL);
+       ctx.stage = STAGE_TABLES;
+
+       is_valid_memberref_method_signature (&ctx, offset);
+       return cleanup_context (&ctx, error_list);
+}
+
+gboolean
+mono_verifier_verify_memberref_field_signature (MonoImage *image, guint32 offset, GSList **error_list)
 {
        VerifyContext ctx;
 
@@ -4024,7 +4094,7 @@ mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSLi
        init_verify_context (&ctx, image, error_list != NULL);
        ctx.stage = STAGE_TABLES;
 
-       is_valid_method_or_field_signature (&ctx, offset);
+       is_valid_field_signature (&ctx, offset);
        return cleanup_context (&ctx, error_list);
 }
 
@@ -4158,8 +4228,6 @@ mono_verifier_is_sig_compatible (MonoImage *image, MonoMethod *method, MonoMetho
                        return FALSE;
                if (original_sig->explicit_this != signature->explicit_this)
                        return FALSE;
-               if (original_sig->call_convention != signature->call_convention)
-                       return FALSE;
                if (original_sig->pinvoke != signature->pinvoke)
                        return FALSE;
                if (original_sig->sentinelpos != signature->sentinelpos)
@@ -4232,19 +4300,13 @@ mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *e
 
        mono_metadata_decode_row (table, row, data, MONO_METHODIMPL_SIZE);
 
-       body = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_BODY], NULL);
-       if (mono_loader_get_last_error ()) {
-               mono_loader_clear_error ();
-               mono_error_set_bad_image (error, image, "Invalid methodimpl body for row %x", row);
+       body = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_BODY], NULL, error);
+       if (!body)
                return FALSE;
-       }
 
-       declaration = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_DECLARATION], NULL);
-       if (mono_loader_get_last_error ()) {
-               mono_loader_clear_error ();
-               mono_error_set_bad_image (error, image, "Invalid methodimpl declaration for row %x", row);
+       declaration = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_DECLARATION], NULL, error);
+       if (!declaration)
                return FALSE;
-       }
 
        /* FIXME
        mono_class_setup_supertypes (class);
@@ -4313,12 +4375,6 @@ mono_verifier_verify_method_signature (MonoImage *image, guint32 offset, MonoErr
        return TRUE;
 }
 
-gboolean
-mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSList **error_list)
-{
-       return TRUE;
-}
-
 gboolean
 mono_verifier_verify_standalone_signature (MonoImage *image, guint32 offset, GSList **error_list)
 {
@@ -4376,4 +4432,16 @@ mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *e
        return TRUE;
 }
 
+gboolean
+mono_verifier_verify_memberref_method_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+       return TRUE;
+}
+
+gboolean
+mono_verifier_verify_memberref_field_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+       return TRUE;
+}
+
 #endif /* DISABLE_VERIFIER */