#include <mono/metadata/tokentype.h>
#include <mono/metadata/mono-basic-block.h>
#include <mono/metadata/attrdefs.h>
+#include <mono/metadata/class-internals.h>
#include <mono/utils/mono-counters.h>
#include <mono/utils/monobitset.h>
#include <string.h>
-#include <signal.h>
#include <ctype.h>
static MiniVerifierMode verifier_mode = MONO_VERIFIER_MODE_OFF;
return FALSE;
break;
}
+ default:
+ break;
}
return TRUE;
}
static MonoClassField*
verifier_load_field (VerifyContext *ctx, int token, MonoClass **out_klass, const char *opcode) {
+ MonoError error;
MonoClassField *field;
MonoClass *klass = NULL;
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;
}
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;
}
* is it a "class Foo<T>" or a "struct Foo<T>"?
*/
return !arg->type->data.generic_class->container_class->valuetype;
+ default:
+ return FALSE;
}
default:
return FALSE;
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])
{
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;
}
}
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;
static void
do_invoke_method (VerifyContext *ctx, int method_token, gboolean virtual)
{
+ MonoError error;
int param_count, i;
MonoMethodSignature *sig;
ILStackDesc *value;
}
}
- 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;
}
static void
do_load_token (VerifyContext *ctx, int token)
{
+ MonoError error;
gpointer handle;
MonoClass *handle_class;
if (!check_overflow (ctx))
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) {
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;
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;
}
/*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));
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;
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));
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