mono_metadata_encode_value (type->type, p, &p);
break;
case MONO_TYPE_PTR:
- g_print ("encode pointer\n");
case MONO_TYPE_SZARRAY:
mono_metadata_encode_value (type->type, p, &p);
encode_type (assembly, type->data.type, p, &p);
mono_image_add_stream_data (&assembly->code, (char*)&clause, sizeof (clause));
}
} else {
- g_error ("No clauses");
+ g_error ("No clauses for ex info block %d", i);
}
}
}
guint32 *values;
char *name;
+ /* maybe this fixup should be done in the C# code */
+ if (fb->attrs & FIELD_ATTRIBUTE_LITERAL)
+ fb->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
table = &assembly->tables [MONO_TABLE_FIELD];
fb->table_idx = table->next_idx ++;
values = table->values + fb->table_idx * MONO_FIELD_SIZE;
guint32 *values;
guint32 cols [MONO_ASSEMBLY_SIZE];
- if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, image))))
+ if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
return token;
mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
token <<= RESOLTION_SCOPE_BITS;
token |= RESOLTION_SCOPE_ASSEMBLYREF;
- g_hash_table_insert (assembly->typeref, image, GUINT_TO_POINTER (token));
+ g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
return token;
}
+static guint32
+create_typespec (MonoDynamicAssembly *assembly, MonoType *type)
+{
+ MonoDynamicTable *table;
+ guint32 *values;
+ guint32 token;
+ char sig [128];
+ char *p = sig;
+ char blob_size [6];
+ char *b = blob_size;
+
+ switch (type->type) {
+ case MONO_TYPE_FNPTR:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ encode_type (assembly, type, p, &p);
+ break;
+ default:
+ return 0;
+ }
+
+ g_assert (p-sig < 128);
+ mono_metadata_encode_value (p-sig, b, &b);
+ token = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+ mono_image_add_stream_data (&assembly->blob, sig, p-sig);
+
+ table = &assembly->tables [MONO_TABLE_TYPESPEC];
+ alloc_table (table, table->rows + 1);
+ values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
+ values [MONO_TYPESPEC_SIGNATURE] = token;
+
+ token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
+ g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
+ table->next_idx ++;
+ return token;
+}
+
+/*
+ * Despite the name, we handle also TypeSpec (with the above helper).
+ */
static guint32
mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type)
{
MonoClass *klass;
token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
+ if (token)
+ return token;
+ token = create_typespec (assembly, type);
if (token)
return token;
klass = mono_class_from_mono_type (type);
{
guint32 token;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, method));
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
if (token)
return token;
token = mono_image_get_memberref_token (assembly, method->klass,
method->name, method_encode_signature (assembly, method->signature));
- g_hash_table_insert (assembly->typeref, method, GUINT_TO_POINTER(token));
+ g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
return token;
}
{
guint32 token;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, field));
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
if (token)
return token;
token = mono_image_get_memberref_token (assembly, klass,
field->name, fieldref_encode_signature (assembly, field));
- g_hash_table_insert (assembly->typeref, field, GUINT_TO_POINTER(token));
+ g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
return token;
}
name = mono_string_to_utf8 (mb->module.name);
table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, name);
g_free (name);
- /* need to set mvid? */
+ i = mono_image_add_stream_data (&assembly->guid, mono_array_addr (mb->guid, char, 0), 16);
+ i /= 16;
+ ++i;
+ table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_MVID] = i;
+ table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENC] = 0;
+ table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENCBASE] = 0;
mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_MODULE, mb->cattrs);
/*
values [MONO_ASSEMBLY_MINOR_VERSION] = 0;
values [MONO_ASSEMBLY_REV_NUMBER] = 0;
values [MONO_ASSEMBLY_BUILD_NUMBER] = 0;
+ values [MONO_ASSEMBLY_FLAGS] = 0;
mono_image_add_cattrs (assembly, 1, CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs);
#endif
assembly->token_fixups = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
- assembly->typeref = g_hash_table_new (g_direct_hash, g_direct_equal);
+ assembly->handleref = g_hash_table_new (g_direct_hash, g_direct_equal);
+ assembly->typeref = g_hash_table_new (mono_metadata_type_hash, mono_metadata_type_equal);
string_heap_init (&assembly->sheap);
mono_image_add_stream_data (&assembly->us, "", 1);
}
+typedef struct {
+ guint32 import_lookup_table;
+ guint32 timestamp;
+ guint32 forwarder;
+ guint32 name_rva;
+ guint32 import_address_table_rva;
+} MonoIDT;
+
+typedef struct {
+ guint32 name_rva;
+ guint32 flags;
+} MonoILT;
+
/*
* mono_image_get_heade:
* @assemblyb: an assembly builder object
{
MonoMSDOSHeader *msdos;
MonoDotNetHeader *header;
- MonoSectionTable *section;
+ MonoSectionTable *section, *reloc;
MonoCLIHeader *cli_header;
guint32 header_size = TEXT_OFFSET + CLI_H_SIZE;
MonoDynamicAssembly *assembly;
+ MonoIDT import_directory;
+ MonoILT import_lookup;
+ static const guchar entrycode [16] = {0xff, 0x25, 0};
+ guint32 entry_offset, import_table_offset, import_hint_offset;
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,
mono_image_build_metadata (assemblyb);
+ memset (&import_directory, 0, sizeof (MonoIDT));
+ assembly->code.index += 3;
+ assembly->code.index &= ~3;
+ import_table_offset = TEXT_OFFSET + CLI_H_SIZE + assembly->code.index;
+ /* calc rva... */
+ import_hint_offset = import_table_offset + 40 + 8;
+ import_hint_offset += 15;
+ import_hint_offset &= ~15;
+
+ import_directory.import_lookup_table = import_table_offset + 40;
+ import_directory.name_rva = import_hint_offset + 14;
+ import_directory.import_address_table_rva = 0x200; /* FIXME */
+
+ mono_image_add_stream_data (&assembly->code, (char*)&import_directory, sizeof (MonoIDT));
+ /* add an empty item to mark the end */
+ memset (&import_directory, 0, sizeof (MonoIDT));
+ mono_image_add_stream_data (&assembly->code, (char*)&import_directory, sizeof (MonoIDT));
+
+ memset (&import_lookup, 0, sizeof (MonoILT));
+ import_lookup.name_rva = import_hint_offset;
+ mono_image_add_stream_data (&assembly->code, (char*)&import_lookup, sizeof (MonoILT));
+ assembly->code.index += 15;
+ assembly->code.index &= ~15;
+ mono_image_add_stream_data (&assembly->code, "", 1);
+ mono_image_add_stream_data (&assembly->code, "", 1);
+ mono_image_add_stream_data (&assembly->code, "_CorExeMain", 12);
+ mono_image_add_stream_data (&assembly->code, "mscoree.dll", 12);
+ mono_image_add_stream_data (&assembly->code, "", 1); /* lame */
+ mono_image_add_stream_data (&assembly->code, "", 1);
+ mono_image_add_stream_data (&assembly->code, "", 1);
+ mono_image_add_stream_data (&assembly->code, "", 1);
+
+ entry_offset = mono_image_add_stream_data (&assembly->code, entrycode, sizeof (entrycode));
+ /*g_print ("ep offset: 0x%08x\n", entry_offset);*/
+
memset (buffer, 0, header_size);
memcpy (buffer, msheader, sizeof (MonoMSDOSHeader));
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 = 2; /* only .text and .reloc supported now */
header->coff.coff_time = time (NULL);
header->coff.coff_opt_header_size = sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4;
/* it's an exe */
header->pe.pe_magic = 0x10B;
header->pe.pe_major = 6;
header->pe.pe_minor = 0;
- /* need to set: pe_code_size pe_data_size pe_rva_entry_point pe_rva_code_base pe_rva_data_base */
+ /* set later: pe_code_size pe_data_size pe_rva_entry_point pe_rva_code_base pe_rva_data_base */
header->nt.pe_image_base = 0x400000;
header->nt.pe_section_align = 8192;
/* Write section tables */
strcpy (section->st_name, ".text");
- section->st_virtual_address = START_TEXT_RVA;
- section->st_virtual_size = assembly->meta_size + assembly->code.index;
+ section->st_virtual_address = assembly->text_rva;
+ section->st_virtual_size = assembly->meta_size + assembly->code.index;
section->st_raw_data_size = section->st_virtual_size + (FILE_ALIGN - 1);
section->st_raw_data_size &= ~(FILE_ALIGN - 1);
section->st_raw_data_ptr = TEXT_OFFSET;
section->st_flags = SECT_FLAGS_HAS_CODE | SECT_FLAGS_MEM_EXECUTE | SECT_FLAGS_MEM_READ;
+ reloc = section + 1;
+ strcpy (reloc->st_name, ".reloc");
+ reloc->st_virtual_address = section->st_virtual_address + section->st_raw_data_size;
+ reloc->st_virtual_size = 12;
+ reloc->st_raw_data_size = reloc->st_virtual_size + (FILE_ALIGN - 1);
+ reloc->st_raw_data_size &= ~(FILE_ALIGN - 1);
+ reloc->st_raw_data_ptr = section->st_raw_data_ptr + section->st_raw_data_size;
+ reloc->st_flags = SECT_FLAGS_MEM_DISCARDABLE | SECT_FLAGS_HAS_INITIALIZED_DATA | SECT_FLAGS_MEM_READ;
+
+
+ header->pe.pe_code_size = section->st_raw_data_size;
+ header->pe.pe_rva_entry_point = TEXT_OFFSET + CLI_H_SIZE + entry_offset;
+
/*
* align: build_compressed_metadata () assumes metadata is aligned
* see below:
ret = (MonoReflectionMethod*)mono_object_new (domain, klass);
ret->method = method;
+ ret->name = mono_string_new (domain, method->name);
CACHE_OBJECT (method, ret);
return ret;
}
idx = find_method_index (rmethod->method);
idx <<= CUSTOM_ATTR_BITS;
idx |= CUSTOM_ATTR_METHODDEF;
- image = method->klass->image;
+ image = rmethod->method->klass->image;
} else if (strcmp ("ParameterInfo", klass->name) == 0) {
MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
return result;
}
+static MonoMethodSignature*
+ctor_builder_to_signature (MonoReflectionCtorBuilder *ctor) {
+ MonoMethodSignature *sig;
+ int count, i;
+
+ count = ctor->parameters? mono_array_length (ctor->parameters): 0;
+
+ sig = g_malloc0 (sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
+ sig->hasthis = 1;
+ sig->param_count = count;
+ sig->sentinelpos = -1; /* FIXME */
+ for (i = 0; i < count; ++i) {
+ MonoReflectionType *pt = mono_array_get (ctor->parameters, MonoReflectionType*, i);
+ sig->params [i] = pt->type;
+ }
+ return sig;
+}
+
/*
* mono_reflection_get_custom_attrs_blob:
* @ctor: custom attribute constructor
guint32 buflen, i, type;
if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
- g_warning ("ConstructorBuilder Custom attribute not yet supported");
- /*
- * maybe we should have a param array to method signature function and
- * continue with the normal codepath.
- */
- result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, 4);
- mono_array_set (result, char, 0, 1);
- return result;
+ sig = ctor_builder_to_signature ((MonoReflectionCtorBuilder*)ctor);
+ } else {
+ sig = ((MonoReflectionMethod*)ctor)->method->signature;
}
buflen = 256;
p = buffer = g_malloc (buflen);
/* write the prolog */
*p++ = 1;
*p++ = 0;
- sig = ((MonoReflectionMethod*)ctor)->method->signature;
/* FIXME: ENOENDIAN */
for (i = 0; i < sig->param_count; ++i) {
if ((p-buffer) + 10 >= buflen) {
p = mono_array_addr (result, char, 0);
memcpy (p, buffer, buflen);
g_free (buffer);
+ if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
+ g_free (sig);
return result;
}