Created
March 12, 2012 11:54
-
-
Save shana/2021384 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 450e35516e454cd511bbaea1429204f804dba6a2 | |
Author: Andreia Gaita <[email protected]> | |
Date: Fri Dec 30 17:58:43 2011 +0000 | |
Add a bit more smarts to the library name resolver | |
On certain OSs (looking at you OSX) the usual "lib" prefix is | |
not quite standard, some libraries don't use a prefix at all. Since | |
the resolver only tries an empty prefix once with the absolute name | |
set on the DllImport directive, the lookup will fail (especially | |
when the suffix also needs to be resolved). This fix tries all | |
combinations of valid prefixes and suffixes, giving preference | |
to the SO prefix first and empty prefix second. | |
diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c | |
index 2b704c2..3bbe218 100644 | |
--- a/mono/metadata/loader.c | |
+++ b/mono/metadata/loader.c | |
@@ -1370,6 +1370,9 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char | |
if (!module) { | |
void *iter = NULL; | |
char *mdirname = g_path_get_dirname (image->name); | |
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, | |
+ "DllImport file_name: '%s' mdirname: '%s'", file_name, mdirname); | |
+ | |
while ((full_name = mono_dl_build_path (mdirname, file_name, &iter))) { | |
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, | |
"DllImport loading library: '%s'.", full_name); | |
diff --git a/mono/utils/mono-dl.c b/mono/utils/mono-dl.c | |
index 2b9d518..3098a41 100644 | |
--- a/mono/utils/mono-dl.c | |
+++ b/mono/utils/mono-dl.c | |
@@ -19,20 +19,24 @@ | |
#ifdef TARGET_WIN32 | |
#define SOPREFIX "" | |
-static const char suffixes [][5] = { | |
- ".dll" | |
+static const char affixes [][2][5] = { | |
+ {"",".dll"} | |
}; | |
#elif defined(__APPLE__) | |
#define SOPREFIX "lib" | |
-static const char suffixes [][8] = { | |
- ".dylib", | |
- ".so", | |
- ".bundle" | |
+static const char affixes [][2][8] = { | |
+ {SOPREFIX,".dylib"}, | |
+ {SOPREFIX,".so"}, | |
+ {SOPREFIX,".bundle"}, | |
+ {"",".dylib"}, | |
+ {"",".so"}, | |
+ {"",".bundle"} | |
}; | |
#else | |
#define SOPREFIX "lib" | |
-static const char suffixes [][4] = { | |
- ".so" | |
+static const char affixes [][2][4] = { | |
+ {SOPREFIX,".so"}, | |
+ {"",".so"} | |
}; | |
#endif | |
@@ -475,7 +479,7 @@ mono_dl_build_path (const char *directory, const char *name, void **iter) | |
/* | |
The first time we are called, idx = 0 (as *iter is initialized to NULL). This is our | |
"bootstrap" phase in which we check the passed name verbatim and only if we fail to find | |
- the dll thus named, we start appending suffixes, each time increasing idx twice (since now | |
+ the dll thus named, we start appending prefixes and suffixes, each time increasing idx twice (since now | |
the 0 value became special and we need to offset idx to a 0-based array index). This is | |
done to handle situations when mapped dll name is specified as libsomething.so.1 or | |
libsomething.so.1.1 or libsomething.so - testing it algorithmically would be an overkill | |
@@ -486,23 +490,24 @@ mono_dl_build_path (const char *directory, const char *name, void **iter) | |
first_call = TRUE; | |
suffix = ""; | |
suffixlen = 0; | |
+ prefix = ""; | |
+ prlen = 0; | |
} else { | |
idx--; | |
- if (idx >= G_N_ELEMENTS (suffixes)) | |
+ if (idx >= G_N_ELEMENTS (affixes)) | |
return NULL; | |
first_call = FALSE; | |
- suffix = suffixes [idx]; | |
+ prefix = affixes [idx][0]; | |
+ prlen = strlen (prefix); | |
+ suffix = affixes [idx][1]; | |
suffixlen = strlen (suffix); | |
- } | |
- prlen = strlen (SOPREFIX); | |
- if (prlen && strncmp (name, SOPREFIX, prlen) != 0) | |
- prefix = SOPREFIX; | |
- else | |
- prefix = ""; | |
+ if (suffixlen && strstr (name, suffix) == (name + strlen (name) - suffixlen)) | |
+ suffix = ""; | |
- if (first_call || (suffixlen && strstr (name, suffix) == (name + strlen (name) - suffixlen))) | |
- suffix = ""; | |
+ if (prlen && strncmp (name, prefix, prlen) == name) | |
+ prefix = ""; | |
+ } | |
if (directory && *directory) | |
res = g_strconcat (directory, G_DIR_SEPARATOR_S, prefix, name, suffix, NULL); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment