X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Floader.c;h=f950055953eaa5f728b435c793012fb8ac6f895d;hb=3953bef4aa4a41009b8051bb60c034a52e8c0ca4;hp=69578884713e17adcb1a0940ff0d6e28dc13cf0a;hpb=8f59998c4f744c7b78cf6cdd7f5849f99902c4b8;p=mono.git diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index 69578884713..f950055953e 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -129,6 +129,7 @@ mono_loader_cleanup (void) static void set_loader_error (MonoLoaderError *error) { + mono_loader_clear_error (); mono_native_tls_set_value (loader_error_thread_id, error); } @@ -531,13 +532,13 @@ mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, return result; } - mono_loader_lock (); + mono_image_lock (image); if ((field = g_hash_table_lookup (image->field_cache, GUINT_TO_POINTER (token)))) { *retklass = field->parent; - mono_loader_unlock (); + mono_image_unlock (image); return field; } - mono_loader_unlock (); + mono_image_unlock (image); if (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF) field = field_from_memberref (image, token, retklass, context); @@ -554,10 +555,10 @@ mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, field = mono_class_get_field (k, token); } - mono_loader_lock (); + mono_image_lock (image); if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container) g_hash_table_insert (image->field_cache, GUINT_TO_POINTER (token), field); - mono_loader_unlock (); + mono_image_unlock (image); return field; } @@ -780,6 +781,25 @@ fail: return NULL; } +/* + * mono_inflate_generic_signature: + * + * Inflate SIG with CONTEXT, and return a canonical copy. On error, set ERROR, and return NULL. + */ +MonoMethodSignature* +mono_inflate_generic_signature (MonoMethodSignature *sig, MonoGenericContext *context, MonoError *error) +{ + MonoMethodSignature *res, *cached; + + res = inflate_generic_signature_checked (NULL, sig, context, error); + if (!mono_error_ok (error)) + return NULL; + cached = mono_metadata_get_inflated_signature (res, context); + if (cached != res) + mono_metadata_free_inflated_signature (res); + return cached; +} + static MonoMethodHeader* inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context) { @@ -835,9 +855,11 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to if (method->klass->generic_class) return mono_method_signature (method); +#ifndef DISABLE_REFLECTION_EMIT if (image->dynamic) { sig = mono_reflection_lookup_signature (image, method, token); } else { +#endif mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE); sig_idx = cols [MONO_MEMBERREF_SIGNATURE]; @@ -866,7 +888,9 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to mono_loader_set_error_bad_image (g_strdup_printf ("Incompatible method signature class token 0x%08x field name %s token 0x%08x on image %s", class, fname, token, image->name)); return NULL; } +#ifndef DISABLE_REFLECTION_EMIT } +#endif if (context) { @@ -1285,6 +1309,19 @@ cached_module_load (const char *name, int flags, char **err) return res; } +static MonoDl *internal_module; + +static gboolean +is_absolute_path (const char *path) +{ +#ifdef PLATFORM_MACOSX + if (!strncmp (path, "@executable_path/", 17) || !strncmp (path, "@loader_path/", 13) || + !strncmp (path, "@rpath/", 7)) + return TRUE; +#endif + return g_path_is_absolute (path); +} + gpointer mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char **exc_arg) { @@ -1361,14 +1398,20 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char "DllImport attempting to load: '%s'.", new_scope); /* we allow a special name to dlopen from the running process namespace */ - if (strcmp (new_scope, "__Internal") == 0) - module = mono_dl_open (NULL, MONO_DL_LAZY, &error_msg); + if (strcmp (new_scope, "__Internal") == 0){ + if (internal_module == NULL) + internal_module = mono_dl_open (NULL, MONO_DL_LAZY, &error_msg); + module = internal_module; + } } /* * Try loading the module using a variety of names */ for (i = 0; i < 4; ++i) { + char *base_name = NULL, *dir_name = NULL; + gboolean is_absolute = is_absolute_path (new_scope); + switch (i) { case 0: /* Try the original name */ @@ -1384,12 +1427,21 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char continue; break; case 2: - if (strstr (new_scope, "lib") != new_scope) { + if (is_absolute) { + dir_name = g_path_get_dirname (new_scope); + base_name = g_path_get_basename (new_scope); + if (strstr (base_name, "lib") != base_name) { + char *tmp = g_strdup_printf ("lib%s", base_name); + g_free (base_name); + base_name = tmp; + file_name = g_strdup_printf ("%s%s%s", dir_name, G_DIR_SEPARATOR_S, base_name); + break; + } + } else if (strstr (new_scope, "lib") != new_scope) { file_name = g_strdup_printf ("lib%s", new_scope); + break; } - else - continue; - break; + continue; default: #ifndef TARGET_WIN32 if (!g_ascii_strcasecmp ("user32.dll", new_scope) || @@ -1404,8 +1456,15 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char break; #endif } - - if (!module && g_path_is_absolute (file_name)) { + + if (is_absolute) { + if (!dir_name) + dir_name = g_path_get_dirname (file_name); + if (!base_name) + base_name = g_path_get_basename (file_name); + } + + if (!module && is_absolute) { module = cached_module_load (file_name, MONO_DL_LAZY, &error_msg); if (!module) { mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, @@ -1417,7 +1476,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char } } - if (!module) { + if (!module && !is_absolute) { void *iter = NULL; char *mdirname = g_path_get_dirname (image->name); while ((full_name = mono_dl_build_path (mdirname, file_name, &iter))) { @@ -1439,7 +1498,8 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char if (!module) { void *iter = NULL; - while ((full_name = mono_dl_build_path (NULL, file_name, &iter))) { + char *file_or_base = is_absolute ? base_name : file_name; + while ((full_name = mono_dl_build_path (dir_name, file_or_base, &iter))) { module = cached_module_load (full_name, MONO_DL_LAZY, &error_msg); if (!module) { mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, @@ -1467,6 +1527,10 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char } g_free (file_name); + if (is_absolute) { + g_free (base_name); + g_free (dir_name); + } if (module) break; @@ -1748,7 +1812,7 @@ MonoMethod * mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass, MonoGenericContext *context) { - MonoMethod *result; + MonoMethod *result = NULL; gboolean used_context = FALSE; /* We do everything inside the lock to prevent creation races */ @@ -1759,7 +1823,7 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass, if (!image->method_cache) image->method_cache = g_hash_table_new (NULL, NULL); result = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token))); - } else { + } else if (!image->dynamic) { if (!image->methodref_cache) image->methodref_cache = g_hash_table_new (NULL, NULL); result = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token)); @@ -1769,16 +1833,18 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass, if (result) return result; + result = mono_get_method_from_token (image, token, klass, context, &used_context); if (!result) return NULL; mono_image_lock (image); if (!used_context && !result->is_inflated) { - MonoMethod *result2; + MonoMethod *result2 = NULL; + if (mono_metadata_token_table (token) == MONO_TABLE_METHOD) result2 = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token))); - else + else if (!image->dynamic) result2 = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token)); if (result2) { @@ -1788,7 +1854,7 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass, if (mono_metadata_token_table (token) == MONO_TABLE_METHOD) g_hash_table_insert (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)), result); - else + else if (!image->dynamic) g_hash_table_insert (image->methodref_cache, GINT_TO_POINTER (token), result); } @@ -2189,7 +2255,7 @@ stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data) return FALSE; case FRAME_TYPE_MANAGED: g_assert (frame->ji); - return d->func (frame->ji->method, frame->native_offset, frame->il_offset, frame->managed, d->user_data); + return d->func (mono_jit_info_get_method (frame->ji), frame->native_offset, frame->il_offset, frame->managed, d->user_data); break; default: g_assert_not_reached (); @@ -2384,9 +2450,8 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) signature = mono_metadata_parse_method_signature_full (img, container, idx, sig_body, NULL); if (!signature) { - mono_loader_clear_error (); + mono_error_set_from_loader_error (error); mono_loader_unlock (); - mono_error_set_method_load (error, m->klass, m->name, ""); return NULL; }