Thu Oct 4 19:10:30 CEST 2001 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Thu, 4 Oct 2001 13:32:23 +0000 (13:32 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Thu, 4 Oct 2001 13:32:23 +0000 (13:32 -0000)
* class.c: MonoTypes stored in MonoClass are stored as
fundamental MonoTypes when the class represents a
fundamental type (System.Int32, ...).
The TypeHandle return by ldtoken is a MonoType*.
* icall.c: ves_icall_get_data_chunk () write out all the
PE/COFF stuff. Implement ves_icall_define_method (),
ves_icall_set_method_body (), ves_icall_type_from_handle ().
* image.c: properly skip unknown streams.
* loader.h, loader.c: add type_class to mono_defaults.
* metadata.c, metadata.h: export compute_size () as
mono_metadata_compute_size () with a better interface.
Typo and C&P fixes.
* pedump.c: don't try to print the entry point RVA if there is no entry point.
* reflection.c, reflection.h: many cleanups, fixes, output method
signatures and headers, typedef and typeref info, compress the metadata
tables, output all the heap streams, cli header etc.
* row-indexes.h: typo fixes.

Thu Oct 4 19:09:13 CEST 2001 Paolo Molaro <lupus@ximian.com>

* x86/tramp.c: allow marshalling valuetypes if they are
4 bytes long.

Thu Oct 4 19:05:56 CEST 2001 Paolo Molaro <lupus@ximian.com>

* dis-cil.c: fix printing of exception stuff.
* dump.c: display some more info in the typedef table dump.
* main.c: typo fix and method list fix.

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

19 files changed:
mono/arch/ChangeLog
mono/arch/x86/tramp.c
mono/dis/ChangeLog
mono/dis/dis-cil.c
mono/dis/dump.c
mono/dis/get.c
mono/dis/main.c
mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/icall.c
mono/metadata/image.c
mono/metadata/loader.c
mono/metadata/loader.h
mono/metadata/metadata.c
mono/metadata/metadata.h
mono/metadata/pedump.c
mono/metadata/reflection.c
mono/metadata/reflection.h
mono/metadata/row-indexes.h

index 15f623f4a9895c6f1a273d779ee67a6abf0be42e..43bb4a958a17589c9443fb153178a8cb013934ef 100644 (file)
@@ -1,4 +1,9 @@
 
+Thu Oct 4 19:09:13 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+       * x86/tramp.c: allow marshalling valuetypes if they are
+       4 bytes long.
+
 Mon Oct 1 18:48:27 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * x86/tramp.c: fix thinko (s/SUB/ADD/) in stack adjustment
index ec83c92ba3e099fc6d4c8227e18a7e69f3056e1d..38ce31fdc006c9bc2fc3b0211bcc21b15b80e1b2 100644 (file)
@@ -95,8 +95,8 @@ mono_create_trampoline (MonoMethod *method)
                        code_size += i < 10 ? 5 : 8;
                        break;
                case MONO_TYPE_VALUETYPE:
-                       if (!sig->params [i]->data.klass->enumtype)
-                               g_error ("can only marshal enums, not generic structures");
+                       if (!sig->params [i]->data.klass->enumtype && (mono_class_value_size (sig->params [i]->data.klass, NULL) != 4))
+                               g_error ("can only marshal enums, not generic structures (size: %d)", mono_class_value_size (sig->params [i]->data.klass, NULL));
                        stack_size += 4;
                        code_size += i < 10 ? 5 : 8;
                        break;
@@ -172,9 +172,18 @@ mono_create_trampoline (MonoMethod *method)
                case MONO_TYPE_CLASS:
                case MONO_TYPE_OBJECT:
                case MONO_TYPE_R4:
-               case MONO_TYPE_VALUETYPE: /* only enums supported right now, anyway */
                        x86_push_membase (p, X86_EDX, arg_pos);
                        break;
+               case MONO_TYPE_VALUETYPE:
+                       if (!sig->params [i - 1]->data.klass->enumtype) {
+                               /* it's a structure that fits in 4 bytes, need to push the value pointed to */
+                               x86_mov_reg_membase (p, X86_EAX, X86_EDX, arg_pos, 4);
+                               x86_push_regp (p, X86_EAX);
+                       } else {
+                               /* it's an enum value */
+                               x86_push_membase (p, X86_EDX, arg_pos);
+                       }
+                       break;
                case MONO_TYPE_R8:
                        x86_alu_reg_imm (p, X86_SUB, X86_ESP, 8);
                        x86_fld_membase (p, X86_EDX, arg_pos, TRUE);
index 80fd27a6f3ed7f100ae6037e27706131ee59ebf0..a20bbca3662dff6f748f872ed3466f8e4ff08d6f 100644 (file)
@@ -1,3 +1,10 @@
+
+Thu Oct 4 19:05:56 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+       * dis-cil.c: fix printing of exception stuff.
+       * dump.c: display some more info in the typedef table dump.
+       * main.c: typo fix and method list fix.
+
 2001-10-04  Dick Porter  <dick@ximian.com>
 
        * meta.h: include mono-endian.h not endian.h
index 13f4b59dad675c74e45b734b4b52461bc2e681aa..0b6a790711361e2f87f9c64a21548c1fef0b38b2 100644 (file)
@@ -102,7 +102,7 @@ dissasemble_cil (MonoMetadata *m, MonoMethodHeader *mh)
 
        while (ptr < end){
                for (i = 0; i < mh->num_clauses; ++i) {
-                       if (!mh->clauses[i].flags && ptr == start + mh->clauses[i].try_offset) {
+                       if ((mh->clauses[i].flags == 0 || mh->clauses[i].flags == 2) && ptr == start + mh->clauses[i].try_offset) {
                                fprintf (output, "\t%s.try { // %d\n", indent, i);
                                CODE_INDENT;
                        }
@@ -285,7 +285,7 @@ dissasemble_cil (MonoMetadata *m, MonoMethodHeader *mh)
 
                fprintf (output, "\n");
                for (i = 0; i < mh->num_clauses; ++i) {
-                       if (!mh->clauses[i].flags && ptr == start + mh->clauses[i].try_offset + mh->clauses[i].try_len) {
+                       if ((mh->clauses[i].flags == 0 || mh->clauses[i].flags == 2)  && ptr == start + mh->clauses[i].try_offset + mh->clauses[i].try_len) {
                                CODE_UNINDENT;
                                fprintf (output, "\t%s} // end .try %d\n", indent, i);
                        }
index feec4de30ffac4156c80e213e299217f91ef0cbb..b1cb2f1607259df8b11adee1b32c8b16111b5941 100644 (file)
@@ -79,7 +79,9 @@ dump_table_typedef (MonoMetadata *m)
 
                mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], i - 1, cols, MONO_TYPEDEF_SIZE);
 
-               fprintf (output, "%d: %s (flist=%d, mlist=%d)\n", i, s, cols [MONO_TYPEDEF_FIELD_LIST], cols [MONO_TYPEDEF_METHOD_LIST]);
+               fprintf (output, "%d: %s (flist=%d, mlist=%d, flags=0x%x, extends=0x%x)\n", i, s, 
+                                       cols [MONO_TYPEDEF_FIELD_LIST], cols [MONO_TYPEDEF_METHOD_LIST],
+                                       cols [MONO_TYPEDEF_FLAGS], cols [MONO_TYPEDEF_EXTENDS]);
                g_free (s);
        }
        fprintf (output, "\n");
index 522139001fba6c97d0f6afd0dde2ac660e448e38..0e2af93c025468a1f84ed668bf441f70d5d822dd 100644 (file)
@@ -503,6 +503,8 @@ dis_stringify_object (MonoMetadata *m, MonoType *type)
        char *otype = type->type == MONO_TYPE_CLASS? "class" : "valuetype";
        char *assemblyref = NULL;
        MonoClass *c = type->data.klass;
+       if (!c)
+               return g_strdup ("Unknown");
        if (m != c->image) {
                /* we cheat */
                if (!strcmp ("corlib", c->image->assembly_name))
index 5c5b484d642673d1b9c477541c70f069f6c110c6..7a3a8df85937301f2efe10a6018925172860560a 100644 (file)
@@ -452,7 +452,7 @@ dis_method_list (MonoMetadata *m, guint32 start, guint32 end)
                mono_metadata_decode_row (t, i, cols, MONO_METHOD_SIZE);
 
                flags = method_flags (cols [MONO_METHOD_FLAGS]);
-               impl_flags = method_impl_flags (cols [MONO_METHOD_IMPLFALGS]);
+               impl_flags = method_impl_flags (cols [MONO_METHOD_IMPLFLAGS]);
 
                sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
                mono_metadata_decode_blob_size (sig, &sig);
@@ -720,7 +720,7 @@ dis_type (MonoMetadata *m, int n)
        else
                last = m->tables [MONO_TABLE_METHOD].rows;
        
-       if (cols [MONO_TYPEDEF_METHOD_LIST] < m->tables [MONO_TABLE_METHOD].rows)
+       if (cols [MONO_TYPEDEF_METHOD_LIST] && cols [MONO_TYPEDEF_METHOD_LIST] <= m->tables [MONO_TABLE_METHOD].rows)
                dis_method_list (m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last);
 
        dis_property_list (m, n);
index 7c5a1b769ad778e2881086729de36a0175da0034..2debf817dd2a06eefd148fe03be52ed29cd1359f 100644 (file)
@@ -1,3 +1,24 @@
+
+Thu Oct 4 19:10:30 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+       * class.c: MonoTypes stored in MonoClass are stored as
+       fundamental MonoTypes when the class represents a
+       fundamental type (System.Int32, ...).
+       The TypeHandle return by ldtoken is a MonoType*.
+       * icall.c: ves_icall_get_data_chunk () write out all the
+       PE/COFF stuff. Implement ves_icall_define_method (),
+       ves_icall_set_method_body (), ves_icall_type_from_handle ().
+       * image.c: properly skip unknown streams.
+       * loader.h, loader.c: add type_class to mono_defaults.
+       * metadata.c, metadata.h: export compute_size () as
+       mono_metadata_compute_size () with a better interface.
+       Typo and C&P fixes.
+       * pedump.c: don't try to print the entry point RVA if there is no entry point.
+       * reflection.c, reflection.h: many cleanups, fixes, output method
+       signatures and headers, typedef and typeref info, compress the metadata
+       tables, output all the heap streams, cli header etc.
+       * row-indexes.h: typo fixes.
+
 2001-10-04  Dick Porter  <dick@ximian.com>
 
        * object.h: Add a synchronisation mutex struct to MonoObject
index 8bac9c57cb04b3ff15e99b78c4b18b1e393d22af..7504d99e2da15f9fe89995705dc6336273e86594 100644 (file)
@@ -235,10 +235,23 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
                        class->valuetype = 1;
                        class->enumtype = 1;
                }
-       }
-       if (class->valuetype) {
-               class->this_arg.type = MONO_TYPE_VALUETYPE;
-               class->byval_arg.type = MONO_TYPE_VALUETYPE;
+               if (class->valuetype) {
+                       int t = MONO_TYPE_VALUETYPE;
+                       /* 
+                        * FIXME: add more cases so that we use the simpler monotype
+                        * for the fundamental types.
+                        */
+                       switch (*name) {
+                       case 'I':
+                               if (!strcmp (name, "Int32")) {
+                                       t = MONO_TYPE_I4;
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+                       class->this_arg.type = class->byval_arg.type = t;
+               }
        }
        
        /*
@@ -629,10 +642,14 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class)
 {
        switch (token & 0xff000000) {
        case MONO_TOKEN_TYPE_DEF:
-       case MONO_TOKEN_TYPE_REF:
+       case MONO_TOKEN_TYPE_REF: {
+               MonoClass *class;
                if (handle_class)
                        *handle_class = mono_defaults.typehandle_class;
-               return mono_class_get (image, token);
+               class = mono_class_get (image, token);
+               /* We return a MonoType* as handle */
+               return &class->byval_arg;
+       }
        case MONO_TOKEN_METHOD_DEF:
        case MONO_TOKEN_FIELD_DEF:
        case MONO_TOKEN_MEMBER_REF:
index 05e58a148ef10242f57b24e4e6c313a92399c69c..5b3d388adab175399b067c5ea6bbd5c46f5624da 100644 (file)
@@ -206,16 +206,21 @@ my_mono_new_object (MonoClass *klass, gpointer data)
 }
 
 static gpointer
-object_impl_pointer (MonoObject *obj)
+object_field_pointer (MonoObject *obj, char *name)
 {
        MonoClassField *field;
        gpointer *slot;
 
-       field = mono_class_get_field_from_name (obj->klass, "_impl");
+       field = mono_class_get_field_from_name (obj->klass, name);
        slot = (gpointer*)((char*)obj + field->offset);
        return *slot;
 }
 
+static gpointer
+object_impl_pointer (MonoObject *obj)
+{
+       return object_field_pointer (obj, "_impl");
+}
 
 static MonoObject *
 ves_icall_app_define_assembly (MonoObject *appdomain, MonoObject *assembly_name, int access)
@@ -237,11 +242,29 @@ static gint32
 ves_icall_get_data_chunk (MonoObject *assb, gint32 type, MonoArrayObject *buf)
 {
        MonoDynamicAssembly *ass = object_impl_pointer (assb);
+       MonoObject *ep;
        int count;
+       /*
+        * get some info from the object
+        */
+       ep = object_field_pointer (assb, "entry_point");
+       if (ep)
+               ass->entry_point = object_impl_pointer (ep);
+       else
+               ass->entry_point = 0;
 
-       count = mono_image_get_header (ass, buf->vector, buf->bounds->length);
-       if (count != -1)
+       if (type == 0) { /* get the header */
+               count = mono_image_get_header (ass, buf->vector, buf->bounds->length);
+               if (count != -1)
+                       return count;
+       } else {
+               count = ass->code.index + ass->meta_size;
+               if (count > buf->bounds->length)
+                       return 0;
+               memcpy (buf->vector, ass->code.data, ass->code.index);
+               memcpy (buf->vector + ass->code.index, ass->assembly.image->raw_metadata, ass->meta_size);
                return count;
+       }
        
        return 0;
 }
@@ -285,11 +308,52 @@ ves_icall_define_type (MonoObject *moduleb, MonoObject *name, int attrs)
 }
 
 static MonoObject *
-ves_icall_define_method (MonoObject *typeb, MonoObject *name, int attrs, int callconv, MonoObject *rettype, MonoObject *paramtypes)
+ves_icall_define_method (MonoObject *typeb, MonoObject *name, int attrs, int callconv, MonoObject *rettype, MonoArrayObject *paramtypes)
 {
        MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "MethodBuilder");
+       MonoMethodBuilder *mb = g_new0 (MonoMethodBuilder, 1);
+       MonoTypeBuilder *tb = object_impl_pointer (typeb);
 
-       return mono_new_object (klass);
+       mb->name = mono_string_to_utf8 (name);
+       mb->attrs = attrs;
+       mb->callconv = callconv;
+       mb->ret = object_impl_pointer (rettype);
+       /* ignore params ... */
+
+       if (!tb->has_default_ctor) {
+               if (strcmp (".ctor", mb->name) == 0 && paramtypes->bounds->length == 0)
+                       tb->has_default_ctor = 1;
+       }
+       
+       tb->methods = g_list_prepend (tb->methods, mb);
+
+       return my_mono_new_object (klass, mb);
+}
+
+static void
+ves_icall_set_method_body (MonoObject *methodb, MonoArrayObject *code, gint32 count)
+{
+       MonoMethodBuilder *mb = object_impl_pointer (methodb);
+       if (code->bounds->length < count) {
+               g_warning ("code len is less than count");
+               return;
+       }
+       g_free (mb->code);
+       mb->code = g_malloc (count);
+       mb->code_size = count;
+       memcpy (mb->code, code->vector, count);
+}
+
+static MonoObject*
+ves_icall_type_from_name (MonoObject *name)
+{
+       return NULL;
+}
+
+static MonoObject*
+ves_icall_type_from_handle (gpointer handle)
+{
+       return my_mono_new_object (mono_defaults.type_class, handle);
 }
 
 static gpointer icall_map [] = {
@@ -338,6 +402,17 @@ static gpointer icall_map [] = {
         */
        "System.Reflection.Emit.TypeBuilder::defineMethod", ves_icall_define_method,
        
+       /*
+        * MethodBuilder
+        */
+       "System.Reflection.Emit.MethodBuilder::set_method_body", ves_icall_set_method_body,
+       
+       /*
+        * System.Type
+        */
+       "System.Type::internal_from_name", ves_icall_type_from_name,
+       "System.Type::internal_from_handle", ves_icall_type_from_handle,
+       
        /*
         * System.Threading
         */
index 2b35afa69abc62460ad79ddd1a1f8549463c644d..51d4d6d941dab0acb18cd6328561c94bff3954f9 100644 (file)
@@ -285,8 +285,10 @@ load_metadata_ptrs (MonoImage *image, MonoCLIImageInfo *iinfo)
                        image->heap_guid.offset = read32 (ptr);
                        image->heap_guid.size = read32 (ptr + 4);
                        ptr += 8 + 6;
-               } else
+               } else {
                        g_message ("Unknown heap type: %s\n", ptr + 8);
+                       ptr += 8 + strlen (ptr) + 1;
+               }
                if (((guint32)ptr) % 4){
                        ptr += 4 - (((guint32)ptr) % 4);
                }
