Merge pull request #3591 from directhex/mono_libdir_fallback
[mono.git] / mono / dis / get.c
index c034e8fc71bd09996e397f8bce965ffeeecf054d..f3724e4384debca76a5eae810a91e4dc8333e278 100755 (executable)
@@ -6,6 +6,7 @@
  *
  * (C) 2001 Ximian, Inc.
  * Copyright 2012 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
 #include <stdio.h>
@@ -20,6 +21,7 @@
 #include <mono/utils/mono-compiler.h>
 #include <mono/metadata/class.h>
 #include <mono/metadata/marshal.h>
+#include <mono/metadata/metadata-internals.h>
 
 extern gboolean substitute_with_mscorlib_p;
 
@@ -1268,6 +1270,7 @@ dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
 const char *
 get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGenericContainer *container)
 {
+       MonoError error;
        const char *start = ptr;
        guint32 type;
        MonoType *t;
@@ -1281,12 +1284,14 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS: {
                guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
-               MonoClass *klass = mono_class_get (m, token);
+               MonoClass *klass = mono_class_get_checked (m, token, &error);
                char *temp;
-               if (klass)
+               if (klass) {
                        temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE);
-               else
-                       temp = g_strdup_printf ("<BROKEN CLASS token_%8x>", token);
+               } else  {
+                       temp = g_strdup_printf ("<BROKEN CLASS token_%8x due to %s>", token, mono_error_get_message (&error));
+                       mono_error_cleanup (&error);
+               }
 
                if (show_tokens) {
                        *result = g_strdup_printf ("%s/*%08x*/", temp, token);
@@ -1322,23 +1327,12 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
        }
 
        default:
-               t = mono_metadata_parse_type_full (m, container, 0, start, &ptr);
+               t = mono_metadata_parse_type_checked (m, container, 0, FALSE, start, &ptr, &error);
                if (t) {
                        *result = dis_stringify_type (m, t, is_def);
                } else {
-                       GString *err = g_string_new ("@!#$<InvalidType>$#!@");
-                       if (container)
-                               t = mono_metadata_parse_type_full (m, NULL, 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);
+                       *result = g_strdup_printf ("Invalid type due to %s", mono_error_get_message (&error));
+                       mono_error_cleanup (&error);
                }
 
                break;
@@ -1900,6 +1894,7 @@ get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContainer *con
 static char *
 get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContainer *container)
 {
+       MonoError error;
        int idx = mono_metadata_token_index (token);
        guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
        char *sig = NULL, *esname;
@@ -1908,7 +1903,7 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConta
        MonoMethod *mh;
        MonoGenericContainer *type_container = container;
 
-       mh = mono_get_method_full (m, token, NULL, (MonoGenericContext *) container);
+       mh = mono_get_method_checked (m, token, NULL, (MonoGenericContext *) container, &error);
        if (mh) {
                if (mono_method_signature (mh)->is_inflated)
                        container = mono_method_get_generic_container (((MonoMethodInflated *) mh)->declaring);
@@ -1920,8 +1915,10 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConta
                        name = g_strdup_printf ("%s%s%s", sig ? sig : "", sig ? "::" : "", esname);
                g_free (sig);
                g_free (esname);
-       } else
+       } else {
                name = NULL;
+               mono_error_cleanup (&error);
+       }
 
        switch (mono_metadata_token_code (token)){
        case MONO_TOKEN_METHOD_DEF:
@@ -2005,13 +2002,14 @@ get_method (MonoImage *m, guint32 token, MonoGenericContainer *container)
 char *
 get_methoddef (MonoImage *m, guint32 idx)
 {
-        guint32 cols [MONO_METHOD_SIZE];
+       MonoError error;
+       guint32 cols [MONO_METHOD_SIZE];
        char *sig;
        const char *name;
 
        MonoMethod *mh;
 
-       mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
+       mh = mono_get_method_checked (m, MONO_TOKEN_METHOD_DEF | idx, NULL, NULL, &error);
        if (mh) {
                sig = dis_stringify_type (m, &mh->klass->byval_arg, FALSE);
                name = g_strdup_printf ("%s%s%s", 
@@ -2019,13 +2017,15 @@ get_methoddef (MonoImage *m, guint32 idx)
                                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);
+       } else {
+               name = g_strdup_printf ("!bad-method-name!");
+               mono_error_cleanup (&error);
+       }
+    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);
         
-        return sig;
+       return sig;
 }
 
 char *
@@ -2068,7 +2068,8 @@ get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContaine
 char *
 get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, MonoGenericContainer *type_container)
 {
-        GString *res = g_string_new ("");
+       MonoError error;
+       GString *res = g_string_new ("");
        guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
         char *s, *type_param;
         const char *ptr;
@@ -2097,8 +2098,13 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, Mo
        ptr = mono_metadata_blob_heap (m, sig);
        mono_metadata_decode_value (ptr, &ptr);
        
-       mh = mono_get_method_full (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container);
-       g_assert (mh);
+       mh = mono_get_method_checked (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container, &error);
+       if (!mh) {
+               g_string_append_printf (res, "Could not decode method token 0x%x due to %s", token, mono_error_get_message (&error));
+               mono_error_cleanup (&error);
+               return g_string_free (res, FALSE);
+       }
+
        container = mono_method_get_generic_container (mh);
        if (!container)
                container = type_container;
@@ -2222,7 +2228,7 @@ get_encoded_user_string_or_bytearray (const unsigned char *ptr, int len)
        char *res, *eres, *result;
        int i;
 
-       res = g_malloc ((len >> 1) + 1);
+       res = (char *)g_malloc ((len >> 1) + 1);
 
        /*
         * I should really use some kind of libunicode here
@@ -3098,8 +3104,9 @@ get_method_override (MonoImage *m, guint32 token, MonoGenericContainer *containe
                decl = method_dor_to_token (cols [MONO_METHODIMPL_DECLARATION]);
 
                if (token == impl) {
+                       MonoError error;
                        MonoMethod *mh = NULL;
-                       mh = mono_get_method_full (m, decl, NULL, (MonoGenericContext *) container);
+                       mh = mono_get_method_checked (m, decl, NULL, (MonoGenericContext *) container, &error);
 
                        if (mh && (mh->klass && (mh->klass->generic_class || mh->klass->generic_container))) {
                                char *meth_str;
@@ -3110,7 +3117,12 @@ get_method_override (MonoImage *m, guint32 token, MonoGenericContainer *containe
                                g_free (meth_str);
                                return ret;
                        } else {
-                               return get_method_core (m, decl, FALSE, container);
+                               char *meth_str = get_method_core (m, decl, FALSE, container);
+                               char *ret = g_strdup_printf ("Could not decode method override %s due to %s", meth_str, mono_error_get_message (&error));
+
+                               mono_error_cleanup (&error);
+                               g_free (meth_str);
+                               return ret;
                        }
                }
        }
@@ -3137,7 +3149,7 @@ check_ambiguous_genparams (MonoGenericContainer *container)
        for (i = 0; i < container->type_argc; i++) {
                MonoGenericParam *param = mono_generic_container_get_param (container, i);
 
-               if ((p = g_hash_table_lookup (table, mono_generic_param_info (param)->name)))
+               if ((p = (gpointer *)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*)mono_generic_param_info (param)->name, GUINT_TO_POINTER (i + 1));
@@ -3171,7 +3183,7 @@ cant_print_generic_param_name (MonoGenericParam *gparam)
        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)));
+                       g_hash_table_lookup (mono_generic_params_with_ambiguous_names, gparam)) || !mono_generic_param_info (gparam));
 }