Native lib relative path (dotnet/coreclr#18239)
authorAaron Robinson <30635565+AaronRobinsonMSFT@users.noreply.github.com>
Fri, 1 Jun 2018 19:16:03 +0000 (12:16 -0700)
committerGitHub <noreply@github.com>
Fri, 1 Jun 2018 19:16:03 +0000 (12:16 -0700)
* Typo in #define

* Don't add prefix for relative path to native images if the path contains a platform path delimiter

* Use already defined delimiter macro
Create max variation count variable

Commit migrated from https://github.com/dotnet/coreclr/commit/93955d4b58380068df9d99c58a699de6ad03f532

src/coreclr/src/vm/ceeload.h
src/coreclr/src/vm/dllimport.cpp

index 03b31f5f1e07973147ba2b765137bf3524ac422a..939d7294b5dcb219c7a03ebdc5ec23ccc807a29a 100644 (file)
@@ -1903,7 +1903,7 @@ protected:
 
     BOOL IsIntrospectionOnly();
 
-#ifndef DACCESS_COMMPILE
+#ifndef DACCESS_COMPILE
     VOID EnsureActive();
     VOID EnsureAllocated();    
     VOID EnsureLibraryLoaded();
index 0f3984130074851b2133b20c97385727c0679f63..d77604b44e41a167e1f7f7ea2bf2aee51a62a4b2 100644 (file)
@@ -6034,62 +6034,78 @@ HMODULE NDirect::LoadFromNativeDllSearchDirectories(AppDomain* pDomain, LPCWSTR
 }
 
 #ifdef FEATURE_PAL
-static void DetermineLibNameVariations(const WCHAR* const** libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath)
+static const int MaxVariationCount = 4;
+static void DetermineLibNameVariations(const WCHAR** libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath)
 {
-    if (libNameIsRelativePath)
+    // Supported lib name variations
+    static auto NameFmt = W("%.0s%s%.0s");
+    static auto PrefixNameFmt = W("%s%s%.0s");
+    static auto NameSuffixFmt = W("%.0s%s%s");
+    static auto PrefixNameSuffixFmt = W("%s%s%s");
+
+    _ASSERTE(*numberOfVariations >= MaxVariationCount);
+
+    int varCount = 0;
+    if (!libNameIsRelativePath)
+    {
+        libNameVariations[varCount++] = NameFmt;
+    }
+    else
     {
         // We check if the suffix is contained in the name, because on Linux it is common to append
         // a version number to the library name (e.g. 'libicuuc.so.57').
-        bool containsSuffix;
+        bool containsSuffix = false;
         SString::CIterator it = libName.Begin();
         if (libName.Find(it, PLATFORM_SHARED_LIB_SUFFIX_W))
         {
-            it += wcslen(PLATFORM_SHARED_LIB_SUFFIX_W);
+            it += COUNTOF(PLATFORM_SHARED_LIB_SUFFIX_W);
             containsSuffix = it == libName.End() || *it == (WCHAR)'.';
         }
-        else
-        {
-            containsSuffix = false;
-        }
+
+        // If the path contains a path delimiter, we don't add a prefix
+        it = libName.Begin();
+        bool containsDelim = libName.Find(it, DIRECTORY_SEPARATOR_STR_W);
 
         if (containsSuffix)
         {
-            static const WCHAR* const SuffixLast[] =
-            {
-                W("%.0s%s"),   // name
-                W("%s%s%.0s"), // prefix+name
-                W("%.0s%s%s"), // name+suffix
-                W("%s%s%s")    // prefix+name+suffix
-            };
-            *libNameVariations = SuffixLast;
-            *numberOfVariations = COUNTOF(SuffixLast);
+            libNameVariations[varCount++] = NameFmt;
+
+            if (!containsDelim)
+                libNameVariations[varCount++] = PrefixNameFmt;
+
+            libNameVariations[varCount++] = NameSuffixFmt;
+
+            if (!containsDelim)
+                libNameVariations[varCount++] = PrefixNameSuffixFmt;
         }
         else
         {
-            static const WCHAR* const SuffixFirst[] =
-            {
-                W("%.0s%s%s"), // name+suffix
-                W("%s%s%s"),   // prefix+name+suffix
-                W("%.0s%s"),   // name
-                W("%s%s%.0s")  // prefix+name
-            };
-            *libNameVariations = SuffixFirst;
-            *numberOfVariations = COUNTOF(SuffixFirst);
+            libNameVariations[varCount++] = NameSuffixFmt;
+
+            if (!containsDelim)
+                libNameVariations[varCount++] = PrefixNameSuffixFmt;
+
+            libNameVariations[varCount++] = NameFmt;
+
+            if (!containsDelim)
+                libNameVariations[varCount++] = PrefixNameFmt;
         }
     }
-    else
-    {
-        static const WCHAR* const NameOnly[] =
-        {
-            W("%.0s%s")
-        };
-        *libNameVariations = NameOnly;
-        *numberOfVariations = COUNTOF(NameOnly);
-    }
+
+    *numberOfVariations = varCount;
 }
 #else // FEATURE_PAL
-static void DetermineLibNameVariations(const WCHAR* const** libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath)
+static const int MaxVariationCount = 2;
+static void DetermineLibNameVariations(const WCHAR** libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath)
 {
+    // Supported lib name variations
+    static auto NameFmt = W("%.0s%s%.0s");
+    static auto NameSuffixFmt = W("%.0s%s%s");
+
+    _ASSERTE(*numberOfVariations >= MaxVariationCount);
+
+    int varCount = 0;
+
     // The purpose of following code is to workaround LoadLibrary limitation: 
     // LoadLibrary won't append extension if filename itself contains '.'. Thus it will break the following scenario:
     // [DllImport("A.B")] // The full name for file is "A.B.dll". This is common code pattern for cross-platform PInvoke
@@ -6104,23 +6120,15 @@ static void DetermineLibNameVariations(const WCHAR* const** libNameVariations, i
         // If the string specifies a full path, the function searches only that path for the module.
         // If the string specifies a module name without a path and the file name extension is omitted, the function appends the default library extension .dll to the module name.
         // To prevent the function from appending .dll to the module name, include a trailing point character (.) in the module name string.
-        static const WCHAR* const NameOnly[] =
-        {
-            W("%.0s%s")
-        };
-        *libNameVariations = NameOnly;
-        *numberOfVariations = COUNTOF(NameOnly);
+        libNameVariations[varCount++] = NameFmt;
     }
     else
     {
-        static const WCHAR* const SuffixLast[] =
-        {
-            W("%.0s%s"),   // name
-            W("%.0s%s%s"), // name+suffix
-        };
-        *libNameVariations = SuffixLast;
-        *numberOfVariations = COUNTOF(SuffixLast);
+        libNameVariations[varCount++] = NameFmt;
+        libNameVariations[varCount++] = NameSuffixFmt;
     }
+
+    *numberOfVariations = varCount;
 }
 #endif // FEATURE_PAL
 
@@ -6194,18 +6202,16 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
     // 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 WCHAR* const* prefixSuffixCombinations = nullptr;
-    int numberOfVariations = 0;
-    DetermineLibNameVariations(&prefixSuffixCombinations, &numberOfVariations, wszLibName, libNameIsRelativePath);
+    const WCHAR* prefixSuffixCombinations[MaxVariationCount] = {};
+    int numberOfVariations = COUNTOF(prefixSuffixCombinations);
+    DetermineLibNameVariations(prefixSuffixCombinations, &numberOfVariations, wszLibName, libNameIsRelativePath);
     for (int i = 0; hmod == NULL && i < numberOfVariations; i++)
     {
         SString currLibNameVariation;
         currLibNameVariation.Printf(prefixSuffixCombinations[i], PLATFORM_SHARED_LIB_PREFIX_W, wszLibName, PLATFORM_SHARED_LIB_SUFFIX_W);
-        if (hmod == NULL)
-        {
-            // NATIVE_DLL_SEARCH_DIRECTORIES set by host is considered well known path 
-            hmod = LoadFromNativeDllSearchDirectories(pDomain, currLibNameVariation, loadWithAlteredPathFlags, pErrorTracker);
-        }
+
+        // NATIVE_DLL_SEARCH_DIRECTORIES set by host is considered well known path
+        hmod = LoadFromNativeDllSearchDirectories(pDomain, currLibNameVariation, loadWithAlteredPathFlags, pErrorTracker);
 
         BOOL searchAssemblyDirectory = TRUE;
         if (hmod == NULL)