X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fpedump.c;h=b52f5d79dbcc50893b9980dadc5a27b7f3bf29e0;hb=2895b137c8cf2d559e0ddbd77ff37b6d799ad04d;hp=f00175fb541855b00fa563d71ec1be2cd9bf47d0;hpb=184e5b1172ecf226625ab6b847152ee5b3f66252;p=mono.git diff --git a/mono/metadata/pedump.c b/mono/metadata/pedump.c index f00175fb541..b52f5d79dbc 100644 --- a/mono/metadata/pedump.c +++ b/mono/metadata/pedump.c @@ -8,12 +8,29 @@ */ #include #include -#include "assembly.h" +#include +#include +#include "image.h" #include #include "cil-coff.h" +#include "mono-endian.h" +#include "verify.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "mono/utils/mono-digest.h" +gboolean dump_data = TRUE; +gboolean verify_pe = FALSE; + +/* unused static void -hex_dump (char *buffer, int base, int count) +hex_dump (const char *buffer, int base, int count) { int i; @@ -24,27 +41,28 @@ hex_dump (char *buffer, int base, int count) printf ("%02x ", (unsigned char) (buffer [i])); } } +*/ static void -hex8 (char *label, unsigned char x) +hex8 (const char *label, unsigned char x) { printf ("\t%s: 0x%02x\n", label, (unsigned char) x); } static void -hex16 (char *label, guint16 x) +hex16 (const char *label, guint16 x) { printf ("\t%s: 0x%04x\n", label, x); } static void -hex32 (char *label, guint32 x) +hex32 (const char *label, guint32 x) { printf ("\t%s: 0x%08x\n", label, x); } static void -dump_coff_header (coff_header_t *coff) +dump_coff_header (MonoCOFFHeader *coff) { printf ("\nCOFF Header:\n"); hex16 (" Machine", coff->coff_machine); @@ -58,7 +76,7 @@ dump_coff_header (coff_header_t *coff) } static void -dump_pe_header (pe_header_t *pe) +dump_pe_header (MonoPEHeader *pe) { printf ("\nPE Header:\n"); hex16 (" Magic (0x010b)", pe->pe_magic); @@ -74,7 +92,7 @@ dump_pe_header (pe_header_t *pe) } static void -dump_nt_header (pe_header_nt_t *nt) +dump_nt_header (MonoPEHeaderNT *nt) { printf ("\nNT Header:\n"); @@ -102,13 +120,52 @@ dump_nt_header (pe_header_nt_t *nt) } static void -dent (const char *label, pe_dir_entry_t de) +dent (const char *label, MonoPEDirEntry de) { printf ("\t%s: 0x%08x [0x%08x]\n", label, de.rva, de.size); } static void -dump_datadir (pe_datadir_t *dd) +dump_blob (const char *desc, const char* p, guint32 size) +{ + int i; + + printf ("%s", desc); + if (!p) { + printf (" none\n"); + return; + } + + for (i = 0; i < size; ++i) { + if (!(i % 16)) + printf ("\n\t"); + printf (" %02X", p [i] & 0xFF); + } + printf ("\n"); +} + +static void +dump_public_key (MonoImage *m) +{ + guint32 size; + const char *p; + + p = mono_image_get_public_key (m, &size); + dump_blob ("\nPublic key:", p, size); +} + +static void +dump_strong_name (MonoImage *m) +{ + guint32 size; + const char *p; + + p = mono_image_get_strong_name (m, &size); + dump_blob ("\nStrong name:", p, size); +} + +static void +dump_datadir (MonoPEDatadir *dd) { printf ("\nData directories:\n"); dent (" Export Table", dd->pe_export_table); @@ -129,7 +186,7 @@ dump_datadir (pe_datadir_t *dd) } static void -dump_dotnet_header (dotnet_header_t *header) +dump_dotnet_header (MonoDotNetHeader *header) { dump_coff_header (&header->coff); dump_pe_header (&header->pe); @@ -138,7 +195,7 @@ dump_dotnet_header (dotnet_header_t *header) } static void -dump_section_table (section_table_t *st) +dump_section_table (MonoSectionTable *st) { guint32 flags = st->st_flags; @@ -166,25 +223,26 @@ dump_section_table (section_table_t *st) } static void -dump_sections (dotnet_image_info_t *iinfo) +dump_sections (MonoCLIImageInfo *iinfo) { - const int top = iinfo->dn_header.coff.coff_sections; + const int top = iinfo->cli_header.coff.coff_sections; int i; for (i = 0; i < top; i++) - dump_section_table (&iinfo->dn_section_tables [i]); + dump_section_table (&iinfo->cli_section_tables [i]); } static void -dump_cli_header (cli_header_t *ch) +dump_cli_header (MonoCLIHeader *ch) { printf ("\n"); printf (" CLI header size: %d\n", ch->ch_size); printf (" Runtime required: %d.%d\n", ch->ch_runtime_major, ch->ch_runtime_minor); - printf (" Flags: %s, %s, %s\n", + printf (" Flags: %s, %s, %s, %s\n", (ch->ch_flags & CLI_FLAGS_ILONLY ? "ilonly" : "contains native"), (ch->ch_flags & CLI_FLAGS_32BITREQUIRED ? "32bits" : "32/64"), - (ch->ch_flags & CLI_FLAGS_ILONLY ? "trackdebug" : "no-trackdebug")); + (ch->ch_flags & CLI_FLAGS_ILONLY ? "trackdebug" : "no-trackdebug"), + (ch->ch_flags & CLI_FLAGS_STRONGNAMESIGNED ? "strongnamesigned" : "notsigned")); dent (" Metadata", ch->ch_metadata); hex32 ("Entry Point Token", ch->ch_entry_point); dent (" Resources at", ch->ch_resources); @@ -195,86 +253,194 @@ dump_cli_header (cli_header_t *ch) } static void -dsh (char *label, dotnet_image_info_t *iinfo, stream_header_t *sh) +dsh (const char *label, MonoImage *meta, MonoStreamHeader *sh) { printf ("%s: 0x%08x - 0x%08x [%d == 0x%08x]\n", label, - sh->sh_offset, sh->sh_offset + sh->sh_size, - sh->sh_size, sh->sh_size); + (int)(sh->data - meta->raw_metadata), (int)(sh->data + sh->size - meta->raw_metadata), + sh->size, sh->size); } static void -dump_metadata_ptrs (dotnet_image_info_t *iinfo) +dump_metadata_ptrs (MonoImage *meta) { - metadata_t *meta = &iinfo->dn_metadata; - printf ("\nMetadata pointers:\n"); - dsh ("\tTables (#~)", iinfo, &meta->heap_tables); - dsh ("\t Strings", iinfo, &meta->heap_strings); - dsh ("\t Blob", iinfo, &meta->heap_blob); - dsh ("\tUser string", iinfo, &meta->heap_us); - dsh ("\t GUID", iinfo, &meta->heap_guid); + dsh ("\tTables (#~)", meta, &meta->heap_tables); + dsh ("\t Strings", meta, &meta->heap_strings); + dsh ("\t Blob", meta, &meta->heap_blob); + dsh ("\tUser string", meta, &meta->heap_us); + dsh ("\t GUID", meta, &meta->heap_guid); } static void -dump_metadata (dotnet_image_info_t *iinfo) +dump_metadata (MonoImage *meta) { - metadata_t *meta = &iinfo->dn_metadata; int table; - dump_metadata_ptrs (iinfo); + dump_metadata_ptrs (meta); printf ("Rows:\n"); - for (table = 0; table < 64; table++){ - if (meta->rows [table] == 0) + for (table = 0; table < MONO_TABLE_NUM; table++){ + if (meta->tables [table].rows == 0) continue; - printf ("Table %s (%d): %d rows\n", mono_meta_table_name (table), table, meta->rows [table]); + printf ("Table %s: %d records (%d bytes, at %p)\n", + mono_meta_table_name (table), + meta->tables [table].rows, + meta->tables [table].row_size, + meta->tables [table].base + ); } } static void -dump_dotnet_iinfo (dotnet_image_info_t *iinfo) +dump_methoddef (MonoImage *metadata, guint32 token) { - dump_dotnet_header (&iinfo->dn_header); + const char *loc; + + if (!token) + return; + loc = mono_metadata_locate_token (metadata, token); + + printf ("RVA for Entry Point: 0x%08x\n", read32 (loc)); +} + +static void +dump_dotnet_iinfo (MonoImage *image) +{ + MonoCLIImageInfo *iinfo = image->image_info; + + dump_dotnet_header (&iinfo->cli_header); dump_sections (iinfo); - dump_cli_header (&iinfo->dn_cli_header); - dump_metadata (iinfo); + dump_cli_header (&iinfo->cli_cli_header); + dump_strong_name (image); + dump_public_key (image); + dump_metadata (image); + + dump_methoddef (image, iinfo->cli_cli_header.ch_entry_point); +} + +static void +dump_verify_info (MonoImage *image, int flags) +{ + GSList *errors, *tmp; + int count = 0; + const char* desc [] = { + "Ok", "Error", "Warning", NULL, "CLS" + }; + + errors = mono_image_verify_tables (image, flags); + + for (tmp = errors; tmp; tmp = tmp->next) { + MonoVerifyInfo *info = tmp->data; + g_print ("%s: %s\n", desc [info->status], info->message); + if (info->status == MONO_VERIFY_ERROR) + count++; + } + mono_free_verify_list (errors); + + if (flags & (MONO_VERIFY_ALL + 1)) { /* verify code */ + int i; + MonoTableInfo *m = &image->tables [MONO_TABLE_METHOD]; + + for (i = 0; i < m->rows; ++i) { + MonoMethod *method; + + method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i+1), NULL); + errors = mono_method_verify (method, flags); + if (errors) { + char *sig; + MonoClass *klass = mono_method_get_class (method); + sig = mono_signature_get_desc (mono_method_signature (method), FALSE); + g_print ("In method: %s.%s::%s(%s)\n", mono_class_get_namespace (klass), mono_class_get_name (klass), mono_method_get_name (method), sig); + g_free (sig); + } + + for (tmp = errors; tmp; tmp = tmp->next) { + MonoVerifyInfo *info = tmp->data; + g_print ("%s: %s\n", desc [info->status], info->message); + if (info->status == MONO_VERIFY_ERROR) + count++; + } + mono_free_verify_list (errors); + } + } + + if (count) + g_print ("Error count: %d\n", count); } static void usage (void) { - printf ("Usage is: pedump [-m] file.exe\n"); + printf ("Usage is: pedump [--verify error,warn,cls,all,code] file.exe\n"); exit (1); } int main (int argc, char *argv []) { - dotnet_image_info_t *iinfo; - MonoAssembly *assembly; + MonoImage *image; char *file = NULL; + char *flags = NULL; + const char *flag_desc [] = {"error", "warn", "cls", "all", "code", NULL}; + guint flag_vals [] = {MONO_VERIFY_ERROR, MONO_VERIFY_WARNING, MONO_VERIFY_CLS, MONO_VERIFY_ALL, MONO_VERIFY_ALL + 1}; int i; for (i = 1; i < argc; i++){ if (argv [i][0] != '-'){ - file = argv [1]; + file = argv [i]; continue; } - if (argv [i][1] == 'h') + if (strcmp (argv [i], "--help") == 0) + usage (); + else if (strcmp (argv [i], "--verify") == 0) { + verify_pe = 1; + dump_data = 0; + ++i; + flags = argv [i]; + } else { usage (); + } } if (!file) usage (); - assembly = mono_assembly_open (file, NULL); - iinfo = assembly->image_info; - - dump_dotnet_iinfo (iinfo); + mono_metadata_init (); + mono_raw_buffer_init (); + mono_images_init (); + mono_assemblies_init (); + mono_loader_init (); + + image = mono_image_open (file, NULL); + if (!image){ + fprintf (stderr, "Can not open image %s\n", file); + exit (1); + } - mono_assembly_close (assembly); + if (dump_data) + dump_dotnet_iinfo (image); + if (verify_pe) { + int f = 0; + char *tok = strtok (flags, ","); + MonoAssembly *assembly; + while (tok) { + for (i = 0; flag_desc [i]; ++i) { + if (strcmp (tok, flag_desc [i]) == 0) { + f |= flag_vals [i]; + break; + } + } + if (!flag_desc [i]) + g_print ("Unknown verify flag %s\n", tok); + tok = strtok (NULL, ","); + } + mono_init (file); + assembly = mono_assembly_open (file, NULL); + dump_verify_info (assembly->image, f); + } else + mono_image_close (image); return 0; }