2009-03-24 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 24 Mar 2009 22:58:15 +0000 (22:58 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 24 Mar 2009 22:58:15 +0000 (22:58 -0000)
* gen-md-tests.c: Add stream-header and cli-metadata
helpers.

* cli-metadata-tests.md: New tests for the cli metadata header
and streams.

* Makefile: Add new tests.

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

mono/tests/metadata-verifier/Changelog
mono/tests/metadata-verifier/Makefile
mono/tests/metadata-verifier/cli-metadata-tests.md [new file with mode: 0644]
mono/tests/metadata-verifier/gen-md-tests.c

index 4884e5dca9c7947d9e3d3dae606b5eb7e2c9b9a4..ca7729df52dda9a1dc7ccde6d50c0b8a5e59ee4f 100644 (file)
@@ -1,3 +1,13 @@
+2009-03-24 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * gen-md-tests.c: Add stream-header and cli-metadata
+       helpers.
+
+       * cli-metadata-tests.md: New tests for the cli metadata header
+       and streams.
+
+       * Makefile: Add new tests.
+
 2009-03-19 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * cli-header-tests.md: More tests for the cli header.
index e0bb9f8d505aa08f1f1233206ac3e61816799a30..69183b085f4e4e89c9edad61d5083deba5bc98b9 100644 (file)
@@ -30,7 +30,11 @@ cli-header-tests.ok: gen-md-tests cli-header-tests.md simple-assembly.exe
        ./gen-md-tests cli-header-tests.md
        touch cli-header-tests.ok
 
-generate-stamp: header-tests.ok section-table-tests.ok data-directory-tests.ok resources-tests.ok cli-header-tests.ok
+cli-metadata-tests.ok: gen-md-tests cli-metadata-tests.md simple-assembly.exe
+       ./gen-md-tests cli-metadata-tests.md
+       touch cli-metadata-tests.ok
+
+generate-stamp: header-tests.ok section-table-tests.ok data-directory-tests.ok resources-tests.ok cli-header-tests.ok cli-metadata-tests.ok
        touch generate-stamp
 
 clean-stamps:
diff --git a/mono/tests/metadata-verifier/cli-metadata-tests.md b/mono/tests/metadata-verifier/cli-metadata-tests.md
new file mode 100644 (file)
index 0000000..1ce3b3e
--- /dev/null
@@ -0,0 +1,59 @@
+cli-metadata-root {
+       assembly simple-assembly.exe
+
+       #signature
+       valid offset translate.rva.ind ( cli-header + 8 ) set-uint 0x424A5342
+       valid offset cli-metadata + 0 set-uint 0x424A5342
+
+       invalid offset cli-metadata + 0 set-uint 0x434A5342
+       invalid offset cli-metadata + 0 set-uint 0x42455342
+       invalid offset cli-metadata + 0 set-uint 0x424A0342
+       invalid offset cli-metadata + 0 set-uint 0x424A5332
+
+       #we don't care about major/minor versions no runtime cares about them
+
+       #size too small
+       invalid offset cli-header + 12 set-uint 15
+       invalid offset cli-header + 12 set-uint 20
+       invalid offset cli-header + 12 set-uint 30
+
+       #version name is irrelevant as well
+
+       #the stream must have exactly 5 streams
+       valid offset cli-metadata + 16 + read.uint ( cli-metadata + 12 ) + 2 set-ushort 5
+       invalid offset cli-metadata + 16 + read.uint ( cli-metadata + 12 ) + 2 set-ushort 4
+}
+
+cli-metadata-stream-headers {
+       assembly simple-assembly.exe
+       #simple-assembly has version v2.0.50727 so the heade takes 32 bytes
+
+       #just to make sure
+       valid offset cli-metadata + 32 set-uint 0x6c
+       valid offset stream-header ( 0 ) + 0 set-uint 0x6c
+
+       #size too small
+       invalid offset cli-header + 12 set-uint 34
+       invalid offset cli-header + 12 set-uint 39
+
+
+       #offset doesn't bounds check
+       invalid offset stream-header ( 0 ) + 0 set-uint 0x888888
+       invalid offset stream-header ( 1 ) + 0 set-uint 0x888888
+       invalid offset stream-header ( 2 ) + 0 set-uint 0x888888
+       invalid offset stream-header ( 3 ) + 0 set-uint 0x888888
+       invalid offset stream-header ( 4 ) + 0 set-uint 0x888888
+
+       #size doesn't bounds check
+       invalid offset stream-header ( 0 ) + 4 set-uint 0x888888
+       invalid offset stream-header ( 1 ) + 4 set-uint 0x888888
+       invalid offset stream-header ( 2 ) + 4 set-uint 0x888888
+       invalid offset stream-header ( 3 ) + 4 set-uint 0x888888
+       invalid offset stream-header ( 4 ) + 4 set-uint 0x888888
+
+       #unkwnown name
+       invalid offset stream-header ( 0 ) + 8 set-byte 0x42
+
+       #duplicate name, change #~ to #US 
+       invalid offset stream-header ( 0 ) + 9 set-byte 0x55 , offset stream-header ( 0 ) + 10 set-byte 0x53
+}
\ No newline at end of file
index 951d0f874f27e64409f656ee7815e1d1971ae7af..8548fedad5e48743d5d38c0ff5c5c9d4f6878cb3 100644 (file)
@@ -66,7 +66,8 @@ function_call:
 fun_name:
        read.uint |
        translate.rva |
-       translate.rva.ind
+       translate.rva.ind |
+       stream-header
 
 arg_list:
        expression |
@@ -78,7 +79,8 @@ variable:
        pe-optional-header |
        pe-signature |
        section-table |
-       cli-header
+       cli-header |
+       cli-metadata
 
 TODO For the sake of a simple implementation, tokens are space delimited.
 */
@@ -285,6 +287,30 @@ translate_rva (test_entry_t *entry, guint32 rva)
        exit (INVALID_RVA);
 }
 
