X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fdis%2Fget.c;h=c1a42a4e39d2fb84f384a5d766b9834685bdd74c;hb=6f43af2ae166ea2820dcb7560c1b8afe05d1864e;hp=43845cd6c1921cdcdc76d959157ad99560768a4d;hpb=dd866d68820e0f66046256bb5d3f84e3988a8be0;p=mono.git diff --git a/mono/dis/get.c b/mono/dis/get.c index 43845cd6c19..c1a42a4e39d 100644 --- a/mono/dis/get.c +++ b/mono/dis/get.c @@ -20,8 +20,11 @@ extern gboolean substitute_with_mscorlib_p; +static MonoGenericContext * +get_memberref_context (MonoImage *m, guint32 mrp_token, MonoGenericContext *context); + static char * -get_memberref_parent (MonoImage *m, guint32 mrp_token); +get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *context); GHashTable *key_table = NULL; gboolean show_method_tokens = FALSE; @@ -51,9 +54,9 @@ get_typedef (MonoImage *m, int idx) "%s%s%s/%s%s", ns, *ns?".":"", outer, mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]), tstring ? tstring : ""); - g_free (outer); + g_free (outer); g_free (tstring); - return result; + return result; } @@ -62,6 +65,7 @@ get_typedef (MonoImage *m, int idx) mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]), tstring ? tstring : ""); g_free (tstring); + return result; } @@ -165,7 +169,7 @@ get_array_shape (MonoImage *m, const char *ptr, char **result) * Returns the stringified representation of a TypeSpec signature (22.2.17) */ char * -get_typespec (MonoImage *m, guint32 idx) +get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *context) { guint32 cols [MONO_TYPESPEC_SIZE]; const char *ptr; @@ -175,8 +179,8 @@ get_typespec (MonoImage *m, guint32 idx) MonoType *type; - type = mono_type_create_from_typespec (m, idx); - + type = mono_type_create_from_typespec_full (m, context, idx); + mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPESPEC], idx-1, cols, MONO_TYPESPEC_SIZE); ptr = mono_metadata_blob_heap (m, cols [MONO_TYPESPEC_SIGNATURE]); len = mono_metadata_decode_value (ptr, &ptr); @@ -193,10 +197,11 @@ get_typespec (MonoImage *m, guint32 idx) if (*ptr == MONO_TYPE_VOID) g_string_append (res, "void"); else { - ptr = get_type (m, ptr, &s); + ptr = get_type (m, ptr, &s, context); if (s) g_string_append (res, s); } + g_string_append (res, "*"); break; case MONO_TYPE_FNPTR: @@ -207,7 +212,7 @@ get_typespec (MonoImage *m, guint32 idx) break; case MONO_TYPE_ARRAY: - ptr = get_type (m, ptr, &s); + ptr = get_type (m, ptr, &s, context); g_string_append (res, s); g_free (s); g_string_append_c (res, ' '); @@ -223,21 +228,14 @@ get_typespec (MonoImage *m, guint32 idx) g_string_append_c (res, ' '); g_free (s); } - ptr = get_type (m, ptr, &s); + ptr = get_type (m, ptr, &s, context); g_string_append (res, s); g_string_append (res, "[]"); g_free (s); break; - case MONO_TYPE_VAR: - case MONO_TYPE_MVAR: - ptr = get_type (m, ptr-1, &s); - g_string_append (res, s); - g_free (s); - break; - default: - s = dis_stringify_type (m, type); + s = dis_stringify_type (m, type, is_def); g_string_append (res, s); g_free (s); break; @@ -323,7 +321,7 @@ get_typeref (MonoImage *m, int idx) * at (dor_token >> 2) */ char * -get_typedef_or_ref (MonoImage *m, guint32 dor_token) +get_typedef_or_ref (MonoImage *m, guint32 dor_token, MonoGenericContext *context) { char *temp = NULL, *s = NULL; int table, idx; @@ -346,7 +344,7 @@ get_typedef_or_ref (MonoImage *m, guint32 dor_token) break; case 2: /* TypeSpec */ - s = get_typespec (m, idx); + s = get_typespec (m, idx, FALSE, context); break; default: @@ -396,7 +394,7 @@ get_encoded_typedef_or_ref (MonoImage *m, const char *ptr, char **result) token = mono_metadata_decode_value (ptr, &ptr); - *result = get_typedef_or_ref (m, token); + *result = get_typedef_or_ref (m, token, NULL); return ptr; } @@ -456,10 +454,10 @@ static dis_map_t element_type_map [] = { static dis_map_t call_conv_type_map [] = { { MONO_CALL_DEFAULT , "default" }, - { MONO_CALL_C , "c" }, - { MONO_CALL_STDCALL , "stdcall" }, - { MONO_CALL_THISCALL , "thiscall" }, - { MONO_CALL_FASTCALL , "fastcall" }, + { MONO_CALL_C , "unmanaged cdecl" }, + { MONO_CALL_STDCALL , "unmanaged stdcall" }, + { MONO_CALL_THISCALL , "unmanaged thiscall" }, + { MONO_CALL_FASTCALL , "unmanaged fastcall" }, { MONO_CALL_VARARG , "vararg" }, { 0, NULL } }; @@ -471,7 +469,7 @@ dis_stringify_token (MonoImage *m, guint32 token) switch (token >> 24) { case MONO_TABLE_TYPEDEF: return get_typedef (m, idx); case MONO_TABLE_TYPEREF: return get_typeref (m, idx); - case MONO_TABLE_TYPESPEC: return get_typespec (m, idx); + case MONO_TABLE_TYPESPEC: return get_typespec (m, idx, FALSE, NULL); default: break; } @@ -479,13 +477,13 @@ dis_stringify_token (MonoImage *m, guint32 token) } char* -dis_stringify_array (MonoImage *m, MonoArrayType *array) +dis_stringify_array (MonoImage *m, MonoArrayType *array, gboolean is_def) { char *type; GString *s = g_string_new(""); int i; - type = dis_stringify_type (m, &array->eklass->byval_arg); + type = dis_stringify_type (m, &array->eklass->byval_arg, is_def); g_string_append (s, type); g_free (type); g_string_append_c (s, '['); @@ -529,10 +527,14 @@ dis_stringify_param (MonoImage *m, MonoType *param) { char *t; char *result; - const char *out = param->attrs & 2 ? "[out] ": ""; - t = dis_stringify_type (m, param); - result = g_strconcat (out, t, NULL); + char *attribs; + const char *out = param->attrs & PARAM_ATTRIBUTE_OUT ? "[out]": ""; + const char *opt = param->attrs & PARAM_ATTRIBUTE_OPTIONAL ? "[opt]": ""; + attribs = g_strconcat(out, opt, NULL); + t = dis_stringify_type (m, param, TRUE); + result = g_strjoin(attribs[0] ? " ":"", attribs, t, NULL); g_free (t); + g_free (attribs); return result; } @@ -545,44 +547,67 @@ dis_stringify_param (MonoImage *m, MonoType *param) * Returns: Allocated stringified generic parameters */ char* -get_generic_param (MonoImage *m, int table_type, guint32 row) +get_generic_param (MonoImage *m, MonoGenericContainer *container) { - MonoTableInfo *t = &m->tables [MONO_TABLE_GENERICPARAM]; - GString *result = g_string_new (""); - char *retval; - guint32 cols [MONO_GENERICPARAM_SIZE]; - int i, own_tok, table, idx, found_count; + GString *result; + char *retval; + int i; - g_assert (table_type != MONO_TYPEORMETHOD_TYPE || table_type != MONO_TYPEORMETHOD_METHOD); - - found_count = 0; - for (i = 1; i <= t->rows; i++) { - mono_metadata_decode_row (t, i-1, cols, MONO_GENERICPARAM_SIZE); - own_tok = cols [MONO_GENERICPARAM_OWNER]; - table = own_tok & MONO_TYPEORMETHOD_MASK; - idx = own_tok >> MONO_TYPEORMETHOD_BITS; - - if (table != table_type || idx != row) - continue; - - if (found_count == 0) - g_string_append_printf (result, "<%s", - mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME])); - else - g_string_append_printf (result, ", %s", - mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME])); - found_count++; + if (!container) + return NULL; + + result = g_string_new (""); + + g_string_append_c (result, '<'); + for (i = 0; i < container->type_argc; i++) { + MonoGenericParam *param = &container->type_params [i]; + MonoClass **constr; + int first = 1; + guint16 flags; + char *esname; + + if (i > 0) + g_string_append (result, ","); + + flags = param->flags & GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK; + if (flags == GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT) + g_string_append (result, "class "); + else if (flags == GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT) + g_string_append (result, "valuetype "); + else if (flags == GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT) + g_string_append (result, ".ctor "); + + for (constr = param->constraints; constr && *constr; constr++) { + char *sig; + + if (first) { + g_string_append_c (result, '('); + first = 0; + } else + g_string_append (result, ", "); + sig = dis_stringify_object_with_class (m, *constr, TRUE, TRUE); + g_string_append (result, sig); + g_free (sig); + } + + if (!first) + g_string_append (result, ") "); + + esname = get_escaped_name (param->name); + g_string_append (result, esname); + g_free (esname); } - if (found_count) - g_string_append_c (result, '>'); + g_string_append_c (result, '>'); + retval = result->str; g_string_free (result, FALSE); return retval; } char* -dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row, gboolean fully_qualified) +dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row, + MonoGenericContext *context, gboolean fully_qualified) { guint32 cols [MONO_METHOD_SIZE]; guint32 pcols [MONO_PARAM_SIZE]; @@ -593,6 +618,7 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m char *type = NULL; char *gen_param = NULL; GString *result = g_string_new (""); + MonoGenericContainer *container = NULL; int i; g_assert (method || methoddef_row); @@ -605,11 +631,20 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m param_index = cols [MONO_METHOD_PARAMLIST]; if (!method) { const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]); + + container = mono_metadata_load_generic_params ( + m, MONO_TOKEN_METHOD_DEF | methoddef_row, context ? context->container : NULL); + if (container) + context = (MonoGenericContext *) container; + mono_metadata_decode_blob_size (sig, &sig); - method = mono_metadata_parse_method_signature (m, methoddef_row, sig, &sig); + method = mono_metadata_parse_method_signature_full (m, context, methoddef_row, sig, &sig); free_method = 1; - } - gen_param = get_generic_param (m, 1, methoddef_row); + } else if (context) + container = context->container; + + if (container && container->is_method) + gen_param = get_generic_param (m, container); } retval = dis_stringify_param (m, method->ret); @@ -694,37 +729,73 @@ dis_stringify_function_ptr (MonoImage *m, MonoMethodSignature *method) } static char * -dis_stringify_object_with_class (MonoImage *m, MonoClass *c) +get_escaped_class_name (MonoClass *c) +{ + char *result, *esname; + + esname = get_escaped_name (c->name); + + if (c->nested_in){ + char *part_a = get_escaped_class_name (c->nested_in); + + result = g_strdup_printf ("%s/%s", part_a, esname); + g_free (part_a); + } else if (*c->name_space) + result = g_strdup_printf ("%s.%s", c->name_space, esname); + else + result = g_strdup (esname); + + g_free (esname); + return result; +} + +char * +dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix, gboolean is_def) { /* FIXME: handle MONO_TYPE_OBJECT ... */ - const char *otype = c->byval_arg.type == MONO_TYPE_CLASS? "class" : "valuetype"; - char *assemblyref = NULL, *result, *esname; + const char *otype = c->byval_arg.type == MONO_TYPE_VALUETYPE ? "valuetype " : "class " ; + char *assemblyref = NULL, *result, *esname, *generic = NULL; + if (m != c->image) { if (c->image->assembly_name) { /* we cheat */ if (substitute_with_mscorlib_p && !strcmp ("corlib", c->image->assembly_name)) assemblyref = g_strdup_printf ("[%s]", "mscorlib"); - else - assemblyref = g_strdup_printf ("[%s]", c->image->assembly->aname.name); + else { + char *esc = get_escaped_name (c->image->assembly->aname.name); + + assemblyref = g_strdup_printf ("[%s]", esc); + g_free (esc); + } } else { assemblyref = g_strdup_printf ("[.module %s]", c->image->module_name); } } - if (c->nested_in) { - result = g_strdup_printf ("%s%s%s/%s", c->nested_in->name_space, - *c->nested_in->name_space?".":"", c->nested_in->name, - c->name); - } else { - result = g_strdup_printf ("%s%s%s", c->name_space, - *c->name_space?".":"", c->name); + esname = get_escaped_class_name (c); + + if (c->generic_class) { + MonoGenericClass *gclass = c->generic_class; + GString *str = g_string_new (""); + int i; + + for (i = 0; i < gclass->inst->type_argc; i++){ + char *t = dis_stringify_type (m, gclass->inst->type_argv [i], is_def); + + g_string_append (str, t); + if (i+1 != gclass->inst->type_argc) + g_string_append (str, ", "); + g_free (t); + } + generic = g_strdup_printf ("<%s>", str->str); + g_string_free (str, TRUE); } - - esname = get_escaped_name (result); - g_free (result); - result = g_strdup_printf ("%s %s%s", otype, assemblyref?assemblyref:"", esname); + + result = g_strdup_printf ("%s%s%s%s", prefix ? otype : "", assemblyref?assemblyref:"", + esname, generic?generic:""); + g_free (generic); g_free (assemblyref); g_free (esname); @@ -732,14 +803,14 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c) } static char * -dis_stringify_object (MonoImage *m, MonoType *type) +dis_stringify_object (MonoImage *m, MonoType *type, gboolean is_def) { MonoClass *c = mono_class_from_mono_type (type); - return dis_stringify_object_with_class (m, c); + return dis_stringify_object_with_class (m, c, TRUE, is_def); } char* -dis_stringify_type (MonoImage *m, MonoType *type) +dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def) { const char *pinned = "", *byref = ""; char *bare = NULL, *mods = NULL; @@ -771,7 +842,7 @@ dis_stringify_type (MonoImage *m, MonoType *type) case MONO_TYPE_VALUETYPE: case MONO_TYPE_CLASS: - bare = dis_stringify_object (m, type); + bare = dis_stringify_object (m, type, is_def); break; case MONO_TYPE_FNPTR: { char *child_type; @@ -782,7 +853,7 @@ dis_stringify_type (MonoImage *m, MonoType *type) } case MONO_TYPE_PTR: { char *child_type; - child_type = dis_stringify_type (m, type->data.type); + child_type = dis_stringify_type (m, type->data.type, is_def); bare = g_strdup_printf ("%s*", child_type); g_free (child_type); @@ -790,34 +861,43 @@ dis_stringify_type (MonoImage *m, MonoType *type) } case MONO_TYPE_SZARRAY: { char *child_type; - child_type = dis_stringify_type (m, &type->data.klass->byval_arg); + child_type = dis_stringify_type (m, &type->data.klass->byval_arg, is_def); bare = g_strdup_printf ("%s[]", child_type); g_free (child_type); break; } case MONO_TYPE_ARRAY: - bare = dis_stringify_array (m, type->data.array); + bare = dis_stringify_array (m, type->data.array, is_def); break; case MONO_TYPE_VOID: bare = g_strdup ("void"); break; case MONO_TYPE_MVAR: - bare = g_strdup_printf ("!!%d", type->data.generic_param->num); + if (is_def) { + g_assert (type->data.generic_param->name); + bare = g_strdup_printf ("!!%s", type->data.generic_param->name); + } else + bare = g_strdup_printf ("!!%d", type->data.generic_param->num); break; case MONO_TYPE_VAR: - bare = g_strdup_printf ("!%d", type->data.generic_param->num); + if (is_def) { + g_assert (type->data.generic_param->name); + bare = g_strdup_printf ("!%s", type->data.generic_param->name); + } else + bare = g_strdup_printf ("!%d", type->data.generic_param->num); break; case MONO_TYPE_GENERICINST: { GString *str = g_string_new (""); int i; - char *generic_type = dis_stringify_type (m, type->data.generic_inst->generic_type); + char *generic_type = dis_stringify_type ( + m, &type->data.generic_class->container_class->byval_arg, is_def); - for (i = 0; i < type->data.generic_inst->type_argc; i++){ - char *t = dis_stringify_type (m, type->data.generic_inst->type_argv [i]); + for (i = 0; i < type->data.generic_class->inst->type_argc; i++){ + char *t = dis_stringify_type (m, type->data.generic_class->inst->type_argv [i], is_def); g_string_append (str, t); - if (i+1 != type->data.generic_inst->type_argc) + if (i+1 != type->data.generic_class->inst->type_argc) g_string_append (str, ", "); g_free (t); } @@ -855,7 +935,7 @@ dis_stringify_type (MonoImage *m, MonoType *type) * Returns: the new ptr to continue decoding */ const char * -get_type (MonoImage *m, const char *ptr, char **result) +get_type (MonoImage *m, const char *ptr, char **result, MonoGenericContext *context) { const char *start = ptr; guint32 type; @@ -871,7 +951,7 @@ get_type (MonoImage *m, const char *ptr, char **result) case MONO_TYPE_CLASS: { guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr); MonoClass *klass = mono_class_get (m, token); - char *temp = dis_stringify_object_with_class (m, klass); + char *temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE); if (show_tokens) { *result = g_strdup_printf ("%s/*%08x*/", temp, token); @@ -886,7 +966,7 @@ get_type (MonoImage *m, const char *ptr, char **result) int count, i; char *temp; - ptr = get_type (m, ptr, &temp); + ptr = get_type (m, ptr, &temp, context); g_string_append (str, temp); g_free (temp); @@ -896,7 +976,7 @@ get_type (MonoImage *m, const char *ptr, char **result) for (i = 0; i < count; i++) { if (i) g_string_append (str, ","); - ptr = get_type (m, ptr, &temp); + ptr = get_type (m, ptr, &temp, context); g_string_append (str, temp); } @@ -907,8 +987,8 @@ get_type (MonoImage *m, const char *ptr, char **result) } default: - t = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, start, &ptr); - *result = dis_stringify_type (m, t); + t = mono_metadata_parse_type_full (m, context, MONO_PARSE_TYPE, 0, start, &ptr); + *result = dis_stringify_type (m, t, FALSE); mono_metadata_free_type (t); break; } @@ -921,7 +1001,7 @@ get_type (MonoImage *m, const char *ptr, char **result) * Returns a stringified representation of a FieldSig (22.2.4) */ char * -get_field_signature (MonoImage *m, guint32 blob_signature) +get_field_signature (MonoImage *m, guint32 blob_signature, MonoGenericContext *context) { char *allocated_modifier_string, *allocated_type_string; const char *ptr = mono_metadata_blob_heap (m, blob_signature); @@ -937,7 +1017,7 @@ get_field_signature (MonoImage *m, guint32 blob_signature) ptr++; len--; ptr = get_custom_mod (m, ptr, &allocated_modifier_string); - ptr = get_type (m, ptr, &allocated_type_string); + ptr = get_type (m, ptr, &allocated_type_string, context); res = g_strdup_printf ( "%s %s", @@ -997,7 +1077,7 @@ decode_literal (MonoImage *m, guint32 token) * Returns: the new ptr to continue decoding. */ const char * -get_ret_type (MonoImage *m, const char *ptr, char **ret_type) +get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContext *context) { GString *str = g_string_new (""); char *mod = NULL; @@ -1022,7 +1102,7 @@ get_ret_type (MonoImage *m, const char *ptr, char **ret_type) ptr++; } - ptr = get_type (m, ptr, &allocated_type_string); + ptr = get_type (m, ptr, &allocated_type_string, context); g_string_append (str, allocated_type_string); g_free (allocated_type_string); } @@ -1044,7 +1124,7 @@ get_ret_type (MonoImage *m, const char *ptr, char **ret_type) * Returns: the new ptr to continue decoding. */ const char * -get_param (MonoImage *m, const char *ptr, char **retval) +get_param (MonoImage *m, const char *ptr, char **retval, MonoGenericContext *context) { GString *str = g_string_new (""); char *allocated_mod_string, *allocated_type_string; @@ -1061,12 +1141,12 @@ get_param (MonoImage *m, const char *ptr, char **retval) ptr++; } else { gboolean by_ref = 0; - if (*ptr == MONO_TYPE_BYREF){ + if (*ptr == MONO_TYPE_BYREF){ g_string_append (str, "[out] "); ptr++; by_ref = 1; } - ptr = get_type (m, ptr, &allocated_type_string); + ptr = get_type (m, ptr, &allocated_type_string, context); g_string_append (str, allocated_type_string); if (by_ref) g_string_append_c (str, '&'); @@ -1095,8 +1175,23 @@ get_escaped_name (const char *name) return g_strdup (name); for (s = name; *s; s++) { - if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' || *s == '?' || *s == '.' || *s == 0) + char *first, *result; + + if (*s != '/') continue; + + first = g_strndup (name, s-name); + result = g_strdup_printf ("%s/%s", get_escaped_name (first), get_escaped_name (s+1)); + g_free (first); + + return result; + } + + for (s = name; *s; s++) { + if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' || + *s == '?' || *s == '.' || *s == 0 || *s == '!') + continue; + return g_strdup_printf ("'%s'", name); } @@ -1122,7 +1217,7 @@ param_flags (guint32 f) } static dis_map_t field_access_map [] = { - { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " }, + { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "privatescope " }, { FIELD_ATTRIBUTE_PRIVATE, "private " }, { FIELD_ATTRIBUTE_FAM_AND_ASSEM, "famandassem " }, { FIELD_ATTRIBUTE_ASSEMBLY, "assembly " }, @@ -1166,22 +1261,19 @@ field_flags (guint32 f) * Returns a stringifed representation of a MethodRefSig (22.2.2) */ char * -get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy_name) +get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy_name, + MonoGenericContext *context) { GString *res = g_string_new (""); const char *ptr = mono_metadata_blob_heap (m, blob_signature); char *allocated_ret_type, *s; - gboolean has_vararg = 0, seen_vararg = 0; + const char *cconv_str; + gboolean seen_vararg = 0; int param_count, signature_len; int i, gen_count = 0; int cconv; - - signature_len = mono_metadata_decode_value (ptr, &ptr); - if (*ptr & 0x05){ - g_string_append (res, "vararg "); - has_vararg = 1; - } + signature_len = mono_metadata_decode_value (ptr, &ptr); if (*ptr & 0x20){ if (*ptr & 0x40) @@ -1193,12 +1285,18 @@ get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy if (*ptr & 0x10) gen_count = 1; cconv = *ptr & 0x0f; + cconv_str = map (cconv, call_conv_type_map); + if (strcmp (cconv_str, "default") != 0) { + g_string_append (res, cconv_str); + g_string_append (res, " "); + } + ptr++; if (gen_count) gen_count = mono_metadata_decode_value (ptr, &ptr); param_count = mono_metadata_decode_value (ptr, &ptr); if (cconv != 0xa) { - ptr = get_ret_type (m, ptr, &allocated_ret_type); + ptr = get_ret_type (m, ptr, &allocated_ret_type, context); g_string_append (res, allocated_ret_type); g_free (allocated_ret_type); } @@ -1229,7 +1327,7 @@ get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy ptr++; } - ptr = get_param (m, ptr, ¶m); + ptr = get_param (m, ptr, ¶m, context); g_string_append (res, param); if (i+1 != param_count) g_string_append (res, ", "); @@ -1249,20 +1347,27 @@ get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy * Returns a stringifed representation of a field ref */ char * -get_fieldref_signature (MonoImage *m, int idx) +get_fieldref_signature (MonoImage *m, int idx, MonoGenericContext *context) { - guint32 cols [MONO_MEMBERREF_SIZE]; + guint32 cols [MONO_MEMBERREF_SIZE]; + MonoGenericContext *new_context; + char *type, *esname; char *sig; - char *full_sig; + char *full_sig; mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF], - idx - 1, cols, MONO_MEMBERREF_SIZE); + idx - 1, cols, MONO_MEMBERREF_SIZE); - sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE]); - full_sig = g_strdup_printf ("%s %s::%s", sig, - get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS]), - mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME])); + new_context = get_memberref_context (m, cols [MONO_MEMBERREF_CLASS], context); + sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE], new_context); + + type = get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS], context); + esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME])); + + full_sig = g_strdup_printf ("%s %s::%s", sig, type, esname); g_free (sig); + g_free (type); + g_free (esname); return full_sig; } @@ -1277,7 +1382,7 @@ get_fieldref_signature (MonoImage *m, int idx) * the TypeDef table and locate the actual "owner" of the field */ char * -get_field (MonoImage *m, guint32 token) +get_field (MonoImage *m, guint32 token, MonoGenericContext *context) { int idx = mono_metadata_token_index (token); guint32 cols [MONO_FIELD_SIZE]; @@ -1289,12 +1394,12 @@ get_field (MonoImage *m, guint32 token) * defined in another module/assembly, just like in get_method () */ if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) { - return get_fieldref_signature (m, idx); + return get_fieldref_signature (m, idx, context); } g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF); mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE); - sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]); + sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], context); /* * To locate the actual "container" for this field, we have to scan @@ -1316,8 +1421,36 @@ get_field (MonoImage *m, guint32 token) return res; } +static MonoGenericContext * +get_memberref_context (MonoImage *m, guint32 mrp_token, MonoGenericContext *context) +{ + MonoClass *klass; + + /* + * mrp_index is a MemberRefParent coded index + */ + guint32 table = mrp_token & 7; + guint32 idx = mrp_token >> 3; + + switch (table){ + case 0: /* TypeDef */ + return (MonoGenericContext *) mono_metadata_load_generic_params ( + m, MONO_TOKEN_TYPE_DEF | idx, NULL); + + case 1: /* TypeRef */ + return NULL; + + case 4: /* TypeSpec */ + klass = mono_class_get_full (m, MONO_TOKEN_TYPE_SPEC | idx, context); + g_assert (klass); + return klass->generic_class ? klass->generic_class->context : NULL; + } + g_assert_not_reached (); + return NULL; +} + static char * -get_memberref_parent (MonoImage *m, guint32 mrp_token) +get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *context) { /* * mrp_index is a MemberRefParent coded index @@ -1339,7 +1472,7 @@ get_memberref_parent (MonoImage *m, guint32 mrp_token) return g_strdup ("TODO:MethodDef"); case 4: /* TypeSpec */ - return get_typespec (m, idx); + return get_typespec (m, idx, FALSE, context); } g_assert_not_reached (); return NULL; @@ -1355,19 +1488,21 @@ get_memberref_parent (MonoImage *m, guint32 mrp_token) * the TypeDef table and locate the actual "owner" of the field */ char * -get_method (MonoImage *m, guint32 token) +get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContext *context) { int idx = mono_metadata_token_index (token); guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE]; - char *sig, *esname; - const char *name; + char *sig = NULL, *esname; + char *name; MonoMethod *mh; - mh = mono_get_method (m, token, NULL); + mh = mono_get_method_full (m, token, NULL, context); if (mh) { + if (mh->signature->is_inflated) + context = ((MonoMethodInflated *) mh)->context; esname = get_escaped_name (mh->name); - sig = dis_stringify_object_with_class (m, mh->klass); + sig = dis_stringify_object_with_class (m, mh->klass, TRUE, TRUE); if (show_tokens) name = g_strdup_printf ("%s/*%08x*/::%s", sig, token, esname); else @@ -1382,7 +1517,7 @@ get_method (MonoImage *m, guint32 token) mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], idx - 1, method_cols, MONO_METHOD_SIZE); - sig = get_methodref_signature (m, method_cols [MONO_METHOD_SIGNATURE], name); + sig = get_methodref_signature (m, method_cols [MONO_METHOD_SIGNATURE], name, context); break; case MONO_TOKEN_MEMBER_REF: { @@ -1390,17 +1525,17 @@ get_method (MonoImage *m, guint32 token) idx - 1, member_cols, MONO_MEMBERREF_SIZE); if (!name) name = g_strdup_printf ("%s::%s", - get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS]), - mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME])); + get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS], context), + mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME])); sig = get_methodref_signature ( - m, member_cols [MONO_MEMBERREF_SIGNATURE], name); + m, member_cols [MONO_MEMBERREF_SIGNATURE], name, context); break; } case MONO_TOKEN_METHOD_SPEC: { mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC], idx - 1, member_cols, MONO_METHODSPEC_SIZE); token = member_cols [MONO_METHODSPEC_METHOD]; - sig = get_methodspec (m, idx, token, name); + sig = get_methodspec (m, idx, token, name, context); break; } @@ -1408,6 +1543,13 @@ get_method (MonoImage *m, guint32 token) g_assert_not_reached (); } + if (fullsig) + g_free (name); + else { + g_free (sig); + return name; + } + if (show_tokens) { char *retval = g_strdup_printf ("%s /* %08x */", sig, token); g_free (sig); @@ -1416,6 +1558,12 @@ get_method (MonoImage *m, guint32 token) return sig; } +char * +get_method (MonoImage *m, guint32 token, MonoGenericContext *context) +{ + return get_method_core (m, token, TRUE, context); +} + /** * get_methoddef * @m: metadata context @@ -1434,20 +1582,20 @@ get_methoddef (MonoImage *m, guint32 idx) mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL); if (mh) { - sig = dis_stringify_object_with_class (m, mh->klass); + sig = dis_stringify_object_with_class (m, mh->klass, TRUE, FALSE); name = g_strdup_printf ("%s::%s", sig, mh->name); g_free (sig); } else name = NULL; mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], idx - 1, cols, MONO_METHOD_SIZE); - sig = get_methodref_signature (m, cols [MONO_METHOD_SIGNATURE], name); + sig = get_methodref_signature (m, cols [MONO_METHOD_SIGNATURE], name, NULL); return sig; } char * -get_method_type_param (MonoImage *m, guint32 blob_signature) +get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContext *context) { GString *res = g_string_new (""); const char *ptr = mono_metadata_blob_heap (m, blob_signature); @@ -1463,8 +1611,8 @@ get_method_type_param (MonoImage *m, guint32 blob_signature) for (i = 0; i < param_count; i++){ char *param = NULL; - - ptr = get_param (m, ptr, ¶m); + + ptr = get_param (m, ptr, ¶m, context); g_string_append (res, param); if (i+1 != param_count) g_string_append (res, ", "); @@ -1484,13 +1632,13 @@ get_method_type_param (MonoImage *m, guint32 blob_signature) */ char * -get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name) +get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, MonoGenericContext *context) { GString *res = g_string_new (""); guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE]; char *s, *type_param; const char *ptr; - guint32 sig; + guint32 sig = 0; int param_count, cconv, i, gen_count = 0; switch (token & MONO_METHODDEFORREF_MASK) { @@ -1529,7 +1677,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name) param_count = mono_metadata_decode_value (ptr, &ptr); if (cconv != 0xa) { char *allocated_ret_type; - ptr = get_ret_type (m, ptr, &allocated_ret_type); + ptr = get_ret_type (m, ptr, &allocated_ret_type, context); g_string_append (res, allocated_ret_type); g_free (allocated_ret_type); } @@ -1542,7 +1690,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name) mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC], idx - 1, member_cols, MONO_METHODSPEC_SIZE); token = member_cols [MONO_METHODSPEC_SIGNATURE]; - type_param = get_method_type_param (m, token); + type_param = get_method_type_param (m, token, context); g_string_append (res, type_param); g_string_append (res, " ("); @@ -1553,7 +1701,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name) for (i = 0; i < param_count; i++){ char *param = NULL; - ptr = get_param (m, ptr, ¶m); + ptr = get_param (m, ptr, ¶m, context); g_string_append (res, param); if (i+1 != param_count) g_string_append (res, ", "); @@ -1581,17 +1729,17 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name) char * get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index) { - const char *ptr = mono_metadata_blob_heap (m, blob_index); + const unsigned char *ptr = mono_metadata_blob_heap (m, blob_index); int len; - len = mono_metadata_decode_value (ptr, &ptr); + len = mono_metadata_decode_value (ptr, (const char**)&ptr); switch (t){ case MONO_TYPE_BOOLEAN: return g_strdup_printf ("%s", *ptr ? "bool(true)" : "bool(false)"); case MONO_TYPE_CHAR: - return g_strdup_printf ("%c", *ptr); /* FIXME: unicode char */ + return g_strdup_printf ("char(0x%04x)", read16(ptr)); case MONO_TYPE_U1: case MONO_TYPE_I1: @@ -1610,7 +1758,7 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index) guint32 low, high; low = read32 (ptr); high = read32 (ptr + 4); - return g_strdup_printf ("0x%08x%08x", high, low); + return g_strdup_printf ("int64(0x%08x%08x)", high, low); } case MONO_TYPE_U8: { guint32 low, high; @@ -1621,54 +1769,51 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index) case MONO_TYPE_R4: { float r; readr4 (ptr, &r); - return g_strdup_printf ("%g", (double) r); + return g_strdup_printf ("float32(%g)", (double) r); } case MONO_TYPE_R8: { double r; readr8 (ptr, &r); - return g_strdup_printf ("%g", r); + return g_strdup_printf ("float64(%g)", r); } case MONO_TYPE_STRING: { - int i, j, e; - char *res; - e = len = 0; - for (i = 0; !ptr [i+1]; i += 2){ - len++; - switch (ptr [i]) { - case '"': - case '\\': - case '\n': /* add more */ - e++; + gchar *str; + int i, j, tspaces = (len%16); + GString *res = g_string_new ("bytearray (\n\t"); + + for(i = 1; i <= len; ++i) { + g_string_append_printf(res, "%02x ", ptr[i-1]); + + if(i%16 == 0) { + if(i == len) + g_string_append(res, ")// "); + else + g_string_append(res, " // "); + + for(j = i-16; j < i; ++j) + g_string_append_printf(res, "%c", isprint(ptr[j]) ? ptr[j] : '.'); + g_string_append(res, "\n\t"); } } - res = g_malloc (len + e + 3); - j = 1; - res [0] = '"'; - - for (i = 0; i < len; i += 2){ - switch(ptr[i]) { - case '"': - res[j++] = '\\'; - res[j++] = '"'; - case '\\': - res[j++] = '\\'; - res[j++] = '\\'; - case '\n': - res[j++] = '\\'; - res[j++] = 'n'; - break; - default: - res[j++] = isprint (ptr [i]) ? ptr [i] : '.'; - break; - } - } - res[j++] = '"'; - res[j] = 0; - return res; + + if(tspaces) { + g_string_append(res, ") "); + for(i = tspaces+1; i < 16; ++i) + g_string_append_printf(res, " "); + + g_string_append(res, " // "); + for(i = len-tspaces; i < len; ++i) + g_string_append_printf(res, "%c", isprint(ptr[i]) ? ptr[i] : '.'); + g_string_append(res, "\n\t"); + } + + str = res->str; + g_string_free(res, FALSE); + return str; } case MONO_TYPE_CLASS: - return g_strdup ("CLASS CONSTANT. MUST BE ZERO"); + return g_strdup ("nullref"); default: g_error ("Unknown MONO_TYPE (%d) on constant at Blob index (0x%08x)\n", @@ -1687,23 +1832,43 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index) * constant. */ char * -get_token (MonoImage *m, guint32 token) +get_token (MonoImage *m, guint32 token, MonoGenericContext *context) { char *temp, *result; guint32 idx = mono_metadata_token_index (token); switch (mono_metadata_token_code (token)){ case MONO_TOKEN_FIELD_DEF: - temp = get_field (m, token); + temp = get_field (m, token, context); result = g_strdup_printf ("field %s", temp); g_free (temp); return result; case MONO_TOKEN_TYPE_DEF: - return get_typedef (m, idx); + temp = get_typedef (m, idx); + result = get_escaped_name (temp); + g_free (temp); + return result; case MONO_TOKEN_TYPE_REF: return get_typeref (m, idx); case MONO_TOKEN_TYPE_SPEC: - return get_typespec (m, idx); + return get_typespec (m, idx, TRUE, context); + case MONO_TOKEN_MEMBER_REF: { + guint32 cols [MONO_MEMBERREF_SIZE]; + const char *sig; + mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE); + sig = mono_metadata_blob_heap (m, cols [MONO_MEMBERREF_SIGNATURE]); + mono_metadata_decode_blob_size (sig, &sig); + if (*sig == 0x6) { /* it's a field */ + temp = get_field (m, token, context); + result = g_strdup_printf ("field %s", temp); + g_free (temp); + return result; + } + else { + g_error ("Do not know how to decode tokens of type 0x%08x", token); + } + break; + } default: g_error ("Do not know how to decode tokens of type 0x%08x", token); } @@ -1722,7 +1887,7 @@ get_token (MonoImage *m, guint32 token) * at (token & 0xffffff) */ char * -get_token_type (MonoImage *m, guint32 token) +get_token_type (MonoImage *m, guint32 token, MonoGenericContext *context) { char *temp = NULL, *s = NULL; int idx; @@ -1741,7 +1906,7 @@ get_token_type (MonoImage *m, guint32 token) break; case MONO_TOKEN_TYPE_SPEC: - s = get_typespec (m, idx); + s = get_typespec (m, idx, FALSE, context); break; default: @@ -1832,7 +1997,7 @@ dis_get_custom_attrs (MonoImage *m, guint32 token) g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]); break; } - method = get_method (m, mtoken); + method = get_method (m, mtoken, NULL); val = mono_metadata_blob_heap (m, cols [MONO_CUSTOM_ATTR_VALUE]); len = mono_metadata_decode_value (val, &val); attr = g_string_new (".custom "); @@ -1935,7 +2100,7 @@ init_key_table (void) { key_table = g_hash_table_new (g_str_hash, g_str_equal); - /* auto generated */ + g_hash_table_insert (key_table, (char *) "9", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "abstract", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "add", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "add.ovf", GINT_TO_POINTER (TRUE)); @@ -1951,8 +2116,8 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "assembly", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "assert", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "at", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "auto", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "autochar", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "auto", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "beforefieldinit", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "beq", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "beq.s", GINT_TO_POINTER (TRUE)); @@ -1963,7 +2128,6 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "bgt", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "bgt.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "bgt.un", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "9", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "bgt.un.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ble", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ble.s", GINT_TO_POINTER (TRUE)); @@ -1979,15 +2143,15 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "bne.un.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "bool", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "box", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "br", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "br.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "break", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brfalse", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brfalse.s", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "br", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brinst", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brinst.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brnull", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brnull.s", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "br.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brtrue", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brtrue.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "brzero", GINT_TO_POINTER (TRUE)); @@ -2014,14 +2178,13 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "clsid", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "clt", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "clt.un", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "Compilercontrolled", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "const", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "conv.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.i1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.i2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.i4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.i8", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "conv.ovf.i", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "conv.ovf.i.un", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "conv.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.i1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.i1.un", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.i2", GINT_TO_POINTER (TRUE)); @@ -2030,8 +2193,8 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "conv.ovf.i4.un", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.i8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.i8.un", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "conv.ovf.u", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "conv.ovf.u.un", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "conv.ovf.i", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "conv.ovf.i.un", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.u1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.u1.un", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.u2", GINT_TO_POINTER (TRUE)); @@ -2040,14 +2203,16 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "conv.ovf.u4.un", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.u8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.ovf.u8.un", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "conv.r.un", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "conv.ovf.u", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "conv.ovf.u.un", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.r4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.r8", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "conv.u", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "conv.r.un", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.u1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.u2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.u4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "conv.u8", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "conv.u", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "cpblk", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "cpobj", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "currency", GINT_TO_POINTER (TRUE)); @@ -2055,7 +2220,6 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "date", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "decimal", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "default", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "default", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "demand", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "deny", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "div", GINT_TO_POINTER (TRUE)); @@ -2075,7 +2239,6 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "family", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "famorassem", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "fastcall", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "fastcall", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "fault", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "field", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "filetime", GINT_TO_POINTER (TRUE)); @@ -2083,9 +2246,9 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "final", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "finally", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "fixed", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "float", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "float32", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "float64", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "float", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "forwardref", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "fromunmanaged", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "handler", GINT_TO_POINTER (TRUE)); @@ -2100,32 +2263,31 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "import", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "in", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "inheritcheck", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "init", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "initblk", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "init", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "initobj", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "initonly", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "instance", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "int", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "int16", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "int32", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "int64", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "int8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "interface", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "internalcall", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "int", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "isinst", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "iunknown", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "jmp", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "lasterr", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "lcid", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldarg", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldarg.0", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldarg.1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldarg.2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldarg.3", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldarg.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldarga", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldarga.s", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldc.i4", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldarg", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldarg.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i4.0", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i4.1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i4.2", GINT_TO_POINTER (TRUE)); @@ -2135,17 +2297,19 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "ldc.i4.6", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i4.7", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i4.8", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldc.i4.M1", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldc.i4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i4.m1", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldc.i4.M1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i4.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.i8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.r4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldc.r8", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldelem.i", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldelema", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.i1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.i2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.i4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.i8", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldelem.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.r4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.r8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.ref", GINT_TO_POINTER (TRUE)); @@ -2153,15 +2317,14 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "ldelem.u2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.u4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldelem.u8", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldelema", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldfld", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldflda", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldfld", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldftn", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldind.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.i1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.i2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.i4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.i8", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldind.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.r4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.r8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.ref", GINT_TO_POINTER (TRUE)); @@ -2170,18 +2333,18 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "ldind.u4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldind.u8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldlen", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldloc", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldloc.0", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldloc.1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldloc.2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldloc.3", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldloc.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldloca", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldloca.s", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldloc", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldloc.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldnull", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldobj", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "ldsfld", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldsflda", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "ldsfld", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldstr", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldtoken", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "ldvirtftn", GINT_TO_POINTER (TRUE)); @@ -2248,7 +2411,7 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "prejitgrant", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "preservesig", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "private", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "Compilercontrolled", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "privatescope", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "protected", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "public", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "readonly", GINT_TO_POINTER (TRUE)); @@ -2282,23 +2445,85 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "starg.s", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "static", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stdcall", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "stdcall", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "stelem.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stelem.i1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stelem.i2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stelem.i4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stelem.i8", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "stelem.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stelem.r4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stelem.r8", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stelem.ref", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stfld", GINT_TO_POINTER (TRUE)); - g_hash_table_insert (key_table, (char *) "stind.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stind.i1", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stind.i2", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stind.i4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stind.i8", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "stind.i", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stind.r4", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "stind.r8", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "storage", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "stored_object", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "streamed_object", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "stream", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "strict", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "string", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "struct", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "synchronized", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "syschar", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "sysstring", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "tbstr", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "thiscall", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "tls", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "to", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "true", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "type", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "typedref", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "unicode", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "unmanagedexp", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "unmanaged", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "unsigned", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "userdefined", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "value", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "valuetype", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "vararg", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "variant", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "vector", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "virtual", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "void", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "wchar", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "winapi", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "with", GINT_TO_POINTER (TRUE)); +} + +guint32 +method_dor_to_token (guint32 idx) { + switch (idx & MONO_METHODDEFORREF_MASK) { + case MONO_METHODDEFORREF_METHODDEF: + return MONO_TOKEN_METHOD_DEF | (idx >> MONO_METHODDEFORREF_BITS); + case MONO_METHODDEFORREF_METHODREF: + return MONO_TOKEN_MEMBER_REF | (idx >> MONO_METHODDEFORREF_BITS); + } + return -1; +} + +char * +get_method_override (MonoImage *m, guint32 token, MonoGenericContext *context) +{ + MonoTableInfo *t = &m->tables [MONO_TABLE_METHODIMPL]; + int i; + + for (i = 1; i <= t->rows; i++){ + guint32 cols [MONO_METHODIMPL_SIZE]; + guint32 decl, impl; + + mono_metadata_decode_row (t, i - 1, cols, MONO_METHODIMPL_SIZE); + + impl = method_dor_to_token (cols [MONO_METHODIMPL_BODY]); + decl = method_dor_to_token (cols [MONO_METHODIMPL_DECLARATION]); + + if (token == impl) + return get_method_core (m, decl, FALSE, context); + } + + return NULL; }