summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pal/inc/pal.h12
-rw-r--r--src/pal/src/include/pal/module.h12
-rw-r--r--src/pal/src/loader/module.cpp37
-rw-r--r--src/vm/dllimport.cpp99
4 files changed, 92 insertions, 68 deletions
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 7bddd88f3e..8846f4bb60 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -6666,6 +6666,18 @@ public:
#define MAKEDLLNAME(x) MAKEDLLNAME_A(x)
#endif
+#define PAL_SHLIB_PREFIX "lib"
+
+#if __APPLE__
+#define PAL_SHLIB_SUFFIX ".dylib"
+#elif _AIX
+#define PAL_SHLIB_SUFFIX ".a"
+#elif _HPUX_
+#define PAL_SHLIB_SUFFIX ".sl"
+#else
+#define PAL_SHLIB_SUFFIX ".so"
+#endif
+
#define DBG_EXCEPTION_HANDLED ((DWORD )0x00010001L)
#define DBG_CONTINUE ((DWORD )0x00010002L)
#define DBG_EXCEPTION_NOT_HANDLED ((DWORD )0x80010001L)
diff --git a/src/pal/src/include/pal/module.h b/src/pal/src/include/pal/module.h
index ce3eaa978f..83c977e450 100644
--- a/src/pal/src/include/pal/module.h
+++ b/src/pal/src/include/pal/module.h
@@ -26,18 +26,6 @@ extern "C"
{
#endif // __cplusplus
-#define PAL_SHLIB_PREFIX "lib"
-
-#if __APPLE__
-#define PAL_SHLIB_SUFFIX ".dylib"
-#elif _AIX
-#define PAL_SHLIB_SUFFIX ".a"
-#elif _HPUX_
-#define PAL_SHLIB_SUFFIX ".sl"
-#else
-#define PAL_SHLIB_SUFFIX ".so"
-#endif
-
typedef BOOL (__stdcall *PDLLMAIN)(HINSTANCE, DWORD, LPVOID); /* entry point of module */
typedef HINSTANCE (PALAPI *PREGISTER_MODULE)(LPCSTR); /* used to create the HINSTANCE for above DLLMain entry point */
typedef VOID (PALAPI *PUNREGISTER_MODULE)(HINSTANCE); /* used to cleanup the HINSTANCE for above DLLMain entry point */
diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp
index dff7de0d1c..aaa6da89be 100644
--- a/src/pal/src/loader/module.cpp
+++ b/src/pal/src/loader/module.cpp
@@ -1611,8 +1611,6 @@ Return value :
--*/
static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
{
- CHAR * fullLibraryName;
- PathCharString fullLibraryNamePS;
HMODULE module = NULL;
HMODULE dl_handle = NULL;
@@ -1637,40 +1635,9 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
// See if file can be dlopen()ed; this should work even if it's already loaded
{
// See GetProcAddress for an explanation why we leave the PAL.
- PAL_LeaveHolder holder;
-
- // P/Invokes are often declared with variations on the actual library name.
- // For example, it's common to leave off the extension/suffix of the library
- // even if it has one, or to leave off a prefix like "lib" even if it has one
- // (both of these are done typically to smooth over cross-platform differences).
- // We try to dlopen with such variations on the original.
- const char* const formatStrings[4] = // used with args: PAL_SHLIB_PREFIX, shortAsciiName, PAL_SHLIB_SUFFIX
- {
- "%s%s%s", // prefix+name+suffix
- "%.0s%s%.0s", // name
- "%.0s%s%s", // name+suffix
- "%s%s%.0s", // prefix+name
- };
- const int skipPrefixing = strchr(shortAsciiName, '/') != NULL; // skip prefixing if the name is actually a path
- for (int i = 0; i < 4; i++)
- {
- if (skipPrefixing && (i == 0 || i == 3)) // 0th and 3rd strings include prefixes
- continue;
+ PAL_LeaveHolder holder;
- _ASSERTE(dl_handle == nullptr);
- fullLibraryName = fullLibraryNamePS.OpenStringBuffer(strlen(PAL_SHLIB_PREFIX)+strlen(shortAsciiName)+strlen(PAL_SHLIB_SUFFIX));
- int size = snprintf(fullLibraryName, fullLibraryNamePS.GetSizeOf(), formatStrings[i], PAL_SHLIB_PREFIX, shortAsciiName, PAL_SHLIB_SUFFIX);
- if (size < fullLibraryNamePS.GetSizeOf())
- {
- fullLibraryNamePS.CloseBuffer(size);
- dl_handle = LOADLoadLibraryDirect(fullLibraryName, false /* setLastError */);
- if (dl_handle != nullptr)
- {
- shortAsciiName = fullLibraryName;
- break;
- }
- }
- }
+ dl_handle = LOADLoadLibraryDirect(shortAsciiName, false /* setLastError */);
}
if (!dl_handle)
diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp
index 2247f44578..20d4db2b1f 100644
--- a/src/vm/dllimport.cpp
+++ b/src/vm/dllimport.cpp
@@ -6964,7 +6964,7 @@ HINSTANCE NDirect::LoadLibraryModule( NDirectMethodDesc * pMD, LoadLibErrorTrack
{
W("mscorpe.dll"), W("mscorpe")
};
-
+
for (int i = 0; i < COUNTOF(rgSxSAwareDlls); i++)
{
if (SString::_wcsicmp(wszLibName, rgSxSAwareDlls[i]) == 0)
@@ -7004,6 +7004,29 @@ HINSTANCE NDirect::LoadLibraryModule( NDirectMethodDesc * pMD, LoadLibErrorTrack
}
#endif // FEATURE_CORESYSTEM && !FEATURE_PAL
+#ifdef FEATURE_PAL
+ // P/Invokes are often declared with variations on the actual library name.
+ // For example, it's common to leave off the extension/suffix of the library
+ // even if it has one, or to leave off a prefix like "lib" even if it has one
+ // (both of these are typically done to smooth over cross-platform differences).
+ // We try to dlopen with such variations on the original.
+ const char* const prefixSuffixCombinations[] =
+ {
+ "%s%s%s", // prefix+name+suffix
+ "%.0s%s%.0s", // name
+ "%.0s%s%s", // name+suffix
+ "%s%s%.0s", // prefix+name
+ };
+
+ const int NUMBER_OF_LIB_NAME_VARIATIONS = COUNTOF(prefixSuffixCombinations);
+
+ SString libNameVariations[NUMBER_OF_LIB_NAME_VARIATIONS];
+ for (int i = 0; i < NUMBER_OF_LIB_NAME_VARIATIONS; i++)
+ {
+ libNameVariations[i].Printf(prefixSuffixCombinations[i], PAL_SHLIB_PREFIX, name, PAL_SHLIB_SUFFIX);
+ }
+#endif // FEATURE_PAL
+
DWORD dllImportSearchPathFlag = 0;
BOOL searchAssemblyDirectory = TRUE;
if (hmod == NULL)
@@ -7032,7 +7055,7 @@ HINSTANCE NDirect::LoadLibraryModule( NDirectMethodDesc * pMD, LoadLibErrorTrack
attributeIsFound = TRUE;
}
}
-
+
if (!attributeIsFound)
{
CheckUnificationList(pMD, &dllImportSearchPathFlag, &searchAssemblyDirectory);
@@ -7058,29 +7081,40 @@ HINSTANCE NDirect::LoadLibraryModule( NDirectMethodDesc * pMD, LoadLibErrorTrack
Assembly* pAssembly = pMD->GetMethodTable()->GetAssembly();
SString path = pAssembly->GetManifestFile()->GetPath();
- SString::Iterator i = path.End();
- if (PEAssembly::FindLastPathSeparator(path, i))
+ SString::Iterator lastPathSeparatorIter = path.End();
+ if (PEAssembly::FindLastPathSeparator(path, lastPathSeparatorIter))
{
- i++;
- path.Truncate(i);
+ lastPathSeparatorIter++;
+ path.Truncate(lastPathSeparatorIter);
- path.Append(wszLibName);
+#ifdef FEATURE_PAL
+ for (int i = 0; i < NUMBER_OF_LIB_NAME_VARIATIONS; i++)
+ {
+ SString fullLibPathMaybe(path);
+ fullLibPathMaybe.Append(libNameVariations[i]);
+ hmod = LocalLoadLibraryHelper(fullLibPathMaybe, loadWithAlteredPathFlags | dllImportSearchPathFlag, pErrorTracker);
+ if (hmod != NULL)
+ break;
+ }
+#else // FEATURE_PAL
+ path.Append(wszLibName);
hmod = LocalLoadLibraryHelper(path, loadWithAlteredPathFlags | dllImportSearchPathFlag, pErrorTracker);
+#endif
}
#ifndef FEATURE_CORECLR
if (hmod == NULL)
- {
+ {
// Try to load the DLL alongside the assembly where the PInvoke was
// declared using the codebase of the assembly. This is required for download
// and shadow copy scenarios.
const WCHAR* ptr;
- SString codebase;
+ SString codebase;
pAssembly->GetCodeBase(codebase);
DWORD dwCodebaseLength = codebase.GetCount();
-
+
// Strip off the protocol
for (ptr = codebase.GetUnicode(); *ptr && *ptr != W(':'); ptr++);
@@ -7090,7 +7124,7 @@ HINSTANCE NDirect::LoadLibraryModule( NDirectMethodDesc * pMD, LoadLibErrorTrack
SString pathFromCodebase;
// After finding the colon move forward until no more forward slashes
- for(ptr++; *ptr && *ptr == W('/'); ptr++);
+ for (ptr++; *ptr && *ptr == W('/'); ptr++);
if (*ptr)
{
// Calculate the number of characters we are interested in
@@ -7103,9 +7137,9 @@ HINSTANCE NDirect::LoadLibraryModule( NDirectMethodDesc * pMD, LoadLibErrorTrack
if (tail > ptr)
{
- for(;ptr <= tail; ptr++)
+ for (;ptr <= tail; ptr++)
{
- if(*ptr == W('/'))
+ if (*ptr == W('/'))
pathFromCodebase.Append(W('\\'));
else
pathFromCodebase.Append(*ptr);
@@ -7129,24 +7163,47 @@ HINSTANCE NDirect::LoadLibraryModule( NDirectMethodDesc * pMD, LoadLibErrorTrack
#ifdef FEATURE_CORECLR
if (hmod == NULL && pDomain->HasNativeDllSearchDirectories())
{
- AppDomain::PathIterator i = pDomain->IterateNativeDllSearchDirectories();
- while (hmod == NULL && i.Next())
+ AppDomain::PathIterator pathIter = pDomain->IterateNativeDllSearchDirectories();
+ while (hmod == NULL && pathIter.Next())
{
- SString qualifiedPath(*(i.GetPath()));
+#ifdef FEATURE_PAL
+ for (int i = 0; i < NUMBER_OF_LIB_NAME_VARIATIONS; i++)
+ {
+ SString qualifiedPath(*(pathIter.GetPath()));
+ qualifiedPath.Append(libNameVariations[i]);
+
+ if (!Path::IsRelative(qualifiedPath))
+ {
+ hmod = LocalLoadLibraryHelper(qualifiedPath, loadWithAlteredPathFlags, pErrorTracker);
+ if (hmod != NULL)
+ break;
+ }
+ }
+#else // FEATURE_PAL
+ SString qualifiedPath(*(pathIter.GetPath()));
qualifiedPath.Append(wszLibName);
if (!Path::IsRelative(qualifiedPath))
{
hmod = LocalLoadLibraryHelper(qualifiedPath, loadWithAlteredPathFlags, pErrorTracker);
}
+#endif
}
}
#endif // FEATURE_CORECLR
- // Do we really need to do this. This call searches the application directory
- // instead of the location for the library.
- if(hmod == NULL)
+ // This call searches the application directory instead of the location for the library.
+ if (hmod == NULL)
{
+#ifdef FEATURE_PAL
+ for (int i = 0; i < NUMBER_OF_LIB_NAME_VARIATIONS; i++)
+ {
+ hmod = LocalLoadLibraryHelper(libNameVariations[i], dllImportSearchPathFlag, pErrorTracker);
+ if (hmod != NULL)
+ break;
+ }
+#else // FEATURE_PAL
hmod = LocalLoadLibraryHelper(wszLibName, dllImportSearchPathFlag, pErrorTracker);
+#endif
}
// This may be an assembly name
@@ -7386,7 +7443,7 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD)
//
if (!pMD->GetModule()->GetSecurityDescriptor()->CanCallUnmanagedCode())
- Security::ThrowSecurityException(g_SecurityPermissionClassName, SPFLAGSUNMANAGEDCODE);
+ Security::ThrowSecurityException(g_SecurityPermissionClassName, SPFLAGSUNMANAGEDCODE);
if (!pMD->IsZapped())
{
@@ -7401,7 +7458,7 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD)
pMD->CheckRestore();
- NDirect::NDirectLink(pMD);
+ NDirect::NDirectLink(pMD);
}
}