*** empty log message ***
[mono.git] / mono / metadata / image.c
index 51d4d6d941dab0acb18cd6328561c94bff3954f9..2f81641c01ebb352609d1f6c938d81f3db123a35 100644 (file)
@@ -21,6 +21,7 @@
 #include "rawbuffer.h"
 #include "mono-endian.h"
 #include "private.h"
+#include "tabledefs.h"
 
 #define INVALID_ADDRESS 0xffffffff
 
@@ -150,7 +151,7 @@ load_section_tables (MonoImage *image, MonoCLIImageInfo *iinfo)
                t->st_lineno_ptr = GUINT32_FROM_LE (t->st_lineno_ptr);
                t->st_reloc_count = GUINT16_FROM_LE (t->st_reloc_count);
                t->st_line_count = GUINT16_FROM_LE (t->st_line_count);
-               t->st_flags = GUINT16_FROM_LE (t->st_flags);
+               t->st_flags = GUINT32_FROM_LE (t->st_flags);
 #endif
                /* consistency checks here */
        }
@@ -266,23 +267,23 @@ load_metadata_ptrs (MonoImage *image, MonoCLIImageInfo *iinfo)
 
        for (i = 0; i < streams; i++){
                if (strncmp (ptr + 8, "#~", 3) == 0){
-                       image->heap_tables.offset = read32 (ptr);
+                       image->heap_tables.data = image->raw_metadata + read32 (ptr);
                        image->heap_tables.size = read32 (ptr + 4);
                        ptr += 8 + 3;
                } else if (strncmp (ptr + 8, "#Strings", 9) == 0){
-                       image->heap_strings.offset = read32 (ptr);
+                       image->heap_strings.data = image->raw_metadata + read32 (ptr);
                        image->heap_strings.size = read32 (ptr + 4);
                        ptr += 8 + 9;
                } else if (strncmp (ptr + 8, "#US", 4) == 0){
-                       image->heap_us.offset = read32 (ptr);
+                       image->heap_us.data = image->raw_metadata + read32 (ptr);
                        image->heap_us.size = read32 (ptr + 4);
                        ptr += 8 + 4;
                } else if (strncmp (ptr + 8, "#Blob", 6) == 0){
-                       image->heap_blob.offset = read32 (ptr);
+                       image->heap_blob.data = image->raw_metadata + read32 (ptr);
                        image->heap_blob.size = read32 (ptr + 4);
                        ptr += 8 + 6;
                } else if (strncmp (ptr + 8, "#GUID", 6) == 0){
-                       image->heap_guid.offset = read32 (ptr);
+                       image->heap_guid.data = image->raw_metadata + read32 (ptr);
                        image->heap_guid.size = read32 (ptr + 4);
                        ptr += 8 + 6;
                } else {
@@ -302,8 +303,8 @@ load_metadata_ptrs (MonoImage *image, MonoCLIImageInfo *iinfo)
 static gboolean
 load_tables (MonoImage *image)
 {
-       char *heap_tables = image->raw_metadata + image->heap_tables.offset;
-       guint32 *rows;
+       const char *heap_tables = image->heap_tables.data;
+       const guint32 *rows;
        guint64 valid_mask;
        int valid = 0, table;
        int heap_sizes;
@@ -314,7 +315,7 @@ load_tables (MonoImage *image)
        image->idx_blob_wide   = ((heap_sizes & 0x04) == 4);
        
        valid_mask = read64 (heap_tables + 8);
-       rows = (guint32 *) (heap_tables + 24);
+       rows = (const guint32 *) (heap_tables + 24);
        
        for (table = 0; table < 64; table++){
                if ((valid_mask & ((guint64) 1 << table)) == 0){
@@ -332,7 +333,7 @@ load_tables (MonoImage *image)
        image->tables_base = (heap_tables + 24) + (4 * valid);
 
        /* They must be the same */
-       g_assert ((void *) image->tables_base == (void *) rows);
+       g_assert ((const void *) image->tables_base == (const void *) rows);
 
        mono_metadata_compute_table_bases (image);
        return TRUE;
@@ -348,29 +349,34 @@ load_metadata (MonoImage *image, MonoCLIImageInfo *iinfo)
 }
 
 static void
-load_class_names (MonoImage *image) {
+load_class_names (MonoImage *image)
+{
        MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEDEF];
        guint32 cols [MONO_TYPEDEF_SIZE];
-       const charname;
+       const char *name;
        const char *nspace;
        GHashTable *nspace_table;
        GHashTable *name_cache = image->name_cache;
-       guint32 i;
+       guint32 i, visib;
 
        for (i = 1; i <= t->rows; ++i) {
                mono_metadata_decode_row (t, i - 1, cols, MONO_TYPEDEF_SIZE);
+               /* nested types are accessed from the nesting name */
+               visib = cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+               if (visib > TYPE_ATTRIBUTE_PUBLIC && visib < TYPE_ATTRIBUTE_NESTED_ASSEMBLY)
+                       continue;
                name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
                nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
                if (!(nspace_table = g_hash_table_lookup (name_cache, nspace))) {
                        nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
-                       g_hash_table_insert (name_cache, nspace, nspace_table);
+                       g_hash_table_insert (name_cache, (char *)nspace, (char *)nspace_table);
                }
-               g_hash_table_insert (nspace_table, name, GUINT_TO_POINTER (i));
+               g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (i));
        }
 }
 
 static MonoImage *
-do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
+do_mono_image_open (const char *fname, MonoImageOpenStatus *status)
 {
        MonoCLIImageInfo *iinfo;
        MonoDotNetHeader *header;
@@ -379,7 +385,7 @@ do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
        int n;
 
        image = g_new0 (MonoImage, 1);
-       image->f = fopen (fname, "r");
+       image->f = fopen (fname, "rb");
        image->name = g_strdup (fname);
        iinfo = g_new0 (MonoCLIImageInfo, 1);
        image->image_info = iinfo;
@@ -418,6 +424,7 @@ do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
 #define SWAP32(x) (x) = GUINT32_FROM_LE ((x))
 #define SWAP16(x) (x) = GUINT16_FROM_LE ((x))
+#define SWAPPDE(x) do { (x).rva = GUINT32_FROM_LE ((x).rva); (x).size = GUINT32_FROM_LE ((x).size);} while (0)
        SWAP32 (header->coff.coff_time);
        SWAP32 (header->coff.coff_symptr);
        SWAP32 (header->coff.coff_symcount);
@@ -433,13 +440,51 @@ do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
        SWAP32 (header->pe.pe_rva_code_base);
        SWAP32 (header->pe.pe_rva_data_base);
        SWAP16 (header->pe.pe_magic);
+
        /* MonoPEHeaderNT: not used yet */
+       SWAP32  (header->nt.pe_image_base);     /* must be 0x400000 */
+       SWAP32  (header->nt.pe_section_align);       /* must be 8192 */
+       SWAP32  (header->nt.pe_file_alignment);      /* must be 512 or 4096 */
+       SWAP16  (header->nt.pe_os_major);            /* must be 4 */
+       SWAP16  (header->nt.pe_os_minor);            /* must be 0 */
+       SWAP16  (header->nt.pe_user_major);
+       SWAP16  (header->nt.pe_user_minor);
+       SWAP16  (header->nt.pe_subsys_major);
+       SWAP16  (header->nt.pe_subsys_minor);
+       SWAP32  (header->nt.pe_reserved_1);
+       SWAP32  (header->nt.pe_image_size);
+       SWAP32  (header->nt.pe_header_size);
+       SWAP32  (header->nt.pe_checksum);
+       SWAP16  (header->nt.pe_subsys_required);
+       SWAP16  (header->nt.pe_dll_flags);
+       SWAP32  (header->nt.pe_stack_reserve);
+       SWAP32  (header->nt.pe_stack_commit);
+       SWAP32  (header->nt.pe_heap_reserve);
+       SWAP32  (header->nt.pe_heap_commit);
+       SWAP32  (header->nt.pe_loader_flags);
+       SWAP32  (header->nt.pe_data_dir_count);
+
        /* MonoDotNetHeader: mostly unused */
-       SWAP32 (header->datadir.pe_cli_header.rva);
-       SWAP32 (header->datadir.pe_cli_header.size);
+       SWAPPDE (header->datadir.pe_export_table);
+       SWAPPDE (header->datadir.pe_import_table);
+       SWAPPDE (header->datadir.pe_resource_table);
+       SWAPPDE (header->datadir.pe_exception_table);
+       SWAPPDE (header->datadir.pe_certificate_table);
+       SWAPPDE (header->datadir.pe_reloc_table);
+       SWAPPDE (header->datadir.pe_debug);
+       SWAPPDE (header->datadir.pe_copyright);
+       SWAPPDE (header->datadir.pe_global_ptr);
+       SWAPPDE (header->datadir.pe_tls_table);
+       SWAPPDE (header->datadir.pe_load_config_table);
+       SWAPPDE (header->datadir.pe_bound_import);
+       SWAPPDE (header->datadir.pe_iat);
+       SWAPPDE (header->datadir.pe_delay_import_desc);
+       SWAPPDE (header->datadir.pe_cli_header);
+       SWAPPDE (header->datadir.pe_reserved);
 
 #undef SWAP32
 #undef SWAP16
+#undef SWAPPDE
 #endif
 
        if (header->coff.coff_machine != 0x14c)
@@ -484,6 +529,13 @@ invalid_image:
                return NULL;
 }
 
+MonoImage *
+mono_image_loaded (const char *name) {
+       if (loaded_images_hash)
+               return g_hash_table_lookup (loaded_images_hash, name);
+       return NULL;
+}
+
 /**
  * mono_image_open:
  * @fname: filename that points to the module we want to open
@@ -493,7 +545,7 @@ invalid_image:
  * if NULL, then check the value of @status for details on the error
  */
 MonoImage *
-mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
+mono_image_open (const char *fname, MonoImageOpenStatus *status)
 {
        MonoImage *image;
        
@@ -514,7 +566,8 @@ mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
        if (!loaded_images_hash)
                loaded_images_hash = g_hash_table_new (g_str_hash, g_str_equal);
        g_hash_table_insert (loaded_images_hash, image->name, image);
-
+       g_hash_table_insert (loaded_images_hash, (char *) image->assembly_name, image);
+       
        return image;
 }
 
@@ -581,7 +634,7 @@ mono_image_close (MonoImage *image)
  * Returns: a string describing the error
  */
 const char *
-mono_image_strerror (enum MonoImageOpenStatus status)
+mono_image_strerror (MonoImageOpenStatus status)
 {
        switch (status){
        case MONO_IMAGE_OK: