Sfoglia il codice sorgente

[linux-port] Use cross-platform dynamic lib load (#1380)

LLVM includes a DynamicLibrary class that works on multiple platforms
Rather than ifdefing between dlopen for non-Windows and LoadLibraryW
on Windows, using this class allows us to abstract platform differences
while using the same code.

Changed DxilLibInitialize to attempt to initialize dxil.dll so the
smart mutex inside the dynamic library object uses the same IMalloc
as the other ManagedStatic objects so they can all be freed in order.
Greg Roth 7 anni fa
parent
commit
3670c1372d

+ 25 - 20
include/dxc/Support/dxcapi.use.h

@@ -13,27 +13,27 @@
 #define __DXCAPI_USE_H__
 
 #include "dxc/dxcapi.h"
+#include "llvm/Support/DynamicLibrary.h"
 
 namespace dxc {
 
 // Helper class to dynamically load the dxcompiler or a compatible libraries.
 class DxcDllSupport {
 protected:
-  HMODULE m_dll;
+  using DynamicLibrary = llvm::sys::DynamicLibrary;
+  DynamicLibrary m_dll;
   DxcCreateInstanceProc m_createFn;
   DxcCreateInstance2Proc m_createFn2;
 
   HRESULT InitializeInternal(LPCWSTR dllName, LPCSTR fnName) {
-    if (m_dll != nullptr) return S_OK;
-    m_dll = LoadLibraryW(dllName);
-
-    if (m_dll == nullptr) return HRESULT_FROM_WIN32(GetLastError());
-    m_createFn = (DxcCreateInstanceProc)GetProcAddress(m_dll, fnName);
+    if (m_dll.isValid()) return S_OK;
+    m_dll = DynamicLibrary::getPermanentLibrary(CW2A(dllName));
+    if (!m_dll.isValid()) return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+    m_createFn = (DxcCreateInstanceProc)m_dll.getAddressOfSymbol(fnName);
 
     if (m_createFn == nullptr) {
       HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
-      FreeLibrary(m_dll);
-      m_dll = nullptr;
+      m_dll = DynamicLibrary();
       return hr;
     }
 
@@ -45,18 +45,18 @@ protected:
       memcpy(fnName2, fnName, s);
       fnName2[s] = '2';
       fnName2[s + 1] = '\0';
-      m_createFn2 = (DxcCreateInstance2Proc)GetProcAddress(m_dll, fnName2);
+      m_createFn2 = (DxcCreateInstance2Proc)m_dll.getAddressOfSymbol(fnName2);
     }
 
     return S_OK;
   }
 
 public:
-  DxcDllSupport() : m_dll(nullptr), m_createFn(nullptr), m_createFn2(nullptr) {
+  DxcDllSupport() : m_dll(), m_createFn(nullptr), m_createFn2(nullptr) {
   }
 
   DxcDllSupport(DxcDllSupport&& other) {
-    m_dll = other.m_dll; other.m_dll = nullptr;
+    m_dll = other.m_dll; other.m_dll = DynamicLibrary();
     m_createFn = other.m_createFn; other.m_createFn = nullptr;
     m_createFn2 = other.m_createFn2; other.m_createFn2 = nullptr;
   }
@@ -66,7 +66,13 @@ public:
   }
 
   HRESULT Initialize() {
+    #ifdef _WIN32
     return InitializeInternal(L"dxcompiler.dll", "DxcCreateInstance");
+    #elif __APPLE__
+    return InitializeInternal(L"libdxcompiler.dylib", "DxcCreateInstance");
+    #else
+    return InitializeInternal(L"libdxcompiler.so", "DxcCreateInstance");
+    #endif
   }
 
   HRESULT InitializeForDll(_In_z_ const wchar_t* dll, _In_z_ const char* entryPoint) {
@@ -80,7 +86,7 @@ public:
 
   HRESULT CreateInstance(REFCLSID clsid, REFIID riid, _Outptr_ IUnknown **pResult) {
     if (pResult == nullptr) return E_POINTER;
-    if (m_dll == nullptr) return E_FAIL;
+    if (!m_dll.isValid()) return E_FAIL;
     HRESULT hr = m_createFn(clsid, riid, (LPVOID*)pResult);
     return hr;
   }
@@ -92,7 +98,7 @@ public:
 
   HRESULT CreateInstance2(IMalloc *pMalloc, REFCLSID clsid, REFIID riid, _Outptr_ IUnknown **pResult) {
     if (pResult == nullptr) return E_POINTER;
-    if (m_dll == nullptr) return E_FAIL;
+    if (!m_dll.isValid()) return E_FAIL;
     if (m_createFn2 == nullptr) return E_FAIL;
     HRESULT hr = m_createFn2(pMalloc, clsid, riid, (LPVOID*)pResult);
     return hr;
@@ -103,21 +109,20 @@ public:
   }
 
   bool IsEnabled() const {
-    return m_dll != nullptr;
+    return m_dll.isValid();
   }
 
   void Cleanup() {
-    if (m_dll != nullptr) {
+    if (m_dll.isValid()) {
       m_createFn = nullptr;
       m_createFn2 = nullptr;
-      FreeLibrary(m_dll);
-      m_dll = nullptr;
+      m_dll = DynamicLibrary();
     }
   }
 
-  HMODULE Detach() {
-    HMODULE module = m_dll;
-    m_dll = nullptr;
+  DynamicLibrary Detach() {
+    DynamicLibrary module = m_dll;
+    m_dll = DynamicLibrary();
     return module;
   }
 };

+ 2 - 1
lib/Support/CMakeLists.txt

@@ -28,7 +28,7 @@ if( NOT MSVC )
 endif( NOT MSVC )
 
 # HLSL Change - add ignored sources
-set(HLSL_IGNORE_SOURCES DynamicLibrary.cpp PluginLoader.cpp)
+set(HLSL_IGNORE_SOURCES PluginLoader.cpp)
 
 add_llvm_library(LLVMSupport
   APFloat.cpp
@@ -52,6 +52,7 @@ add_llvm_library(LLVMSupport
   DeltaAlgorithm.cpp
   DAGDeltaAlgorithm.cpp
   Dwarf.cpp
+  DynamicLibrary.cpp
   ErrorHandling.cpp
   FileUtilities.cpp
   FileOutputBuffer.cpp

+ 5 - 0
tools/clang/tools/dxcompiler/dxillib.cpp

@@ -25,6 +25,11 @@ static llvm::sys::Mutex *cs = nullptr;
 // This function is to prevent multiple attempts to load dxil.dll 
 HRESULT DxilLibInitialize() {
   cs = new llvm::sys::Mutex;
+#if LLVM_ON_WIN32
+  cs->lock();
+  g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance");
+  cs->unlock();
+#endif
   return S_OK;
 }