index 9e22e1dc91fb26461f25ad187bf555b3ae230b5e..c28c800a91ab3b90e431dd961c31060ff8b3fd96 100644 (file)
@@ -166,9 +166,9 @@ mono_init (void)
                 mono_defaults.corlib, "System", "RuntimeFieldHandle");
        g_assert (mono_defaults.fieldhandle_class != 0);
 
-       mono_defaults.typehandle_class = mono_class_from_name (
-                mono_defaults.corlib, "System", "RuntimeTypeHandle");
-       g_assert (mono_defaults.typehandle_class != 0);
+       mono_defaults.type_class = mono_class_from_name (
+                mono_defaults.corlib, "System", "Type");
+       g_assert (mono_defaults.type_class != 0);
 
 }
 
index a719e3a7fc2f0e6820744915f564aa800f069c40..6939cd517e110995852d5ae80101ea2d9124fe1b 100644 (file)
@@ -50,6 +50,7 @@ typedef struct {
        MonoClass *typehandle_class;
        MonoClass *fieldhandle_class;
        MonoClass *methodhandle_class;
+       MonoClass *type_class;
 } MonoDefaults;
 
 extern MonoDefaults mono_defaults;
index 00ce474c0dc3160d4ab646f9999d59758d0b65b8..4605d6c810440794f1cdcc4dbf05724a65eb11f8 100644 (file)
@@ -366,13 +366,14 @@ inverse of this mapping.
 #define idx_size(tableidx) (meta->tables [(tableidx)].rows < 65536 ? 2 : 4)
 
 /* Reference: Partition II - 23.2.6 */