+static guint32
+get_cli_header (test_entry_t *entry)
+{
+       guint32 offset = get_pe_header (entry) + 20; /*pe-optional-header*/
+       offset += 208; /*cli header entry offset in the pe-optional-header*/
+       return translate_rva (entry, READ_VAR (guint32, entry->data + offset));
+}
+
+static guint32
+get_cli_metadata_root (test_entry_t *entry)
+{
+       guint32 offset = get_cli_header (entry);
+       offset += 8; /*metadata rva offset*/
+       return translate_rva (entry, READ_VAR (guint32, entry->data + offset));
+}
+
+static guint32
+pad4 (guint32 offset)
+{
+       if (offset % 4)
+               offset += 4 - (offset % 4);
+       return offset;
+}
+
 static guint32
 lookup_var (test_entry_t *entry, const char *name)
 {
@@ -298,12 +324,10 @@ lookup_var (test_entry_t *entry, const char *name)
                return get_pe_header (entry) + 20; 
        if (!strcmp ("section-table", name))
                return get_pe_header (entry) + 244; 
-       if (!strcmp ("cli-header", name)) {
-               guint32 offset = get_pe_header (entry) + 20; /*pe-optional-header*/
-               offset += 208; /*cli header entry offset in the pe-optional-header*/
-
-               return translate_rva (entry, READ_VAR (guint32, entry->data + offset));
-       }
+       if (!strcmp ("cli-header", name))
+               return get_cli_header (entry);
+       if (!strcmp ("cli-metadata", name)) 
+               return get_cli_metadata_root (entry);
 
        printf ("Unknown variable in expression %s\n", name);
        exit (INVALID_VARIABLE_NAME);
@@ -340,6 +364,30 @@ call_func (test_entry_t *entry, const char *name, GSList *args)
                rva = READ_VAR (guint32, entry->data + rva);
                return translate_rva (entry, rva);
        }
+       if (!strcmp ("stream-header", name)) {
+               guint32 idx, offset;
+               if (g_slist_length (args) != 1) {
+                       printf ("Invalid number of args to translate.rva %d\b", g_slist_length (args));
+                       exit (INVALID_ARG_COUNT);
+               }
+               idx = expression_eval (args->data, entry);
+               offset = get_cli_metadata_root (entry);
+               offset = pad4 (offset + 16 + READ_VAR (guint32, entry->data + offset + 12));
+
+               offset += 4;
+
+               while (idx--) {
+                       int i;
+
+                       offset += 8;
+                       for (i = 0; i < 32; ++i) {
+                               if (!READ_VAR (guint8, entry->data + offset))
+                                       break;
+                       }
+                       offset = pad4 (offset);
+               }
+               return offset;
+       }
 
        printf ("Unknown function %s\n", name);
        exit (INVALID_FUNCTION_NAME);