2004-08-21 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / dis / get.c
1 /*
2  * get.c: Functions to get stringified values from the metadata tables.
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 <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <glib.h>
15 #include "meta.h"
16 #include "util.h"
17 #include "get.h"
18 #include <mono/metadata/class.h>
19 #include <mono/metadata/marshal.h>
20
21 extern gboolean substitute_with_mscorlib_p;
22
23 static char *
24 get_memberref_parent (MonoImage *m, guint32 mrp_token);
25
26 GHashTable *key_table = NULL;
27 gboolean show_method_tokens = FALSE;
28 gboolean show_tokens = FALSE;
29
30 char *
31 get_typedef (MonoImage *m, int idx)
32 {
33         guint32 cols [MONO_TYPEDEF_SIZE];
34         const char *ns;
35         char *tstring, *result;
36         guint32 token;
37         
38         mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], idx - 1, cols, MONO_TYPEDEF_SIZE);
39
40         ns = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]);
41
42         /* Check if this is a nested type */
43         token = MONO_TOKEN_TYPE_DEF | (idx);
44         token = mono_metadata_nested_in_typedef (m, token);
45         tstring = show_tokens ? g_strdup_printf ("/*%08x*/", token) : NULL;
46         if (token) {
47                 char *outer;
48                 
49                 outer = get_typedef (m, mono_metadata_token_index (token));
50                 result = g_strdup_printf (
51                         "%s%s%s/%s%s", ns, *ns?".":"", outer,
52                         mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]),
53                         tstring ? tstring : "");
54                 g_free (outer);
55                 g_free (tstring);
56                 return result;
57         }
58         
59         
60         result = g_strdup_printf (
61                 "%s%s%s%s", ns, *ns?".":"",
62                 mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]),
63                 tstring ? tstring : "");
64         g_free (tstring);
65
66         return result;
67 }
68
69 char *
70 get_module (MonoImage *m, int idx)
71 {
72         guint32 cols [MONO_MODULE_SIZE];
73         
74         /*
75          * There MUST BE only one module in the Module table
76          */
77         g_assert (idx == 1);
78             
79         mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULE], idx - 1, cols, MONO_MODULE_SIZE);
80
81         return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]));
82 }
83
84 char *
85 get_moduleref (MonoImage *m, int idx)
86 {
87         guint32 cols [MONO_MODULEREF_SIZE];
88         
89         mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULEREF], idx - 1, cols, MONO_MODULEREF_SIZE);
90
91         return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]));
92 }
93
94 char *
95 get_assemblyref (MonoImage *m, int idx)
96 {
97         guint32 cols [MONO_ASSEMBLYREF_SIZE];
98         
99         mono_metadata_decode_row (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, cols, MONO_ASSEMBLYREF_SIZE);
100
101         return g_strdup (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
102 }
103
104 /*
105  *
106  * Returns a string representing the ArrayShape (22.2.16).
107  */
108 static const char *
109 get_array_shape (MonoImage *m, const char *ptr, char **result)
110 {
111         GString *res = g_string_new ("[");
112         guint32 rank, num_sizes, num_lo_bounds;
113         guint32 *sizes = NULL, *lo_bounds = NULL;
114         int i, r;
115         char buffer [80];
116         
117         rank = mono_metadata_decode_value (ptr, &ptr);
118         num_sizes = mono_metadata_decode_value (ptr, &ptr);
119
120         if (num_sizes > 0)
121                 sizes = g_new (guint32, num_sizes);
122         
123         for (i = 0; i < num_sizes; i++)
124                 sizes [i] = mono_metadata_decode_value (ptr, &ptr);
125
126         num_lo_bounds = mono_metadata_decode_value (ptr, &ptr);
127         if (num_lo_bounds > 0)
128                 lo_bounds = g_new (guint32, num_lo_bounds);
129         
130         for (i = 0; i < num_lo_bounds; i++)
131                 lo_bounds [i] = mono_metadata_decode_value (ptr, &ptr);
132
133         for (r = 0; r < rank; r++){
134                 if (r < num_sizes){
135                         if (r < num_lo_bounds){
136                                 sprintf (buffer, "%d..%d", lo_bounds [r], lo_bounds [r] + sizes [r] - 1);
137                         } else {
138                                 sprintf (buffer, "0..%d", sizes [r] - 1);
139                         }
140                 } else
141                         buffer [0] = 0;
142                 
143                 g_string_append (res, buffer);
144                 if ((r + 1) != rank)
145                         g_string_append (res, ", ");
146         }
147         g_string_append (res, "]");
148         
149         if (sizes)
150                 g_free (sizes);
151
152         if (lo_bounds)
153                 g_free (lo_bounds);
154
155         *result = res->str;
156         g_string_free (res, FALSE);
157
158         return ptr;
159 }
160
161 /**
162  * get_typespec:
163  * @m: metadata context
164  * @blob_idx: index into the blob heap
165  *
166  * Returns the stringified representation of a TypeSpec signature (22.2.17)
167  */
168 char *
169 get_typespec (MonoImage *m, guint32 idx)
170 {
171         guint32 cols [MONO_TYPESPEC_SIZE];
172         const char *ptr;
173         char *s, *result;
174         GString *res = g_string_new ("");
175         int len;
176
177         MonoType *type;
178
179         type = mono_type_create_from_typespec (m, idx);
180                 
181         mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPESPEC], idx-1, cols, MONO_TYPESPEC_SIZE);
182         ptr = mono_metadata_blob_heap (m, cols [MONO_TYPESPEC_SIGNATURE]);
183         len = mono_metadata_decode_value (ptr, &ptr);
184         
185         switch (*ptr++){
186         case MONO_TYPE_PTR:
187                 ptr = get_custom_mod (m, ptr, &s);
188                 if (s){
189                         g_string_append (res, s);
190                         g_string_append_c (res, ' ');
191                         g_free (s);
192                 }
193                 
194                 if (*ptr == MONO_TYPE_VOID)
195                         g_string_append (res, "void");
196                 else {
197                         ptr = get_type (m, ptr, &s);
198                         if (s)
199                                 g_string_append (res, s);
200                 }
201                 g_string_append (res, "*");
202                 break;
203                 
204         case MONO_TYPE_FNPTR:
205                 s = dis_stringify_function_ptr (m, type->data.method);
206                 g_string_append (res, "method ");
207                 g_string_append (res, s);
208                 g_free (s);
209                 break;
210                         
211         case MONO_TYPE_ARRAY:
212                 ptr = get_type (m, ptr, &s);
213                 g_string_append (res, s);
214                 g_free (s);
215                 g_string_append_c (res, ' ');
216                 ptr = get_array_shape (m, ptr, &s);
217                 g_string_append (res, s);
218                 g_free (s);
219                 break;
220                 
221         case MONO_TYPE_SZARRAY:
222                 ptr = get_custom_mod (m, ptr, &s);
223                 if (s){
224                         g_string_append (res, s);
225                         g_string_append_c (res, ' ');
226                         g_free (s);
227                 }
228                 ptr = get_type (m, ptr, &s);
229                 g_string_append (res, s);
230                 g_string_append (res, "[]");
231                 g_free (s);
232                 break;
233
234         case MONO_TYPE_VAR:
235         case MONO_TYPE_MVAR:
236                 ptr = get_type (m, ptr-1, &s);
237                 g_string_append (res, s);
238                 g_free (s);
239                 break;
240                 
241         default:
242                 s = dis_stringify_type (m, type);
243                 g_string_append (res, s);
244                 g_free (s);
245                 break;
246         }
247
248         if (show_tokens) {
249                 int token = mono_metadata_make_token (MONO_TABLE_TYPESPEC, idx);
250                 result = g_strdup_printf ("%s/*%08x*/", res->str, token);
251         } else
252                 result = res->str;
253
254         g_string_free (res, FALSE);
255
256         return result;
257 }
258
259 char *
260 get_typeref (MonoImage *m, int idx)
261 {
262         guint32 cols [MONO_TYPEREF_SIZE];
263         const char *s, *t;
264         char *x, *ret;
265         guint32 rs_idx, table;
266         
267         mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEREF], idx - 1, cols, MONO_TYPEREF_SIZE);
268
269         t = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]);
270         s = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]);
271
272         rs_idx = cols [MONO_TYPEREF_SCOPE] >> MONO_RESOLTION_SCOPE_BITS;
273         table = cols [MONO_TYPEREF_SCOPE] & MONO_RESOLTION_SCOPE_MASK;
274         
275         switch (table){
276         case MONO_RESOLTION_SCOPE_MODULE: /* Module */
277                 x = get_module (m, rs_idx);
278                 ret = g_strdup_printf ("[%s] %s%s%s", x, s, *s?".":"", t);
279                 g_free (x);
280                 break;
281
282         case MONO_RESOLTION_SCOPE_MODULEREF: /* ModuleRef */
283                 x = get_moduleref (m, rs_idx);
284                 ret = g_strdup_printf ("[.module %s]%s%s%s", x, s, *s ? "." : "", t);
285                 break;
286                               
287         case MONO_RESOLTION_SCOPE_ASSEMBLYREF: /*
288                  * AssemblyRef (ECMA docs claim it is 3, but it looks to
289                  * me like it is 2 (tokens are prefixed with 0x23)
290                  */
291                 x = get_assemblyref (m, rs_idx);
292                 ret = g_strdup_printf ("[%s]%s%s%s", x, s, *s?".":"", t);
293                 g_free (x);
294                 break;
295                 
296         case MONO_RESOLTION_SCOPE_TYPEREF: /* TypeRef */
297                 x = get_typeref (m, rs_idx);
298                 ret =  g_strdup_printf ("%s/%s", x, t);
299                 g_free (x);
300                 break;
301                 
302         default:
303                 ret = g_strdup_printf ("Unknown table in TypeRef %d", table);
304         }
305
306         if (show_tokens) {
307                 int token = mono_metadata_make_token (MONO_TABLE_TYPEREF, idx);
308                 char *temp = g_strdup_printf ("%s/*%08x*/", ret, token);
309                 g_free (ret);
310                 ret = temp;
311         }
312
313         return ret;
314 }
315
316 /**
317  * get_typedef_or_ref:
318  * @m: metadata context
319  * @dor_token: def or ref encoded index
320  *
321  * Low two bits contain table to lookup from
322  * high bits contain the index into the def or ref table
323  *
324  * Returns: a stringified version of the MethodDef or MethodRef
325  * at (dor_token >> 2) 
326  */
327 char *
328 get_typedef_or_ref (MonoImage *m, guint32 dor_token)
329 {
330         char *temp = NULL, *s = NULL;
331         int table, idx;
332
333         /*
334          * low 2 bits contain encoding
335          */
336         table = dor_token & MONO_TYPEDEFORREF_MASK;
337         idx = dor_token >> MONO_TYPEDEFORREF_BITS;
338         
339         switch (table){
340         case 0: /* TypeDef */
341                 temp = get_typedef (m, idx);
342                 s = g_strdup_printf ("%s", temp);
343                 break;
344                 
345         case 1: /* TypeRef */
346                 temp = get_typeref (m, idx);
347                 s = g_strdup_printf ("%s", temp);
348                 break;
349                 
350         case 2: /* TypeSpec */
351                 s = get_typespec (m, idx);
352                 break;
353
354         default:
355                 g_error ("Unhandled encoding for typedef-or-ref coded index 0x%08x", dor_token);
356
357         }
358         
359         if (temp)
360                 g_free (temp);
361
362         return s;
363 }
364
365 /**
366  * get_type_or_methdef
367  * @m: metadata context
368  * @dor_token: type or method def encoded index
369  *
370  * Low bit contains the table to lookup from
371  * high bits contain the index into the type def or method def table
372  *
373  * Returns: a stringified version of the TypeOrMethodDef token
374  */
375 char *
376 get_type_or_methdef (MonoImage *m, guint32 dor_token)
377 {
378         if (dor_token & MONO_TYPEORMETHOD_METHOD) /* MethodDef */
379                 return get_methoddef (m, dor_token >> MONO_TYPEORMETHOD_BITS);
380         else  /* TypeDef */
381                 return get_typedef (m, dor_token >> MONO_TYPEORMETHOD_BITS);
382 }
383
384 /** 
385  * get_encoded_typedef_or_ref:
386  * @m: metadata context 
387  * @ptr: location to decode from.
388  * @result: pointer to string where resulting decoded string is stored
389  *
390  * result will point to a g_malloc()ed string.
391  *
392  * Returns: the new ptr to continue decoding
393  */
394 const char *
395 get_encoded_typedef_or_ref (MonoImage *m, const char *ptr, char **result)
396 {
397         guint32 token;
398         
399         token = mono_metadata_decode_value (ptr, &ptr);
400
401         *result = get_typedef_or_ref (m, token);
402
403         return ptr;
404 }
405
406 /**
407  * get_custom_mod:
408  *
409  * Decodes a CustomMod (22.2.7)
410  *
411  * Returns: updated pointer location
412  */
413 const char *
414 get_custom_mod (MonoImage *m, const char *ptr, char **return_value)
415 {
416         char *s;
417         const char *reqd;
418         
419         *return_value = NULL;
420         while ((*ptr == MONO_TYPE_CMOD_OPT) ||
421                    (*ptr == MONO_TYPE_CMOD_REQD)) {
422                 reqd = (*ptr == MONO_TYPE_CMOD_REQD) ? "reqd" : "opt";
423                 ptr++;
424                 ptr = get_encoded_typedef_or_ref (m, ptr, &s);
425
426                 if (*return_value == NULL)
427                         *return_value = g_strconcat (reqd, " ", s, NULL);
428                 else
429                         *return_value = g_strconcat (*return_value, " ", reqd, " ", s, NULL);
430                 g_free (s);
431         }
432         return ptr;
433 }
434
435
436 static dis_map_t element_type_map [] = {
437         { MONO_TYPE_END        , "end" },
438         { MONO_TYPE_VOID       , "void" },
439         { MONO_TYPE_BOOLEAN    , "bool" },
440         { MONO_TYPE_CHAR       , "char" }, 
441         { MONO_TYPE_I1         , "int8" },
442         { MONO_TYPE_U1         , "unsigned int8" }, 
443         { MONO_TYPE_I2         , "int16" },
444         { MONO_TYPE_U2         , "unsigned int16" },
445         { MONO_TYPE_I4         , "int32" },
446         { MONO_TYPE_U4         , "unsigned int32" },
447         { MONO_TYPE_I8         , "int64" },
448         { MONO_TYPE_U8         , "unsigned int64" },
449         { MONO_TYPE_R4         , "float32" },
450         { MONO_TYPE_R8         , "float64" },
451         { MONO_TYPE_STRING     , "string" },
452         { MONO_TYPE_TYPEDBYREF , "TypedByRef" },
453         { MONO_TYPE_I          , "native int" },
454         { MONO_TYPE_U          , "native unsigned int" },
455         { MONO_TYPE_OBJECT     , "object" },
456         { 0, NULL }
457 };
458
459 static dis_map_t call_conv_type_map [] = {
460         { MONO_CALL_DEFAULT     , "default" },
461         { MONO_CALL_C           , "c" },
462         { MONO_CALL_STDCALL     , "stdcall" },
463         { MONO_CALL_THISCALL    , "thiscall" },
464         { MONO_CALL_FASTCALL    , "fastcall" },
465         { MONO_CALL_VARARG      , "vararg" },
466         { 0, NULL }
467 };
468
469 char*
470 dis_stringify_token (MonoImage *m, guint32 token)
471 {
472         guint idx = token & 0xffffff;
473         switch (token >> 24) {
474         case MONO_TABLE_TYPEDEF: return get_typedef (m, idx);
475         case MONO_TABLE_TYPEREF: return get_typeref (m, idx);
476         case MONO_TABLE_TYPESPEC: return get_typespec (m, idx);
477         default:
478                  break;
479         }
480         return g_strdup_printf("0x%08x", token);
481 }
482
483 char*
484 dis_stringify_array (MonoImage *m, MonoArrayType *array) 
485 {
486         char *type;
487         GString *s = g_string_new("");
488         int i;
489         
490         type = dis_stringify_type (m, &array->eklass->byval_arg);
491         g_string_append (s, type);
492         g_free (type);
493         g_string_append_c (s, '[');
494         for (i = 0; i < array->rank; ++i) {
495                 if (i)
496                         g_string_append_c (s, ',');
497                 if (i < array->numsizes) {
498                         if (i < array->numlobounds && array->lobounds[i] != 0)
499                                 g_string_sprintfa (s, "%d..%d", array->lobounds[i], array->sizes[i]);
500                         else
501                                 g_string_sprintfa (s, "%d", array->sizes[i]);
502                 }
503         }
504         g_string_append_c (s, ']');
505         type = s->str;
506         g_string_free (s, FALSE);
507         return type;
508 }
509
510 char*
511 dis_stringify_modifiers (MonoImage *m, int n, MonoCustomMod *mod)
512 {
513         GString *s = g_string_new("");
514         char *result;
515         int i;
516         for (i = 0; i < n; ++i) {
517                 char *tok = dis_stringify_token (m, mod[i].token);
518                 if (i > 0)
519                         g_string_sprintfa (s, " ");
520                 g_string_sprintfa (s, "%s (%s)", mod[i].required ? "modreq": "modopt", tok);
521                 g_free (tok);
522         }
523         g_string_append_c (s, ' ');
524         result = s->str;
525         g_string_free (s, FALSE);
526         return result;
527 }
528
529 char*
530 dis_stringify_param (MonoImage *m, MonoType *param) 
531 {
532         char *t;
533         char *result;
534         char *attribs;
535         const char *out = param->attrs & PARAM_ATTRIBUTE_OUT ? "[out]": "";
536         const char *opt = param->attrs & PARAM_ATTRIBUTE_OPTIONAL ? "[opt]": "";
537         attribs = g_strconcat(out, opt, NULL);
538         t = dis_stringify_type (m, param);
539         result = g_strjoin(attribs[0] ? " ":"", attribs, t, NULL);
540         g_free (t);
541         g_free (attribs);
542         return result;
543 }
544
545 /**
546  * get_generic_param
547  * @m: metadata context 
548  * @table_type: The type of table we are getting generics for (0 for typedef, 1 for method)
549  * @row: The row in the table
550  *
551  * Returns: Allocated stringified generic parameters
552  */
553 char*
554 get_generic_param (MonoImage *m, int table_type, guint32 row)
555 {
556         MonoTableInfo *t = &m->tables [MONO_TABLE_GENERICPARAM];
557         GString *result = g_string_new ("");
558         char *retval;
559         guint32 cols [MONO_GENERICPARAM_SIZE];
560         int i, own_tok, table, idx, found_count;
561
562         g_assert (table_type != MONO_TYPEORMETHOD_TYPE || table_type != MONO_TYPEORMETHOD_METHOD);
563         
564         found_count = 0;
565         for (i = 1; i <= t->rows; i++) {
566                 mono_metadata_decode_row (t, i-1, cols, MONO_GENERICPARAM_SIZE);
567                 own_tok = cols [MONO_GENERICPARAM_OWNER];
568                 table = own_tok & MONO_TYPEORMETHOD_MASK;
569                 idx = own_tok >> MONO_TYPEORMETHOD_BITS;
570                 
571                 if (table != table_type || idx != row)
572                         continue;
573
574                 if (found_count == 0)
575                         g_string_append_printf (result, "<%s",
576                                         mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
577                 else
578                         g_string_append_printf (result, ", %s",
579                                         mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
580                 found_count++;
581         }
582
583         if (found_count)
584                 g_string_append_c (result, '>');
585         retval = result->str;
586         g_string_free (result, FALSE);
587         return retval;
588 }
589
590 char*
591 dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row, gboolean fully_qualified)
592 {
593         guint32 cols [MONO_METHOD_SIZE];
594         guint32 pcols [MONO_PARAM_SIZE];
595         guint32 param_index = 0;
596         const char *name = "";
597         int free_method = 0;
598         char *retval, *esname;
599         char *type = NULL;
600         char *gen_param = NULL;
601         GString *result = g_string_new ("");
602         int i;
603         
604         g_assert (method || methoddef_row);
605
606         if (methoddef_row) {
607                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row -1, cols, MONO_METHOD_SIZE);
608                 if (fully_qualified)
609                         type = get_typedef (m, mono_metadata_typedef_from_method (m, methoddef_row));
610                 name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
611                 param_index = cols [MONO_METHOD_PARAMLIST];
612                 if (!method) {
613                         const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
614                         mono_metadata_decode_blob_size (sig, &sig);
615                         method = mono_metadata_parse_method_signature (m, methoddef_row, sig, &sig);
616                         free_method = 1;
617                 }      
618                 gen_param = get_generic_param (m, 1, methoddef_row);
619         }
620         
621         retval = dis_stringify_param (m, method->ret);
622         if (method->hasthis)
623                 g_string_append (result, "instance ");
624         g_string_append (result, map (method->call_convention, call_conv_type_map));
625         g_string_sprintfa (result, " %s ", retval);
626         if (type) {
627                 char *estype = get_escaped_name (type);
628                 g_string_sprintfa (result, "%s::", estype);
629                 g_free (estype);
630         }
631         esname = get_escaped_name (name);
632         g_string_append (result, esname);
633         g_free (esname);
634         if (gen_param) {
635                 g_string_append (result, gen_param);
636                 g_free (gen_param);
637         }
638         g_string_append (result, " (");
639         g_free (retval);
640         for (i = 0; i < method->param_count; ++i) {
641                 if (param_index && param_index <= m->tables [MONO_TABLE_PARAM].rows) {
642                         mono_metadata_decode_row (&m->tables [MONO_TABLE_PARAM], param_index - 1, pcols, MONO_PARAM_SIZE);
643                         name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
644                         method->params [i]->attrs = pcols [MONO_PARAM_FLAGS];
645                         param_index++;
646                 } else {
647                         name = "";
648                 }
649                 if (i)
650                         g_string_append (result, ", ");
651                 retval = dis_stringify_param (m, method->params [i]);
652                 esname = get_escaped_name (name);
653                 g_string_append_printf (result, "%s %s", retval, esname);
654                 g_free (retval);
655                 g_free (esname);
656         }
657         g_string_append (result, ") ");
658
659         if (show_method_tokens && methoddef_row)
660                 g_string_append_printf (result, " /* 0x%X */ ",
661                                 (methoddef_row >> MONO_TYPEORMETHOD_BITS) | MONO_TOKEN_METHOD_DEF);
662
663         if (free_method)
664                 mono_metadata_free_method_signature (method);
665         retval = result->str;
666         g_string_free (result, FALSE);
667
668         return retval;
669 }
670
671 char*
672 dis_stringify_function_ptr (MonoImage *m, MonoMethodSignature *method)
673 {
674         char *retval;
675         GString *result = g_string_new ("");
676         int i;
677         
678         g_assert (method);
679
680         g_string_append (result, map (method->call_convention, call_conv_type_map));
681
682         retval = dis_stringify_param (m, method->ret);
683         g_string_sprintfa (result, " %s ", retval);
684         g_free (retval);
685
686         g_string_append (result, " *(");
687         for (i = 0; i < method->param_count; ++i) {
688                 if (i)
689                         g_string_append (result, ", ");
690                 retval = dis_stringify_param (m, method->params [i]);
691                 g_string_append (result, retval);
692                 g_free (retval);
693         }
694         g_string_append (result, ") ");
695
696         retval = result->str;
697         g_string_free (result, FALSE);
698
699         return retval;
700 }
701
702 static char *
703 dis_stringify_object_with_class (MonoImage *m, MonoClass *c)
704 {
705         /* FIXME: handle MONO_TYPE_OBJECT ... */
706         const char *otype = c->byval_arg.type == MONO_TYPE_VALUETYPE ? "valuetype" : "class" ;
707         char *assemblyref = NULL, *result, *esname, *generic = NULL;
708         if (m != c->image) {
709                 if (c->image->assembly_name) {
710                         /* we cheat */
711                         if (substitute_with_mscorlib_p && !strcmp ("corlib", c->image->assembly_name))
712                                 assemblyref = g_strdup_printf ("[%s]", "mscorlib");
713                         else
714                                 assemblyref = g_strdup_printf ("[%s]", c->image->assembly->aname.name);
715                 } else {
716                         assemblyref = g_strdup_printf ("[.module %s]", c->image->module_name);
717                 }
718         }
719
720         if (c->nested_in) {
721                 result = g_strdup_printf ("%s%s%s/%s", c->nested_in->name_space, 
722                                 *c->nested_in->name_space?".":"", c->nested_in->name,
723                                 c->name);
724         } else {
725                 result = g_strdup_printf ("%s%s%s", c->name_space, 
726                                 *c->name_space?".":"", c->name);
727         }
728         
729         esname = get_escaped_name (result);
730         g_free (result);
731
732         if (c->generic_inst) {
733                 MonoGenericInst *ginst = c->generic_inst;
734                 GString *str = g_string_new ("");
735                 int i;
736
737                 for (i = 0; i < ginst->type_argc; i++){
738                         char *t = dis_stringify_type (m, ginst->type_argv [i]);
739
740                         g_string_append (str, t);
741                         if (i+1 != ginst->type_argc)
742                                 g_string_append (str, ", ");
743                         g_free (t);
744                 }
745                 generic = g_strdup_printf ("<%s>", str->str);
746                 g_string_free (str, TRUE);
747         }
748
749
750         result = g_strdup_printf ("%s %s%s%s", otype, assemblyref?assemblyref:"",
751                                   esname, generic?generic:"");
752         
753         g_free (generic);
754         g_free (assemblyref);
755         g_free (esname);
756         
757         return result;
758 }
759
760 static char *
761 dis_stringify_object (MonoImage *m, MonoType *type)
762 {
763         MonoClass *c = mono_class_from_mono_type (type);
764         return dis_stringify_object_with_class (m, c);
765 }
766
767 char*
768 dis_stringify_type (MonoImage *m, MonoType *type)
769 {
770         const char *pinned = "", *byref = "";
771         char *bare = NULL, *mods = NULL;
772         char *result;
773
774         if (type->num_mods)
775                 mods = dis_stringify_modifiers (m, type->num_mods, type->modifiers);
776
777         switch (type->type){
778         case MONO_TYPE_BOOLEAN:
779         case MONO_TYPE_CHAR:
780         case MONO_TYPE_I1:
781         case MONO_TYPE_U1:
782         case MONO_TYPE_I2:
783         case MONO_TYPE_U2:
784         case MONO_TYPE_I4:
785         case MONO_TYPE_U4:
786         case MONO_TYPE_I8:
787         case MONO_TYPE_U8:
788         case MONO_TYPE_R4:
789         case MONO_TYPE_R8:
790         case MONO_TYPE_I:
791         case MONO_TYPE_U:
792         case MONO_TYPE_STRING:
793         case MONO_TYPE_OBJECT:
794         case MONO_TYPE_TYPEDBYREF:
795                 bare = g_strdup (map (type->type, element_type_map));
796                 break;
797                 
798         case MONO_TYPE_VALUETYPE:
799         case MONO_TYPE_CLASS:
800                 bare = dis_stringify_object (m, type);
801                 break;
802         case MONO_TYPE_FNPTR: {
803                 char *child_type;
804                 child_type = dis_stringify_function_ptr (m, type->data.method);
805                 bare = g_strdup_printf ("method %s", child_type);
806                 g_free (child_type);
807                 break;
808         }
809         case MONO_TYPE_PTR: {
810                 char *child_type;
811                 child_type = dis_stringify_type (m, type->data.type);
812                 
813                 bare = g_strdup_printf ("%s*", child_type);
814                 g_free (child_type);
815                 break;
816         }
817         case MONO_TYPE_SZARRAY: {
818                 char *child_type;
819                 child_type = dis_stringify_type (m, &type->data.klass->byval_arg);
820                 
821                 bare = g_strdup_printf ("%s[]", child_type);
822                 g_free (child_type);
823                 break;
824         }
825         case MONO_TYPE_ARRAY:
826                 bare = dis_stringify_array (m, type->data.array);
827                 break;
828         case MONO_TYPE_VOID:
829                 bare = g_strdup ("void");
830                 break;
831         case MONO_TYPE_MVAR:
832                 bare = g_strdup_printf ("!!%d", type->data.generic_param->num);
833                 break;
834         case MONO_TYPE_VAR:
835                 bare = g_strdup_printf ("!%d", type->data.generic_param->num);
836                 break;
837         case MONO_TYPE_GENERICINST: {
838                 GString *str = g_string_new ("");
839                 int i;
840                 char *generic_type = dis_stringify_type (m, type->data.generic_inst->generic_type);
841
842                 for (i = 0; i < type->data.generic_inst->type_argc; i++){
843                         char *t = dis_stringify_type (m, type->data.generic_inst->type_argv [i]);
844
845                         g_string_append (str, t);
846                         if (i+1 != type->data.generic_inst->type_argc)
847                                 g_string_append (str, ", ");
848                         g_free (t);
849                 }
850                 bare = g_strdup_printf ("%s<%s>", generic_type, str->str);
851                 g_string_free (str, TRUE);
852                 break;
853         }
854                 
855         default:
856                 g_error ("Do not know how to stringify type 0x%x", type->type);
857         }
858         
859         if (type->pinned)
860                 pinned = " pinned";
861
862         if (type->byref)
863                 byref = "&";
864                 
865         result = g_strconcat (mods ? mods : "", bare, byref, pinned, NULL);
866
867         g_free (bare);
868
869         return result;
870 }
871
872 /**
873  * get_type:
874  * @m: metadata context 
875  * @ptr: location to decode from.
876  * @result: pointer to string where resulting decoded string is stored
877  *
878  * This routine returs in @result the stringified type pointed by @ptr.
879  * (22.2.12)
880  *
881  * Returns: the new ptr to continue decoding
882  */
883 const char *
884 get_type (MonoImage *m, const char *ptr, char **result)
885 {
886         const char *start = ptr;
887         guint32 type;
888         MonoType *t;
889
890         if (*ptr == MONO_TYPE_BYREF)
891                 ++ptr;
892
893         type = mono_metadata_decode_value (ptr, &ptr);
894
895         switch (type){
896         case MONO_TYPE_VALUETYPE:
897         case MONO_TYPE_CLASS: {
898                 guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
899                 MonoClass *klass = mono_class_get (m, token);
900                 char *temp = dis_stringify_object_with_class (m, klass);
901
902                 if (show_tokens) {
903                         *result = g_strdup_printf ("%s/*%08x*/", temp, token);
904                         g_free (temp);
905                 } else
906                         *result = temp;
907                 break;
908         }
909
910         case MONO_TYPE_GENERICINST: {
911                 GString *str = g_string_new ("");
912                 int count, i;
913                 char *temp;
914
915                 ptr = get_type (m, ptr, &temp);
916                 g_string_append (str, temp);
917                 g_free (temp);
918
919                 count = mono_metadata_decode_value (ptr, &ptr);
920                 g_string_append (str, "<");
921
922                 for (i = 0; i < count; i++) {
923                         if (i)
924                                 g_string_append (str, ",");
925                         ptr = get_type (m, ptr, &temp);
926                         g_string_append (str, temp);
927                 }
928
929                 g_string_append (str, ">");
930                 *result = str->str;
931                 g_string_free (str, FALSE);
932                 break;
933         }
934
935         default:
936                 t = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, start, &ptr);
937                 *result = dis_stringify_type (m, t);
938                 mono_metadata_free_type (t);
939                 break;
940         }
941
942         return ptr;
943 }
944
945 /**
946  * 
947  * Returns a stringified representation of a FieldSig (22.2.4)
948  */
949 char *
950 get_field_signature (MonoImage *m, guint32 blob_signature)
951 {
952         char *allocated_modifier_string, *allocated_type_string;
953         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
954         const char *base;
955         char *res;
956         int len;
957         
958         len = mono_metadata_decode_value (ptr, &ptr);
959         base = ptr;
960         /* FIELD is 0x06 */
961         g_assert (*ptr == 0x06);
962 /*      hex_dump (ptr, 0, len); */
963         ptr++; len--;
964         
965         ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
966         ptr = get_type (m, ptr, &allocated_type_string);
967
968         res = g_strdup_printf (
969                 "%s %s",
970                 allocated_modifier_string ? allocated_modifier_string : "",
971                 allocated_type_string);
972         
973         if (allocated_modifier_string)
974                 g_free (allocated_modifier_string);
975         if (allocated_type_string)
976                 g_free (allocated_type_string);
977         
978         return res;
979 }
980
981 MonoTypeEnum
982 get_field_literal_type (MonoImage *m, guint32 blob_signature)
983 {
984         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
985         int len;
986         char *allocated_modifier_string;
987         
988         len = mono_metadata_decode_value (ptr, &ptr);
989
990         /* FIELD is 0x06 */
991         g_assert (*ptr == 0x06);
992         ptr++; len--;
993         
994         ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
995         if (allocated_modifier_string)
996                 g_free (allocated_modifier_string);
997
998         return (MonoTypeEnum) *ptr;
999         
1000 }
1001
1002 /**
1003  * decode_literal:
1004  * @m: metadata context
1005  * @token: token to decode
1006  *
1007  * decodes the literal indexed by @token.
1008  */
1009 char *
1010 decode_literal (MonoImage *m, guint32 token)
1011 {
1012         return g_strdup ("LITERAL_VALUE");
1013 }
1014
1015 /**
1016  * get_ret_type:
1017  * @m: metadata context 
1018  * @ptr: location to decode from.
1019  * @result: pointer to string where resulting decoded string is stored
1020  *
1021  * This routine returns in @result the stringified RetType (22.2.11)
1022  *
1023  * Returns: the new ptr to continue decoding.
1024  */
1025 const char *
1026 get_ret_type (MonoImage *m, const char *ptr, char **ret_type)
1027 {
1028         GString *str = g_string_new ("");
1029         char *mod = NULL;
1030         char *allocated_type_string;
1031         
1032         ptr = get_custom_mod (m, ptr, &mod);
1033         if (mod){
1034                 g_string_append (str, mod);
1035                 g_string_append_c (str, ' ');
1036                 g_free (mod);
1037         }
1038
1039         if (*ptr == MONO_TYPE_TYPEDBYREF){
1040                 g_string_append (str, "typedbyref");
1041                 ptr++;
1042         } else if (*ptr == MONO_TYPE_VOID){
1043                  g_string_append (str, "void");
1044                  ptr++;
1045         } else {
1046                 if (*ptr == MONO_TYPE_BYREF){
1047                         g_string_append (str, "[out] ");
1048                         ptr++;
1049                 }
1050
1051                 ptr = get_type (m, ptr, &allocated_type_string);
1052                 g_string_append (str, allocated_type_string);
1053                 g_free (allocated_type_string);
1054         }
1055
1056         *ret_type = str->str;
1057         g_string_free (str, FALSE);
1058
1059         return ptr;
1060 }
1061
1062 /**
1063  * get_param:
1064  * @m: metadata context 
1065  * @ptr: location to decode from.
1066  * @result: pointer to string where resulting decoded string is stored
1067  *
1068  * This routine returns in @result the stringified Param (22.2.10)
1069  *
1070  * Returns: the new ptr to continue decoding.
1071  */
1072 const char *
1073 get_param (MonoImage *m, const char *ptr, char **retval)
1074 {
1075         GString *str = g_string_new ("");
1076         char *allocated_mod_string, *allocated_type_string;
1077         
1078         ptr = get_custom_mod (m, ptr, &allocated_mod_string);
1079         if (allocated_mod_string){
1080                 g_string_append (str, allocated_mod_string);
1081                 g_string_append_c (str, ' ');
1082                 g_free (allocated_mod_string);
1083         }
1084         
1085         if (*ptr == MONO_TYPE_TYPEDBYREF){
1086                 g_string_append (str, " typedbyref ");
1087                 ptr++;
1088         } else {
1089                 gboolean by_ref = 0;
1090                  if (*ptr == MONO_TYPE_BYREF){
1091                         g_string_append (str, "[out] ");
1092                         ptr++;
1093                         by_ref = 1;
1094                 }
1095                 ptr = get_type (m, ptr, &allocated_type_string);
1096                 g_string_append (str, allocated_type_string);
1097                 if (by_ref)
1098                         g_string_append_c (str, '&');
1099                 g_free (allocated_type_string);
1100         }
1101
1102         *retval = str->str;
1103         g_string_free (str, FALSE);
1104         return ptr;
1105 }
1106
1107 /**
1108  * get_escaped_name
1109  *
1110  * Returns: An allocated escaped name. A name needs to be escaped
1111  * because it might be an ilasm keyword.
1112  */
1113 char*
1114 get_escaped_name (const char *name)
1115 {
1116         const char *s;
1117
1118         g_assert (key_table);
1119
1120         if (strlen (name) == 0)
1121                 return g_strdup (name);
1122
1123         for (s = name; *s; s++) {
1124                 if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' || *s == '?' || *s == '.' || *s == 0)
1125                         continue;
1126                 return g_strdup_printf ("'%s'", name);
1127         }
1128         
1129         if (g_hash_table_lookup (key_table, name))
1130                 return g_strdup_printf ("'%s'", name);
1131                         
1132         return g_strdup (name);
1133 }
1134
1135 static dis_map_t param_map [] = {
1136         { PARAM_ATTRIBUTE_IN,                "[in] " },
1137         { PARAM_ATTRIBUTE_OUT,               "[out] " },
1138         { PARAM_ATTRIBUTE_OPTIONAL,          "optional " },
1139         { PARAM_ATTRIBUTE_HAS_DEFAULT,       "hasdefault " },
1140         { PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL, "fieldmarshal " },
1141         { 0, NULL }
1142 };
1143
1144 char *
1145 param_flags (guint32 f)
1146 {
1147         return g_strdup (flags (f, param_map));
1148 }
1149
1150 static dis_map_t field_access_map [] = {
1151         { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
1152         { FIELD_ATTRIBUTE_PRIVATE,             "private " },
1153         { FIELD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem " },
1154         { FIELD_ATTRIBUTE_ASSEMBLY,            "assembly " },
1155         { FIELD_ATTRIBUTE_FAMILY,              "family " },
1156         { FIELD_ATTRIBUTE_FAM_OR_ASSEM,        "famorassem " },
1157         { FIELD_ATTRIBUTE_PUBLIC,              "public " },
1158         { 0, NULL }
1159 };
1160
1161 static dis_map_t field_flags_map [] = {
1162         { FIELD_ATTRIBUTE_STATIC,              "static " },
1163         { FIELD_ATTRIBUTE_INIT_ONLY,           "initonly " },
1164         { FIELD_ATTRIBUTE_LITERAL,             "literal " },
1165         { FIELD_ATTRIBUTE_NOT_SERIALIZED,      "notserialized " },
1166         { FIELD_ATTRIBUTE_SPECIAL_NAME,        "specialname " },
1167         { FIELD_ATTRIBUTE_PINVOKE_IMPL,        "FIXME:pinvokeimpl " },
1168         { FIELD_ATTRIBUTE_RT_SPECIAL_NAME,        "rtspecialname " },
1169         { FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL,        "hasfieldmarshal " },
1170         { 0, NULL }
1171 };
1172
1173 /**
1174  * field_flags:
1175  *
1176  * Returns a stringified version of a Field's flags
1177  */
1178 char *
1179 field_flags (guint32 f)
1180 {
1181         char buffer [1024];
1182         int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
1183         
1184         buffer [0] = 0;
1185
1186         strcat (buffer, map (access, field_access_map));
1187         strcat (buffer, flags (f, field_flags_map));
1188         return g_strdup (buffer);
1189 }
1190
1191 /**
1192  * Returns a stringifed representation of a MethodRefSig (22.2.2)
1193  */
1194 char *
1195 get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy_name)
1196 {
1197         GString *res = g_string_new ("");
1198         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
1199         char *allocated_ret_type, *s;
1200         gboolean has_vararg = 0, seen_vararg = 0;
1201         int param_count, signature_len;
1202         int i, gen_count = 0;
1203         int cconv;
1204         
1205         signature_len = mono_metadata_decode_value (ptr, &ptr);
1206
1207         if (*ptr & 0x05){
1208                 g_string_append (res, "vararg ");
1209                 has_vararg = 1;
1210         }
1211
1212         if (*ptr & 0x20){
1213                 if (*ptr & 0x40)
1214                         g_string_append (res, "explicit-this ");
1215                 else
1216                         g_string_append (res, "instance "); /* has-this */
1217         }
1218
1219         if (*ptr & 0x10)
1220                 gen_count = 1;
1221         cconv = *ptr & 0x0f;
1222         ptr++;
1223         if (gen_count)
1224                 gen_count = mono_metadata_decode_value (ptr, &ptr);
1225         param_count = mono_metadata_decode_value (ptr, &ptr);
1226         if (cconv != 0xa) {
1227                 ptr = get_ret_type (m, ptr, &allocated_ret_type);
1228                 g_string_append (res, allocated_ret_type);
1229                 g_free (allocated_ret_type);
1230         }
1231
1232         if (fancy_name){
1233                 g_string_append_c (res, ' ');
1234                 g_string_append (res, fancy_name);
1235         }
1236         
1237         g_string_append (res, "(");
1238
1239         /*
1240          * param_count describes parameters *before* and *after*
1241          * the vararg sentinel
1242          */
1243         for (i = 0; i < param_count; i++){
1244                 char *param = NULL;
1245                 
1246                 /*
1247                  * If ptr is a SENTINEL
1248                  */
1249                 if (*ptr == 0x41){
1250                         if (!seen_vararg){
1251                                 g_string_append (res, "..., ");
1252                                 seen_vararg = 1;
1253                         }
1254
1255                         ptr++;
1256                 }
1257
1258                 ptr = get_param (m, ptr, &param);
1259                 g_string_append (res, param);
1260                 if (i+1 != param_count)
1261                         g_string_append (res, ", ");
1262                 g_free (param);
1263         }
1264         g_string_append (res, ")");
1265         
1266         /*
1267          * cleanup and return
1268          */
1269         s = res->str;
1270         g_string_free (res, FALSE);
1271         return s;
1272 }
1273
1274 /**
1275  * Returns a stringifed representation of a field ref
1276  */
1277 char *
1278 get_fieldref_signature (MonoImage *m, int idx)
1279 {
1280         guint32 cols [MONO_MEMBERREF_SIZE];
1281         char *sig;
1282         char *full_sig;
1283
1284         mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
1285                         idx - 1, cols, MONO_MEMBERREF_SIZE);
1286
1287         sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE]);
1288         full_sig = g_strdup_printf ("%s %s::%s", sig,
1289                         get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS]),
1290                         mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]));
1291         g_free (sig);
1292         
1293         return full_sig;
1294 }
1295
1296 /**
1297  * get_field:
1298  * @m: metadata context
1299  * @token: a FIELD_DEF token
1300  *
1301  * This routine has to locate the TypeDef that "owns" this Field.
1302  * Since there is no backpointer in the Field table, we have to scan
1303  * the TypeDef table and locate the actual "owner" of the field
1304  */
1305 char *
1306 get_field (MonoImage *m, guint32 token)
1307 {
1308         int idx = mono_metadata_token_index (token);
1309         guint32 cols [MONO_FIELD_SIZE];
1310         char *sig, *res, *type, *estype, *esname;
1311         guint32 type_idx;
1312
1313         /*
1314          * We can get here also with a MenberRef token (for a field
1315          * defined in another module/assembly, just like in get_method ()
1316          */
1317         if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) {
1318                 return get_fieldref_signature (m, idx);
1319         }
1320         g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF);
1321
1322         mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE);
1323         sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
1324
1325         /*
1326          * To locate the actual "container" for this field, we have to scan
1327          * the TypeDef table.  LAME!
1328          */
1329         type_idx = mono_metadata_typedef_from_field (m, idx);
1330
1331         type = get_typedef (m, type_idx);
1332         estype = get_escaped_name (type);
1333         esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
1334         res = g_strdup_printf ("%s %s::%s",
1335                         sig, estype, esname);
1336
1337         g_free (type);
1338         g_free (sig);
1339         g_free (estype);
1340         g_free (esname);
1341
1342         return res;
1343 }
1344
1345 static char *
1346 get_memberref_parent (MonoImage *m, guint32 mrp_token)
1347 {
1348         /*
1349          * mrp_index is a MemberRefParent coded index
1350          */
1351         guint32 table = mrp_token & 7;
1352         guint32 idx = mrp_token >> 3;
1353
1354         switch (table){
1355         case 0: /* TypeDef */
1356                 return get_typedef (m, idx);
1357                 
1358         case 1: /* TypeRef */
1359                 return get_typeref (m, idx);
1360                 
1361         case 2: /* ModuleRef */
1362                 return g_strdup_printf ("TODO:MemberRefParent-ModuleRef");
1363                 
1364         case 3: /* MethodDef */
1365                 return g_strdup ("TODO:MethodDef");
1366                 
1367         case 4: /* TypeSpec */
1368                 return get_typespec (m, idx);
1369         }
1370         g_assert_not_reached ();
1371         return NULL;
1372 }
1373
1374 /**
1375  * get_method:
1376  * @m: metadata context
1377  * @token: a METHOD_DEF or MEMBER_REF token
1378  *
1379  * This routine has to locate the TypeDef that "owns" this Field.
1380  * Since there is no backpointer in the Field table, we have to scan
1381  * the TypeDef table and locate the actual "owner" of the field
1382  */
1383 char *
1384 get_method (MonoImage *m, guint32 token)
1385 {
1386         int idx = mono_metadata_token_index (token);
1387         guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
1388         char *sig, *esname;
1389         const char *name;
1390
1391         MonoMethod *mh;
1392
1393         mh = mono_get_method (m, token, NULL);
1394         if (mh) {
1395                 esname = get_escaped_name (mh->name);
1396                 sig = dis_stringify_object_with_class (m, mh->klass);
1397                 if (show_tokens)
1398                         name = g_strdup_printf ("%s/*%08x*/::%s", sig, token, esname);
1399                 else
1400                         name = g_strdup_printf ("%s::%s", sig, esname);
1401                 g_free (sig);
1402                 g_free (esname);
1403         } else
1404                 name = NULL;
1405
1406         switch (mono_metadata_token_code (token)){
1407         case MONO_TOKEN_METHOD_DEF:
1408                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], 
1409                                           idx - 1, method_cols, MONO_METHOD_SIZE);
1410
1411                 sig = get_methodref_signature (m, method_cols [MONO_METHOD_SIGNATURE], name);
1412                 break;
1413                 
1414         case MONO_TOKEN_MEMBER_REF: {
1415                 mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
1416                                           idx - 1, member_cols, MONO_MEMBERREF_SIZE);
1417                 if (!name)
1418                         name = g_strdup_printf ("%s::%s",
1419                                         get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS]),
1420                                         mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME]));
1421                 sig = get_methodref_signature (
1422                         m, member_cols [MONO_MEMBERREF_SIGNATURE], name);
1423                 break;
1424         }
1425         case MONO_TOKEN_METHOD_SPEC: {
1426                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
1427                                 idx - 1, member_cols, MONO_METHODSPEC_SIZE);
1428                 token = member_cols [MONO_METHODSPEC_METHOD];
1429                 sig = get_methodspec (m, idx, token, name);
1430                 break;
1431         }
1432
1433         default:
1434                 g_assert_not_reached ();
1435         }
1436
1437         if (show_tokens) {
1438                 char *retval = g_strdup_printf ("%s /* %08x */", sig, token);
1439                 g_free (sig);
1440                 return retval;
1441         } else
1442                 return sig;
1443 }
1444
1445 /**
1446  * get_methoddef
1447  * @m: metadata context
1448  * @idx: index into the method table
1449  *
1450  * Returns: A stringified version of the method signature.
1451  */
1452 char *
1453 get_methoddef (MonoImage *m, guint32 idx)
1454 {
1455         guint32 cols [MONO_METHOD_SIZE];
1456         char *sig;
1457         const char *name;
1458
1459         MonoMethod *mh;
1460
1461         mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
1462         if (mh) {
1463                 sig = dis_stringify_object_with_class (m, mh->klass);
1464                 name = g_strdup_printf ("%s::%s", sig, mh->name);
1465                 g_free (sig);
1466         } else
1467                 name = NULL;
1468         mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], 
1469                         idx - 1, cols, MONO_METHOD_SIZE);
1470         sig = get_methodref_signature (m, cols [MONO_METHOD_SIGNATURE], name);
1471         
1472         return sig;
1473 }
1474
1475 char *
1476 get_method_type_param (MonoImage *m, guint32 blob_signature)
1477 {
1478         GString *res = g_string_new ("");
1479         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
1480         int param_count;
1481         int i = 0;
1482         char *s;
1483         
1484         mono_metadata_decode_value (ptr, &ptr);
1485         ptr++;
1486         param_count = mono_metadata_decode_value (ptr, &ptr);
1487         
1488         g_string_append_c (res, '<');
1489         
1490         for (i = 0; i < param_count; i++){
1491                 char *param = NULL;
1492                 
1493                 ptr = get_param (m, ptr, &param);
1494                 g_string_append (res, param);
1495                 if (i+1 != param_count)
1496                         g_string_append (res, ", ");
1497                 g_free (param);
1498         }
1499         g_string_append_c (res, '>');
1500         
1501         s = res->str;
1502         g_string_free (res, FALSE);
1503         return s;
1504 }
1505
1506 /**
1507  * get_methodspec
1508  *
1509  * Returns: An allocated stringified version of the methodspec signature.
1510  */
1511
1512 char *
1513 get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name)
1514 {
1515         GString *res = g_string_new ("");
1516         guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
1517         char *s, *type_param;
1518         const char *ptr;
1519         guint32 sig;
1520         int param_count, cconv, i, gen_count = 0;
1521
1522         switch (token & MONO_METHODDEFORREF_MASK) {
1523         case MONO_METHODDEFORREF_METHODDEF:
1524                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], 
1525                                           (token >> MONO_METHODDEFORREF_BITS) - 1,
1526                                           method_cols, MONO_METHOD_SIZE);
1527                 sig = method_cols [MONO_METHOD_SIGNATURE];
1528                 break;
1529         case MONO_METHODDEFORREF_METHODREF:
1530                 mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF], 
1531                                           (token >> MONO_METHODDEFORREF_BITS) - 1,
1532                                           member_cols, MONO_MEMBERREF_SIZE);
1533                 sig = member_cols [MONO_MEMBERREF_SIGNATURE];
1534                 break;
1535         default:
1536                 g_assert_not_reached ();
1537         }
1538
1539         ptr = mono_metadata_blob_heap (m, sig);
1540         mono_metadata_decode_value (ptr, &ptr);
1541
1542         if (*ptr & 0x20){
1543                 if (*ptr & 0x40)
1544                         g_string_append (res, "explicit-this ");
1545                 else
1546                         g_string_append (res, "instance "); /* has-this */
1547         }
1548
1549         if (*ptr & 0x10)
1550                 gen_count = 1;
1551         cconv = *ptr & 0x0f;
1552         ptr++;
1553         if (gen_count)
1554                 gen_count = mono_metadata_decode_value (ptr, &ptr);
1555         param_count = mono_metadata_decode_value (ptr, &ptr);
1556         if (cconv != 0xa) {
1557                 char *allocated_ret_type;
1558                 ptr = get_ret_type (m, ptr, &allocated_ret_type);
1559                 g_string_append (res, allocated_ret_type);
1560                 g_free (allocated_ret_type);
1561         }
1562
1563         if (fancy_name){
1564                 g_string_append_c (res, ' ');
1565                 g_string_append (res, fancy_name);
1566         }
1567
1568         mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
1569                         idx - 1, member_cols, MONO_METHODSPEC_SIZE);
1570         token = member_cols [MONO_METHODSPEC_SIGNATURE];
1571         type_param = get_method_type_param (m, token);
1572         g_string_append (res, type_param);
1573         g_string_append (res, " (");
1574
1575         /*
1576          * methodspecs can not be varargs so we don't need to worry about that here
1577          */
1578          
1579         for (i = 0; i < param_count; i++){
1580                 char *param = NULL;
1581                 
1582                 ptr = get_param (m, ptr, &param);
1583                 g_string_append (res, param);
1584                 if (i+1 != param_count)
1585                         g_string_append (res, ", ");
1586                 g_free (param);
1587         }
1588         g_string_append (res, ")");
1589         
1590         /*
1591          * cleanup and return
1592          */
1593         s = res->str;
1594         g_string_free (res, FALSE);
1595         return s;
1596 }
1597
1598
1599 /**
1600  * get_constant:
1601  * @m: metadata context
1602  * @blob_index: index into the blob where the constant is stored
1603  *
1604  * Returns: An allocated value representing a stringified version of the
1605  * constant.
1606  */
1607 char *
1608 get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
1609 {
1610         const char *ptr = mono_metadata_blob_heap (m, blob_index);
1611         int len;
1612         
1613         len = mono_metadata_decode_value (ptr, &ptr);
1614         
1615         switch (t){
1616         case MONO_TYPE_BOOLEAN:
1617                 return g_strdup_printf ("%s", *ptr ? "bool(true)" : "bool(false)");
1618                 
1619         case MONO_TYPE_CHAR:
1620                 return g_strdup_printf ("%c", *ptr); /* FIXME: unicode char */
1621                 
1622         case MONO_TYPE_U1:
1623         case MONO_TYPE_I1:
1624                 return g_strdup_printf ("int8(0x%02x)", (int) (*ptr));
1625                 break;
1626                 
1627         case MONO_TYPE_U2:
1628         case MONO_TYPE_I2:
1629                 return g_strdup_printf ("int16(0x%08x)", (int) read16 (ptr));
1630                 
1631         case MONO_TYPE_U4:
1632         case MONO_TYPE_I4:
1633                 return g_strdup_printf ("int32(%d)", read32 (ptr));
1634                 
1635         case MONO_TYPE_I8: {
1636                 guint32 low, high;
1637                 low = read32 (ptr);
1638                 high = read32 (ptr + 4);
1639                 return g_strdup_printf ("0x%08x%08x", high, low);
1640         }
1641         case MONO_TYPE_U8: {
1642                 guint32 low, high;
1643                 low = read32 (ptr);
1644                 high = read32 (ptr + 4);
1645                 return g_strdup_printf ("0x%08x%08x", high, low);
1646         }
1647         case MONO_TYPE_R4: {
1648                 float r;
1649                 readr4 (ptr, &r);
1650                 return g_strdup_printf ("float32(%g)", (double) r);
1651         }
1652         case MONO_TYPE_R8: {
1653                 double r;
1654                 readr8 (ptr, &r);
1655                 return g_strdup_printf ("float64(%g)", r);
1656         }
1657         case MONO_TYPE_STRING: {
1658                 int i, j, e;
1659                 char *res;
1660                 e = len = 0;
1661                 for (i = 0; !ptr [i+1]; i += 2){
1662                         len++;
1663                         switch (ptr [i]) {
1664                         case '"':
1665                         case '\\':
1666                         case '\n': /* add more */
1667                                 e++;
1668                         }
1669                 }
1670                 res = g_malloc (len + e + 3);
1671                 j = 1;
1672                 res [0] = '"';
1673
1674                 for (i = 0; i < len; i += 2){
1675                         switch(ptr[i]) {
1676                         case '"': 
1677                                 res[j++] = '\\';
1678                                 res[j++] = '"';
1679                         case '\\': 
1680                                 res[j++] = '\\';
1681                                 res[j++] = '\\';
1682                         case '\n':
1683                                 res[j++] = '\\';
1684                                 res[j++] = 'n';
1685                                 break;
1686                         default:
1687                                 res[j++] = isprint (ptr [i]) ? ptr [i] : '.';
1688                                 break;
1689                         }
1690                 }
1691                 res[j++] = '"';
1692                 res[j] = 0;
1693                 return res;
1694         }
1695                 
1696         case MONO_TYPE_CLASS:
1697                 return g_strdup ("CLASS CONSTANT.  MUST BE ZERO");
1698                 
1699         default:
1700                 g_error ("Unknown MONO_TYPE (%d) on constant at Blob index (0x%08x)\n",
1701                          (int) *ptr, blob_index);
1702                 return g_strdup_printf ("Unknown");
1703         }
1704
1705 }
1706
1707 /**
1708  * get_token:
1709  * @m: metadata context
1710  * @token: token that we want to decode.
1711  *
1712  * Returns: An allocated value representing a stringified version of the
1713  * constant.
1714  */
1715 char *
1716 get_token (MonoImage *m, guint32 token)
1717 {
1718         char *temp, *result;
1719         guint32 idx = mono_metadata_token_index (token);
1720
1721         switch (mono_metadata_token_code (token)){
1722         case MONO_TOKEN_FIELD_DEF:
1723                 temp = get_field (m, token);
1724                 result = g_strdup_printf ("field %s", temp);
1725                 g_free (temp);
1726                 return result;
1727         case MONO_TOKEN_TYPE_DEF:
1728                 return get_typedef (m, idx);
1729         case MONO_TOKEN_TYPE_REF:
1730                 return get_typeref (m, idx);
1731         case MONO_TOKEN_TYPE_SPEC:
1732                 return get_typespec (m, idx);
1733         default:                
1734                 g_error ("Do not know how to decode tokens of type 0x%08x", token);
1735         }
1736
1737         g_assert_not_reached ();
1738         return g_strdup ("ERROR");
1739 }
1740
1741 /**
1742  * get_token_type:
1743  * @m: metadata context
1744  * @token: the token can belong to any of the following tables:
1745  * MONO_TOKEN_TYPE_REF, MONO_TOKEN_TYPE_DEF, MONO_TOKEN_TYPE_SPEC
1746  *
1747  * Returns: a stringified version of the MethodDef or MethodRef or TypeSpecn
1748  * at (token & 0xffffff) 
1749  */
1750 char *
1751 get_token_type (MonoImage *m, guint32 token)
1752 {
1753         char *temp = NULL, *s = NULL;
1754         int idx;
1755
1756         idx = mono_metadata_token_index (token);
1757         
1758         switch (mono_metadata_token_code (token)){
1759         case MONO_TOKEN_TYPE_DEF:
1760                 temp = get_typedef (m, idx);
1761                 s = g_strdup_printf ("%s", temp);
1762                 break;
1763                 
1764         case MONO_TOKEN_TYPE_REF: 
1765                 temp = get_typeref (m, idx);
1766                 s = g_strdup_printf ("%s", temp);
1767                 break;
1768                 
1769         case MONO_TOKEN_TYPE_SPEC:
1770                 s = get_typespec (m, idx);
1771                 break;
1772
1773         default:
1774                 g_error ("Unhandled encoding for token 0x%08x", token);
1775
1776         }
1777         
1778         if (temp)
1779                 g_free (temp);
1780
1781         return s;
1782 }
1783
1784 char *
1785 get_guid (MonoImage *m, guint32 guid_index)
1786 {
1787         const unsigned char *guid;
1788         char *result;
1789
1790         guid = mono_metadata_guid_heap (m, guid_index);
1791
1792         result = g_strdup_printf ("{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 
1793                         guid [3], guid [2], guid [1], guid [0], guid [5], guid [4], guid [7], guid [6],
1794                         guid [8], guid [9], guid [10], guid [11], guid [12], guid [13], guid [14], guid [15]);
1795         return result;
1796 }
1797
1798 GList *
1799 dis_get_custom_attrs (MonoImage *m, guint32 token)
1800 {
1801         GList *list = NULL;
1802         guint32 idx, i, len, mtoken;
1803         guint32 cols [MONO_CUSTOM_ATTR_SIZE];
1804         MonoTableInfo *ca;
1805         char *method;
1806         GString *attr;
1807         const char *val;
1808
1809         idx = mono_metadata_token_index (token);
1810         idx <<= MONO_CUSTOM_ATTR_BITS;
1811         
1812         switch (mono_metadata_token_table (token)) {
1813         case MONO_TABLE_TYPEDEF:
1814                 idx |= MONO_CUSTOM_ATTR_TYPEDEF;
1815                 break;
1816         case MONO_TABLE_ASSEMBLY:
1817                 idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
1818                 break;
1819         case MONO_TABLE_MODULE:
1820                 idx |= MONO_CUSTOM_ATTR_MODULE;
1821                 break;
1822         case MONO_TABLE_PROPERTY:
1823                 idx |= MONO_CUSTOM_ATTR_PROPERTY;
1824                 break;
1825         case MONO_TABLE_EVENT:
1826                 idx |= MONO_CUSTOM_ATTR_EVENT;
1827                 break;
1828         case MONO_TABLE_FIELD:
1829                 idx |= MONO_CUSTOM_ATTR_FIELDDEF;
1830                 break;
1831         case MONO_TABLE_METHOD:
1832                 idx |= MONO_CUSTOM_ATTR_METHODDEF;
1833                 break;
1834         case MONO_TABLE_PARAM:
1835                 idx |= MONO_CUSTOM_ATTR_PARAMDEF;
1836                 break;
1837         default:
1838                 g_print ("Missing custom attr get support for token 0x%08x\n", token);
1839                 return NULL;
1840         }
1841
1842         ca = &m->tables [MONO_TABLE_CUSTOMATTRIBUTE];
1843         /* the table is not sorted */
1844         for (i = 0; i < ca->rows; ++i) {
1845                 char *dump;
1846                 mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
1847                 if (cols [MONO_CUSTOM_ATTR_PARENT] != idx)
1848                         continue;
1849                 mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
1850                 switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
1851                 case MONO_CUSTOM_ATTR_TYPE_METHODDEF:
1852                         mtoken |= MONO_TOKEN_METHOD_DEF;
1853                         break;
1854                 case MONO_CUSTOM_ATTR_TYPE_MEMBERREF:
1855                         mtoken |= MONO_TOKEN_MEMBER_REF;
1856                         break;
1857                 default:
1858                         g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
1859                         break;
1860                 }
1861                 method = get_method (m, mtoken);
1862                 val = mono_metadata_blob_heap (m, cols [MONO_CUSTOM_ATTR_VALUE]);
1863                 len = mono_metadata_decode_value (val, &val);
1864                 attr = g_string_new (".custom ");
1865                 dump = data_dump (val, len, "\t\t");
1866                 g_string_sprintfa (attr, "%s = %s", method, dump);
1867                 g_free (dump);
1868                 list = g_list_append (list, attr->str);
1869                 g_string_free (attr, FALSE);
1870                 g_free (method);
1871         }
1872         return list;
1873 }
1874
1875 char*
1876 get_marshal_info (MonoImage *m, const char *blob) {
1877         int len, size = 0;
1878
1879         len = mono_metadata_decode_blob_size (blob, &blob);
1880
1881         switch (*blob) {
1882         case MONO_NATIVE_BOOLEAN:
1883                 return g_strdup ("bool");
1884         case MONO_NATIVE_I1:
1885                 return g_strdup ("int8");
1886         case MONO_NATIVE_U1:
1887                 return g_strdup ("unsigned int8");
1888         case MONO_NATIVE_I2:
1889                 return g_strdup ("int16");
1890         case MONO_NATIVE_U2:
1891                 return g_strdup ("unsigned int16");
1892         case MONO_NATIVE_I4:
1893                 return g_strdup ("int32");
1894         case MONO_NATIVE_U4:
1895                 return g_strdup ("unsigned int32");
1896         case MONO_NATIVE_I8:
1897                 return g_strdup ("int64");
1898         case MONO_NATIVE_U8:
1899                 return g_strdup ("unsigned int64");
1900         case MONO_NATIVE_R4:
1901                 return g_strdup ("float32");
1902         case MONO_NATIVE_R8:
1903                 return g_strdup ("float64");
1904         case MONO_NATIVE_CURRENCY:
1905                 return g_strdup ("currency");
1906         case MONO_NATIVE_BSTR:
1907                 return g_strdup ("bstr");
1908         case MONO_NATIVE_LPSTR:
1909                 return g_strdup ("lpstr");
1910         case MONO_NATIVE_LPWSTR:
1911                 return g_strdup ("lpwstr");
1912         case MONO_NATIVE_LPTSTR:
1913                 return g_strdup ("lptstr");
1914         case MONO_NATIVE_BYVALTSTR:
1915                 size = mono_metadata_decode_value (blob + 1, &blob);
1916                 return g_strdup_printf ("fixed sysstring [%d]", size);
1917         case MONO_NATIVE_IUNKNOWN:
1918                 return g_strdup ("iunknown");
1919         case MONO_NATIVE_IDISPATCH:
1920                 return g_strdup ("idispatch");
1921         case MONO_NATIVE_STRUCT:
1922                 return g_strdup ("struct");
1923         case MONO_NATIVE_INTERFACE:
1924                 return g_strdup ("interface");
1925         case MONO_NATIVE_SAFEARRAY:
1926                 return g_strdup ("safearray");
1927         case MONO_NATIVE_BYVALARRAY:
1928                 size = mono_metadata_decode_value (blob + 1, &blob);
1929                 return g_strdup_printf ("fixed array [%d]", size);
1930         case MONO_NATIVE_INT:
1931                 return g_strdup ("int");
1932         case MONO_NATIVE_UINT:
1933                 return g_strdup ("unsigned int");
1934         case MONO_NATIVE_VBBYREFSTR:
1935                 return g_strdup ("vbbyrefstr");
1936         case MONO_NATIVE_ANSIBSTR:
1937                 return g_strdup ("ansi bstr");
1938         case MONO_NATIVE_TBSTR:
1939                 return g_strdup ("tbstr");
1940         case MONO_NATIVE_VARIANTBOOL:
1941                 return g_strdup ("variant bool");
1942         case MONO_NATIVE_FUNC:
1943                 return g_strdup ("method");
1944         case MONO_NATIVE_ASANY:
1945                 return g_strdup ("as any");
1946         case MONO_NATIVE_LPARRAY:
1947                 return g_strdup ("[]");
1948         case MONO_NATIVE_LPSTRUCT:
1949                 return g_strdup ("lpstruct");
1950         case MONO_NATIVE_CUSTOM:
1951                 return g_strdup ("custom");
1952         case MONO_NATIVE_ERROR:
1953                 return g_strdup ("error");
1954         default:
1955                 return g_strdup ("unknown");
1956         }
1957 }
1958
1959 void
1960 init_key_table (void)
1961 {
1962         key_table = g_hash_table_new (g_str_hash, g_str_equal);
1963
1964         /* auto generated */
1965         g_hash_table_insert (key_table, (char *) "abstract", GINT_TO_POINTER (TRUE));
1966         g_hash_table_insert (key_table, (char *) "add", GINT_TO_POINTER (TRUE));
1967         g_hash_table_insert (key_table, (char *) "add.ovf", GINT_TO_POINTER (TRUE));
1968         g_hash_table_insert (key_table, (char *) "add.ovf.un", GINT_TO_POINTER (TRUE));
1969         g_hash_table_insert (key_table, (char *) "algorithm", GINT_TO_POINTER (TRUE));
1970         g_hash_table_insert (key_table, (char *) "alignment", GINT_TO_POINTER (TRUE));
1971         g_hash_table_insert (key_table, (char *) "and", GINT_TO_POINTER (TRUE));
1972         g_hash_table_insert (key_table, (char *) "ansi", GINT_TO_POINTER (TRUE));
1973         g_hash_table_insert (key_table, (char *) "any", GINT_TO_POINTER (TRUE));
1974         g_hash_table_insert (key_table, (char *) "arglist", GINT_TO_POINTER (TRUE));
1975         g_hash_table_insert (key_table, (char *) "array", GINT_TO_POINTER (TRUE));
1976         g_hash_table_insert (key_table, (char *) "as", GINT_TO_POINTER (TRUE));
1977         g_hash_table_insert (key_table, (char *) "assembly", GINT_TO_POINTER (TRUE));
1978         g_hash_table_insert (key_table, (char *) "assert", GINT_TO_POINTER (TRUE));
1979         g_hash_table_insert (key_table, (char *) "at", GINT_TO_POINTER (TRUE));
1980         g_hash_table_insert (key_table, (char *) "auto", GINT_TO_POINTER (TRUE));
1981         g_hash_table_insert (key_table, (char *) "autochar", GINT_TO_POINTER (TRUE));
1982         g_hash_table_insert (key_table, (char *) "beforefieldinit", GINT_TO_POINTER (TRUE));
1983         g_hash_table_insert (key_table, (char *) "beq", GINT_TO_POINTER (TRUE));
1984         g_hash_table_insert (key_table, (char *) "beq.s", GINT_TO_POINTER (TRUE));
1985         g_hash_table_insert (key_table, (char *) "bge", GINT_TO_POINTER (TRUE));
1986         g_hash_table_insert (key_table, (char *) "bge.s", GINT_TO_POINTER (TRUE));
1987         g_hash_table_insert (key_table, (char *) "bge.un", GINT_TO_POINTER (TRUE));
1988         g_hash_table_insert (key_table, (char *) "bge.un.s", GINT_TO_POINTER (TRUE));
1989         g_hash_table_insert (key_table, (char *) "bgt", GINT_TO_POINTER (TRUE));
1990         g_hash_table_insert (key_table, (char *) "bgt.s", GINT_TO_POINTER (TRUE));
1991         g_hash_table_insert (key_table, (char *) "bgt.un", GINT_TO_POINTER (TRUE));
1992         g_hash_table_insert (key_table, (char *) "9", GINT_TO_POINTER (TRUE));
1993         g_hash_table_insert (key_table, (char *) "bgt.un.s", GINT_TO_POINTER (TRUE));
1994         g_hash_table_insert (key_table, (char *) "ble", GINT_TO_POINTER (TRUE));
1995         g_hash_table_insert (key_table, (char *) "ble.s", GINT_TO_POINTER (TRUE));
1996         g_hash_table_insert (key_table, (char *) "ble.un", GINT_TO_POINTER (TRUE));
1997         g_hash_table_insert (key_table, (char *) "ble.un.s", GINT_TO_POINTER (TRUE));
1998         g_hash_table_insert (key_table, (char *) "blob", GINT_TO_POINTER (TRUE));
1999         g_hash_table_insert (key_table, (char *) "blob_object", GINT_TO_POINTER (TRUE));
2000         g_hash_table_insert (key_table, (char *) "blt", GINT_TO_POINTER (TRUE));
2001         g_hash_table_insert (key_table, (char *) "blt.s", GINT_TO_POINTER (TRUE));
2002         g_hash_table_insert (key_table, (char *) "blt.un", GINT_TO_POINTER (TRUE));
2003         g_hash_table_insert (key_table, (char *) "blt.un.s", GINT_TO_POINTER (TRUE));
2004         g_hash_table_insert (key_table, (char *) "bne.un", GINT_TO_POINTER (TRUE));
2005         g_hash_table_insert (key_table, (char *) "bne.un.s", GINT_TO_POINTER (TRUE));
2006         g_hash_table_insert (key_table, (char *) "bool", GINT_TO_POINTER (TRUE));
2007         g_hash_table_insert (key_table, (char *) "box", GINT_TO_POINTER (TRUE));
2008         g_hash_table_insert (key_table, (char *) "br", GINT_TO_POINTER (TRUE));
2009         g_hash_table_insert (key_table, (char *) "br.s", GINT_TO_POINTER (TRUE));
2010         g_hash_table_insert (key_table, (char *) "break", GINT_TO_POINTER (TRUE));
2011         g_hash_table_insert (key_table, (char *) "brfalse", GINT_TO_POINTER (TRUE));
2012         g_hash_table_insert (key_table, (char *) "brfalse.s", GINT_TO_POINTER (TRUE));
2013         g_hash_table_insert (key_table, (char *) "brinst", GINT_TO_POINTER (TRUE));
2014         g_hash_table_insert (key_table, (char *) "brinst.s", GINT_TO_POINTER (TRUE));
2015         g_hash_table_insert (key_table, (char *) "brnull", GINT_TO_POINTER (TRUE));
2016         g_hash_table_insert (key_table, (char *) "brnull.s", GINT_TO_POINTER (TRUE));
2017         g_hash_table_insert (key_table, (char *) "brtrue", GINT_TO_POINTER (TRUE));
2018         g_hash_table_insert (key_table, (char *) "brtrue.s", GINT_TO_POINTER (TRUE));
2019         g_hash_table_insert (key_table, (char *) "brzero", GINT_TO_POINTER (TRUE));
2020         g_hash_table_insert (key_table, (char *) "brzero.s", GINT_TO_POINTER (TRUE));
2021         g_hash_table_insert (key_table, (char *) "bstr", GINT_TO_POINTER (TRUE));
2022         g_hash_table_insert (key_table, (char *) "bytearray", GINT_TO_POINTER (TRUE));
2023         g_hash_table_insert (key_table, (char *) "byvalstr", GINT_TO_POINTER (TRUE));
2024         g_hash_table_insert (key_table, (char *) "call", GINT_TO_POINTER (TRUE));
2025         g_hash_table_insert (key_table, (char *) "calli", GINT_TO_POINTER (TRUE));
2026         g_hash_table_insert (key_table, (char *) "callmostderived", GINT_TO_POINTER (TRUE));
2027         g_hash_table_insert (key_table, (char *) "callvirt", GINT_TO_POINTER (TRUE));
2028         g_hash_table_insert (key_table, (char *) "carray", GINT_TO_POINTER (TRUE));
2029         g_hash_table_insert (key_table, (char *) "castclass", GINT_TO_POINTER (TRUE));
2030         g_hash_table_insert (key_table, (char *) "catch", GINT_TO_POINTER (TRUE));
2031         g_hash_table_insert (key_table, (char *) "cdecl", GINT_TO_POINTER (TRUE));
2032         g_hash_table_insert (key_table, (char *) "ceq", GINT_TO_POINTER (TRUE));
2033         g_hash_table_insert (key_table, (char *) "cf", GINT_TO_POINTER (TRUE));
2034         g_hash_table_insert (key_table, (char *) "cgt", GINT_TO_POINTER (TRUE));
2035         g_hash_table_insert (key_table, (char *) "cgt.un", GINT_TO_POINTER (TRUE));
2036         g_hash_table_insert (key_table, (char *) "char", GINT_TO_POINTER (TRUE));
2037         g_hash_table_insert (key_table, (char *) "cil", GINT_TO_POINTER (TRUE));
2038         g_hash_table_insert (key_table, (char *) "ckfinite", GINT_TO_POINTER (TRUE));
2039         g_hash_table_insert (key_table, (char *) "class", GINT_TO_POINTER (TRUE));
2040         g_hash_table_insert (key_table, (char *) "clsid", GINT_TO_POINTER (TRUE));
2041         g_hash_table_insert (key_table, (char *) "clt", GINT_TO_POINTER (TRUE));
2042         g_hash_table_insert (key_table, (char *) "clt.un", GINT_TO_POINTER (TRUE));
2043         g_hash_table_insert (key_table, (char *) "const", GINT_TO_POINTER (TRUE));
2044         g_hash_table_insert (key_table, (char *) "conv.i", GINT_TO_POINTER (TRUE));
2045         g_hash_table_insert (key_table, (char *) "conv.i1", GINT_TO_POINTER (TRUE));
2046         g_hash_table_insert (key_table, (char *) "conv.i2", GINT_TO_POINTER (TRUE));
2047         g_hash_table_insert (key_table, (char *) "conv.i4", GINT_TO_POINTER (TRUE));
2048         g_hash_table_insert (key_table, (char *) "conv.i8", GINT_TO_POINTER (TRUE));
2049         g_hash_table_insert (key_table, (char *) "conv.ovf.i", GINT_TO_POINTER (TRUE));
2050         g_hash_table_insert (key_table, (char *) "conv.ovf.i.un", GINT_TO_POINTER (TRUE));
2051         g_hash_table_insert (key_table, (char *) "conv.ovf.i1", GINT_TO_POINTER (TRUE));
2052         g_hash_table_insert (key_table, (char *) "conv.ovf.i1.un", GINT_TO_POINTER (TRUE));
2053         g_hash_table_insert (key_table, (char *) "conv.ovf.i2", GINT_TO_POINTER (TRUE));
2054         g_hash_table_insert (key_table, (char *) "conv.ovf.i2.un", GINT_TO_POINTER (TRUE));
2055         g_hash_table_insert (key_table, (char *) "conv.ovf.i4", GINT_TO_POINTER (TRUE));
2056         g_hash_table_insert (key_table, (char *) "conv.ovf.i4.un", GINT_TO_POINTER (TRUE));
2057         g_hash_table_insert (key_table, (char *) "conv.ovf.i8", GINT_TO_POINTER (TRUE));
2058         g_hash_table_insert (key_table, (char *) "conv.ovf.i8.un", GINT_TO_POINTER (TRUE));
2059         g_hash_table_insert (key_table, (char *) "conv.ovf.u", GINT_TO_POINTER (TRUE));
2060         g_hash_table_insert (key_table, (char *) "conv.ovf.u.un", GINT_TO_POINTER (TRUE));
2061         g_hash_table_insert (key_table, (char *) "conv.ovf.u1", GINT_TO_POINTER (TRUE));
2062         g_hash_table_insert (key_table, (char *) "conv.ovf.u1.un", GINT_TO_POINTER (TRUE));
2063         g_hash_table_insert (key_table, (char *) "conv.ovf.u2", GINT_TO_POINTER (TRUE));
2064         g_hash_table_insert (key_table, (char *) "conv.ovf.u2.un", GINT_TO_POINTER (TRUE));
2065         g_hash_table_insert (key_table, (char *) "conv.ovf.u4", GINT_TO_POINTER (TRUE));
2066         g_hash_table_insert (key_table, (char *) "conv.ovf.u4.un", GINT_TO_POINTER (TRUE));
2067         g_hash_table_insert (key_table, (char *) "conv.ovf.u8", GINT_TO_POINTER (TRUE));
2068         g_hash_table_insert (key_table, (char *) "conv.ovf.u8.un", GINT_TO_POINTER (TRUE));
2069         g_hash_table_insert (key_table, (char *) "conv.r.un", GINT_TO_POINTER (TRUE));
2070         g_hash_table_insert (key_table, (char *) "conv.r4", GINT_TO_POINTER (TRUE));
2071         g_hash_table_insert (key_table, (char *) "conv.r8", GINT_TO_POINTER (TRUE));
2072         g_hash_table_insert (key_table, (char *) "conv.u", GINT_TO_POINTER (TRUE));
2073         g_hash_table_insert (key_table, (char *) "conv.u1", GINT_TO_POINTER (TRUE));
2074         g_hash_table_insert (key_table, (char *) "conv.u2", GINT_TO_POINTER (TRUE));
2075         g_hash_table_insert (key_table, (char *) "conv.u4", GINT_TO_POINTER (TRUE));
2076         g_hash_table_insert (key_table, (char *) "conv.u8", GINT_TO_POINTER (TRUE));
2077         g_hash_table_insert (key_table, (char *) "cpblk", GINT_TO_POINTER (TRUE));
2078         g_hash_table_insert (key_table, (char *) "cpobj", GINT_TO_POINTER (TRUE));
2079         g_hash_table_insert (key_table, (char *) "currency", GINT_TO_POINTER (TRUE));
2080         g_hash_table_insert (key_table, (char *) "custom", GINT_TO_POINTER (TRUE));
2081         g_hash_table_insert (key_table, (char *) "date", GINT_TO_POINTER (TRUE));
2082         g_hash_table_insert (key_table, (char *) "decimal", GINT_TO_POINTER (TRUE));
2083         g_hash_table_insert (key_table, (char *) "default", GINT_TO_POINTER (TRUE));
2084         g_hash_table_insert (key_table, (char *) "default", GINT_TO_POINTER (TRUE));
2085         g_hash_table_insert (key_table, (char *) "demand", GINT_TO_POINTER (TRUE));
2086         g_hash_table_insert (key_table, (char *) "deny", GINT_TO_POINTER (TRUE));
2087         g_hash_table_insert (key_table, (char *) "div", GINT_TO_POINTER (TRUE));
2088         g_hash_table_insert (key_table, (char *) "div.un", GINT_TO_POINTER (TRUE));
2089         g_hash_table_insert (key_table, (char *) "dup", GINT_TO_POINTER (TRUE));
2090         g_hash_table_insert (key_table, (char *) "endfault", GINT_TO_POINTER (TRUE));
2091         g_hash_table_insert (key_table, (char *) "endfilter", GINT_TO_POINTER (TRUE));
2092         g_hash_table_insert (key_table, (char *) "endfinally", GINT_TO_POINTER (TRUE));
2093         g_hash_table_insert (key_table, (char *) "endmac", GINT_TO_POINTER (TRUE));
2094         g_hash_table_insert (key_table, (char *) "enum", GINT_TO_POINTER (TRUE));
2095         g_hash_table_insert (key_table, (char *) "error", GINT_TO_POINTER (TRUE));
2096         g_hash_table_insert (key_table, (char *) "explicit", GINT_TO_POINTER (TRUE));
2097         g_hash_table_insert (key_table, (char *) "extends", GINT_TO_POINTER (TRUE));
2098         g_hash_table_insert (key_table, (char *) "extern", GINT_TO_POINTER (TRUE));
2099         g_hash_table_insert (key_table, (char *) "false", GINT_TO_POINTER (TRUE));
2100         g_hash_table_insert (key_table, (char *) "famandassem", GINT_TO_POINTER (TRUE));
2101         g_hash_table_insert (key_table, (char *) "family", GINT_TO_POINTER (TRUE));
2102         g_hash_table_insert (key_table, (char *) "famorassem", GINT_TO_POINTER (TRUE));
2103         g_hash_table_insert (key_table, (char *) "fastcall", GINT_TO_POINTER (TRUE));
2104         g_hash_table_insert (key_table, (char *) "fastcall", GINT_TO_POINTER (TRUE));
2105         g_hash_table_insert (key_table, (char *) "fault", GINT_TO_POINTER (TRUE));
2106         g_hash_table_insert (key_table, (char *) "field", GINT_TO_POINTER (TRUE));
2107         g_hash_table_insert (key_table, (char *) "filetime", GINT_TO_POINTER (TRUE));
2108         g_hash_table_insert (key_table, (char *) "filter", GINT_TO_POINTER (TRUE));
2109         g_hash_table_insert (key_table, (char *) "final", GINT_TO_POINTER (TRUE));
2110         g_hash_table_insert (key_table, (char *) "finally", GINT_TO_POINTER (TRUE));
2111         g_hash_table_insert (key_table, (char *) "fixed", GINT_TO_POINTER (TRUE));
2112         g_hash_table_insert (key_table, (char *) "float", GINT_TO_POINTER (TRUE));
2113         g_hash_table_insert (key_table, (char *) "float32", GINT_TO_POINTER (TRUE));
2114         g_hash_table_insert (key_table, (char *) "float64", GINT_TO_POINTER (TRUE));
2115         g_hash_table_insert (key_table, (char *) "forwardref", GINT_TO_POINTER (TRUE));
2116         g_hash_table_insert (key_table, (char *) "fromunmanaged", GINT_TO_POINTER (TRUE));
2117         g_hash_table_insert (key_table, (char *) "handler", GINT_TO_POINTER (TRUE));
2118         g_hash_table_insert (key_table, (char *) "hidebysig", GINT_TO_POINTER (TRUE));
2119         g_hash_table_insert (key_table, (char *) "hresult", GINT_TO_POINTER (TRUE));
2120         g_hash_table_insert (key_table, (char *) "idispatch", GINT_TO_POINTER (TRUE));
2121         g_hash_table_insert (key_table, (char *) "il", GINT_TO_POINTER (TRUE));
2122         g_hash_table_insert (key_table, (char *) "illegal", GINT_TO_POINTER (TRUE));
2123         g_hash_table_insert (key_table, (char *) "implements", GINT_TO_POINTER (TRUE));
2124         g_hash_table_insert (key_table, (char *) "implicitcom", GINT_TO_POINTER (TRUE));
2125         g_hash_table_insert (key_table, (char *) "implicitres", GINT_TO_POINTER (TRUE));
2126         g_hash_table_insert (key_table, (char *) "import", GINT_TO_POINTER (TRUE));
2127         g_hash_table_insert (key_table, (char *) "in", GINT_TO_POINTER (TRUE));
2128         g_hash_table_insert (key_table, (char *) "inheritcheck", GINT_TO_POINTER (TRUE));
2129         g_hash_table_insert (key_table, (char *) "init", GINT_TO_POINTER (TRUE));
2130         g_hash_table_insert (key_table, (char *) "initblk", GINT_TO_POINTER (TRUE));
2131         g_hash_table_insert (key_table, (char *) "initobj", GINT_TO_POINTER (TRUE));
2132         g_hash_table_insert (key_table, (char *) "initonly", GINT_TO_POINTER (TRUE));
2133         g_hash_table_insert (key_table, (char *) "instance", GINT_TO_POINTER (TRUE));
2134         g_hash_table_insert (key_table, (char *) "int", GINT_TO_POINTER (TRUE));
2135         g_hash_table_insert (key_table, (char *) "int16", GINT_TO_POINTER (TRUE));
2136         g_hash_table_insert (key_table, (char *) "int32", GINT_TO_POINTER (TRUE));
2137         g_hash_table_insert (key_table, (char *) "int64", GINT_TO_POINTER (TRUE));
2138         g_hash_table_insert (key_table, (char *) "int8", GINT_TO_POINTER (TRUE));
2139         g_hash_table_insert (key_table, (char *) "interface", GINT_TO_POINTER (TRUE));
2140         g_hash_table_insert (key_table, (char *) "internalcall", GINT_TO_POINTER (TRUE));
2141         g_hash_table_insert (key_table, (char *) "isinst", GINT_TO_POINTER (TRUE));
2142         g_hash_table_insert (key_table, (char *) "iunknown", GINT_TO_POINTER (TRUE));
2143         g_hash_table_insert (key_table, (char *) "jmp", GINT_TO_POINTER (TRUE));
2144         g_hash_table_insert (key_table, (char *) "lasterr", GINT_TO_POINTER (TRUE));
2145         g_hash_table_insert (key_table, (char *) "lcid", GINT_TO_POINTER (TRUE));
2146         g_hash_table_insert (key_table, (char *) "ldarg", GINT_TO_POINTER (TRUE));
2147         g_hash_table_insert (key_table, (char *) "ldarg.0", GINT_TO_POINTER (TRUE));
2148         g_hash_table_insert (key_table, (char *) "ldarg.1", GINT_TO_POINTER (TRUE));
2149         g_hash_table_insert (key_table, (char *) "ldarg.2", GINT_TO_POINTER (TRUE));
2150         g_hash_table_insert (key_table, (char *) "ldarg.3", GINT_TO_POINTER (TRUE));
2151         g_hash_table_insert (key_table, (char *) "ldarg.s", GINT_TO_POINTER (TRUE));
2152         g_hash_table_insert (key_table, (char *) "ldarga", GINT_TO_POINTER (TRUE));
2153         g_hash_table_insert (key_table, (char *) "ldarga.s", GINT_TO_POINTER (TRUE));
2154         g_hash_table_insert (key_table, (char *) "ldc.i4", GINT_TO_POINTER (TRUE));
2155         g_hash_table_insert (key_table, (char *) "ldc.i4.0", GINT_TO_POINTER (TRUE));
2156         g_hash_table_insert (key_table, (char *) "ldc.i4.1", GINT_TO_POINTER (TRUE));
2157         g_hash_table_insert (key_table, (char *) "ldc.i4.2", GINT_TO_POINTER (TRUE));
2158         g_hash_table_insert (key_table, (char *) "ldc.i4.3", GINT_TO_POINTER (TRUE));
2159         g_hash_table_insert (key_table, (char *) "ldc.i4.4", GINT_TO_POINTER (TRUE));
2160         g_hash_table_insert (key_table, (char *) "ldc.i4.5", GINT_TO_POINTER (TRUE));
2161         g_hash_table_insert (key_table, (char *) "ldc.i4.6", GINT_TO_POINTER (TRUE));
2162         g_hash_table_insert (key_table, (char *) "ldc.i4.7", GINT_TO_POINTER (TRUE));
2163         g_hash_table_insert (key_table, (char *) "ldc.i4.8", GINT_TO_POINTER (TRUE));
2164         g_hash_table_insert (key_table, (char *) "ldc.i4.M1", GINT_TO_POINTER (TRUE));
2165         g_hash_table_insert (key_table, (char *) "ldc.i4.m1", GINT_TO_POINTER (TRUE));
2166         g_hash_table_insert (key_table, (char *) "ldc.i4.s", GINT_TO_POINTER (TRUE));
2167         g_hash_table_insert (key_table, (char *) "ldc.i8", GINT_TO_POINTER (TRUE));
2168         g_hash_table_insert (key_table, (char *) "ldc.r4", GINT_TO_POINTER (TRUE));
2169         g_hash_table_insert (key_table, (char *) "ldc.r8", GINT_TO_POINTER (TRUE));
2170         g_hash_table_insert (key_table, (char *) "ldelem.i", GINT_TO_POINTER (TRUE));
2171         g_hash_table_insert (key_table, (char *) "ldelem.i1", GINT_TO_POINTER (TRUE));
2172         g_hash_table_insert (key_table, (char *) "ldelem.i2", GINT_TO_POINTER (TRUE));
2173         g_hash_table_insert (key_table, (char *) "ldelem.i4", GINT_TO_POINTER (TRUE));
2174         g_hash_table_insert (key_table, (char *) "ldelem.i8", GINT_TO_POINTER (TRUE));
2175         g_hash_table_insert (key_table, (char *) "ldelem.r4", GINT_TO_POINTER (TRUE));
2176         g_hash_table_insert (key_table, (char *) "ldelem.r8", GINT_TO_POINTER (TRUE));
2177         g_hash_table_insert (key_table, (char *) "ldelem.ref", GINT_TO_POINTER (TRUE));
2178         g_hash_table_insert (key_table, (char *) "ldelem.u1", GINT_TO_POINTER (TRUE));
2179         g_hash_table_insert (key_table, (char *) "ldelem.u2", GINT_TO_POINTER (TRUE));
2180         g_hash_table_insert (key_table, (char *) "ldelem.u4", GINT_TO_POINTER (TRUE));
2181         g_hash_table_insert (key_table, (char *) "ldelem.u8", GINT_TO_POINTER (TRUE));
2182         g_hash_table_insert (key_table, (char *) "ldelema", GINT_TO_POINTER (TRUE));
2183         g_hash_table_insert (key_table, (char *) "ldfld", GINT_TO_POINTER (TRUE));
2184         g_hash_table_insert (key_table, (char *) "ldflda", GINT_TO_POINTER (TRUE));
2185         g_hash_table_insert (key_table, (char *) "ldftn", GINT_TO_POINTER (TRUE));
2186         g_hash_table_insert (key_table, (char *) "ldind.i", GINT_TO_POINTER (TRUE));
2187         g_hash_table_insert (key_table, (char *) "ldind.i1", GINT_TO_POINTER (TRUE));
2188         g_hash_table_insert (key_table, (char *) "ldind.i2", GINT_TO_POINTER (TRUE));
2189         g_hash_table_insert (key_table, (char *) "ldind.i4", GINT_TO_POINTER (TRUE));
2190         g_hash_table_insert (key_table, (char *) "ldind.i8", GINT_TO_POINTER (TRUE));
2191         g_hash_table_insert (key_table, (char *) "ldind.r4", GINT_TO_POINTER (TRUE));
2192         g_hash_table_insert (key_table, (char *) "ldind.r8", GINT_TO_POINTER (TRUE));
2193         g_hash_table_insert (key_table, (char *) "ldind.ref", GINT_TO_POINTER (TRUE));
2194         g_hash_table_insert (key_table, (char *) "ldind.u1", GINT_TO_POINTER (TRUE));
2195         g_hash_table_insert (key_table, (char *) "ldind.u2", GINT_TO_POINTER (TRUE));
2196         g_hash_table_insert (key_table, (char *) "ldind.u4", GINT_TO_POINTER (TRUE));
2197         g_hash_table_insert (key_table, (char *) "ldind.u8", GINT_TO_POINTER (TRUE));
2198         g_hash_table_insert (key_table, (char *) "ldlen", GINT_TO_POINTER (TRUE));
2199         g_hash_table_insert (key_table, (char *) "ldloc", GINT_TO_POINTER (TRUE));
2200         g_hash_table_insert (key_table, (char *) "ldloc.0", GINT_TO_POINTER (TRUE));
2201         g_hash_table_insert (key_table, (char *) "ldloc.1", GINT_TO_POINTER (TRUE));
2202         g_hash_table_insert (key_table, (char *) "ldloc.2", GINT_TO_POINTER (TRUE));
2203         g_hash_table_insert (key_table, (char *) "ldloc.3", GINT_TO_POINTER (TRUE));
2204         g_hash_table_insert (key_table, (char *) "ldloc.s", GINT_TO_POINTER (TRUE));
2205         g_hash_table_insert (key_table, (char *) "ldloca", GINT_TO_POINTER (TRUE));
2206         g_hash_table_insert (key_table, (char *) "ldloca.s", GINT_TO_POINTER (TRUE));
2207         g_hash_table_insert (key_table, (char *) "ldnull", GINT_TO_POINTER (TRUE));
2208         g_hash_table_insert (key_table, (char *) "ldobj", GINT_TO_POINTER (TRUE));
2209         g_hash_table_insert (key_table, (char *) "ldsfld", GINT_TO_POINTER (TRUE));
2210         g_hash_table_insert (key_table, (char *) "ldsflda", GINT_TO_POINTER (TRUE));
2211         g_hash_table_insert (key_table, (char *) "ldstr", GINT_TO_POINTER (TRUE));
2212         g_hash_table_insert (key_table, (char *) "ldtoken", GINT_TO_POINTER (TRUE));
2213         g_hash_table_insert (key_table, (char *) "ldvirtftn", GINT_TO_POINTER (TRUE));
2214         g_hash_table_insert (key_table, (char *) "leave", GINT_TO_POINTER (TRUE));
2215         g_hash_table_insert (key_table, (char *) "leave.s", GINT_TO_POINTER (TRUE));
2216         g_hash_table_insert (key_table, (char *) "linkcheck", GINT_TO_POINTER (TRUE));
2217         g_hash_table_insert (key_table, (char *) "literal", GINT_TO_POINTER (TRUE));
2218         g_hash_table_insert (key_table, (char *) "localloc", GINT_TO_POINTER (TRUE));
2219         g_hash_table_insert (key_table, (char *) "lpstr", GINT_TO_POINTER (TRUE));
2220         g_hash_table_insert (key_table, (char *) "lpstruct", GINT_TO_POINTER (TRUE));
2221         g_hash_table_insert (key_table, (char *) "lptstr", GINT_TO_POINTER (TRUE));
2222         g_hash_table_insert (key_table, (char *) "lpvoid", GINT_TO_POINTER (TRUE));
2223         g_hash_table_insert (key_table, (char *) "lpwstr", GINT_TO_POINTER (TRUE));
2224         g_hash_table_insert (key_table, (char *) "managed", GINT_TO_POINTER (TRUE));
2225         g_hash_table_insert (key_table, (char *) "marshal", GINT_TO_POINTER (TRUE));
2226         g_hash_table_insert (key_table, (char *) "method", GINT_TO_POINTER (TRUE));
2227         g_hash_table_insert (key_table, (char *) "mkrefany", GINT_TO_POINTER (TRUE));
2228         g_hash_table_insert (key_table, (char *) "modopt", GINT_TO_POINTER (TRUE));
2229         g_hash_table_insert (key_table, (char *) "modreq", GINT_TO_POINTER (TRUE));
2230         g_hash_table_insert (key_table, (char *) "mul", GINT_TO_POINTER (TRUE));
2231         g_hash_table_insert (key_table, (char *) "mul.ovf", GINT_TO_POINTER (TRUE));
2232         g_hash_table_insert (key_table, (char *) "mul.ovf.un", GINT_TO_POINTER (TRUE));
2233         g_hash_table_insert (key_table, (char *) "native", GINT_TO_POINTER (TRUE));
2234         g_hash_table_insert (key_table, (char *) "neg", GINT_TO_POINTER (TRUE));
2235         g_hash_table_insert (key_table, (char *) "nested", GINT_TO_POINTER (TRUE));
2236         g_hash_table_insert (key_table, (char *) "newarr", GINT_TO_POINTER (TRUE));
2237         g_hash_table_insert (key_table, (char *) "newobj", GINT_TO_POINTER (TRUE));
2238         g_hash_table_insert (key_table, (char *) "newslot", GINT_TO_POINTER (TRUE));
2239         g_hash_table_insert (key_table, (char *) "noappdomain", GINT_TO_POINTER (TRUE));
2240         g_hash_table_insert (key_table, (char *) "noinlining", GINT_TO_POINTER (TRUE));
2241         g_hash_table_insert (key_table, (char *) "nomachine", GINT_TO_POINTER (TRUE));
2242         g_hash_table_insert (key_table, (char *) "nomangle", GINT_TO_POINTER (TRUE));
2243         g_hash_table_insert (key_table, (char *) "nometadata", GINT_TO_POINTER (TRUE));
2244         g_hash_table_insert (key_table, (char *) "noncasdemand", GINT_TO_POINTER (TRUE));
2245         g_hash_table_insert (key_table, (char *) "noncasinheritance", GINT_TO_POINTER (TRUE));
2246         g_hash_table_insert (key_table, (char *) "noncaslinkdemand", GINT_TO_POINTER (TRUE));
2247         g_hash_table_insert (key_table, (char *) "nop", GINT_TO_POINTER (TRUE));
2248         g_hash_table_insert (key_table, (char *) "noprocess", GINT_TO_POINTER (TRUE));
2249         g_hash_table_insert (key_table, (char *) "not", GINT_TO_POINTER (TRUE));
2250         g_hash_table_insert (key_table, (char *) "not_in_gc_heap", GINT_TO_POINTER (TRUE));
2251         g_hash_table_insert (key_table, (char *) "notremotable", GINT_TO_POINTER (TRUE));
2252         g_hash_table_insert (key_table, (char *) "notserialized", GINT_TO_POINTER (TRUE));
2253         g_hash_table_insert (key_table, (char *) "null", GINT_TO_POINTER (TRUE));
2254         g_hash_table_insert (key_table, (char *) "nullref", GINT_TO_POINTER (TRUE));
2255         g_hash_table_insert (key_table, (char *) "object", GINT_TO_POINTER (TRUE));
2256         g_hash_table_insert (key_table, (char *) "objectref", GINT_TO_POINTER (TRUE));
2257         g_hash_table_insert (key_table, (char *) "opt", GINT_TO_POINTER (TRUE));
2258         g_hash_table_insert (key_table, (char *) "optil", GINT_TO_POINTER (TRUE));
2259         g_hash_table_insert (key_table, (char *) "or", GINT_TO_POINTER (TRUE));
2260         g_hash_table_insert (key_table, (char *) "out", GINT_TO_POINTER (TRUE));
2261         g_hash_table_insert (key_table, (char *) "permitonly", GINT_TO_POINTER (TRUE));
2262         g_hash_table_insert (key_table, (char *) "pinned", GINT_TO_POINTER (TRUE));
2263         g_hash_table_insert (key_table, (char *) "pinvokeimpl", GINT_TO_POINTER (TRUE));
2264         g_hash_table_insert (key_table, (char *) "pop", GINT_TO_POINTER (TRUE));
2265         g_hash_table_insert (key_table, (char *) "prefix1", GINT_TO_POINTER (TRUE));
2266         g_hash_table_insert (key_table, (char *) "prefix2", GINT_TO_POINTER (TRUE));
2267         g_hash_table_insert (key_table, (char *) "prefix3", GINT_TO_POINTER (TRUE));
2268         g_hash_table_insert (key_table, (char *) "prefix4", GINT_TO_POINTER (TRUE));
2269         g_hash_table_insert (key_table, (char *) "prefix5", GINT_TO_POINTER (TRUE));
2270         g_hash_table_insert (key_table, (char *) "prefix6", GINT_TO_POINTER (TRUE));
2271         g_hash_table_insert (key_table, (char *) "prefix7", GINT_TO_POINTER (TRUE));
2272         g_hash_table_insert (key_table, (char *) "prefixref", GINT_TO_POINTER (TRUE));
2273         g_hash_table_insert (key_table, (char *) "prejitdeny", GINT_TO_POINTER (TRUE));
2274         g_hash_table_insert (key_table, (char *) "prejitgrant", GINT_TO_POINTER (TRUE));
2275         g_hash_table_insert (key_table, (char *) "preservesig", GINT_TO_POINTER (TRUE));
2276         g_hash_table_insert (key_table, (char *) "private", GINT_TO_POINTER (TRUE));
2277         g_hash_table_insert (key_table, (char *) "Compilercontrolled", GINT_TO_POINTER (TRUE));
2278         g_hash_table_insert (key_table, (char *) "protected", GINT_TO_POINTER (TRUE));
2279         g_hash_table_insert (key_table, (char *) "public", GINT_TO_POINTER (TRUE));
2280         g_hash_table_insert (key_table, (char *) "readonly", GINT_TO_POINTER (TRUE));
2281         g_hash_table_insert (key_table, (char *) "record", GINT_TO_POINTER (TRUE));
2282         g_hash_table_insert (key_table, (char *) "refany", GINT_TO_POINTER (TRUE));
2283         g_hash_table_insert (key_table, (char *) "refanytype", GINT_TO_POINTER (TRUE));
2284         g_hash_table_insert (key_table, (char *) "refanyval", GINT_TO_POINTER (TRUE));
2285         g_hash_table_insert (key_table, (char *) "rem", GINT_TO_POINTER (TRUE));
2286         g_hash_table_insert (key_table, (char *) "rem.un", GINT_TO_POINTER (TRUE));
2287         g_hash_table_insert (key_table, (char *) "reqmin", GINT_TO_POINTER (TRUE));
2288         g_hash_table_insert (key_table, (char *) "reqopt", GINT_TO_POINTER (TRUE));
2289         g_hash_table_insert (key_table, (char *) "reqrefuse", GINT_TO_POINTER (TRUE));
2290         g_hash_table_insert (key_table, (char *) "reqsecobj", GINT_TO_POINTER (TRUE));
2291         g_hash_table_insert (key_table, (char *) "request", GINT_TO_POINTER (TRUE));
2292         g_hash_table_insert (key_table, (char *) "ret", GINT_TO_POINTER (TRUE));
2293         g_hash_table_insert (key_table, (char *) "rethrow", GINT_TO_POINTER (TRUE));
2294         g_hash_table_insert (key_table, (char *) "retval", GINT_TO_POINTER (TRUE));
2295         g_hash_table_insert (key_table, (char *) "rtspecialname", GINT_TO_POINTER (TRUE));
2296         g_hash_table_insert (key_table, (char *) "runtime", GINT_TO_POINTER (TRUE));
2297         g_hash_table_insert (key_table, (char *) "safearray", GINT_TO_POINTER (TRUE));
2298         g_hash_table_insert (key_table, (char *) "sealed", GINT_TO_POINTER (TRUE));
2299         g_hash_table_insert (key_table, (char *) "sequential", GINT_TO_POINTER (TRUE));
2300         g_hash_table_insert (key_table, (char *) "serializable", GINT_TO_POINTER (TRUE));
2301         g_hash_table_insert (key_table, (char *) "shl", GINT_TO_POINTER (TRUE));
2302         g_hash_table_insert (key_table, (char *) "shr", GINT_TO_POINTER (TRUE));
2303         g_hash_table_insert (key_table, (char *) "shr.un", GINT_TO_POINTER (TRUE));
2304         g_hash_table_insert (key_table, (char *) "sizeof", GINT_TO_POINTER (TRUE));
2305         g_hash_table_insert (key_table, (char *) "special", GINT_TO_POINTER (TRUE));
2306         g_hash_table_insert (key_table, (char *) "specialname", GINT_TO_POINTER (TRUE));
2307         g_hash_table_insert (key_table, (char *) "starg", GINT_TO_POINTER (TRUE));
2308         g_hash_table_insert (key_table, (char *) "starg.s", GINT_TO_POINTER (TRUE));
2309         g_hash_table_insert (key_table, (char *) "static", GINT_TO_POINTER (TRUE));
2310         g_hash_table_insert (key_table, (char *) "stdcall", GINT_TO_POINTER (TRUE));
2311         g_hash_table_insert (key_table, (char *) "stdcall", GINT_TO_POINTER (TRUE));
2312         g_hash_table_insert (key_table, (char *) "stelem.i", GINT_TO_POINTER (TRUE));
2313         g_hash_table_insert (key_table, (char *) "stelem.i1", GINT_TO_POINTER (TRUE));
2314         g_hash_table_insert (key_table, (char *) "stelem.i2", GINT_TO_POINTER (TRUE));
2315         g_hash_table_insert (key_table, (char *) "stelem.i4", GINT_TO_POINTER (TRUE));
2316         g_hash_table_insert (key_table, (char *) "stelem.i8", GINT_TO_POINTER (TRUE));
2317         g_hash_table_insert (key_table, (char *) "stelem.r4", GINT_TO_POINTER (TRUE));
2318         g_hash_table_insert (key_table, (char *) "stelem.r8", GINT_TO_POINTER (TRUE));
2319         g_hash_table_insert (key_table, (char *) "stelem.ref", GINT_TO_POINTER (TRUE));
2320         g_hash_table_insert (key_table, (char *) "stfld", GINT_TO_POINTER (TRUE));
2321         g_hash_table_insert (key_table, (char *) "stind.i", GINT_TO_POINTER (TRUE));
2322         g_hash_table_insert (key_table, (char *) "stind.i1", GINT_TO_POINTER (TRUE));
2323         g_hash_table_insert (key_table, (char *) "stind.i2", GINT_TO_POINTER (TRUE));
2324         g_hash_table_insert (key_table, (char *) "stind.i4", GINT_TO_POINTER (TRUE));
2325         g_hash_table_insert (key_table, (char *) "stind.i8", GINT_TO_POINTER (TRUE));
2326         g_hash_table_insert (key_table, (char *) "stind.r4", GINT_TO_POINTER (TRUE));
2327         g_hash_table_insert (key_table, (char *) "stind.r8", GINT_TO_POINTER (TRUE));
2328         g_hash_table_insert (key_table, (char *) "to", GINT_TO_POINTER (TRUE));
2329         g_hash_table_insert (key_table, (char *) "value", GINT_TO_POINTER (TRUE));
2330 }
2331
2332 guint32
2333 method_dor_to_token (guint32 idx) {
2334         switch (idx & MONO_METHODDEFORREF_MASK) {
2335         case MONO_METHODDEFORREF_METHODDEF:
2336                 return MONO_TOKEN_METHOD_DEF | (idx >> MONO_METHODDEFORREF_BITS);
2337         case MONO_METHODDEFORREF_METHODREF:
2338                 return MONO_TOKEN_MEMBER_REF | (idx >> MONO_METHODDEFORREF_BITS);
2339         }
2340         return -1;
2341 }
2342
2343 char *
2344 get_method_override (MonoImage *m, guint32 token)
2345 {
2346         MonoTableInfo *t = &m->tables [MONO_TABLE_METHODIMPL];
2347         int i;
2348
2349         for (i = 1; i <= t->rows; i++){
2350                 guint32 cols [MONO_METHODIMPL_SIZE];
2351                 guint32 decl, impl;
2352
2353                 mono_metadata_decode_row (t, i - 1, cols, MONO_METHODIMPL_SIZE);
2354
2355                 impl = method_dor_to_token (cols [MONO_METHODIMPL_BODY]);
2356                 decl = method_dor_to_token (cols [MONO_METHODIMPL_DECLARATION]);
2357
2358                 if (token == impl)
2359                         return get_method (m, decl);
2360         }
2361
2362         return NULL;
2363 }