-static int
-compute_size (MonoMetadata *meta, MonoMetaTable *table, int tableindex, guint32 *result_bitfield)
+int
+mono_metadata_compute_size (MonoMetadata *meta, int tableindex, guint32 *result_bitfield)
 {
        guint32 bitfield = 0;
        int size = 0, field_size;
        int i, n, code;
        int shift = 0;
+       MonoMetaTable *table = tables [tableindex].table;
 
        for (i = 0; (code = table [i].code) != MONO_MT_END; i++){
                switch (code){
@@ -674,9 +675,8 @@ mono_metadata_compute_table_bases (MonoMetadata *meta)
                if (meta->tables [i].rows == 0)
                        continue;
 
-               meta->tables [i].row_size = compute_size (
-                       meta, tables [i].table, i,
-                       &meta->tables [i].size_bitfield);
+               meta->tables [i].row_size = mono_metadata_compute_size (
+                       meta, i, &meta->tables [i].size_bitfield);
                meta->tables [i].base = base;
                base += meta->tables [i].rows * meta->tables [i].row_size;
        }
@@ -1457,12 +1457,12 @@ mono_metadata_parse_mh (MonoMetadata *m, const char *ptr)
        if (local_var_sig_tok) {
                MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
                const char *ptr;
-               guint32 cols [MONO_STAND_ALONG_SIGNATURE_SIZE];
+               guint32 cols [MONO_STAND_ALONE_SIGNATURE_SIZE];
                int len=0, i, bsize;
                guint offset = 0;
 
                mono_metadata_decode_row (t, (local_var_sig_tok & 0xffffff)-1, cols, 1);
-               ptr = mono_metadata_blob_heap (m, cols [MONO_STAND_ALONG_SIGNATURE]);
+               ptr = mono_metadata_blob_heap (m, cols [MONO_STAND_ALONE_SIGNATURE]);
                bsize = mono_metadata_decode_blob_size (ptr, &ptr);
                if (*ptr != 0x07)
                        g_warning ("wrong signature for locals blob");
@@ -1889,7 +1889,7 @@ mono_metadata_encode_value (guint32 value, char *buf, char **endbuf)
        char *p = buf;
        
        if (value <= 127)
-               *p++ = 127;
+               *p++ = value;
        else if (value <= 16384) {
                p [0] = 0x80 | (value >> 8);
                p [1] = value & 0xff;
index d10b24e14d7bcdf3161115042950abde8eaa2a95..514b6aeed54f8bb35f38f55889795e5715230985 100644 (file)
@@ -95,6 +95,10 @@ guint32      mono_metadata_decode_row_col (MonoTableInfo *t,
 #define mono_metadata_table_size(bitfield,table) ((((bitfield) >> ((table)*2)) & 0x3) + 1)
 #define mono_metadata_table_count(bitfield) ((bitfield) >> 24)
 
+int mono_metadata_compute_size (MonoMetadata   *meta,
+                                int             tableindex,
+                                guint32        *result_bitfield);
+
 /*
  *
  */
index cc47d92d1b776e880e49ed44bf8ffdcb62e0975f..0adc75350b424173e2f88017be058eb673954741 100644 (file)
@@ -253,6 +253,8 @@ dump_methoddef (MonoMetadata *metadata, guint32 token)
 {
        char *loc;
 
+       if (!token)
+               return;
        loc = mono_metadata_locate_token (metadata, token);
 
        printf ("RVA for Entry Point: 0x%08x\n", read32 (loc));
index 08bef01f6affc03fca34ed83cc58a1ac18977fec..65cc14c1ddde8a8db7e72124bc17e14fe56e5c81 100644 (file)
@@ -10,6 +10,8 @@
  */
 #include <config.h>
 #include "mono/metadata/reflection.h"
+#include "mono/metadata/tabledefs.h"
+#include "mono/metadata/tokentype.h"
 #include <stdio.h>
 #include <glib.h>
 #include <errno.h>
 #include "mono-endian.h"
 #include "private.h"
 
+#define TEXT_OFFSET 512
+#define CLI_H_SIZE 136
+#define FILE_ALIGN 512
+
+const unsigned char table_sizes [64] = {
+       MONO_MODULE_SIZE,
+       MONO_TYPEREF_SIZE,
+       MONO_TYPEDEF_SIZE,
+       0,
+       MONO_FIELD_SIZE,
+       0,
+       MONO_METHOD_SIZE,
+       0,
+       MONO_PARAM_SIZE,
+       MONO_INTERFACEIMPL_SIZE,
+       MONO_MEMBERREF_SIZE,    /* 0x0A */
+       MONO_CONSTANT_SIZE,
+       MONO_CUSTOM_ATTR_SIZE,
+       MONO_FIELD_MARSHAL_SIZE,
+       MONO_DECL_SECURITY_SIZE,
+       MONO_CLASS_LAYOUT_SIZE,
+       MONO_FIELD_LAYOUT_SIZE, /* 0x10 */
+       MONO_STAND_ALONE_SIGNATURE_SIZE,
+       MONO_EVENT_MAP_SIZE,
+       0,
+       MONO_EVENT_SIZE,
+       MONO_PROPERTY_MAP_SIZE,
+       0,
+       MONO_PROPERTY_SIZE,
+       MONO_METHOD_SEMA_SIZE,
+       MONO_MTHODIMPL_SIZE,
+       MONO_MODULEREF_SIZE,    /* 0x1A */
+       MONO_TYPESPEC_SIZE,
+       MONO_IMPLMAP_SIZE,      
+       MONO_FIELD_RVA_SIZE,
+       0,
+       0,
+       MONO_ASSEMBLY_SIZE,     /* 0x20 */
+       MONO_ASSEMBLY_PROCESSOR_SIZE,
+       MONO_ASSEMBLYOS_SIZE,
+       MONO_ASSEMBLYREF_SIZE,
+       MONO_ASSEMBLYREFPROC_SIZE,
+       MONO_ASSEMBLYREFOS_SIZE,
+       MONO_FILE_SIZE,
+       MONO_EXP_TYPE_SIZE,
+       MONO_MANIFEST_SIZE,
+       MONO_NESTED_CLASS_SIZE,
+       0       /* 0x2A */
+};
+
+static void
+alloc_table (MonoDynamicTable *table, guint nrows)
+{
+       table->rows = nrows;
+       g_assert (table->columns);
+       table->values = g_realloc (table->values, (1 + table->rows) * table->columns * sizeof (guint32));
+}
 
 static guint32
-string_heap_insert (MonoStringHeap *sh, char *str)
+string_heap_insert (MonoStringHeap *sh, const char *str)
 {
-       guint32 idx = GPOINTER_TO_UINT(g_hash_table_lookup (sh, str));
+       guint32 idx;
        guint32 len;
-       if (idx)
-               return idx;
+       gpointer oldkey, oldval;
+
+       if (g_hash_table_lookup_extended (sh->hash, str, &oldkey, &oldval))
+               return GPOINTER_TO_UINT (oldval);
+
        len = strlen (str) + 1;
        idx = sh->index;
        if (idx + len > sh->alloc_size) {
@@ -64,25 +126,172 @@ string_heap_free (MonoStringHeap *sh)
        g_hash_table_destroy (sh->hash);
 }
 
+static guint32
+mono_image_add_stream_data (MonoDynamicStream *stream, char *data, guint32 len)
+{
+       guint32 idx;
+       if (stream->alloc_size < stream->index + len) {
+               stream->alloc_size += len + 4096;
+               stream->data = g_realloc (stream->data, stream->alloc_size);
+       }
+       memcpy (stream->data + stream->index, data, len);
+       idx = stream->index;
+       stream->index += len;
+       /* 
+        * align index? Not without adding an additional param that controls it since
+        * we may store a blob value in pieces.
+        */
+       return idx;
+}
+
 static void
-mono_image_add_blob_data (MonoDynamicAssembly *assembly, char *data, guint32 len)
+encode_type (MonoType *type, char *p, char **endbuf)
+{
+       switch (type->type){
+       case MONO_TYPE_VOID:
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+       case MONO_TYPE_R4:
+       case MONO_TYPE_R8:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U:
+       case MONO_TYPE_STRING:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_TYPEDBYREF:
+               mono_metadata_encode_value (type->type, p, endbuf);
+               break;
+       default:
+               g_error ("need to encode type %d", type->type);
+       }
+}
+
+static guint32
+method_encode_signature (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
+{
+       char *buf;
+       char *p;
+       int i;
+       guint32 size = 10 + mb->nparams * 10;
+       guint32 idx;
+       char blob_size [6];
+       char *b = blob_size;
+       
+       p = buf = g_malloc (size);
+       if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
+               *p |= 0x20; /* hasthis */
+       /* 
+        * FIXME: set also call convention and explict_this if needed.
+        */
+       p++;
+       mono_metadata_encode_value (mb->nparams, p, &p);
+       encode_type (mb->ret, p, &p);
+       for (i = 0; i < mb->nparams; ++i) {
+               encode_type (mb->params [i], p, &p);
+       }
+       /* store length */
+       mono_metadata_encode_value (p-buf, b, &b);
+       idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+       mono_image_add_stream_data (&assembly->blob, buf, p-buf);
+       g_free (buf);
+       return idx;
+}
+
+static guint32
+method_encode_code (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
 {
-       if (assembly->blob.alloc_size < assembly->blob.index + len) {
-               assembly->blob.alloc_size += len + 4096;
-               assembly->blob.data = g_realloc (assembly->blob.data, assembly->blob.alloc_size);
+       /* we use only tiny formats now: need  to implement ILGenerator */
+       char flags = 0;
+       guint32 idx;
+       /* check for exceptions, maxstack, locals */
+       if (mb->code_size < 64 && !(mb->code_size & 1)) {
+               flags = (mb->code_size << 2) | 0x2;
+       } else if (mb->code_size < 32 && (mb->code_size & 1)) {
+               flags = (mb->code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
+       } else {
+               g_error ("fat method headers not yet supported");
        }
-       memcpy (assembly->blob.data + assembly->blob.index, data, len);
-       assembly->blob.index += len;
+       idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
+       mono_image_add_stream_data (&assembly->code, mb->code, mb->code_size);
+       return assembly->text_rva + idx + CLI_H_SIZE;
+}
+
+static void
+mono_image_get_method_info (MonoMethodBuilder *mb, MonoDynamicAssembly *assembly)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+
+       table = &assembly->tables [MONO_TABLE_METHOD];
+       mb->table_idx = table->next_idx ++;
+       values = table->values + mb->table_idx * MONO_METHOD_SIZE;
+       values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, mb->name);
+       values [MONO_METHOD_FLAGS] = mb->attrs;
+       values [MONO_METHOD_IMPLFLAGS] = 0;
+       values [MONO_METHOD_SIGNATURE] = method_encode_signature (assembly, mb);
+       values [MONO_METHOD_PARAMLIST] = 1; /* FIXME: add support later */
+       values [MONO_METHOD_RVA] = method_encode_code (assembly, mb);
+}
+
+static guint32
+mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoClass *klass)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token;
+
+       if (!assembly->typeref)
+               assembly->typeref = g_hash_table_new (g_direct_hash, g_direct_equal);
+       
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, klass));
+       if (token)
+               return token;
+       if (klass->image != mono_defaults.corlib)
+               g_error ("multiple assemblyref not yet supported");
+
+       table = &assembly->tables [MONO_TABLE_TYPEREF];
+       alloc_table (table, table->rows + 1);
+       values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
+       values [MONO_TYPEREF_SCOPE] = (1 << 2) | 2; /* first row in assemblyref LAMESPEC, see get.c */
+       values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
+       values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+       token = 1 | (table->next_idx << 2); /* typeref */
+       g_hash_table_insert (assembly->typeref, klass, GUINT_TO_POINTER(token));
+       table->next_idx ++;
+       return token;
 }
 
 static void
 mono_image_get_type_info (MonoTypeBuilder *tb, MonoDynamicAssembly *assembly)
 {
        MonoDynamicTable *table;
+       guint *values;
+
+       table = &assembly->tables [MONO_TABLE_TYPEDEF];
+       tb->table_idx = table->next_idx ++;
+       values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
+       values [MONO_TYPEDEF_FLAGS] = tb->attrs;
+       /* use tb->base later */
+       values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, mono_defaults.object_class);
+       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, tb->name);
+       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, tb->nspace);
+       values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
+       values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;
+
+       table = &assembly->tables [MONO_TABLE_METHOD];
+       table->rows += g_list_length (tb->methods);
+       /*if (!tb->has_default_ctor)
+               table->rows++;*/
+       alloc_table (table, table->rows);
+       g_list_foreach (tb->methods, mono_image_get_method_info, assembly);
 
-       assembly->tables [MONO_TABLE_METHOD].rows += g_list_length (tb->methods);
-       if (!tb->has_default_ctor)
-               assembly->tables [MONO_TABLE_METHOD].rows++;
        /* Do the same with fields, properties etc.. */
 }
 
@@ -92,14 +301,203 @@ mono_image_fill_module_table (MonoModuleBuilder *mb, MonoDynamicAssembly *assemb
        MonoDynamicTable *table;
 
        table = &assembly->tables [MONO_TABLE_MODULE];
-       /* FIXME: handle multiple modules */
-       table->values [MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, mb->name);
+       mb->table_idx = table->next_idx ++;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, mb->name);
        /* need to set mvid? */
 
        /*
         * fill-in info in other tables as well.
         */
-       assembly->tables [MONO_TABLE_TYPEDEF].rows += g_list_length (mb->types);
+       table = &assembly->tables [MONO_TABLE_TYPEDEF];
+       table->rows += g_list_length (mb->types);
+       alloc_table (table, table->rows);
+       g_list_foreach (mb->types, mono_image_get_type_info, assembly);
+}
+
+static void
+build_compressed_metadata (MonoDynamicAssembly *assembly)
+{
+       int i;
+       guint64 valid_mask = 0;
+       guint32 heapt_size = 0;
+       guint32 meta_size = 256; /* allow for header and other stuff */
+       guint32 table_offset;
+       guint32 ntables = 0;
+       guint64 *int64val;
+       guint32 *int32val;
+       guint16 *int16val;
+       MonoImage *meta;
+       unsigned char *p;
+       char *version = "mono" VERSION;
+       
+       /* Compute table sizes */
+       meta = assembly->assembly.image = g_new0 (MonoImage, 1);
+       
+       /* Setup the info used by compute_sizes () */
+       meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0;
+       meta->idx_guid_wide = assembly->guid.index >= 65536 ? 1 : 0;
+       meta->idx_string_wide = assembly->sheap.index >= 65536 ? 1 : 0;
+
+       meta_size += assembly->blob.index;
+       meta_size += assembly->guid.index;
+       meta_size += assembly->sheap.index;
+       meta_size += assembly->us.index;
+
+       for (i=0; i < 64; ++i)
+               meta->tables [i].rows = assembly->tables [i].rows;
+       
+       for (i = 0; i < 64; i++){
+               if (meta->tables [i].rows == 0)
+                       continue;
+               valid_mask |= (guint64)1 << i;
+               ntables ++;
+               meta->tables [i].row_size = mono_metadata_compute_size (
+                       meta, i, &meta->tables [i].size_bitfield);
+               heapt_size += meta->tables [i].row_size * meta->tables [i].rows;
+       }
+       heapt_size += 24; /* #~ header size */
+       heapt_size += ntables * 4;
+       meta_size += heapt_size;
+       meta->raw_metadata = g_malloc0 (meta_size);
+       p = meta->raw_metadata;
+       /* the metadata signature */
+       *p++ = 'B'; *p++ = 'S'; *p++ = 'J'; *p++ = 'B';
+       /* version numbers and 4 bytes reserved */
+       int16val = (guint16*)p;
+       *int16val++ = 1;
+       *int16val = 1;
+       p += 8;
+       /* version string */
+       int32val = (guint32*)p;
+       *int32val = strlen (version);
+       p += 4;
+       memcpy (p, version, *int32val);
+       p += *int32val;
+       p += 3; p = (guint32)p & ~3; /* align */
+       int16val = (guint16*)p;
+       *int16val++ = 0; /* flags must be 0 */
+       *int16val = 5; /* number of streams */
+       p += 4;
+
+       /*
+        * write the stream info.
+        */
+       table_offset = (p - (unsigned char*)meta->raw_metadata) + 5 * 8 + 40; /* room needed for stream headers */
+       
+       int32val = (guint32*)p;
+       *int32val++ = assembly->tstream.offset = table_offset;
+       *int32val = heapt_size;
+       table_offset += *int32val;
+       p += 8;
+       strcpy (p, "#~");
+       /* 
+        * FIXME: alignment not 64 bit safe: same problem in metadata/image.c 
+        */
+       p += 3 + 3; p = (guint32)p & ~3;
+
+       int32val = (guint32*)p;
+       *int32val++ = assembly->sheap.offset = table_offset;
+       *int32val = assembly->sheap.index;
+       table_offset += *int32val;
+       p += 8;
+       strcpy (p, "#Strings");
+       p += 9 + 3; p = (guint32)p & ~3;
+
+       int32val = (guint32*)p;
+       *int32val++ = assembly->us.offset = table_offset;
+       *int32val = assembly->us.index;
+       table_offset += *int32val;
+       p += 8;
+       strcpy (p, "#US");
+       p += 4 + 3; p = (guint32)p & ~3;
+
+       int32val = (guint32*)p;
+       *int32val++ = assembly->blob.offset = table_offset;
+       *int32val = assembly->blob.index;
+       table_offset += *int32val;
+       p += 8;
+       strcpy (p, "#Blob");
+       p += 6 + 3; p = (guint32)p & ~3;
+
+       int32val = (guint32*)p;
+       *int32val++ = assembly->guid.offset = table_offset;
+       *int32val = assembly->guid.index;
+       table_offset += *int32val;
+       p += 8;
+       strcpy (p, "#GUID");
+       p += 6 + 3; p = (guint32)p & ~3;
+
+       /* 
+        * now copy the data, the table stream header and contents goes first.
+        */
+       g_assert ((p - (unsigned char*)meta->raw_metadata) < assembly->tstream.offset);
+       p = meta->raw_metadata + assembly->tstream.offset;
+       int32val = (guint32*)p;
+       *int32val = 0; /* reserved */
+       p += 4;
+       *p++ = 1; /* version */
+       *p++ = 0;
+       if (meta->idx_string_wide)
+               *p |= 0x01;
+       if (meta->idx_guid_wide)
+               *p |= 0x02;
+       if (meta->idx_blob_wide)
+               *p |= 0x04;
+       ++p;
+       *p++ = 0; /* reserved */
+       int64val = (guint64*)p;
+       *int64val++ = valid_mask;
+       *int64val++ = 0; /* bitvector of sorted tables, set to 0 for now  */
+       p += 16;
+       int32val = (guint32*)p;
+       for (i = 0; i < 64; i++){
+               if (meta->tables [i].rows == 0)
+                       continue;
+               *int32val++ = meta->tables [i].rows;
+       }
+       p = (unsigned char*)int32val;
+       /* compress the tables */
+       for (i = 0; i < 64; i++){
+               int row, col;
+               guint32 *values;
+               guint32 bitfield = meta->tables [i].size_bitfield;
+               if (!meta->tables [i].rows)
+                       continue;
+               if (assembly->tables [i].columns != mono_metadata_table_count (bitfield))
+                       g_error ("col count mismatch in %d: %d %d", i, assembly->tables [i].columns, mono_metadata_table_count (bitfield));
+               meta->tables [i].base = p;
+               for (row = 1; row <= meta->tables [i].rows; ++row) {
+                       values = assembly->tables [i].values + row * assembly->tables [i].columns;
+                       for (col = 0; col < assembly->tables [i].columns; ++col) {
+                               switch (mono_metadata_table_size (bitfield, col)) {
+                               case 1:
+                                       *p++ = values [col];
+                                       break;
+                               case 2:
+                                       int16val = (guint16*)p;
+                                       *int16val = values [col];
+                                       p += 2;
+                                       break;
+                               case 4:
+                                       int32val = (guint32*)p;
+                                       *int32val = values [col];
+                                       p += 4;
+                                       break;
+                               default:
+                                       g_assert_not_reached ();
+                               }
+                       }
+               }
+               g_assert ((p - (unsigned char*)meta->tables [i].base) == (meta->tables [i].rows * meta->tables [i].row_size));
+       }
+       
+       g_assert (assembly->guid.offset + assembly->guid.index < meta_size);
+       memcpy (meta->raw_metadata + assembly->sheap.offset, assembly->sheap.data, assembly->sheap.index);
+       memcpy (meta->raw_metadata + assembly->us.offset, assembly->us.data, assembly->us.index);
+       memcpy (meta->raw_metadata + assembly->blob.offset, assembly->blob.data, assembly->blob.index);
+       memcpy (meta->raw_metadata + assembly->guid.offset, assembly->guid.data, assembly->guid.index);
+
+       assembly->meta_size = assembly->guid.offset + assembly->guid.index;
 }
 
 static void
@@ -109,40 +507,61 @@ mono_image_build_metadata (MonoDynamicAssembly *assembly)
        MonoDynamicTable *table;
        GList *type;
        guint32 len;
+       guint32 *values;
+       int i;
        
        /*
         * FIXME: check if metadata was already built. 
         */
        string_heap_init (&assembly->sheap);
+       mono_image_add_stream_data (&assembly->us, "", 1);
+       mono_image_add_stream_data (&assembly->blob, "", 1);
+
+       assembly->text_rva =  0x00002000;
+
+       for (i=0; i < 64; ++i) {
+               assembly->tables [i].next_idx = 1;
+               assembly->tables [i].columns = table_sizes [i];
+       }
        
        table = &assembly->tables [MONO_TABLE_ASSEMBLY];
-       table->rows = 1;
-       table->values = g_malloc (table->rows * MONO_ASSEMBLY_SIZE);
-       table->values [MONO_ASSEMBLY_HASH_ALG] = 0x8004;
-       table->values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, assembly->name);
+       alloc_table (table, 1);
+       values = table->values + MONO_ASSEMBLY_SIZE;
+       values [MONO_ASSEMBLY_HASH_ALG] = 0x8004;
+       values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, assembly->name);
+       values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, "");
+
+       assembly->tables [MONO_TABLE_TYPEDEF].rows = 1; /* .<Module> */
+       assembly->tables [MONO_TABLE_TYPEDEF].next_idx++;
 
-       assembly->tables [MONO_TABLE_TYPEDEF].rows = 1; /* .<Module>*/
        len = g_list_length (assembly->modules);
        table = &assembly->tables [MONO_TABLE_MODULE];
-       table->rows = len;
-       table->values = g_malloc (table->rows * MONO_MODULE_SIZE);
+       alloc_table (table, len);
        g_list_foreach (assembly->modules, mono_image_fill_module_table, assembly);
 
        table = &assembly->tables [MONO_TABLE_TYPEDEF];
        /* 
         * table->rows is already set above and in mono_image_fill_module_table.
         */
-       table->values = g_malloc (table->rows * MONO_TYPEDEF_SIZE);
+       alloc_table (table, table->rows);
        /*
         * Set the first entry.
         */
-       table->values [MONO_TYPEDEF_FLAGS] = 0;
-       table->values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, "<Module>") ;
-       table->values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, "") ;
-       table->values [MONO_TYPEDEF_EXTENDS] = 0;
-       table->values [MONO_TYPEDEF_FIELD_LIST] = 1;
-       table->values [MONO_TYPEDEF_METHOD_LIST] = 1;
+       values = table->values + table->columns;
+       values [MONO_TYPEDEF_FLAGS] = 0;
+       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, "<Module>") ;
+       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, "") ;
+       values [MONO_TYPEDEF_EXTENDS] = 0;
+       values [MONO_TYPEDEF_FIELD_LIST] = 1;
+       values [MONO_TYPEDEF_METHOD_LIST] = 1;
+
+       /* later include all the assemblies referenced */
+       table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
+       alloc_table (table, 1);
+       values = table->values + table->columns;
+       values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, "corlib");
 
