X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fverify.c;h=68fe0688774e03bdf70e4f80f566f1e98cc3abf8;hb=0a9b468aa9e09f392460c9c7246ce1f1835b41a7;hp=95bde8efbc5433a93c092b52b3d363ee63b859b5;hpb=f0d2ee46f839cc3cebcdaa674b3a31d9a3e22863;p=mono.git diff --git a/mono/metadata/verify.c b/mono/metadata/verify.c index 95bde8efbc5..68fe0688774 100644 --- a/mono/metadata/verify.c +++ b/mono/metadata/verify.c @@ -26,10 +26,10 @@ #include #include #include +#include #include #include #include -#include #include static MiniVerifierMode verifier_mode = MONO_VERIFIER_MODE_OFF; @@ -531,6 +531,8 @@ mono_type_is_valid_type_in_context_full (MonoType *type, MonoGenericContext *con return FALSE; break; } + default: + break; } return TRUE; } @@ -934,6 +936,7 @@ mono_method_is_valid_in_context (VerifyContext *ctx, MonoMethod *method) static MonoClassField* verifier_load_field (VerifyContext *ctx, int token, MonoClass **out_klass, const char *opcode) { + MonoError error; MonoClassField *field; MonoClass *klass = NULL; @@ -946,12 +949,12 @@ verifier_load_field (VerifyContext *ctx, int token, MonoClass **out_klass, const return NULL; } - field = mono_field_from_token (ctx->image, token, &klass, ctx->generic_context); + field = mono_field_from_token_checked (ctx->image, token, &klass, ctx->generic_context, &error); + mono_error_cleanup (&error); /*FIXME don't swallow the error */ } - if (!field || !field->parent || !klass || mono_loader_get_last_error ()) { + if (!field || !field->parent || !klass) { ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Cannot load field from token 0x%08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE); - mono_loader_clear_error (); return NULL; } @@ -973,20 +976,22 @@ static MonoMethod* verifier_load_method (VerifyContext *ctx, int token, const char *opcode) { MonoMethod* method; + if (ctx->method->wrapper_type != MONO_WRAPPER_NONE) { method = mono_method_get_wrapper_data (ctx->method, (guint32)token); } else { + MonoError error; if (!IS_METHOD_DEF_OR_REF_OR_SPEC (token) || !token_bounds_check (ctx->image, token)) { ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid method token 0x%08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE); return NULL; } - method = mono_get_method_full (ctx->image, token, NULL, ctx->generic_context); + method = mono_get_method_checked (ctx->image, token, NULL, ctx->generic_context, &error); + mono_error_cleanup (&error); /* FIXME don't swallow this error */ } - if (!method || mono_loader_get_last_error ()) { + if (!method) { ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Cannot load method from token 0x%08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE); - mono_loader_clear_error (); return NULL; } @@ -1446,6 +1451,8 @@ is_valid_bool_arg (ILStackDesc *arg) * is it a "class Foo" or a "struct Foo"? */ return !arg->type->data.generic_class->container_class->valuetype; + default: + return FALSE; } default: return FALSE; @@ -2982,6 +2989,12 @@ stack_slot_is_complex_type_not_reference_type (ILStackDesc *slot) return stack_slot_get_type (slot) == TYPE_COMPLEX && !MONO_TYPE_IS_REFERENCE (slot->type) && !stack_slot_is_boxed_value (slot); } +static gboolean +stack_slot_is_reference_value (ILStackDesc *slot) +{ + return stack_slot_get_type (slot) == TYPE_COMPLEX && (MONO_TYPE_IS_REFERENCE (slot->type) || stack_slot_is_boxed_value (slot)); +} + static void do_branch_op (VerifyContext *ctx, signed int delta, const unsigned char table [TYPE_MAX][TYPE_MAX]) { @@ -3055,7 +3068,8 @@ do_cmp_op (VerifyContext *ctx, const unsigned char table [TYPE_MAX][TYPE_MAX], g a = stack_pop (ctx); if (opcode == CEE_CGT_UN) { - if (stack_slot_get_type (a) == TYPE_COMPLEX && stack_slot_get_type (b) == TYPE_COMPLEX) { + if ((stack_slot_is_reference_value (a) && stack_slot_is_null_literal (b)) || + (stack_slot_is_reference_value (b) && stack_slot_is_null_literal (a))) { stack_push_val (ctx, TYPE_I4, &mono_defaults.int32_class->byval_arg); return; } @@ -3078,7 +3092,11 @@ do_cmp_op (VerifyContext *ctx, const unsigned char table [TYPE_MAX][TYPE_MAX], g } if(res == TYPE_INV) { - CODE_NOT_VERIFIABLE (ctx, g_strdup_printf("Compare instruction applyed to ill formed stack (%s x %s) at 0x%04x", stack_slot_get_name (a), stack_slot_get_name (b), ctx->ip_offset)); + char *left_type = stack_slot_full_name (a); + char *right_type = stack_slot_full_name (b); + CODE_NOT_VERIFIABLE (ctx, g_strdup_printf("Compare instruction applyed to ill formed stack (%s x %s) at 0x%04x", left_type, right_type, ctx->ip_offset)); + g_free (left_type); + g_free (right_type); } else if (res & NON_VERIFIABLE_RESULT) { CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Compare instruction is not verifiable (%s x %s) at 0x%04x", stack_slot_get_name (a), stack_slot_get_name (b), ctx->ip_offset)); res = res & ~NON_VERIFIABLE_RESULT; @@ -3126,6 +3144,7 @@ do_ret (VerifyContext *ctx) static void do_invoke_method (VerifyContext *ctx, int method_token, gboolean virtual) { + MonoError error; int param_count, i; MonoMethodSignature *sig; ILStackDesc *value; @@ -3155,12 +3174,15 @@ do_invoke_method (VerifyContext *ctx, int method_token, gboolean virtual) } } - if (!(sig = mono_method_get_signature_full (method, ctx->image, method_token, ctx->generic_context))) - sig = mono_method_get_signature (method, ctx->image, method_token); + if (!(sig = mono_method_get_signature_checked (method, ctx->image, method_token, ctx->generic_context, &error))) { + mono_error_cleanup (&error); + sig = mono_method_get_signature_checked (method, ctx->image, method_token, NULL, &error); + } if (!sig) { char *name = mono_type_get_full_name (method->klass); - ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Could not resolve signature of %s:%s at 0x%04x", name, method->name, ctx->ip_offset)); + ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Could not resolve signature of %s:%s at 0x%04x due to: %s", name, method->name, ctx->ip_offset, mono_error_get_message (&error))); + mono_error_cleanup (&error); g_free (name); return; } @@ -3591,6 +3613,7 @@ do_conversion (VerifyContext *ctx, int kind) static void do_load_token (VerifyContext *ctx, int token) { + MonoError error; gpointer handle; MonoClass *handle_class; if (!check_overflow (ctx)) @@ -3620,11 +3643,12 @@ do_load_token (VerifyContext *ctx, int token) return; } - handle = mono_ldtoken (ctx->image, token, &handle_class, ctx->generic_context); + handle = mono_ldtoken_checked (ctx->image, token, &handle_class, ctx->generic_context, &error); } if (!handle) { - ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid token 0x%x for ldtoken at 0x%04x", token, ctx->ip_offset)); + ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid token 0x%x for ldtoken at 0x%04x due to %s", token, ctx->ip_offset, mono_error_get_message (&error))); + mono_error_cleanup (&error); return; } if (handle_class == mono_defaults.typehandle_class) { @@ -3882,6 +3906,8 @@ do_cast (VerifyContext *ctx, int token, const char *opcode) { case MONO_TYPE_PTR: case MONO_TYPE_TYPEDBYREF: CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid value for %s at 0x%04x", opcode, ctx->ip_offset)); + default: + break; } do_box = is_boxed || mono_type_is_generic_argument(type) || mono_class_from_mono_type (type)->valuetype; @@ -4397,8 +4423,6 @@ do_sizeof (VerifyContext *ctx, int token) static void do_localloc (VerifyContext *ctx) { - ILStackDesc *top; - if (ctx->eval.size != 1) { ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Stack must have only size item in localloc at 0x%04x", ctx->ip_offset)); return; @@ -4410,7 +4434,7 @@ do_localloc (VerifyContext *ctx) } /*TODO verify top type*/ - top = stack_pop (ctx); + /* top = */ stack_pop (ctx); set_stack_value (ctx, stack_push (ctx), &mono_defaults.int_class->byval_arg, FALSE); CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Instruction localloc in never verifiable at 0x%04x", ctx->ip_offset)); @@ -4802,7 +4826,7 @@ mono_method_verify (MonoMethod *method, int level) MonoSimpleBasicBlock *bb = NULL, *original_bb = NULL; int i, n, need_merge = 0, start = 0; - guint token, ip_offset = 0, prefix = 0; + guint ip_offset = 0, prefix = 0; MonoGenericContext *generic_context = NULL; MonoImage *image; VerifyContext ctx; @@ -5347,7 +5371,7 @@ mono_method_verify (MonoMethod *method, int level) code_bounds_check (5); if (ctx.eval.size) ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Eval stack must be empty in jmp at 0x%04x", ip_offset)); - token = read32 (ip + 1); + /* token = read32 (ip + 1); */ if (in_any_block (ctx.header, ip_offset)) ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("jmp cannot escape exception blocks at 0x%04x", ip_offset)); @@ -5366,7 +5390,7 @@ mono_method_verify (MonoMethod *method, int level) case CEE_CALLI: code_bounds_check (5); - token = read32 (ip + 1); + /* token = read32 (ip + 1); */ /* * FIXME: check signature, retval, arguments etc. * FIXME: check requirements for tail call