diff options
-rw-r--r-- | src/pal/inc/pal.h | 12 | ||||
-rw-r--r-- | src/pal/src/include/pal/module.h | 12 | ||||
-rw-r--r-- | src/pal/src/loader/module.cpp | 37 | ||||
-rw-r--r-- | src/vm/dllimport.cpp | 99 |
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); } } |