+       build_compressed_metadata (assembly);
 }
 
 int
@@ -151,6 +570,9 @@ mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
        MonoMSDOSHeader *msdos;
        MonoDotNetHeader *header;
        MonoSectionTable *section;
+       MonoCLIHeader *cli_header;
+       guint32 header_size =  TEXT_OFFSET + CLI_H_SIZE;
+
        static const unsigned char msheader[] = {
                0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,  0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
                0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -162,11 +584,13 @@ mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
                0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        };
 
-       if (maxsize < sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader) + sizeof (MonoSectionTable))
+       if (maxsize < header_size)
                return -1;
 
+       mono_image_build_metadata (assembly);
+
+       memset (buffer, 0, header_size);
        memcpy (buffer, msheader, sizeof (MonoMSDOSHeader));
-       memset (buffer + sizeof (MonoMSDOSHeader), 0, sizeof (MonoDotNetHeader) + sizeof (MonoSectionTable));
 
        msdos = (MonoMSDOSHeader *)buffer;
        header = (MonoDotNetHeader *)(buffer + sizeof (MonoMSDOSHeader));
@@ -180,7 +604,7 @@ mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
        header->pesig [2] = header->pesig [3] = 0;
 
        header->coff.coff_machine = 0x14c;
-       header->coff.coff_sections = 1; /* only text supported now */
+       header->coff.coff_sections = 1; /* only .text supported now */
        header->coff.coff_time = time (NULL);
        header->coff.coff_opt_header_size = sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4;
        /* it's an exe */
