2 * pedump.c: Dumps the contents of an extended PE/COFF file
5 * Miguel de Icaza (miguel@ximian.com)
7 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
8 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
15 #include <mono/metadata/image.h>
17 #include <mono/metadata/cil-coff.h>
18 #include <mono/metadata/mono-endian.h>
19 #include <mono/metadata/verify.h>
20 #include <mono/metadata/class.h>
21 #include <mono/metadata/debug-helpers.h>
22 #include <mono/metadata/tokentype.h>
23 #include <mono/metadata/appdomain.h>
24 #include <mono/metadata/assembly-internals.h>
25 #include <mono/metadata/metadata-internals.h>
26 #include <mono/metadata/class-internals.h>
27 #include <mono/metadata/verify-internals.h>
28 #include <mono/metadata/marshal.h>
29 #include <mono/metadata/w32handle.h>
30 #include "mono/utils/mono-digest.h"
31 #include <mono/utils/mono-mmap.h>
32 #include <mono/utils/mono-counters.h>
33 #include <sys/types.h>
39 gboolean dump_data
= TRUE
;
40 gboolean verify_pe
= FALSE
;
41 gboolean verify_metadata
= FALSE
;
42 gboolean verify_code
= FALSE
;
43 gboolean verify_partial_md
= FALSE
;
45 static char *assembly_directory
[2];
47 static MonoAssembly
*pedump_preload (MonoAssemblyName
*aname
, gchar
**assemblies_path
, gpointer user_data
);
48 static void pedump_assembly_load_hook (MonoAssembly
*assembly
, gpointer user_data
);
49 static MonoAssembly
*pedump_assembly_search_hook (MonoAssemblyName
*aname
, gpointer user_data
);
53 hex_dump (const char *buffer, int base, int count)
57 for (i = 0; i < count; i++){
59 printf ("\n0x%08x: ", (unsigned char) base + i);
61 printf ("%02x ", (unsigned char) (buffer [i]));
67 hex8 (const char *label
, unsigned char x
)
69 printf ("\t%s: 0x%02x\n", label
, (unsigned char) x
);
73 hex16 (const char *label
, guint16 x
)
75 printf ("\t%s: 0x%04x\n", label
, x
);
79 hex32 (const char *label
, guint32 x
)
81 printf ("\t%s: 0x%08x\n", label
, x
);
85 dump_coff_header (MonoCOFFHeader
*coff
)
87 printf ("\nCOFF Header:\n");
88 hex16 (" Machine", coff
->coff_machine
);
89 hex16 (" Sections", coff
->coff_sections
);
90 hex32 (" Time stamp", coff
->coff_time
);
91 hex32 ("Pointer to Symbol Table", coff
->coff_symptr
);
92 hex32 (" Symbol Count", coff
->coff_symcount
);
93 hex16 (" Optional Header Size", coff
->coff_opt_header_size
);
94 hex16 (" Characteristics", coff
->coff_attributes
);
99 dump_pe_header (MonoPEHeader
*pe
)
101 printf ("\nPE Header:\n");
102 hex16 (" Magic (0x010b)", pe
->pe_magic
);
103 hex8 (" LMajor (6)", pe
->pe_major
);
104 hex8 (" LMinor (0)", pe
->pe_minor
);
105 hex32 (" Code Size", pe
->pe_code_size
);
106 hex32 (" Initialized Data Size", pe
->pe_data_size
);
107 hex32 ("Uninitialized Data Size", pe
->pe_uninit_data_size
);
108 hex32 (" Entry Point RVA", pe
->pe_rva_entry_point
);
109 hex32 (" Code Base RVA", pe
->pe_rva_code_base
);
110 hex32 (" Data Base RVA", pe
->pe_rva_data_base
);
115 dump_nt_header (MonoPEHeaderNT
*nt
)
117 printf ("\nNT Header:\n");
119 hex32 (" Image Base (0x400000)", nt
->pe_image_base
);
120 hex32 ("Section Alignment (8192)", nt
->pe_section_align
);
121 hex32 (" File Align (512/4096)", nt
->pe_file_alignment
);
122 hex16 (" OS Major (4)", nt
->pe_os_major
);
123 hex16 (" OS Minor (0)", nt
->pe_os_minor
);
124 hex16 (" User Major (0)", nt
->pe_user_major
);
125 hex16 (" User Minor (0)", nt
->pe_user_minor
);
126 hex16 (" Subsys major (4)", nt
->pe_subsys_major
);
127 hex16 (" Subsys minor (0)", nt
->pe_subsys_minor
);
128 hex32 (" Reserverd", nt
->pe_reserved_1
);
129 hex32 (" Image Size", nt
->pe_image_size
);
130 hex32 (" Header Size", nt
->pe_header_size
);
131 hex32 (" Checksum (0)", nt
->pe_checksum
);
132 hex16 (" Subsystem", nt
->pe_subsys_required
);
133 hex16 (" DLL Flags (0)", nt
->pe_dll_flags
);
134 hex32 (" Stack Reserve Size (1M)", nt
->pe_stack_reserve
);
135 hex32 ("Stack commit Size (4096)", nt
->pe_stack_commit
);
136 hex32 (" Heap Reserve Size (1M)", nt
->pe_heap_reserve
);
137 hex32 (" Heap Commit Size (4096)", nt
->pe_heap_commit
);
138 hex32 (" Loader flags (0x1)", nt
->pe_loader_flags
);
139 hex32 (" Data Directories (16)", nt
->pe_data_dir_count
);
143 dent (const char *label
, MonoPEDirEntry de
)
145 printf ("\t%s: 0x%08x [0x%08x]\n", label
, de
.rva
, de
.size
);
149 dump_blob (const char *desc
, const char* p
, guint32 size
)
159 for (i
= 0; i
< size
; ++i
) {
162 printf (" %02X", p
[i
] & 0xFF);
168 dump_public_key (MonoImage
*m
)
173 p
= mono_image_get_public_key (m
, &size
);
174 dump_blob ("\nPublic key:", p
, size
);
178 dump_strong_name (MonoImage
*m
)
183 p
= mono_image_get_strong_name (m
, &size
);
184 dump_blob ("\nStrong name:", p
, size
);
188 dump_datadir (MonoPEDatadir
*dd
)
190 printf ("\nData directories:\n");
191 dent (" Export Table", dd
->pe_export_table
);
192 dent (" Import Table", dd
->pe_import_table
);
193 dent (" Resource Table", dd
->pe_resource_table
);
194 dent (" Exception Table", dd
->pe_exception_table
);
195 dent ("Certificate Table", dd
->pe_certificate_table
);
196 dent (" Reloc Table", dd
->pe_reloc_table
);
197 dent (" Debug", dd
->pe_debug
);
198 dent (" Copyright", dd
->pe_copyright
);
199 dent (" Global Ptr", dd
->pe_global_ptr
);
200 dent (" TLS Table", dd
->pe_tls_table
);
201 dent ("Load Config Table", dd
->pe_load_config_table
);
202 dent (" Bound Import", dd
->pe_bound_import
);
203 dent (" IAT", dd
->pe_iat
);
204 dent ("Delay Import Desc", dd
->pe_delay_import_desc
);
205 dent (" CLI Header", dd
->pe_cli_header
);
209 dump_dotnet_header (MonoDotNetHeader
*header
)
211 dump_coff_header (&header
->coff
);
212 dump_pe_header (&header
->pe
);
213 dump_nt_header (&header
->nt
);
214 dump_datadir (&header
->datadir
);
218 dump_section_table (MonoSectionTable
*st
)
220 guint32 flags
= st
->st_flags
;
222 printf ("\n\tName: %s\n", st
->st_name
);
223 hex32 (" Virtual Size", st
->st_virtual_size
);
224 hex32 ("Virtual Address", st
->st_virtual_address
);
225 hex32 (" Raw Data Size", st
->st_raw_data_size
);
226 hex32 (" Raw Data Ptr", st
->st_raw_data_ptr
);
227 hex32 (" Reloc Ptr", st
->st_reloc_ptr
);
228 hex32 (" LineNo Ptr", st
->st_lineno_ptr
);
229 hex16 (" Reloc Count", st
->st_reloc_count
);
230 hex16 (" Line Count", st
->st_line_count
);
232 printf ("\tFlags: %s%s%s%s%s%s%s%s%s%s\n",
233 (flags
& SECT_FLAGS_HAS_CODE
) ? "code, " : "",
234 (flags
& SECT_FLAGS_HAS_INITIALIZED_DATA
) ? "data, " : "",
235 (flags
& SECT_FLAGS_HAS_UNINITIALIZED_DATA
) ? "bss, " : "",
236 (flags
& SECT_FLAGS_MEM_DISCARDABLE
) ? "discard, " : "",
237 (flags
& SECT_FLAGS_MEM_NOT_CACHED
) ? "nocache, " : "",
238 (flags
& SECT_FLAGS_MEM_NOT_PAGED
) ? "nopage, " : "",
239 (flags
& SECT_FLAGS_MEM_SHARED
) ? "shared, " : "",
240 (flags
& SECT_FLAGS_MEM_EXECUTE
) ? "exec, " : "",
241 (flags
& SECT_FLAGS_MEM_READ
) ? "read, " : "",
242 (flags
& SECT_FLAGS_MEM_WRITE
) ? "write" : "");
246 dump_sections (MonoCLIImageInfo
*iinfo
)
248 const int top
= iinfo
->cli_header
.coff
.coff_sections
;
251 for (i
= 0; i
< top
; i
++)
252 dump_section_table (&iinfo
->cli_section_tables
[i
]);
256 dump_cli_header (MonoCLIHeader
*ch
)
259 printf (" CLI header size: %d\n", ch
->ch_size
);
260 printf (" Runtime required: %d.%d\n", ch
->ch_runtime_major
, ch
->ch_runtime_minor
);
261 printf (" Flags: %s, %s, %s, %s\n",
262 (ch
->ch_flags
& CLI_FLAGS_ILONLY
? "ilonly" : "contains native"),
263 (ch
->ch_flags
& CLI_FLAGS_32BITREQUIRED
? "32bits" : "32/64"),
264 (ch
->ch_flags
& CLI_FLAGS_TRACKDEBUGDATA
? "trackdebug" : "no-trackdebug"),
265 (ch
->ch_flags
& CLI_FLAGS_STRONGNAMESIGNED
? "strongnamesigned" : "notsigned"));
266 dent (" Metadata", ch
->ch_metadata
);
267 hex32 ("Entry Point Token", ch
->ch_entry_point
);
268 dent (" Resources at", ch
->ch_resources
);
269 dent (" Strong Name at", ch
->ch_strong_name
);
270 dent (" Code Manager at", ch
->ch_code_manager_table
);
271 dent (" VTableFixups at", ch
->ch_vtable_fixups
);
272 dent (" EAT jumps at", ch
->ch_export_address_table_jumps
);
276 dsh (const char *label
, MonoImage
*meta
, MonoStreamHeader
*sh
)
278 printf ("%s: 0x%08x - 0x%08x [%d == 0x%08x]\n",
280 (int)(sh
->data
- meta
->raw_metadata
), (int)(sh
->data
+ sh
->size
- meta
->raw_metadata
),
285 dump_metadata_header (MonoImage
*meta
)
287 printf ("\nMetadata header:\n");
288 printf (" Version: %d.%d\n", meta
->md_version_major
, meta
->md_version_minor
);
289 printf (" Version string: %s\n", meta
->version
);
293 dump_metadata_ptrs (MonoImage
*meta
)
295 printf ("\nMetadata pointers:\n");
296 dsh ("\tTables (#~)", meta
, &meta
->heap_tables
);
297 dsh ("\t Strings", meta
, &meta
->heap_strings
);
298 dsh ("\t Blob", meta
, &meta
->heap_blob
);
299 dsh ("\tUser string", meta
, &meta
->heap_us
);
300 dsh ("\t GUID", meta
, &meta
->heap_guid
);
304 dump_metadata (MonoImage
*meta
)
308 dump_metadata_header (meta
);
310 dump_metadata_ptrs (meta
);
313 for (table
= 0; table
< MONO_TABLE_NUM
; table
++){
314 if (meta
->tables
[table
].rows
== 0)
316 printf ("Table %s: %d records (%d bytes, at %x)\n",
317 mono_meta_table_name (table
),
318 meta
->tables
[table
].rows
,
319 meta
->tables
[table
].row_size
,
320 (unsigned int)(meta
->tables
[table
].base
- meta
->raw_data
)
326 dump_methoddef (MonoImage
*metadata
, guint32 token
)
332 loc
= mono_metadata_locate_token (metadata
, token
);
334 printf ("RVA for Entry Point: 0x%08x\n", read32 (loc
));
338 dump_dotnet_iinfo (MonoImage
*image
)
340 MonoCLIImageInfo
*iinfo
= (MonoCLIImageInfo
*)image
->image_info
;
342 dump_dotnet_header (&iinfo
->cli_header
);
343 dump_sections (iinfo
);
344 dump_cli_header (&iinfo
->cli_cli_header
);
345 dump_strong_name (image
);
346 dump_public_key (image
);
347 dump_metadata (image
);
349 dump_methoddef (image
, iinfo
->cli_cli_header
.ch_entry_point
);
353 dump_verify_info (MonoImage
*image
, int flags
, gboolean valid_only
)
355 GSList
*errors
, *tmp
;
356 int count
= 0, verifiable
= 0;
357 const char* desc
[] = {
358 "Ok", "Error", "Warning", NULL
, "CLS", NULL
, NULL
, NULL
, "Not Verifiable"
361 if (verify_code
) { /* verify code */
363 MonoTableInfo
*m
= &image
->tables
[MONO_TABLE_METHOD
];
365 for (i
= 0; i
< m
->rows
; ++i
) {
369 method
= mono_get_method_checked (image
, MONO_TOKEN_METHOD_DEF
| (i
+1), NULL
, NULL
, error
);
371 g_print ("Warning: Cannot lookup method with token 0x%08x due to %s\n", i
+ 1, mono_error_get_message (error
));
372 mono_error_cleanup (error
);
375 errors
= mono_method_verify (method
, flags
);
377 MonoClass
*klass
= mono_method_get_class (method
);
378 char *name
= mono_type_full_name (&klass
->byval_arg
);
379 if (mono_method_signature (method
) == NULL
) {
380 g_print ("In method: %s::%s(ERROR)\n", name
, mono_method_get_name (method
));
383 sig
= mono_signature_get_desc (mono_method_signature (method
), FALSE
);
384 g_print ("In method: %s::%s(%s)\n", name
, mono_method_get_name (method
), sig
);
390 for (tmp
= errors
; tmp
; tmp
= tmp
->next
) {
391 MonoVerifyInfo
*info
= (MonoVerifyInfo
*)tmp
->data
;
392 if (info
->status
== MONO_VERIFY_NOT_VERIFIABLE
&& valid_only
)
395 g_print ("%s: %s\n", desc
[info
->status
], info
->message
);
396 if (info
->status
== MONO_VERIFY_ERROR
) {
400 if(info
->status
== MONO_VERIFY_NOT_VERIFIABLE
) {
405 mono_free_verify_list (errors
);
410 g_print ("Error count: %d\n", count
);
417 printf ("Usage is: pedump [--verify error,warn,cls,all,code,fail-on-verifiable,non-strict,valid-only,metadata] file.exe\n");
422 verify_image_file (const char *fname
)
424 GSList
*errors
= NULL
, *tmp
;
426 MonoTableInfo
*table
;
427 MonoAssembly
*assembly
;
428 MonoImageOpenStatus status
;
430 const char* desc
[] = {
431 "Ok", "Error", "Warning", NULL
, "CLS", NULL
, NULL
, NULL
, "Not Verifiable"
434 if (!strstr (fname
, "mscorlib.dll")) {
435 image
= mono_image_open_raw (fname
, &status
);
437 printf ("Could not open %s\n", fname
);
441 if (!mono_verifier_verify_pe_data (image
, &errors
))
444 if (!mono_image_load_pe_data (image
)) {
445 printf ("Could not load pe data for assembly %s\n", fname
);
449 if (!mono_verifier_verify_cli_data (image
, &errors
))
452 if (!mono_image_load_cli_data (image
)) {
453 printf ("Could not load cli data for assembly %s\n", fname
);
457 if (!mono_verifier_verify_table_data (image
, &errors
))
460 mono_image_load_names (image
);
462 /*fake an assembly for class loading to work*/
463 assembly
= g_new0 (MonoAssembly
, 1);
464 assembly
->in_gac
= FALSE
;
465 assembly
->image
= image
;
466 image
->assembly
= assembly
;
467 mono_assembly_fill_assembly_name (image
, &assembly
->aname
);
469 /*Finish initializing the runtime*/
470 mono_install_assembly_load_hook (pedump_assembly_load_hook
, NULL
);
471 mono_install_assembly_search_hook (pedump_assembly_search_hook
, NULL
);
473 mono_init_version ("pedump", image
->version
);
475 mono_install_assembly_preload_hook (pedump_preload
, GUINT_TO_POINTER (FALSE
));
478 mono_marshal_init ();
480 /*Finish initializing the runtime*/
481 mono_install_assembly_load_hook (pedump_assembly_load_hook
, NULL
);
482 mono_install_assembly_search_hook (pedump_assembly_search_hook
, NULL
);
484 mono_init_version ("pedump", NULL
);
486 mono_install_assembly_preload_hook (pedump_preload
, GUINT_TO_POINTER (FALSE
));
489 mono_marshal_init ();
490 image
= mono_get_corlib ();
492 if (!mono_verifier_verify_pe_data (image
, &errors
))
495 if (!mono_image_load_pe_data (image
)) {
496 printf ("Could not load pe data for assembly %s\n", fname
);
500 if (!mono_verifier_verify_cli_data (image
, &errors
))
503 if (!mono_image_load_cli_data (image
)) {
504 printf ("Could not load cli data for assembly %s\n", fname
);
508 if (!mono_verifier_verify_table_data (image
, &errors
))
512 if (!verify_partial_md
&& !mono_verifier_verify_full_table_data (image
, &errors
))
516 table
= &image
->tables
[MONO_TABLE_TYPEDEF
];
517 for (i
= 1; i
<= table
->rows
; ++i
) {
519 guint32 token
= i
| MONO_TOKEN_TYPE_DEF
;
520 MonoClass
*klass
= mono_class_get_checked (image
, token
, error
);
522 printf ("Could not load class with token %x due to %s\n", token
, mono_error_get_message (error
));
523 mono_error_cleanup (error
);
526 mono_class_init (klass
);
527 if (mono_class_has_failure (klass
)) {
528 ERROR_DECL (type_load_error
);
529 mono_error_set_for_class_failure (type_load_error
, klass
);
530 printf ("Could not initialize class(0x%08x) %s.%s due to %s\n", token
, klass
->name_space
, klass
->name
, mono_error_get_message (type_load_error
));
531 mono_error_cleanup (type_load_error
);
535 mono_class_setup_vtable (klass
);
536 if (mono_class_has_failure (klass
)) {
537 ERROR_DECL (type_load_error
);
538 mono_error_set_for_class_failure (type_load_error
, klass
);
539 printf ("Could not initialize vtable of class(0x%08x) %s.%s due to %s\n", token
, klass
->name_space
, klass
->name
, mono_error_get_message (type_load_error
));
540 mono_error_cleanup (type_load_error
);
549 for (tmp
= errors
; tmp
; tmp
= tmp
->next
) {
550 MonoVerifyInfo
*info
= (MonoVerifyInfo
*)tmp
->data
;
551 g_print ("%s: %s\n", desc
[info
->status
], info
->message
);
552 if (info
->status
== MONO_VERIFY_ERROR
)
555 mono_free_verify_list (errors
);
557 g_print ("Error count: %d\n", count
);
562 try_load_from (MonoAssembly
**assembly
, const gchar
*path1
, const gchar
*path2
,
563 const gchar
*path3
, const gchar
*path4
, gboolean refonly
)
568 fullpath
= g_build_filename (path1
, path2
, path3
, path4
, NULL
);
569 if (g_file_test (fullpath
, G_FILE_TEST_IS_REGULAR
))
570 *assembly
= mono_assembly_open_predicate (fullpath
, refonly
, FALSE
, NULL
, NULL
, NULL
);
573 return (*assembly
!= NULL
);
576 static MonoAssembly
*
577 real_load (gchar
**search_path
, const gchar
*culture
, const gchar
*name
, gboolean refonly
)
579 MonoAssembly
*result
= NULL
;
582 const gchar
*local_culture
;
585 if (!culture
|| *culture
== '\0') {
588 local_culture
= culture
;
591 filename
= g_strconcat (name
, ".dll", NULL
);
592 len
= strlen (filename
);
594 for (path
= search_path
; *path
; path
++) {
596 continue; /* Ignore empty ApplicationBase */
598 /* See test cases in bug #58992 and bug #57710 */
599 /* 1st try: [culture]/[name].dll (culture may be empty) */
600 strcpy (filename
+ len
- 4, ".dll");
601 if (try_load_from (&result
, *path
, local_culture
, "", filename
, refonly
))
604 /* 2nd try: [culture]/[name].exe (culture may be empty) */
605 strcpy (filename
+ len
- 4, ".exe");
606 if (try_load_from (&result
, *path
, local_culture
, "", filename
, refonly
))
609 /* 3rd try: [culture]/[name]/[name].dll (culture may be empty) */
610 strcpy (filename
+ len
- 4, ".dll");
611 if (try_load_from (&result
, *path
, local_culture
, name
, filename
, refonly
))
614 /* 4th try: [culture]/[name]/[name].exe (culture may be empty) */
615 strcpy (filename
+ len
- 4, ".exe");
616 if (try_load_from (&result
, *path
, local_culture
, name
, filename
, refonly
))
625 * Try to load referenced assemblies from assemblies_path.
627 static MonoAssembly
*
628 pedump_preload (MonoAssemblyName
*aname
,
629 gchar
**assemblies_path
,
632 MonoAssembly
*result
= NULL
;
633 gboolean refonly
= GPOINTER_TO_UINT (user_data
);
635 if (assemblies_path
&& assemblies_path
[0] != NULL
) {
636 result
= real_load (assemblies_path
, aname
->culture
, aname
->name
, refonly
);
639 result
= real_load (assembly_directory
, aname
->culture
, aname
->name
, refonly
);
644 static GList
*loaded_assemblies
= NULL
;
647 pedump_assembly_load_hook (MonoAssembly
*assembly
, gpointer user_data
)
649 loaded_assemblies
= g_list_prepend (loaded_assemblies
, assembly
);
652 static MonoAssembly
*
653 pedump_assembly_search_hook (MonoAssemblyName
*aname
, gpointer user_data
)
657 for (tmp
= loaded_assemblies
; tmp
; tmp
= tmp
->next
) {
658 MonoAssembly
*ass
= (MonoAssembly
*)tmp
->data
;
659 if (mono_assembly_names_equal (aname
, &ass
->aname
))
666 thread_state_init (MonoThreadUnwindState
*ctx
)
670 #define VALID_ONLY_FLAG 0x08000000
671 #define VERIFY_CODE_ONLY MONO_VERIFY_ALL + 1
672 #define VERIFY_METADATA_ONLY VERIFY_CODE_ONLY + 1
673 #define VERIFY_PARTIAL_METADATA VERIFY_CODE_ONLY + 2
676 main (int argc
, char *argv
[])
678 int image_result
= 0;
682 MiniVerifierMode verifier_mode
= MONO_VERIFIER_MODE_VERIFIABLE
;
683 const char *flag_desc
[] = {"error", "warn", "cls", "all", "code", "fail-on-verifiable", "non-strict", "valid-only", "metadata", "partial-md", NULL
};
684 guint flag_vals
[] = {MONO_VERIFY_ERROR
, MONO_VERIFY_WARNING
, MONO_VERIFY_CLS
, MONO_VERIFY_ALL
, VERIFY_CODE_ONLY
, MONO_VERIFY_FAIL_FAST
, MONO_VERIFY_NON_STRICT
, VALID_ONLY_FLAG
, VERIFY_METADATA_ONLY
, VERIFY_PARTIAL_METADATA
, 0};
685 int i
, verify_flags
= MONO_VERIFY_REPORT_ALL_ERRORS
, run_new_metadata_verifier
= 0;
686 MonoThreadInfoRuntimeCallbacks ticallbacks
;
688 for (i
= 1; i
< argc
; i
++){
689 if (argv
[i
][0] != '-'){
694 if (strcmp (argv
[i
], "--help") == 0)
696 else if (strcmp (argv
[i
], "--verify") == 0) {
709 //We have to force the runtime to load the corlib under verification as its own corlib so core types are properly populated in mono_defaults.
710 if (strstr (file
, "mscorlib.dll"))
711 g_setenv ("MONO_PATH", g_path_get_dirname (file
), 1);
712 assembly_directory
[0] = g_path_get_dirname (file
);
713 assembly_directory
[1] = NULL
;
715 #ifndef DISABLE_PERFCOUNTERS
716 mono_perfcounters_init ();
718 mono_counters_init ();
719 mono_tls_init_runtime_keys ();
720 memset (&ticallbacks
, 0, sizeof (ticallbacks
));
721 ticallbacks
.thread_state_init
= thread_state_init
;
723 mono_w32handle_init ();
725 mono_thread_info_runtime_init (&ticallbacks
);
727 mono_metadata_init ();
729 mono_assemblies_init ();
734 char *tok
= strtok (flags
, ",");
739 for (i
= 0; flag_desc
[i
]; ++i
) {
740 if (strcmp (tok
, flag_desc
[i
]) == 0) {
741 if (flag_vals
[i
] == VERIFY_CODE_ONLY
) {
744 } else if(flag_vals
[i
] == MONO_VERIFY_ALL
) {
746 } else if(flag_vals
[i
] == VERIFY_METADATA_ONLY
) {
748 run_new_metadata_verifier
= 1;
749 } else if(flag_vals
[i
] == VERIFY_PARTIAL_METADATA
) {
750 verify_partial_md
= 1;
752 if (flag_vals
[i
] == VALID_ONLY_FLAG
)
753 verifier_mode
= MONO_VERIFIER_MODE_VALID
;
755 verify_flags
|= flag_vals
[i
];
760 g_print ("Unknown verify flag %s\n", tok
);
761 tok
= strtok (NULL
, ",");
764 mono_verifier_set_mode (verifier_mode
);
768 if (verify_pe
|| run_new_metadata_verifier
) {
769 run_new_metadata_verifier
= 1;
772 if (run_new_metadata_verifier
) {
773 mono_verifier_set_mode (verifier_mode
);
775 image_result
= verify_image_file (file
);
776 if (image_result
== 1 || !verify_code
)
780 image
= mono_image_open (file
, NULL
);
782 fprintf (stderr
, "Cannot open image %s\n", file
);
787 dump_dotnet_iinfo (image
);
789 MonoAssembly
*assembly
;
791 MonoImageOpenStatus status
;
794 mono_verifier_set_mode (verifier_mode
);
796 assembly
= mono_assembly_open_predicate (file
, FALSE
, FALSE
, NULL
, NULL
, NULL
);
797 /*fake an assembly for netmodules so the verifier works*/
798 if (!assembly
&& (image
= mono_image_open (file
, &status
)) && image
->tables
[MONO_TABLE_ASSEMBLY
].rows
== 0) {
799 assembly
= g_new0 (MonoAssembly
, 1);
800 assembly
->in_gac
= FALSE
;
801 assembly
->image
= image
;
802 image
->assembly
= assembly
;
806 g_print ("Could not open assembly %s\n", file
);
810 code_result
= dump_verify_info (assembly
->image
, verify_flags
, verifier_mode
== MONO_VERIFIER_MODE_VALID
);
811 return code_result
? code_result
: image_result
;
813 mono_image_close (image
);