New test.
[mono.git] / mono / dis / dump.c
1 /*
2  * dump.c: Dumping routines for the disassembler.
3  *
4  * Author:
5  *   Miguel de Icaza (miguel@ximian.com)
6  *
7  * (C) 2001 Ximian, Inc.
8  */
9 #include <config.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <glib.h>
13 #include <math.h>
14 #include "meta.h"
15 #include "util.h"
16 #include "dump.h"
17 #include "get.h"
18 #include "declsec.h"
19 #include "mono/metadata/loader.h"
20 #include "mono/metadata/class.h"
21 #include "mono/metadata/class-internals.h"
22 #include "mono/utils/mono-compiler.h"
23
24 #ifndef HAVE_ISINF
25
26 #ifdef HAVE_IEEEFP_H
27 extern int isinf (double);
28 #endif
29
30 #endif
31
32 void
33 dump_table_assembly (MonoImage *m)
34 {
35         MonoTableInfo *t = &m->tables [MONO_TABLE_ASSEMBLY];
36         guint32 cols [MONO_ASSEMBLY_SIZE];
37         const char *ptr;
38         int len;
39
40         fprintf (output, "Assembly Table\n");
41
42         if (!t->rows)
43                 return;
44
45         mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
46
47         fprintf (output, "Name:          %s\n", mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]));
48         fprintf (output, "Hash Algoritm: 0x%08x\n", cols [MONO_ASSEMBLY_HASH_ALG]);
49         fprintf (output, "Version:       %d.%d.%d.%d\n", cols [MONO_ASSEMBLY_MAJOR_VERSION], 
50                                         cols [MONO_ASSEMBLY_MINOR_VERSION], 
51                                         cols [MONO_ASSEMBLY_BUILD_NUMBER], 
52                                         cols [MONO_ASSEMBLY_REV_NUMBER]);
53         fprintf (output, "Flags:         0x%08x\n", cols [MONO_ASSEMBLY_FLAGS]);
54         fprintf (output, "PublicKey:     BlobPtr (0x%08x)\n", cols [MONO_ASSEMBLY_PUBLIC_KEY]);
55
56         ptr = mono_metadata_blob_heap (m, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
57         len = mono_metadata_decode_value (ptr, &ptr);
58         if (len > 0){
59                 fprintf (output, "\tDump:");
60                 hex_dump (ptr, 0, len);
61                 fprintf (output, "\n");
62         } else
63                 fprintf (output, "\tZero sized public key\n");
64         
65         fprintf (output, "Culture:       %s\n", mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_CULTURE]));
66         fprintf (output, "\n");
67 }
68
69 void
70 dump_table_typeref (MonoImage *m)
71 {
72         MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEREF];
73         int i;
74
75         fprintf (output, "Typeref Table\n");
76         
77         for (i = 1; i <= t->rows; i++){
78                 char *s = get_typeref (m, i);
79                 
80                 fprintf (output, "%d: %s\n", i, s);
81                 g_free (s);
82         }
83         fprintf (output, "\n");
84 }
85
86 void
87 dump_table_typedef (MonoImage *m)
88 {
89         MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
90         int i;
91
92         fprintf (output, "Typedef Table\n");
93         
94         for (i = 1; i <= t->rows; i++){
95                 char *s = get_typedef (m, i);
96                 guint32 cols [MONO_TYPEDEF_SIZE];
97
98                 mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], i - 1, cols, MONO_TYPEDEF_SIZE);
99
100                 fprintf (output, "%d: %s (flist=%d, mlist=%d, flags=0x%x, extends=0x%x)\n", i, s, 
101                                         cols [MONO_TYPEDEF_FIELD_LIST], cols [MONO_TYPEDEF_METHOD_LIST],
102                                         cols [MONO_TYPEDEF_FLAGS], cols [MONO_TYPEDEF_EXTENDS]);
103                 g_free (s);
104         }
105         fprintf (output, "\n");
106 }
107
108 void
109 dump_table_typespec (MonoImage *m)
110 {
111         MonoTableInfo *t = &m->tables [MONO_TABLE_TYPESPEC];
112         int i;
113
114         fprintf (output, "Typespec Table\n");
115         
116         for (i = 1; i <= t->rows; i++){         
117                 char *typespec = get_typespec (m, i, TRUE, NULL);
118
119                 fprintf (output, "%d: %s\n", i, typespec);
120                 g_free (typespec);
121         }
122         fprintf (output, "\n");
123 }
124
125 void
126 dump_table_assemblyref (MonoImage *m)
127 {
128         MonoTableInfo *t = &m->tables [MONO_TABLE_ASSEMBLYREF];
129         int i;
130
131         fprintf (output, "AssemblyRef Table\n");
132         
133         for (i = 0; i < t->rows; i++){
134                 const char *ptr;
135                 int len;
136                 guint32 cols [MONO_ASSEMBLYREF_SIZE];
137
138                 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
139                 fprintf (output, "%d: Version=%d.%d.%d.%d\n\tName=%s\n", i + 1,
140                          cols [MONO_ASSEMBLYREF_MAJOR_VERSION], 
141                          cols [MONO_ASSEMBLYREF_MINOR_VERSION], 
142                          cols [MONO_ASSEMBLYREF_BUILD_NUMBER], 
143                          cols [MONO_ASSEMBLYREF_REV_NUMBER],
144                          mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
145                 ptr = mono_metadata_blob_heap (m, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
146                 len = mono_metadata_decode_value (ptr, &ptr);
147                 if (len > 0){
148                         fprintf (output, "\tPublic Key:");
149                         hex_dump (ptr, 0, len);
150                         fprintf (output, "\n");
151                 } else
152                         fprintf (output, "\tZero sized public key\n");
153                 
154         }
155         fprintf (output, "\n");
156 }
157
158 void
159 dump_table_param (MonoImage *m)
160 {
161         MonoTableInfo *t = &m->tables [MONO_TABLE_PARAM];
162         int i;
163
164         fprintf (output, "Param Table\n");
165         
166         for (i = 0; i < t->rows; i++){
167                 guint32 cols [MONO_PARAM_SIZE];
168
169                 mono_metadata_decode_row (t, i, cols, MONO_PARAM_SIZE);
170                 fprintf (output, "%d: 0x%04x %d %s\n",
171                          i + 1,
172                          cols [MONO_PARAM_FLAGS], cols [MONO_PARAM_SEQUENCE], 
173                          mono_metadata_string_heap (m, cols [MONO_PARAM_NAME]));
174         }
175         fprintf (output, "\n");
176 }
177
178 void
179 dump_table_field (MonoImage *m)
180 {
181         MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
182         MonoTableInfo *td = &m->tables [MONO_TABLE_TYPEDEF];
183         MonoTableInfo *fl = &m->tables [MONO_TABLE_FIELDLAYOUT];
184         MonoTableInfo *rva = &m->tables [MONO_TABLE_FIELDRVA];
185         int i, current_type, offset_row, rva_row;
186         guint32 first_m, last_m;
187
188         fprintf (output, "Field Table (1..%d)\n", t->rows);
189         
190         rva_row = offset_row = current_type = 1;
191         last_m = first_m = 1;
192         for (i = 1; i <= t->rows; i++){
193                 guint32 cols [MONO_FIELD_SIZE];
194                 char *sig, *flags;
195
196                 /*
197                  * Find the next type.
198                  */
199                 while (current_type <= td->rows && i >= (last_m = mono_metadata_decode_row_col (td, current_type - 1, MONO_TYPEDEF_FIELD_LIST))) {
200                         current_type++;
201                 }
202                 if (i == first_m) {
203                         fprintf (output, "########## %s.%s\n",
204                                 mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAMESPACE)),
205                                 mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAME)));
206                         first_m = last_m;
207                 }
208                 mono_metadata_decode_row (t, i - 1, cols, MONO_FIELD_SIZE);
209                 sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], NULL);
210                 flags = field_flags (cols [MONO_FIELD_FLAGS]);
211                 fprintf (output, "%d: %s %s: %s\n",
212                          i,
213                          sig,
214                          mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]),
215                          flags);
216                 g_free (sig);
217                 g_free (flags);
218                 if (offset_row <= fl->rows && (mono_metadata_decode_row_col (fl, offset_row - 1, MONO_FIELD_LAYOUT_FIELD) == i)) {
219                         fprintf (output, "\texplicit offset: %d\n", mono_metadata_decode_row_col (fl, offset_row - 1, MONO_FIELD_LAYOUT_OFFSET));
220                         offset_row ++;
221                 }
222                 if (rva_row <= rva->rows && (mono_metadata_decode_row_col (rva, rva_row - 1, MONO_FIELD_RVA_FIELD) == i)) {
223                         fprintf (output, "\trva: %d\n", mono_metadata_decode_row_col (rva, rva_row - 1, MONO_FIELD_RVA_RVA));
224                         rva_row ++;
225                 }
226         }
227         fprintf (output, "\n");
228 }
229
230 void
231 dump_table_memberref (MonoImage *m)
232 {
233         MonoTableInfo *t = &m->tables [MONO_TABLE_MEMBERREF];
234         int i, kind, idx;
235         char *x, *xx;
236         char *sig;
237         const char *blob, *ks = NULL;
238
239         fprintf (output, "MemberRef Table (1..%d)\n", t->rows);
240
241         for (i = 0; i < t->rows; i++){
242                 guint32 cols [MONO_MEMBERREF_SIZE];
243
244                 mono_metadata_decode_row (t, i, cols, MONO_MEMBERREF_SIZE);
245                 
246                 kind = cols [MONO_MEMBERREF_CLASS] & 7;
247                 idx = cols [MONO_MEMBERREF_CLASS] >> 3;
248
249                 x = g_strdup ("UNHANDLED CASE");
250                 
251                 switch (kind){
252                 case 0:
253                         ks = "TypeDef";
254                         xx = get_typedef (m, idx);
255                         x = g_strconcat (xx, ".", mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]), NULL);
256                         g_free (xx);
257                         break;
258                 case 1:
259                         ks = "TypeRef";
260                         xx = get_typeref (m, idx);
261                         x = g_strconcat (xx, ".", mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]), NULL);
262                         g_free (xx);
263                         break;
264                 case 2:
265                         ks = "ModuleRef"; break;
266                 case 3:
267                         ks = "MethodDef";
268                         x = get_methoddef (m, idx);
269                         break;
270                 case 4:
271                         ks = "TypeSpec";
272                         xx = get_typespec (m, idx, FALSE, NULL);
273                         x = g_strconcat (xx, ".", mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]), NULL);
274                         g_free (xx);
275                         break;
276                 default:
277                         g_error ("Unknown tag: %d\n", kind);
278                 }
279                 blob = mono_metadata_blob_heap (m, cols [MONO_MEMBERREF_SIGNATURE]);
280                 mono_metadata_decode_blob_size (blob, &blob);
281                 if (*blob == 0x6) { /* it's a field */
282                         sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE], NULL);
283                 } else {
284                         sig = get_methodref_signature (m, cols [MONO_MEMBERREF_SIGNATURE], NULL);
285                 }
286                 fprintf (output, "%d: %s[%d] %s\n\tResolved: %s\n\tSignature: %s\n\t\n",
287                          i + 1,
288                          ks, idx,
289                          mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]),
290                          x ? x : "",
291                          sig);
292
293                 if (x)
294                         g_free (x);
295                 g_free (sig);
296         }
297 }
298
299 void
300 dump_table_class_layout (MonoImage *m)
301 {
302         MonoTableInfo *t = &m->tables [MONO_TABLE_CLASSLAYOUT];
303         int i;
304         fprintf (output, "ClassLayout Table (1..%d)\n", t->rows);
305
306         for (i = 0; i < t->rows; i++){
307                 guint32 cols [MONO_CLASS_LAYOUT_SIZE];
308                 
309                 mono_metadata_decode_row (t, i, cols, MONO_CLASS_LAYOUT_SIZE);
310
311                 fprintf (output, "%d: PackingSize=%d  ClassSize=%d  Parent=%s\n",
312                          i + 1, cols [MONO_CLASS_LAYOUT_PACKING_SIZE], 
313                          cols [MONO_CLASS_LAYOUT_CLASS_SIZE], 
314                          get_typedef (m, cols [MONO_CLASS_LAYOUT_PARENT]));
315         }
316 }
317
318 void
319 dump_table_constant (MonoImage *m)
320 {
321         MonoTableInfo *t = &m->tables [MONO_TABLE_CONSTANT];
322         int i;
323         const char *desc [] = {
324                 "Field",
325                 "Param",
326                 "Property",
327                 ""
328         };
329         fprintf (output, "Constant Table (1..%d)\n", t->rows);
330
331         for (i = 0; i < t->rows; i++){
332                 guint32 cols [MONO_CONSTANT_SIZE];
333                 const char *parent;
334                 mono_metadata_decode_row (t, i, cols, MONO_CONSTANT_SIZE);
335                 parent = desc [cols [MONO_CONSTANT_PARENT] & MONO_HASCONSTANT_MASK];
336
337                 fprintf (output, "%d: Parent= %s: %d %s\n",
338                          i + 1, parent, cols [MONO_CONSTANT_PARENT] >> MONO_HASCONSTANT_BITS, 
339                          get_constant (m, (MonoTypeEnum) cols [MONO_CONSTANT_TYPE], cols [MONO_CONSTANT_VALUE]));
340         }
341         
342 }
343
344 void
345 dump_table_property_map (MonoImage *m)
346 {
347         MonoTableInfo *t = &m->tables [MONO_TABLE_PROPERTYMAP];
348         int i;
349         char *s;
350         
351         fprintf (output, "Property Map Table (1..%d)\n", t->rows);
352         
353         for (i = 0; i < t->rows; i++){
354                 guint32 cols [MONO_PROPERTY_MAP_SIZE];
355                 
356                 mono_metadata_decode_row (t, i, cols, MONO_PROPERTY_MAP_SIZE);
357                 s = get_typedef (m, cols [MONO_PROPERTY_MAP_PARENT]);
358                 fprintf (output, "%d: %s (%d) %d\n", i + 1, s, cols [MONO_PROPERTY_MAP_PARENT], cols [MONO_PROPERTY_MAP_PROPERTY_LIST]);
359                 g_free (s);
360         }
361 }
362
363 void
364 dump_table_property (MonoImage *m)
365 {
366         MonoTableInfo *t = &m->tables [MONO_TABLE_PROPERTY];
367         int i, j, pcount;
368         const char *ptr;
369         char flags[128];
370
371         fprintf (output, "Property Table (1..%d)\n", t->rows);
372
373         for (i = 0; i < t->rows; i++){
374                 guint32 cols [MONO_PROPERTY_SIZE];
375                 char *type;
376                 int bsize;
377                 int prop_flags;
378                 
379                 mono_metadata_decode_row (t, i, cols, MONO_PROPERTY_SIZE);
380                 flags [0] = 0;
381                 prop_flags = cols [MONO_PROPERTY_FLAGS];
382                 if (prop_flags & 0x0200)
383                         strcat (flags, "special ");
384                 if (prop_flags & 0x0400)
385                         strcat (flags, "runtime ");
386                 if (prop_flags & 0x1000)
387                         strcat (flags, "hasdefault ");
388
389                 ptr = mono_metadata_blob_heap (m, cols [MONO_PROPERTY_TYPE]);
390                 bsize = mono_metadata_decode_blob_size (ptr, &ptr);
391                 /* ECMA claims 0x08 ... */
392                 if (*ptr != 0x28 && *ptr != 0x08)
393                         g_warning("incorrect signature in propert blob: 0x%x", *ptr);
394                 ptr++;
395                 pcount = mono_metadata_decode_value (ptr, &ptr);
396                 ptr = get_type (m, ptr, &type, FALSE, NULL);
397                 fprintf (output, "%d: %s %s (",
398                          i + 1, type, mono_metadata_string_heap (m, cols [MONO_PROPERTY_NAME]));
399                 g_free (type);
400
401                 for (j = 0; j < pcount; j++){
402                         ptr = get_param (m, ptr, &type, NULL);
403                         fprintf (output, "%s%s", j > 0? ", " : "",type);
404                         g_free (type);
405                 }
406                 fprintf (output, ") %s\n", flags);
407         }
408 }
409
410 void
411 dump_table_event (MonoImage *m)
412 {
413         MonoTableInfo *t = &m->tables [MONO_TABLE_EVENT];
414         int i;
415         fprintf (output, "Event Table (1..%d)\n", t->rows);
416
417         for (i = 0; i < t->rows; i++){
418                 guint32 cols [MONO_EVENT_SIZE];
419                 const char *name;
420                 char *type;
421                 
422                 mono_metadata_decode_row (t, i, cols, MONO_EVENT_SIZE);
423
424                 name = mono_metadata_string_heap (m, cols [MONO_EVENT_NAME]);
425                 type = get_typedef_or_ref (m, cols [MONO_EVENT_TYPE], NULL);
426                 fprintf (output, "%d: %s %s %s\n", i + 1, type, name,
427                          cols [MONO_EVENT_FLAGS] & 0x200 ? "specialname " : "");
428                 g_free (type);
429         }
430         
431 }
432
433 void
434 dump_table_file (MonoImage *m)
435 {
436         MonoTableInfo *t = &m->tables [MONO_TABLE_FILE];
437         int i, j, len;
438         fprintf (output, "File Table (1..%d)\n", t->rows);
439
440         for (i = 0; i < t->rows; i++){
441                 guint32 cols [MONO_FILE_SIZE];
442                 const char *name, *hash;
443                 
444                 mono_metadata_decode_row (t, i, cols, MONO_FILE_SIZE);
445
446                 name = mono_metadata_string_heap (m, cols [MONO_FILE_NAME]);
447                 fprintf (output, "%d: %s %s [", i + 1, name, 
448                                 cols [MONO_FILE_FLAGS] & 0x1 ? "nometadata" : "containsmetadata");
449                 hash = mono_metadata_blob_heap (m, cols [MONO_FILE_HASH_VALUE]);
450                 len = mono_metadata_decode_blob_size (hash, &hash);
451                 for (j = 0; j < len; ++j)
452                         fprintf (output, "%s%02X", j? " ": "", hash [j] & 0xff);
453                 fprintf (output, "]\n");
454         }
455         
456 }
457
458 static char*
459 get_manifest_implementation (MonoImage *m, guint32 idx)
460 {
461         guint32 row;
462         const char* table = "";
463         if (!idx)
464                 return g_strdup ("current module");
465         row = idx >> MONO_IMPLEMENTATION_BITS;
466         switch (idx & MONO_IMPLEMENTATION_MASK) {
467         case MONO_IMPLEMENTATION_FILE:
468                 table = "file";
469                 break;
470         case MONO_IMPLEMENTATION_ASSEMBLYREF:
471                 table = "assemblyref";
472                 break;
473         case MONO_IMPLEMENTATION_EXP_TYPE:
474                 table = "exportedtype";
475                 break;
476         default:
477                 g_assert_not_reached ();
478         }
479         return g_strdup_printf ("%s %d", table, row);
480 }
481
482 static const char*
483 get_manifest_flags (guint32 mf)
484 {
485         mf &= 3;
486         switch (mf) {
487         case 1: return "public";
488         case 2: return "private";
489         default:
490                 return "";
491         }
492 }
493
494 void
495 dump_table_manifest (MonoImage *m)
496 {
497         MonoTableInfo *t = &m->tables [MONO_TABLE_MANIFESTRESOURCE];
498         int i;
499         fprintf (output, "Manifestresource Table (1..%d)\n", t->rows);
500
501         for (i = 0; i < t->rows; i++){
502                 guint32 cols [MONO_MANIFEST_SIZE];
503                 const char *name, *mf;
504                 char *impl;
505                 
506                 mono_metadata_decode_row (t, i, cols, MONO_MANIFEST_SIZE);
507
508                 name = mono_metadata_string_heap (m, cols [MONO_MANIFEST_NAME]);
509                 mf = get_manifest_flags (cols [MONO_MANIFEST_FLAGS]);
510                 impl = get_manifest_implementation (m, cols [MONO_MANIFEST_IMPLEMENTATION]);
511                 fprintf (output, "%d: %s '%s' at offset %u in %s\n", i + 1, mf, name, cols [MONO_MANIFEST_OFFSET], impl);
512                 g_free (impl);
513         }
514         
515 }
516
517 void
518 dump_table_moduleref (MonoImage *m)
519 {
520         MonoTableInfo *t = &m->tables [MONO_TABLE_MODULEREF];
521         int i;
522         fprintf (output, "ModuleRef Table (1..%d)\n", t->rows);
523
524         for (i = 0; i < t->rows; i++){
525                 guint32 cols [MONO_MODULEREF_SIZE];
526                 const char *name;
527                 
528                 mono_metadata_decode_row (t, i, cols, MONO_MODULEREF_SIZE);
529
530                 name = mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]);
531                 fprintf (output, "%d: %s\n", i + 1, name);
532         }
533         
534 }
535
536 void
537 dump_table_module (MonoImage *m)
538 {
539         MonoTableInfo *t = &m->tables [MONO_TABLE_MODULE];
540         int i;
541         fprintf (output, "ModuleRef Table (1..%d)\n", t->rows);
542
543         for (i = 0; i < t->rows; i++){
544                 guint32 cols [MONO_MODULE_SIZE];
545                 const char *name;
546                 char *guid;
547                 
548                 mono_metadata_decode_row (t, i, cols, MONO_MODULE_SIZE);
549
550                 name = mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]);
551                 guid = get_guid (m, cols [MONO_MODULE_MVID]);
552                 fprintf (output, "%d: %s %d %s\n", i + 1, name, cols [MONO_MODULE_MVID], guid);
553         }       
554 }
555
556 void
557 dump_table_method (MonoImage *m)
558 {
559         MonoTableInfo *t = &m->tables [MONO_TABLE_METHOD];
560         MonoTableInfo *td = &m->tables [MONO_TABLE_TYPEDEF];
561         int i, current_type;
562         guint32 first_m, last_m;
563         /* Generic container for Type & method */
564         MonoGenericContainer *type_container = NULL, *method_container = NULL;
565
566         fprintf (output, "Method Table (1..%d)\n", t->rows);
567
568         current_type = 1;
569         last_m = first_m = 1;
570         for (i = 1; i <= t->rows; i++){
571                 guint32 cols [MONO_METHOD_SIZE];
572                 char *sig;
573                 const char *sigblob;
574                 MonoMethodSignature *method;
575
576                 /*
577                  * Find the next type.
578                  */
579                 while (current_type <= td->rows && i >= (last_m = mono_metadata_decode_row_col (td, current_type - 1, MONO_TYPEDEF_METHOD_LIST))) {
580                         current_type++;
581                 }
582                 if (i == first_m) {
583                         fprintf (output, "########## %s.%s\n",
584                                 mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAMESPACE)),
585                                 mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAME)));
586                         first_m = last_m;
587                         type_container = mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), NULL);
588                         if (type_container)
589                                 mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), type_container);
590                 }
591
592                 method_container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | i, type_container);
593                 if (method_container)
594                         mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | i, method_container);
595                 mono_metadata_decode_row (t, i - 1, cols, MONO_METHOD_SIZE);
596                 sigblob = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
597                 mono_metadata_decode_blob_size (sigblob, &sigblob);
598                 method = mono_metadata_parse_method_signature_full (m, method_container ? method_container : type_container, i, sigblob, &sigblob);
599                 sig = dis_stringify_method_signature (m, method, i, (MonoGenericContext *) (method_container ? method_container : type_container), FALSE);
600                 fprintf (output, "%d: %s (param: %d)\n", i, sig, cols [MONO_METHOD_PARAMLIST]);
601                 g_free (sig);
602                 mono_metadata_free_method_signature (method);
603         }
604         
605 }
606
607 void
608 dump_table_implmap (MonoImage *m)
609 {
610         MonoTableInfo *t = &m->tables [MONO_TABLE_IMPLMAP];
611         MonoTableInfo *td = &m->tables [MONO_TABLE_MODULEREF];
612         int i;
613
614         fprintf (output, "ImplMap Table (1..%d)\n", t->rows);
615
616         for (i = 1; i <= t->rows; i++){
617                 guint32 cols [MONO_IMPLMAP_SIZE];
618                 char *method;
619
620                 mono_metadata_decode_row (t, i - 1, cols, MONO_IMPLMAP_SIZE);
621
622                 method = get_method (m, MONO_TOKEN_METHOD_DEF | (cols [MONO_IMPLMAP_MEMBER] >> MONO_MEMBERFORWD_BITS), NULL);
623                 
624                 fprintf (output, "%d: %s %d (%s %s)\n", i, 
625                                  method,
626                                  cols [MONO_IMPLMAP_FLAGS], 
627                                  mono_metadata_string_heap (m, cols [MONO_IMPLMAP_NAME]),
628                                  mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME)));
629         }
630 }
631
632 void
633 dump_table_methodimpl (MonoImage *m)
634 {
635         MonoTableInfo *t = &m->tables [MONO_TABLE_METHODIMPL];
636         /*MonoTableInfo *td = &m->tables [MONO_TABLE_TYPEDEF];*/
637         int i;
638
639         fprintf (output, "MethodImpl Table (1..%d)\n", t->rows);
640
641         for (i = 1; i <= t->rows; i++){
642                 guint32 cols [MONO_METHODIMPL_SIZE];
643                 char *class, *impl, *decl;
644
645                 mono_metadata_decode_row (t, i - 1, cols, MONO_METHODIMPL_SIZE);
646                 class = get_typedef (m, cols [MONO_METHODIMPL_CLASS]);
647                 impl = get_method (m, method_dor_to_token (cols [MONO_METHODIMPL_BODY]), NULL);
648                 decl = get_method (m, method_dor_to_token (cols [MONO_METHODIMPL_DECLARATION]), NULL);
649                 fprintf (output, "%d: %s\n\tdecl: %s\n\timpl: %s\n", i, class, decl, impl);
650                 g_free (class);
651                 g_free (impl);
652                 g_free (decl);
653         }
654         
655 }
656
657 static dis_map_t semantics_map [] = {
658                 {1, "setter"},
659                 {2, "getter"},
660                 {4, "other"},
661                 {8, "add-on"},
662                 {0x10, "remove-on"},
663                 {0x20, "fire"},
664                 {0, NULL},
665 };
666
667 void
668 dump_table_methodsem (MonoImage *m)
669 {
670         MonoTableInfo *t = &m->tables [MONO_TABLE_METHODSEMANTICS];
671         int i, is_property, index;
672         const char *semantics;
673         
674         fprintf (output, "Method Semantics Table (1..%d)\n", t->rows);
675         for (i = 1; i <= t->rows; i++){
676                 guint32 cols [MONO_METHOD_SEMA_SIZE];
677                 
678                 mono_metadata_decode_row (t, i - 1, cols, MONO_METHOD_SEMA_SIZE);
679                 semantics = flags (cols [MONO_METHOD_SEMA_SEMANTICS], semantics_map);
680                 is_property = cols [MONO_METHOD_SEMA_ASSOCIATION] & MONO_HAS_SEMANTICS_MASK;
681                 index = cols [MONO_METHOD_SEMA_ASSOCIATION] >> MONO_HAS_SEMANTICS_BITS;
682                 fprintf (output, "%d: [%d] %s method: %d %s %d\n", i, cols [MONO_METHOD_SEMA_ASSOCIATION], semantics,
683                                                 cols [MONO_METHOD_SEMA_METHOD] - 1, 
684                                                 is_property? "property" : "event",
685                                                 index);
686         }
687 }
688
689 void 
690 dump_table_interfaceimpl (MonoImage *m)
691 {
692         MonoTableInfo *t = &m->tables [MONO_TABLE_INTERFACEIMPL];
693         int i;
694
695         fprintf (output, "Interface Implementation Table (1..%d)\n", t->rows);
696         for (i = 1; i <= t->rows; i++) {
697                 guint32 cols [MONO_INTERFACEIMPL_SIZE];
698                 
699                 mono_metadata_decode_row (t, i - 1, cols, MONO_INTERFACEIMPL_SIZE);
700                 fprintf (output, "%d: %s implements %s\n", i,
701                          get_typedef (m, cols [MONO_INTERFACEIMPL_CLASS]),
702                          get_typedef_or_ref (m, cols [MONO_INTERFACEIMPL_INTERFACE], NULL));
703         }
704 }
705
706 static char*
707 has_cattr_get_table (MonoImage *m, guint32 val)
708 {
709         guint32 t = val & MONO_CUSTOM_ATTR_MASK;
710         guint32 index = val >> MONO_CUSTOM_ATTR_BITS;
711         const char *table;
712
713         switch (t) {
714         case MONO_CUSTOM_ATTR_METHODDEF:
715                 table = "MethodDef";
716                 break;
717         case MONO_CUSTOM_ATTR_FIELDDEF:
718                 table = "FieldDef";
719                 break;
720         case MONO_CUSTOM_ATTR_TYPEREF:
721                 table = "TypeRef";
722                 break;
723         case MONO_CUSTOM_ATTR_TYPEDEF:
724                 table = "TypeDef";
725                 break;
726         case MONO_CUSTOM_ATTR_PARAMDEF:
727                 table = "Param";
728                 break;
729         case MONO_CUSTOM_ATTR_INTERFACE:
730                 table = "InterfaceImpl";
731                 break;
732         case MONO_CUSTOM_ATTR_MEMBERREF:
733                 table = "MemberRef";
734                 break;
735         case MONO_CUSTOM_ATTR_MODULE:
736                 table = "Module";
737                 break;
738         case MONO_CUSTOM_ATTR_PERMISSION:
739                 table = "DeclSecurity?";
740                 break;
741         case MONO_CUSTOM_ATTR_PROPERTY:
742                 table = "Property";
743                 break;
744         case MONO_CUSTOM_ATTR_EVENT:
745                 table = "Event";
746                 break;
747         case MONO_CUSTOM_ATTR_SIGNATURE:
748                 table = "StandAloneSignature";
749                 break;
750         case MONO_CUSTOM_ATTR_MODULEREF:
751                 table = "ModuleRef";
752                 break;
753         case MONO_CUSTOM_ATTR_TYPESPEC:
754                 table = "TypeSpec";
755                 break;
756         case MONO_CUSTOM_ATTR_ASSEMBLY:
757                 table = "Assembly";
758                 break;
759         case MONO_CUSTOM_ATTR_ASSEMBLYREF:
760                 table = "AssemblyRef";
761                 break;
762         case MONO_CUSTOM_ATTR_FILE:
763                 table = "File";
764                 break;
765         case MONO_CUSTOM_ATTR_EXP_TYPE:
766                 table = "ExportedType";
767                 break;
768         case MONO_CUSTOM_ATTR_MANIFEST:
769                 table = "Manifest";
770                 break;
771         case MONO_CUSTOM_ATTR_GENERICPAR:
772                 table = "GenericParam";
773                 break;
774         default:
775                 table = "Unknown";
776                 break;
777         }
778         /*
779          * FIXME: we should decode the index into something more uman-friendly.
780          */
781         return g_strdup_printf ("%s: %d", table, index);
782 }
783
784 static char*
785 custom_attr_params (MonoImage *m, MonoMethodSignature* sig, const char* value)
786 {
787         int len, i, slen, type;
788         GString *res;
789         char *s;
790         const char *p = value;
791
792         len = mono_metadata_decode_value (p, &p);
793         if (len < 2 || read16 (p) != 0x0001) /* Prolog */
794                 return g_strdup ("");
795
796         /* skip prolog */
797         p += 2;
798         res = g_string_new ("");
799         for (i = 0; i < sig->param_count; ++i) {
800                 if (i != 0)
801                         g_string_append (res, ", ");
802                 type = sig->params [i]->type;
803 handle_enum:
804                 switch (type) {
805                 case MONO_TYPE_U1:
806                         g_string_sprintfa (res, "%d", (unsigned int)*p);
807                         ++p;
808                         break;
809                 case MONO_TYPE_I1:
810                         g_string_sprintfa (res, "%d", *p);
811                         ++p;
812                         break;
813                 case MONO_TYPE_BOOLEAN:
814                         g_string_sprintfa (res, "%s", *p?"true":"false");
815                         ++p;
816                         break;
817                 case MONO_TYPE_CHAR:
818                         g_string_sprintfa (res, "'%c'", read16 (p));
819                         p += 2;
820                         break;
821                 case MONO_TYPE_U2:
822                         g_string_sprintfa (res, "%d", read16 (p));
823                         p += 2;
824                         break;
825                 case MONO_TYPE_I2:
826                         g_string_sprintfa (res, "%d", (gint16)read16 (p));
827                         p += 2;
828                         break;
829                 case MONO_TYPE_U4:
830                         g_string_sprintfa (res, "%d", read32 (p));
831                         p += 4;
832                         break;
833                 case MONO_TYPE_I4:
834                         g_string_sprintfa (res, "%d", (gint32)read32 (p));
835                         p += 4;
836                         break;
837                 case MONO_TYPE_U8:
838                         g_string_sprintfa (res, "%lld", (long long)read64 (p));
839                         p += 8;
840                         break;
841                 case MONO_TYPE_I8:
842                         g_string_sprintfa (res, "%lld", (long long)read64 (p));
843                         p += 8;
844                         break;
845                 case MONO_TYPE_R4: {
846                         float val;
847                         int inf;
848                         readr4 (p, &val);
849                         inf = isinf (val);
850                         if (inf == -1) 
851                                 g_string_sprintfa (res, "(00 00 80 ff)"); /* negative infinity */
852                         else if (inf == 1)
853                                 g_string_sprintfa (res, "(00 00 80 7f)"); /* positive infinity */
854                         else if (isnan (val))
855                                 g_string_sprintfa (res, "(00 00 c0 ff)"); /* NaN */
856                         else
857                                 g_string_sprintfa (res, "%g", val);
858                         p += 4;
859                         break;
860                 }
861                 case MONO_TYPE_R8: {
862                         double val;
863                         int inf;
864                         
865                         readr8 (p, &val);
866                         inf = isinf (val);
867                         if (inf == -1) 
868                                 g_string_sprintfa (res, "(00 00 00 00 00 00 f0 ff)"); /* negative infinity */
869                         else if (inf == 1)
870                                 g_string_sprintfa (res, "(00 00 00 00 00 00 f0 7f)"); /* positive infinity */
871                         else if (isnan (val))
872                                 g_string_sprintfa (res, "(00 00 00 00 00 00 f8 ff)"); /* NaN */
873                         else
874                                 g_string_sprintfa (res, "%g", val);
875                         p += 8;
876                         break;
877                 }
878                 case MONO_TYPE_VALUETYPE:
879                         if (mono_class_is_enum (sig->params [i]->data.klass)) {
880                                 type = mono_class_enum_basetype (sig->params [i]->data.klass)->type;
881                                 goto handle_enum;
882                         } else {
883                                 g_warning ("generic valutype not handled in custom attr value decoding");
884                         }
885                         break;
886                 case MONO_TYPE_CLASS: /* It must be a Type: check? */
887                 case MONO_TYPE_STRING:
888                         if (*p == (char)0xff) {
889                                 g_string_append (res, "null");
890                                 p++;
891                                 break;
892                         }
893                         slen = mono_metadata_decode_value (p, &p);
894                         g_string_append_c (res, '"');
895                         g_string_append (res, p);
896                         g_string_append_c (res, '"');
897                         p += slen;
898                         break;
899                 default:
900                         g_warning ("Type %02x not handled in custom attr value decoding", sig->params [i]->type);
901                         break;
902                 }
903         }
904         slen = read16 (p);
905         if (slen) {
906                 g_string_sprintfa (res, " %d named args: (", slen);
907                 slen = len - (p - value) + 1;
908                 for (i = 0; i < slen; ++i) {
909                         g_string_sprintfa (res, " %02X", (p [i] & 0xff));
910                 }
911                 g_string_append_c (res, ')');
912         }
913         s = res->str;
914         g_string_free (res, FALSE);
915         return s;
916 }
917
918 void
919 dump_table_customattr (MonoImage *m)
920 {
921         MonoTableInfo *t = &m->tables [MONO_TABLE_CUSTOMATTRIBUTE];
922         int i;
923
924         fprintf (output, "Custom Attributes Table (1..%d)\n", t->rows);
925         for (i = 1; i <= t->rows; i++) {
926                 guint32 cols [MONO_CUSTOM_ATTR_SIZE];
927                 guint32 mtoken;
928                 char * desc;
929                 char *method;
930                 char *params;
931                 MonoMethod *meth;
932                 
933                 mono_metadata_decode_row (t, i - 1, cols, MONO_CUSTOM_ATTR_SIZE);
934                 desc = has_cattr_get_table (m, cols [MONO_CUSTOM_ATTR_PARENT]);
935                 mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
936                 switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
937                 case MONO_CUSTOM_ATTR_TYPE_METHODDEF:
938                         mtoken |= MONO_TOKEN_METHOD_DEF;
939                         break;
940                 case MONO_CUSTOM_ATTR_TYPE_MEMBERREF:
941                         mtoken |= MONO_TOKEN_MEMBER_REF;
942                         break;
943                 default:
944                         g_warning ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
945                         break;
946                 }
947                 method = get_method (m, mtoken, NULL);
948                 meth = mono_get_method (m, mtoken, NULL);
949                 params = custom_attr_params (m, mono_method_signature (meth), mono_metadata_blob_heap (m, cols [MONO_CUSTOM_ATTR_VALUE]));
950                 fprintf (output, "%d: %s: %s [%s]\n", i, desc, method, params);
951                 g_free (desc);
952                 g_free (method);
953                 g_free (params);
954         }
955 }
956
957 void
958 dump_table_nestedclass (MonoImage *m)
959 {
960         MonoTableInfo *t = &m->tables [MONO_TABLE_NESTEDCLASS];
961         guint32 cols [MONO_NESTED_CLASS_SIZE];
962         int i;
963         char *nested, *nesting;
964         fprintf (output, "NestedClass Table (1..%d)\n", t->rows);
965
966         for (i = 1; i <= t->rows; i++){
967                 mono_metadata_decode_row (t, i - 1, cols, MONO_NESTED_CLASS_SIZE);
968                 nested = get_typedef (m, cols [MONO_NESTED_CLASS_NESTED]);
969                 nesting = get_typedef (m, cols [MONO_NESTED_CLASS_ENCLOSING]);
970                 fprintf (output, "%d: %d %d: %s in %s\n", i,
971                                 cols [MONO_NESTED_CLASS_NESTED], 
972                                 cols [MONO_NESTED_CLASS_ENCLOSING], nested, nesting);
973                 g_free (nested);
974                 g_free (nesting);
975         }
976         
977 }
978
979 void
980 dump_table_exported (MonoImage *m)
981 {
982         MonoTableInfo *t = &m->tables [MONO_TABLE_EXPORTEDTYPE];
983         guint32 cols [MONO_EXP_TYPE_SIZE];
984         int i;
985         const char *name, *nspace;
986         char *impl;
987         guint32 index;
988         fprintf (output, "ExportedType Table (1..%d)\n", t->rows);
989
990         for (i = 1; i <= t->rows; i++) {
991                 mono_metadata_decode_row (t, i - 1, cols, MONO_EXP_TYPE_SIZE);
992                 name = mono_metadata_string_heap (m, cols [MONO_EXP_TYPE_NAME]);
993                 nspace = mono_metadata_string_heap (m, cols [MONO_EXP_TYPE_NAMESPACE]);
994                 impl = get_manifest_implementation (m, cols [MONO_EXP_TYPE_IMPLEMENTATION]);
995                 index = cols [MONO_EXP_TYPE_TYPEDEF];
996                 fprintf (output, "%d: %s%s%s is in %s, token %x\n", i, nspace, *nspace ? "." : "", name, impl, index);
997                 g_free (impl);
998         }
999         
1000 }
1001
1002 static void
1003 dump_blob (MonoImage *m, const char* blob)
1004 {
1005         int j, bsize;
1006
1007         bsize = mono_metadata_decode_blob_size (blob, &blob);
1008
1009         for (j = 0; j < bsize; j++) {
1010                 fprintf (output, "%02x ", blob [j] & 0xff);
1011         }
1012 }
1013
1014 void
1015 dump_table_field_marshal (MonoImage *m)
1016 {
1017         MonoTableInfo *t = &m->tables [MONO_TABLE_FIELDMARSHAL];
1018         guint32 cols [MONO_FIELD_MARSHAL_SIZE];
1019         int i, is_field, idx;
1020         const char *blob;
1021         char *native;
1022         
1023         fprintf (output, "FieldMarshal Table (1..%d)\n", t->rows);
1024
1025         for (i = 1; i <= t->rows; i++) {
1026                 mono_metadata_decode_row (t, i - 1, cols, MONO_FIELD_MARSHAL_SIZE);
1027                 blob = mono_metadata_blob_heap (m, cols [MONO_FIELD_MARSHAL_NATIVE_TYPE]);
1028                 native = get_marshal_info (m, blob);
1029                 is_field = (cols [MONO_FIELD_MARSHAL_PARENT] & MONO_HAS_FIELD_MARSHAL_MASK) == MONO_HAS_FIELD_MARSHAL_FIELDSREF;
1030                 idx = cols [MONO_FIELD_MARSHAL_PARENT] >> MONO_HAS_FIELD_MARSHAL_BITS;
1031                 fprintf (output, "%d: (0x%04x) %s %d: %s\n", i, cols [MONO_FIELD_MARSHAL_PARENT], is_field? "Field" : "Param", idx, native);
1032                 fprintf (output, "\tblob encoding: ");
1033                 dump_blob (m, blob);
1034                 fprintf (output, "\n");
1035                 g_free (native);
1036         }
1037         
1038 }
1039
1040 static const char*
1041 get_security_action (int val) {
1042         static char buf [32];
1043
1044         switch (val) {
1045         case SECURITY_ACTION_DEMAND:
1046                 return "Demand";
1047         case SECURITY_ACTION_ASSERT:
1048                 return "Assert";
1049         case SECURITY_ACTION_DENY:
1050                 return "Deny";
1051         case SECURITY_ACTION_PERMITONLY:
1052                 return "PermitOnly";
1053         case SECURITY_ACTION_LINKDEMAND:
1054                 return "LinkDemand";
1055         case SECURITY_ACTION_INHERITDEMAND:
1056                 return "InheritanceDemand";
1057         case SECURITY_ACTION_REQMIN:
1058                 return "RequestMinimum";
1059         case SECURITY_ACTION_REQOPT:
1060                 return "RequestOptional";
1061         case SECURITY_ACTION_REQREFUSE:
1062                 return "RequestRefuse";
1063         /* Special actions (for non CAS permissions) */
1064         case SECURITY_ACTION_NONCASDEMAND:
1065                 return "NonCasDemand";
1066         case SECURITY_ACTION_NONCASLINKDEMAND:
1067                 return "NonCasLinkDemand";
1068         case SECURITY_ACTION_NONCASINHERITANCE:
1069                 return "NonCasInheritance";
1070         /* Fx 2.0 actions (for both CAS and non-CAS permissions) */
1071         case SECURITY_ACTION_LINKDEMANDCHOICE:
1072                 return "LinkDemandChoice";
1073         case SECURITY_ACTION_INHERITDEMANDCHOICE:
1074                 return "InheritanceDemandChoice";
1075         case SECURITY_ACTION_DEMANDCHOICE:
1076                 return "DemandChoice";
1077         default:
1078                 g_snprintf (buf, sizeof (buf), "0x%04X", val);
1079                 return buf;
1080         }
1081 }
1082
1083 void 
1084 dump_table_declsec (MonoImage *m)
1085 {
1086         MonoTableInfo *t = &m->tables [MONO_TABLE_DECLSECURITY];
1087         guint32 cols [MONO_DECL_SECURITY_SIZE];
1088         int i, len;
1089         guint32 idx;
1090         const char *blob, *action;
1091         const char* parent[] = {
1092                 "TypeDef", "MethodDef", "Assembly", ""
1093         };
1094         
1095         fprintf (output, "DeclSecurity Table (1..%d)\n", t->rows);
1096
1097         for (i = 1; i <= t->rows; i++) {
1098                 mono_metadata_decode_row (t, i - 1, cols, MONO_DECL_SECURITY_SIZE);
1099                 blob = mono_metadata_blob_heap (m, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
1100                 len = mono_metadata_decode_blob_size (blob, &blob);
1101                 action = get_security_action (cols [MONO_DECL_SECURITY_ACTION]);
1102                 idx = cols [MONO_DECL_SECURITY_PARENT];
1103                 fprintf (output, "%d: %s on %s %d%s", i, action, parent [idx & MONO_HAS_DECL_SECURITY_MASK], idx >> MONO_HAS_DECL_SECURITY_BITS, len? ":\n\t":"\n");
1104                 if (!len)
1105                         continue;
1106                 if (blob [0] == MONO_DECLSEC_FORMAT_20) {
1107                         /* 2.0 declarative security format */
1108                         char *declsec = dump_declsec_entry20 (m, blob, "\t");
1109                         fprintf (output, "%s", declsec);
1110                         g_free (declsec);
1111                 } else {
1112                         /* 1.0 declarative security format - Unicode XML */
1113                         for (idx = 0; idx < len; ++idx)
1114                                 fprintf (output, "%c", blob [idx]);
1115                 }
1116                 fprintf (output, "\n");
1117         }
1118 }
1119
1120 void 
1121 dump_table_genericpar (MonoImage *m)
1122 {
1123         MonoTableInfo *t = &m->tables [MONO_TABLE_GENERICPARAM];
1124         guint32 cols [MONO_GENERICPARAM_SIZE];
1125         int i;
1126
1127         fprintf (output, "GenericParameters (1..%d)\n", t->rows);
1128         
1129         for (i = 1; i <= t->rows; i++) {
1130                 char *sig;
1131                 mono_metadata_decode_row (t, i - 1, cols, MONO_GENERICPARAM_SIZE);
1132
1133                 // sig = get_type_or_methdef (m, cols [MONO_GENERICPARAM_OWNER]);
1134                 sig = g_strdup_printf ("%x", cols [MONO_GENERICPARAM_OWNER]);
1135                 fprintf (output, "%d: %d, flags=%d, owner=%s %s\n", i,
1136                          cols [MONO_GENERICPARAM_NUMBER],
1137                          cols [MONO_GENERICPARAM_FLAGS], sig,
1138                          mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
1139                 g_free (sig);
1140         }
1141 }
1142
1143 void
1144 dump_table_methodspec (MonoImage *m)
1145 {
1146         MonoTableInfo *t = &m->tables [MONO_TABLE_METHODSPEC];
1147         guint32 cols [MONO_METHODSPEC_SIZE];
1148         int i;
1149         
1150         fprintf (output, "MethodSpec (1..%d)\n", t->rows);
1151
1152         for (i = 1; i <= t->rows; i++) {
1153                 char *sig;
1154                 char *method;
1155                 guint32 token;
1156                 
1157                 mono_metadata_decode_row (t, i - 1, cols, MONO_METHODSPEC_SIZE);
1158
1159                 /* build a methodspec token to get the method */
1160                 token = MONO_TOKEN_METHOD_SPEC | i;
1161                 method = get_method (m, token, NULL);
1162                 
1163                 sig = get_method_type_param (m, cols [MONO_METHODSPEC_SIGNATURE], NULL);
1164                 fprintf (output, "%d: %s, %s\n", i, method, sig);
1165                 g_free (sig);
1166                 g_free (method);
1167         }
1168 }
1169
1170 void
1171 dump_table_parconstraint (MonoImage *m)
1172 {
1173         MonoTableInfo *t = &m->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
1174         guint32 cols [MONO_GENPARCONSTRAINT_SIZE];
1175         int i;
1176         
1177         fprintf (output, "Generic Param Constraint (1..%d)\n", t->rows);
1178
1179         for (i = 1; i <= t->rows; i++) {
1180                 char *sig;
1181                 mono_metadata_decode_row (t, i - 1, cols, MONO_GENPARCONSTRAINT_SIZE);
1182
1183                 // sig = get_typedef_or_ref (m, cols [MONO_GENPARCONSTRAINT_CONSTRAINT], NULL);
1184                 sig = g_strdup_printf ("%x", cols [MONO_GENPARCONSTRAINT_CONSTRAINT]);
1185                 fprintf (output, "%d: gen-par=%d, Constraint=%s\n", i,
1186                          cols [MONO_GENPARCONSTRAINT_GENERICPAR], sig);
1187                 g_free (sig);
1188         }
1189 }
1190
1191 void
1192 dump_stream_blob (MonoImage *m)
1193 {
1194         int i;
1195
1196         fprintf (output, "Blob heap contents\n");
1197
1198         for (i = 0; i < m->heap_blob.size; i++) {
1199                 if (i > 0) {
1200                         if ((i % 16) == 0)
1201                                 fprintf (output, "\n");
1202                         else if ((i % 8) == 0)
1203                                 fprintf (output, "- ");
1204                 }
1205                 fprintf (output, "%02x ", m->heap_blob.data [i] & 0xff);
1206         }
1207
1208         fprintf (output, "\n");
1209 }
1210
1211 void
1212 dump_table_standalonesig (MonoImage *m)
1213 {
1214         MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
1215         guint32 cols [MONO_STAND_ALONE_SIGNATURE_SIZE];
1216         int i;
1217         
1218         fprintf (output, "Stand alone signature (1..%d)\n", t->rows);
1219
1220         for (i = 1; i <= t->rows; i++) {
1221                 const char *locals_ptr;
1222                 int j, bsize;
1223
1224                 mono_metadata_decode_row (t, i - 1, cols, MONO_STAND_ALONE_SIGNATURE_SIZE);
1225
1226                 locals_ptr = mono_metadata_blob_heap (m, cols [MONO_STAND_ALONE_SIGNATURE]);
1227                 bsize = mono_metadata_decode_blob_size (locals_ptr, &locals_ptr);
1228
1229                 fprintf (output, "%d: blob[0x%x] = ", i, cols [MONO_STAND_ALONE_SIGNATURE]);
1230
1231                 for (j = 0; j < bsize; j++) {
1232                         fprintf (output, "%02x ", locals_ptr [j] & 0xff);
1233                 }
1234                 fprintf (output, "\n");
1235         }
1236 }