X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fdis%2Fget.c;h=34f87b0c8ad7913118ebbb5fcdb0d55fe66ce618;hb=34df6ae34b64211d88dfae1aa2bedd91d9549b05;hp=1a3a90cd3bde60aea13107f0ce96cb6ee121d7f9;hpb=70b7a2985e1dc2755d79b26e1c116a8dcdc22039;p=mono.git diff --git a/mono/dis/get.c b/mono/dis/get.c old mode 100644 new mode 100755 index 1a3a90cd3bd..34f87b0c8ad --- a/mono/dis/get.c +++ b/mono/dis/get.c @@ -5,6 +5,7 @@ * Miguel de Icaza (miguel@ximian.com) * * (C) 2001 Ximian, Inc. + * Copyright 2012 Xamarin Inc */ #include #include @@ -125,12 +126,12 @@ stringify_array (guint32 rank, guint32 num_sizes, guint32 num_lo_bounds, gint32 if (i) g_string_append_c (res, ','); if (i < num_lo_bounds) - g_string_sprintfa (res, "%d...", lo_bounds [i]); + g_string_append_printf (res, "%d...", lo_bounds [i]); if (i < num_sizes) { if (i < num_lo_bounds) - g_string_sprintfa (res, "%d", lo_bounds [i] + sizes [i] - 1); + g_string_append_printf (res, "%d", lo_bounds [i] + sizes [i] - 1); else - g_string_sprintfa (res, "%d", sizes [i]); + g_string_append_printf (res, "%d", sizes [i]); } } @@ -511,8 +512,8 @@ dis_stringify_modifiers (MonoImage *m, int n, MonoCustomMod *mod) for (i = 0; i < n; ++i) { char *tok = dis_stringify_token (m, mod[i].token); if (i > 0) - g_string_sprintfa (s, " "); - g_string_sprintfa (s, " %s (%s)", mod[i].required ? "modreq": "modopt", tok); + g_string_append_printf (s, " "); + g_string_append_printf (s, " %s (%s)", mod[i].required ? "modreq": "modopt", tok); g_free (tok); } g_string_append_c (s, ' '); @@ -787,7 +788,8 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container) g_string_append_c (result, '<'); for (i = 0; i < container->type_argc; i++) { - MonoGenericParam *param = &container->type_params [i]; + MonoGenericParam *param = mono_generic_container_get_param (container, i); + MonoGenericParamInfo *param_info = mono_generic_param_info (param); MonoClass **constr; int first = 1; guint16 flags; @@ -796,13 +798,13 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container) if (i > 0) g_string_append (result, ","); - flags = param->flags & GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK; + flags = param_info->flags & GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK; if ((flags & GENERIC_PARAMETER_ATTRIBUTE_COVARIANT) == GENERIC_PARAMETER_ATTRIBUTE_COVARIANT) g_string_append (result, "+ "); if ((flags & GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT) == GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT) g_string_append (result, "- "); - flags = param->flags & GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK; + flags = param_info->flags & GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK; if ((flags & GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT) == GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT) g_string_append (result, "class "); if ((flags & GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT) == GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT) @@ -810,7 +812,7 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container) if ((flags & GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT) == GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT) g_string_append (result, ".ctor "); - for (constr = param->constraints; constr && *constr; constr++) { + for (constr = param_info->constraints; constr && *constr; constr++) { char *sig; if (first) { @@ -826,7 +828,7 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container) if (!first) g_string_append (result, ") "); - esname = get_escaped_name (param->name); + esname = get_escaped_name (mono_generic_param_info (param)->name); g_string_append (result, esname); g_free (esname); } @@ -877,8 +879,13 @@ dis_stringify_method_signature_full (MonoImage *m, MonoMethodSignature *method, if (methoddef_row) { mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row -1, cols, MONO_METHOD_SIZE); - if (fully_qualified) - type = get_typedef (m, mono_metadata_typedef_from_method (m, methoddef_row)); + if (fully_qualified) { + guint32 type_idx = mono_metadata_typedef_from_method (m, methoddef_row); + if (type_idx) + type = get_typedef (m, type_idx); + else + type = g_strdup (""); + } method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]); param_index = cols [MONO_METHOD_PARAMLIST]; if (!method) { @@ -926,13 +933,19 @@ dis_stringify_method_signature_full (MonoImage *m, MonoMethodSignature *method, const char *tp; MonoMarshalSpec *spec; tp = mono_metadata_get_marshal_info (m, param_index - 1, FALSE); - g_assert (tp); - spec = mono_metadata_parse_marshal_spec (m, tp); - - if (i) - marshal_info = dis_stringify_marshal_spec (spec); - else - ret_marshal_info = dis_stringify_marshal_spec (spec); + if (tp) { + spec = mono_metadata_parse_marshal_spec (m, tp); + + if (i) + marshal_info = dis_stringify_marshal_spec (spec); + else + ret_marshal_info = dis_stringify_marshal_spec (spec); + } else { + if (i) + marshal_info = g_strdup ("(missing)"); + else + ret_marshal_info = g_strdup ("(missing)"); + } } param_index ++; } else { @@ -961,11 +974,11 @@ dis_stringify_method_signature_full (MonoImage *m, MonoMethodSignature *method, if (method->hasthis) g_string_append (result_ret, "instance "); g_string_append (result_ret, map (method->call_convention, call_conv_type_map)); - g_string_sprintfa (result_ret, " %s%s ", retval, ret_marshal_info ? ret_marshal_info :""); + g_string_append_printf (result_ret, " %s%s ", retval, ret_marshal_info ? ret_marshal_info :""); g_free (ret_marshal_info); if (type) { char *estype = get_escaped_name (type); - g_string_sprintfa (result_ret, "%s::", estype); + g_string_append_printf (result_ret, "%s::", estype); g_free (estype); g_free (type); } @@ -1006,7 +1019,7 @@ dis_stringify_function_ptr (MonoImage *m, MonoMethodSignature *method) g_string_append (result, map (method->call_convention, call_conv_type_map)); retval = dis_stringify_param (m, method->ret); - g_string_sprintfa (result, " %s ", retval); + g_string_append_printf (result, " %s ", retval); g_free (retval); g_string_append (result, " *("); @@ -1185,15 +1198,15 @@ dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def) break; case MONO_TYPE_MVAR: if (is_def && !cant_print_generic_param_name (type->data.generic_param)) - bare = g_strdup_printf ("!!%s", get_escaped_name (type->data.generic_param->name)); + bare = g_strdup_printf ("!!%s", get_escaped_name (mono_generic_param_info (type->data.generic_param)->name)); else - bare = g_strdup_printf ("!!%d", type->data.generic_param->num); + bare = g_strdup_printf ("!!%d", mono_type_get_generic_param_num (type)); break; case MONO_TYPE_VAR: if (is_def && !cant_print_generic_param_name (type->data.generic_param)) - bare = g_strdup_printf ("!%s", get_escaped_name (type->data.generic_param->name)); + bare = g_strdup_printf ("!%s", get_escaped_name (mono_generic_param_info (type->data.generic_param)->name)); else - bare = g_strdup_printf ("!%d", type->data.generic_param->num); + bare = g_strdup_printf ("!%d", mono_type_get_generic_param_num (type)); break; case MONO_TYPE_GENERICINST: { GString *str = g_string_new (""); @@ -1264,7 +1277,11 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen 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, TRUE, FALSE); + char *temp; + if (klass) + temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE); + else + temp = g_strdup_printf ("", token); if (show_tokens) { *result = g_strdup_printf ("%s/*%08x*/", temp, token); @@ -1301,7 +1318,24 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen default: t = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, start, &ptr); - *result = dis_stringify_type (m, t, is_def); + if (t) { + *result = dis_stringify_type (m, t, is_def); + } else { + GString *err = g_string_new ("@!#$$#!@"); + if (container) + t = mono_metadata_parse_type_full (m, NULL, MONO_PARSE_TYPE, 0, start, &ptr); + if (t) { + char *name = dis_stringify_type (m, t, is_def); + g_warning ("Encountered a generic type inappropriate for its context"); + g_string_append (err, " // "); + g_string_append (err, name); + g_free (name); + } else { + g_warning ("Encountered an invalid type"); + } + *result = g_string_free (err, FALSE); + } + break; } @@ -1540,7 +1574,7 @@ get_escaped_name (const char *name) for (s = name; *s; s++) { if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' || - *s == '?' || *s == '.' || *s == 0 || *s == '!' || *s == '`') + *s == '?' || (*s == '.' && s != name) || *s == 0 || *s == '!' || *s == '`') continue; esc = str_escape (name, "'\\"); @@ -1589,7 +1623,15 @@ static dis_map_t field_flags_map [] = { { FIELD_ATTRIBUTE_SPECIAL_NAME, "specialname " }, { FIELD_ATTRIBUTE_PINVOKE_IMPL, "FIXME:pinvokeimpl " }, { FIELD_ATTRIBUTE_RT_SPECIAL_NAME, "rtspecialname " }, - /*{ FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL, "hasfieldmarshal " },*/ + + /* This is set when a MarshalAs attribute is seen. FIXME: round-trip? */ + { FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL, "" }, + + /* This seems to be set if LITERAL is set. FIXME: round-trip? */ + { FIELD_ATTRIBUTE_HAS_DEFAULT, "" }, + + /* This seems to be set on compiler-generated array initializer fields. FIXME: round-trip? */ + { FIELD_ATTRIBUTE_HAS_FIELD_RVA, "" }, { 0, NULL } }; @@ -1603,11 +1645,12 @@ field_flags (guint32 f) { char buffer [1024]; int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK; + int rest = f & ~access; buffer [0] = 0; strcat (buffer, map (access, field_access_map)); - strcat (buffer, flags (f, field_flags_map)); + strcat (buffer, flags (rest, field_flags_map)); return g_strdup (buffer); } @@ -1763,6 +1806,11 @@ get_field (MonoImage *m, guint32 token, MonoGenericContainer *container) * the TypeDef table. LAME! */ type_idx = mono_metadata_typedef_from_field (m, idx); + if (!type_idx) { + res = g_strdup_printf (" %s", sig); + g_free (sig); + return res; + } type = get_typedef (m, type_idx); estype = get_escaped_name (type); @@ -1860,7 +1908,7 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConta mh = mono_get_method_full (m, token, NULL, (MonoGenericContext *) container); if (mh) { if (mono_method_signature (mh)->is_inflated) - container = ((MonoMethodInflated *) mh)->declaring->generic_container; + container = mono_method_get_generic_container (((MonoMethodInflated *) mh)->declaring); esname = get_escaped_name (mh->name); sig = dis_stringify_type (m, &mh->klass->byval_arg, TRUE); if (show_tokens) @@ -1894,11 +1942,11 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConta if (mh) { int arity = 0; - if (mh->generic_container) - arity = mh->generic_container->type_argc; + if (mh->is_generic) + arity = mono_method_get_generic_container (mh)->type_argc; else - if (mh->is_inflated && ((MonoMethodInflated *)mh)->declaring->generic_container) - arity = ((MonoMethodInflated*) mh)->declaring->generic_container->type_argc; + if (mh->is_inflated && ((MonoMethodInflated *)mh)->declaring->is_generic) + arity = mono_method_get_generic_container (((MonoMethodInflated*) mh)->declaring)->type_argc; if (arity > 0) { char *str = g_strdup_printf ("%s <[%d]>", name, arity); @@ -2048,7 +2096,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, Mo mh = mono_get_method_full (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container); g_assert (mh); - container = mh->generic_container; + container = mono_method_get_generic_container (mh); if (!container) container = type_container; @@ -2259,10 +2307,10 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index) readr4 (ptr, &r); /* Crazy solaris systems doesn't have isnormal */ -#ifdef HAVE_FINITE - normal = finite (r); +#ifdef HAVE_ISFINITE + normal = isfinite (r); #else - normal = isnormal (r); + normal = !dis_isinf (r) && !dis_isnan (r); #endif if (!normal) { return g_strdup_printf ("float32(0x%08x)", read32 (ptr)); @@ -2279,8 +2327,8 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index) readr8 (ptr, &r); /* Crazy solaris systems doesn't have isnormal */ -#ifdef HAVE_FINITE - normal = finite (r); +#ifdef HAVE_ISFINITE + normal = isfinite (r); #else normal = isnormal (r); #endif @@ -2330,6 +2378,12 @@ get_token (MonoImage *m, guint32 token, MonoGenericContainer *container) result = g_strdup_printf ("field %s", temp); g_free (temp); return result; + case MONO_TOKEN_METHOD_DEF: + case MONO_TOKEN_METHOD_SPEC: + temp = get_method (m, token, container); + result = g_strdup_printf ("method %s", temp); + g_free (temp); + return result; case MONO_TOKEN_TYPE_DEF: temp = get_typedef (m, idx); result = get_escaped_name (temp); @@ -2497,7 +2551,7 @@ dis_get_custom_attrs (MonoImage *m, guint32 token) len = mono_metadata_decode_value (val, &val); attr = g_string_new (".custom "); dump = data_dump (val, len, "\t\t"); - g_string_sprintfa (attr, "%s = %s", method, dump); + g_string_append_printf (attr, "%s = %s", method, dump); g_free (dump); list = g_list_append (list, attr->str); g_string_free (attr, FALSE); @@ -2850,6 +2904,7 @@ init_key_table (void) g_hash_table_insert (key_table, (char *) "ldvirtftn", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "leave", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "leave.s", GINT_TO_POINTER (TRUE)); + g_hash_table_insert (key_table, (char *) "legacy", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "linkcheck", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "literal", GINT_TO_POINTER (TRUE)); g_hash_table_insert (key_table, (char *) "localloc", GINT_TO_POINTER (TRUE)); @@ -3077,12 +3132,12 @@ check_ambiguous_genparams (MonoGenericContainer *container) table = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; i < container->type_argc; i++) { - MonoGenericParam *param = &container->type_params [i]; + MonoGenericParam *param = mono_generic_container_get_param (container, i); - if ((p = g_hash_table_lookup (table, param->name))) + if ((p = g_hash_table_lookup (table, mono_generic_param_info (param)->name))) dup_list = g_slist_prepend (g_slist_prepend (dup_list, GUINT_TO_POINTER (i + 1)), p); else - g_hash_table_insert (table, (char*)param->name, GUINT_TO_POINTER (i + 1)); + g_hash_table_insert (table, (char*)mono_generic_param_info (param)->name, GUINT_TO_POINTER (i + 1)); } if (dup_list) { @@ -3091,8 +3146,8 @@ check_ambiguous_genparams (MonoGenericContainer *container) for (l = dup_list; l; l = l->next) { int param = GPOINTER_TO_UINT (l->data); g_hash_table_insert (mono_generic_params_with_ambiguous_names, - &container->type_params [param-1], - &container->type_params [param-1]); + mono_generic_container_get_param (container, param-1), + mono_generic_container_get_param (container, param-1)); } g_slist_free (dup_list); } @@ -3107,11 +3162,56 @@ check_ambiguous_genparams (MonoGenericContainer *container) static gboolean cant_print_generic_param_name (MonoGenericParam *gparam) { + MonoGenericContainer *container; g_assert (gparam); - check_ambiguous_genparams (gparam->owner); - return (!gparam->owner || (mono_generic_params_with_ambiguous_names && + container = mono_generic_param_owner (gparam); + check_ambiguous_genparams (container); + return (!container || (mono_generic_params_with_ambiguous_names && g_hash_table_lookup (mono_generic_params_with_ambiguous_names, gparam))); } +static dis_map_t method_impl_map [] = { + { METHOD_IMPL_ATTRIBUTE_IL, "cil " }, + { METHOD_IMPL_ATTRIBUTE_NATIVE, "native " }, + { METHOD_IMPL_ATTRIBUTE_OPTIL, "optil " }, + { METHOD_IMPL_ATTRIBUTE_RUNTIME, "runtime " }, + { 0, NULL } +}; + +static dis_map_t managed_type_map [] = { + { METHOD_IMPL_ATTRIBUTE_UNMANAGED, "unmanaged " }, + { METHOD_IMPL_ATTRIBUTE_MANAGED, "managed " }, + { 0, NULL } +}; + +static dis_map_t managed_impl_flags [] = { + { METHOD_IMPL_ATTRIBUTE_FORWARD_REF, "fwdref " }, + { METHOD_IMPL_ATTRIBUTE_PRESERVE_SIG, "preservesig " }, + { METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL, "internalcall " }, + { METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED, "synchronized " }, + { METHOD_IMPL_ATTRIBUTE_NOINLINING, "noinlining " }, + { METHOD_IMPL_ATTRIBUTE_NOOPTIMIZATION, "nooptimization " }, + { METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING, "agressive-inlining" }, + { 0, NULL } +}; + +char * +get_method_impl_flags (guint32 f) +{ + GString *str = g_string_new (""); + char *s; + int code_type = f & METHOD_IMPL_ATTRIBUTE_CODE_TYPE_MASK; + int managed_type = f & METHOD_IMPL_ATTRIBUTE_MANAGED_MASK; + int rest = f & ~(code_type | managed_type); + + g_string_append (str, map (code_type, method_impl_map)); + g_string_append (str, map (managed_type, managed_type_map)); + g_string_append (str, flags (rest, managed_impl_flags)); + + s = str->str; + g_string_free (str, FALSE); + return s; +} +