@@ -194,7 +618,7 @@ mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
 
        header->nt.pe_image_base = 0x400000;
        header->nt.pe_section_align = 8192;
-       header->nt.pe_file_alignment = 512;
+       header->nt.pe_file_alignment = FILE_ALIGN;
        header->nt.pe_os_major = 4;
        header->nt.pe_os_minor = 0;
        header->nt.pe_subsys_major = 4;
@@ -214,17 +638,39 @@ mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
        pe_reloc_table
        pe_iat  
 #endif
-       header->datadir.pe_cli_header.size = 0x48;
-       header->datadir.pe_cli_header.rva = 0x00002008;
+       header->datadir.pe_cli_header.size = CLI_H_SIZE;
+       header->datadir.pe_cli_header.rva = assembly->text_rva; /* we put it always at the beginning */
 
        /* Write section tables */
        strcpy (section->st_name, ".text");
-       section->st_virtual_size = 1024;
-       section->st_virtual_address = 0x00002000;
-       section->st_raw_data_size = 1024;
-       section->st_raw_data_ptr = 0x00000100;
+       section->st_virtual_size = 1024; /* FIXME */
+       section->st_virtual_address = assembly->text_rva;
+       section->st_raw_data_size = 1024; /* FIXME */
+       section->st_raw_data_ptr = TEXT_OFFSET;
        section->st_flags = SECT_FLAGS_HAS_CODE | SECT_FLAGS_MEM_EXECUTE | SECT_FLAGS_MEM_READ;
 
