Mon Dec 24 17:23:45 CET 2001 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / image.c
index 2b2ba0af0d727d4e41366c574fa1f5d611783962..4fbb06f9bca0231765384685558377d3a84d1a41 100644 (file)
@@ -19,8 +19,9 @@
 #include "image.h"
 #include "cil-coff.h"
 #include "rawbuffer.h"
-#include "endian.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 */
        }
@@ -172,7 +173,7 @@ load_cli_header (MonoImage *image, MonoCLIImageInfo *iinfo)
        if (offset == INVALID_ADDRESS)
                return FALSE;
 
-       if (fseek (image->f, offset, 0) != 0)
+       if (fseek (image->f, offset, SEEK_SET) != 0)
                return FALSE;
        
        if ((n = fread (&iinfo->cli_cli_header, sizeof (MonoCLIHeader), 1, image->f)) != 1)
@@ -285,8 +286,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);
                }
@@ -353,10 +356,14 @@ load_class_names (MonoImage *image) {
        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))) {
@@ -367,38 +374,6 @@ load_class_names (MonoImage *image) {
        }
 }
 
-int
-mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
-{
-       MonoMSDOSHeader *msdos;
-       MonoDotNetHeader *header;
-
-       if (maxsize < sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader))
-               return -1;
-
-       memset (buffer, 0, sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader));
-
-       msdos = (MonoMSDOSHeader *)buffer;
-       header = (MonoDotNetHeader *)(buffer + sizeof (MonoMSDOSHeader));
-
-       /* FIXME: byteswap as needed */
-       msdos->msdos_header [0] = 'M';
-       msdos->msdos_header [1] = 'Z';
-
-       msdos->pe_offset = sizeof (MonoMSDOSHeader);
-
-       header->coff.coff_machine = 0x14c;
-       header->coff.coff_time = time (NULL);
-       header->coff.coff_opt_header_size = sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4;
-       header->pe.pe_magic = 0x10B;
-       header->pe.pe_major = 6;
-       header->pe.pe_minor = 0;
-
-       /* Write section tables */
-
-       return sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader);
-}
-
 static MonoImage *
 do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
 {
@@ -409,7 +384,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;
@@ -448,6 +423,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);
@@ -463,13 +439,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)
@@ -478,7 +492,7 @@ do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
        if (header->coff.coff_opt_header_size != (sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4))
                goto invalid_image;
 
-       if (header->pe.pe_magic != 0x10B)
+       if (header->pesig[0] != 'P' || header->pesig[1] != 'E' || header->pe.pe_magic != 0x10B)
                goto invalid_image;
 
        if (header->pe.pe_major != 6 || header->pe.pe_minor != 0)