2009-06-19 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Fri, 19 Jun 2009 22:18:34 +0000 (22:18 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 19 Jun 2009 22:18:34 +0000 (22:18 -0000)
* metadata-verify.c: Add new mono_verifier_verify_full_table_data
function that perform the offline metadata verification steps.

* metadata-verify.c (verify_typedef_table): Move some checks to
verify_typedef_table_full and make it been called by new function
mono_verifier_verify_full_table_data.

* pedump.c: Call mono_verifier_verify_full_table_data.

* verify-internals.h: Export mono_verifier_verify_full_table_data as
part of the internal API.

svn path=/trunk/mono/; revision=136527

mono/metadata/ChangeLog
mono/metadata/metadata-verify.c
mono/metadata/pedump.c
mono/metadata/verify-internals.h

index 23d4c3d9bbb94380135910c8888a6a9b2284da56..bb4ea1ab72380e4574aa16bbe44abd453cc9fca7 100644 (file)
@@ -1,3 +1,17 @@
+2009-06-19 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * metadata-verify.c: Add new mono_verifier_verify_full_table_data
+       function that perform the offline metadata verification steps.
+
+       * metadata-verify.c (verify_typedef_table): Move some checks to
+       verify_typedef_table_full and make it been called by new function
+       mono_verifier_verify_full_table_data.
+
+       * pedump.c: Call mono_verifier_verify_full_table_data.
+
+       * verify-internals.h: Export mono_verifier_verify_full_table_data as
+       part of the internal API.
+
 2009-06-19 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * metadata-verify.c (typedef_is_system_object): Fix System.Object
@@ -13,7 +27,6 @@
 
        * pedump.c: Call mono_image_load_names.
 
-
 2009-06-19 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * image.c: Extract mono_image_load_names from do_mono_image_load.
index db4907843e9f23a7f8e721ab14e48fff9363b764..6fc02958db38f6b4f65d97fc6e3a1e8cb6b113a3 100644 (file)
@@ -1988,9 +1988,6 @@ verify_typedef_table (VerifyContext *ctx)
                        if (data [MONO_TYPEDEF_EXTENDS] != 0)
                                ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row 0 for the special <module> type must have a null extend field"));
                } else {
-                       if (typedef_is_system_object (ctx, data) && data [MONO_TYPEDEF_EXTENDS] != 0)
-                               ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d for System.Object must have a null extend field", i));
-       
                        if (data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_INTERFACE) {
                                if (data [MONO_TYPEDEF_EXTENDS])
                                        ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d for interface type must have a null extend field", i));
@@ -1999,9 +1996,6 @@ verify_typedef_table (VerifyContext *ctx)
                        } else {
                                if (!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 (!get_coded_index_token (TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS])) 
-                                       ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d for non-interface type must have a non-null extend field", i));
                        }
                }
 
@@ -2029,6 +2023,34 @@ verify_typedef_table (VerifyContext *ctx)
        }
 }
 
+static void
+verify_typedef_table_full (VerifyContext *ctx)
+{
+       MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_TYPEDEF];
+       guint32 data [MONO_TYPEDEF_SIZE];
+       int i;
+
+       if (table->rows == 0)
+               ADD_ERROR (ctx, g_strdup_printf ("Typedef table must have exactly at least one row"));
+
+       for (i = 1; i < table->rows; ++i) {
+               mono_metadata_decode_row (table, i, data, MONO_TYPEDEF_SIZE);
+               if (!(data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_INTERFACE)) {
+                       gboolean is_sys_obj = typedef_is_system_object (ctx, data);
+                       gboolean has_parent = get_coded_index_token (TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS]) != 0;
+
+                       if (is_sys_obj) {
+                               if (has_parent)
+                                       ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d for System.Object must have a null extend field", i));
+                       } else {
+                               if (!has_parent) {
+                                       ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d for non-interface type must have a non-null extend field", i));
+                               }
+                       }
+               }
+       }
+}
+
 /*bits 3,11,14 */
 #define INVALID_FIELD_FLAG_BITS ((1 << 3) | (1 << 11) | (1 << 14))
 static void
@@ -3160,6 +3182,18 @@ cleanup:
        return cleanup_context (&ctx, error_list);
 }
 
+
+/*
+ * Verifies basic table constraints such as global table invariants (sorting, field monotonicity, etc).
+ * Other verification checks are meant to be done lazily by the runtime. Those include:
+ *     blob items (signatures, method headers, custom attributes, etc)
+ *  type semantics related
+ *  vtable related
+ *  stuff that should not block other pieces from running such as bad types/methods/fields/etc.
+ * 
+ * The whole idea is that if this succeed the runtime is free to play around safely but any complex
+ * operation still need more checking.
+ */
 gboolean
 mono_verifier_verify_table_data (MonoImage *image, GSList **error_list)
 {
@@ -3175,6 +3209,27 @@ mono_verifier_verify_table_data (MonoImage *image, GSList **error_list)
 
        return cleanup_context (&ctx, error_list);
 }
+
+
+/*
+ * Verifies all other constraints.
+ */
+gboolean
+mono_verifier_verify_full_table_data (MonoImage *image, GSList **error_list)
+{
+       VerifyContext ctx;
+
+       if (!mono_verifier_is_enabled_for_image (image))
+               return TRUE;
+
+       init_verify_context (&ctx, image, error_list);
+       ctx.stage = STAGE_TABLES;
+
+       verify_typedef_table_full (&ctx);
+
+       return cleanup_context (&ctx, error_list);
+}
+
 #else
 gboolean
 mono_verifier_verify_table_data (MonoImage *image, GSList **error_list)
@@ -3193,4 +3248,11 @@ mono_verifier_verify_pe_data (MonoImage *image, GSList **error_list)
 {
        return TRUE;
 }
+
+gboolean
+mono_verifier_verify_full_table_data (MonoImage *image, GSList **error_list)
+{
+       return TRUE;
+}
+
 #endif /* DISABLE_VERIFIER */
index e7184bb90b955e603e740472f1776c0e35441b5c..83091fcbffb040c784e2584c45478f661c5b11b5 100644 (file)
@@ -452,6 +452,9 @@ verify_image_file (const char *fname)
 
        mono_image_load_names (image);
 
+       if (!mono_verifier_verify_full_table_data (image, &errors))
+               goto invalid_image;
+
        return 0;
 
 invalid_image:
index 9476ca95170933330380caa13558169c16f3e033..7e3c478afabc84d33d9695e0098dd93a5f3997cc 100644 (file)
@@ -30,6 +30,8 @@ gboolean mono_verifier_verify_pe_data (MonoImage *image, GSList **error_list) MO
 gboolean mono_verifier_verify_cli_data (MonoImage *image, GSList **error_list) MONO_INTERNAL;
 gboolean mono_verifier_verify_table_data (MonoImage *image, GSList **error_list) MONO_INTERNAL;
 
+gboolean mono_verifier_verify_full_table_data (MonoImage *image, GSList **error_list) MONO_INTERNAL;
+
 G_END_DECLS
 
 #endif  /* __MONO_METADATA_VERIFY_INTERNAL_H__ */