-       return sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader) + sizeof (MonoSectionTable);;
+       /* 
+        * align: build_compressed_metadata () assumes metadata is aligned 
+        * see below:
+        * cli_header->ch_metadata.rva = assembly->text_rva + assembly->code.index + CLI_H_SIZE;
+        */
+       assembly->code.index += 3;
+       assembly->code.index &= ~3;
+
+       /*
+        * Write the MonoCLIHeader header 
+        */
+       cli_header = (MonoCLIHeader*)(buffer + TEXT_OFFSET);
+       cli_header->ch_size = CLI_H_SIZE;
+       cli_header->ch_runtime_major = 2;
+       cli_header->ch_flags = CLI_FLAGS_ILONLY;
+       if (assembly->entry_point) 
+               cli_header->ch_entry_point = assembly->entry_point->table_idx | MONO_TOKEN_METHOD_DEF;
+       else
+               cli_header->ch_entry_point = 0;
+       cli_header->ch_metadata.rva = assembly->text_rva + assembly->code.index + CLI_H_SIZE;
+       cli_header->ch_metadata.size = assembly->meta_size;
+       
+       return header_size;
 }
 
index 2a107e56592581af70122d7944fe72c4f4ff081c..5e9fcef3fd3688dbfab203535a1a30b52cb6f9d7 100644 (file)
@@ -10,12 +10,14 @@ typedef struct {
        char *data;
        guint32 alloc_size; /* malloced bytes */
        guint32 index;
+       guint32 offset; /* from start of metadata */
 } MonoDynamicStream;
 
 typedef struct {
        char *name;
        char *fname;
        GList *types;
+       guint32 table_idx;
 } MonoModuleBuilder;
 
 typedef struct {
@@ -23,6 +25,7 @@ typedef struct {
        char *nspace;
        int attrs;
        int has_default_ctor;
+       guint32 table_idx;
        MonoType *base;
        GList *methods;
        GList *fields;
@@ -34,8 +37,11 @@ typedef struct {
        guint32 attrs;
        guint32 callconv;
        guint32 nparams;
+       guint32 table_idx;
        MonoType *ret;
        MonoType **params;
+       char *code;
+       guint32 code_size;
 } MonoMethodBuilder;
 
 typedef struct {
@@ -44,6 +50,7 @@ typedef struct {
        guint32 columns;
        guint32 column_sizes [9]; 
        guint32 *values; /* rows * columns */
+       guint32 next_idx;
 } MonoDynamicTable;
 
 typedef struct {
@@ -51,13 +58,20 @@ typedef struct {
        char *data;
        guint32 index;
        guint32 alloc_size;
+       guint32 offset; /* from start of metadata */
 } MonoStringHeap;
 
 typedef struct {
+       MonoAssembly assembly;
        char *name;
-       MonoAssembly *assembly;
        GList *modules;
+       guint32 meta_size;
+       guint32 text_rva;
+       guint32 metadata_rva;
+       MonoMethodBuilder *entry_point;
+       GHashTable *typeref;
        MonoStringHeap sheap;
+       MonoDynamicStream code; /* used to store method headers and bytecode */
        MonoDynamicStream us;
        MonoDynamicStream blob;
        MonoDynamicStream tstream;
index ee7d352e3afb74665223d5ffd3f7d63190452937..abd8984f20525ddb139283a48194d590adde7e49 100644 (file)
@@ -173,7 +173,7 @@ enum {
 
 enum {
        MONO_METHOD_RVA,
-       MONO_METHOD_IMPLFALGS,
+       MONO_METHOD_IMPLFLAGS,
        MONO_METHOD_FLAGS,
        MONO_METHOD_NAME,
        MONO_METHOD_SIGNATURE,
@@ -236,8 +236,8 @@ enum {
 };
 
 enum {
-       MONO_STAND_ALONG_SIGNATURE,
-       MONO_STAND_ALONG_SIGNATURE_SIZE
+       MONO_STAND_ALONE_SIGNATURE,
+       MONO_STAND_ALONE_SIGNATURE_SIZE
 };
 
 enum {