-// SwiftShader Software Renderer\r
-//\r
-// Copyright(c) 2005-2012 TransGaming Inc.\r
-//\r
-// All rights reserved. No part of this software may be copied, distributed, transmitted,\r
-// transcribed, stored in a retrieval system, translated into any human or computer\r
-// language by any means, or disclosed to third parties without the explicit written\r
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express\r
-// or implied, including but not limited to any patent rights, are granted to you.\r
-//\r
-\r
-#if defined(_WIN32)\r
- #include <Windows.h>\r
-#else\r
- #include <dlfcn.h>\r
-#endif\r
-\r
-void *getLibraryHandle(const char *path);\r
-void *loadLibrary(const char *path);\r
-\r
-template<int n>\r
-void *loadLibrary(const char *(&names)[n])\r
-{\r
- for(int i = 0; i < n; i++)\r
- {\r
- void *library = getLibraryHandle(names[i]);\r
-\r
- if(library)\r
- {\r
- return library;\r
- }\r
- }\r
-\r
- for(int i = 0; i < n; i++)\r
- {\r
- void *library = loadLibrary(names[i]);\r
-\r
- if(library)\r
- {\r
- return library;\r
- }\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-#if defined(_WIN32)\r
- inline void *loadLibrary(const char *path)\r
- {\r
- return (void*)LoadLibrary(path);\r
- }\r
-\r
- inline void *getLibraryHandle(const char *path)\r
- {\r
- HMODULE module = 0;\r
- GetModuleHandleEx(0, path, &module);\r
- return (void*)module;\r
- }\r
-\r
- inline void freeLibrary(void *library)\r
- {\r
- FreeLibrary((HMODULE)library);\r
- }\r
-\r
- inline void *getProcAddress(void *library, const char *name)\r
- {\r
- return (void*)GetProcAddress((HMODULE)library, name);\r
- }\r
-#else\r
- inline void *loadLibrary(const char *path)\r
- {\r
- return dlopen(path, RTLD_LAZY);\r
- }\r
-\r
- inline void *getLibraryHandle(const char *path)\r
- {\r
- #ifdef __ANDROID__\r
- // bionic doesn't support RTLD_NOLOAD before L\r
- return dlopen(path, RTLD_NOW);\r
- #else\r
- void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD);\r
-\r
- if(resident)\r
- {\r
- return dlopen(path, RTLD_LAZY); // Increment reference count\r
- }\r
-\r
- return 0;\r
- #endif\r
- }\r
-\r
- inline void freeLibrary(void *library)\r
- {\r
- if(library)\r
- {\r
- dlclose(library);\r
- }\r
- }\r
-\r
- inline void *getProcAddress(void *library, const char *name)\r
- {\r
- return library ? dlsym(library, name) : 0;\r
- }\r
-#endif\r
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SharedLibrary_hpp
+#define SharedLibrary_hpp
+
+#if defined(_WIN32)
+ #include <Windows.h>
+#else
+ #include <dlfcn.h>
+#endif
+
+#include <string>
+
+void *getLibraryHandle(const char *path);
+void *loadLibrary(const char *path);
+void freeLibrary(void *library);
+void *getProcAddress(void *library, const char *name);
+
+template<int n>
+void *loadLibrary(const std::string &libraryDirectory, const char *(&names)[n], const char *mustContainSymbol = nullptr)
+{
+ if(!libraryDirectory.empty())
+ {
+ for(int i = 0; i < n; i++)
+ {
+ std::string nameWithPath = libraryDirectory + names[i];
+ void *library = getLibraryHandle(nameWithPath.c_str());
+
+ if(library)
+ {
+ if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+ {
+ return library;
+ }
+
+ freeLibrary(library);
+ }
+ }
+ }
+
+ for(int i = 0; i < n; i++)
+ {
+ void *library = getLibraryHandle(names[i]);
+
+ if(library)
+ {
+ if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+ {
+ return library;
+ }
+
+ freeLibrary(library);
+ }
+ }
+
+ for(int i = 0; i < n; i++)
+ {
+ void *library = loadLibrary(names[i]);
+
+ if(library)
+ {
+ if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+ {
+ return library;
+ }
+
+ freeLibrary(library);
+ }
+ }
+
+ return nullptr;
+}
+
+#if defined(_WIN32)
+ inline void *loadLibrary(const char *path)
+ {
+ return (void*)LoadLibrary(path);
+ }
+
+ inline void *getLibraryHandle(const char *path)
+ {
+ HMODULE module = NULL;
+ GetModuleHandleEx(0, path, &module);
+ return (void*)module;
+ }
+
+ inline void freeLibrary(void *library)
+ {
+ FreeLibrary((HMODULE)library);
+ }
+
+ inline void *getProcAddress(void *library, const char *name)
+ {
+ return (void*)GetProcAddress((HMODULE)library, name);
+ }
+
+ inline std::string getLibraryDirectoryFromSymbol(void* symbol)
+ {
+ HMODULE module = NULL;
+ GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)symbol, &module);
+ char filename[1024];
+ if(module && (GetModuleFileName(module, filename, sizeof(filename)) != 0))
+ {
+ std::string directory(filename);
+ return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
+ }
+ else
+ {
+ return "";
+ }
+ }
+#else
+ inline void *loadLibrary(const char *path)
+ {
+ return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
+ }
+
+ inline void *getLibraryHandle(const char *path)
+ {
+ #ifdef __ANDROID__
+ // bionic doesn't support RTLD_NOLOAD before L
+ return dlopen(path, RTLD_NOW | RTLD_LOCAL);
+ #else
+ void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD | RTLD_LOCAL);
+
+ if(resident)
+ {
+ return dlopen(path, RTLD_LAZY | RTLD_LOCAL); // Increment reference count
+ }
+
+ return nullptr;
+ #endif
+ }
+
+ inline void freeLibrary(void *library)
+ {
+ if(library)
+ {
+ dlclose(library);
+ }
+ }
+
+ inline void *getProcAddress(void *library, const char *name)
+ {
+ void *symbol = dlsym(library, name);
+
+ if(!symbol)
+ {
+ const char *reason = dlerror(); // Silence the error
+ (void)reason;
+ }
+
+ return symbol;
+ }
+
+ inline std::string getLibraryDirectoryFromSymbol(void* symbol)
+ {
+ Dl_info dl_info;
+ if(dladdr(symbol, &dl_info) != 0)
+ {
+ std::string directory(dl_info.dli_fname);
+ return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
+ }
+ else
+ {
+ return "";
+ }
+ }
+#endif
+
+#endif // SharedLibrary_hpp