• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SharedLibrary_hpp
16 #define SharedLibrary_hpp
17 
18 #if defined(_WIN32)
19 	#include <Windows.h>
20 #else
21 	#include <dlfcn.h>
22 #endif
23 
24 #include <string>
25 
26 void *getLibraryHandle(const char *path);
27 void *loadLibrary(const char *path);
28 void freeLibrary(void *library);
29 void *getProcAddress(void *library, const char *name);
30 std::string getModuleDirectory();
31 
32 template<int n>
loadLibrary(const std::string & libraryDirectory,const char * (& names)[n],const char * mustContainSymbol=nullptr)33 void *loadLibrary(const std::string &libraryDirectory, const char *(&names)[n], const char *mustContainSymbol = nullptr)
34 {
35 	for(const char *libraryName : names)
36 	{
37 		std::string libraryPath = libraryDirectory + libraryName;
38 		void *library = getLibraryHandle(libraryPath.c_str());
39 
40 		if(library)
41 		{
42 			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
43 			{
44 				return library;
45 			}
46 
47 			freeLibrary(library);
48 		}
49 	}
50 
51 	for(const char *libraryName : names)
52 	{
53 		std::string libraryPath = libraryDirectory + libraryName;
54 		void *library = loadLibrary(libraryPath.c_str());
55 
56 		if(library)
57 		{
58 			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
59 			{
60 				return library;
61 			}
62 
63 			freeLibrary(library);
64 		}
65 	}
66 
67 	return nullptr;
68 }
69 
70 #if defined(_WIN32)
loadLibrary(const char * path)71 	inline void *loadLibrary(const char *path)
72 	{
73 		return (void*)LoadLibrary(path);
74 	}
75 
getLibraryHandle(const char * path)76 	inline void *getLibraryHandle(const char *path)
77 	{
78 		HMODULE module = NULL;
79 		GetModuleHandleEx(0, path, &module);
80 		return (void*)module;
81 	}
82 
freeLibrary(void * library)83 	inline void freeLibrary(void *library)
84 	{
85 		FreeLibrary((HMODULE)library);
86 	}
87 
getProcAddress(void * library,const char * name)88 	inline void *getProcAddress(void *library, const char *name)
89 	{
90 		return (void*)GetProcAddress((HMODULE)library, name);
91 	}
92 #else
loadLibrary(const char * path)93 	inline void *loadLibrary(const char *path)
94 	{
95 		return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
96 	}
97 
getLibraryHandle(const char * path)98 	inline void *getLibraryHandle(const char *path)
99 	{
100 		#ifdef __ANDROID__
101 			// bionic doesn't support RTLD_NOLOAD before L
102 			return dlopen(path, RTLD_NOW | RTLD_LOCAL);
103 		#else
104 			void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD | RTLD_LOCAL);
105 
106 			if(resident)
107 			{
108 				return dlopen(path, RTLD_LAZY | RTLD_LOCAL);   // Increment reference count
109 			}
110 
111 			return nullptr;
112 		#endif
113 	}
114 
freeLibrary(void * library)115 	inline void freeLibrary(void *library)
116 	{
117 		if(library)
118 		{
119 			dlclose(library);
120 		}
121 	}
122 
getProcAddress(void * library,const char * name)123 	inline void *getProcAddress(void *library, const char *name)
124 	{
125 		void *symbol = dlsym(library, name);
126 
127 		if(!symbol)
128 		{
129 			const char *reason = dlerror();   // Silence the error
130 			(void)reason;
131 		}
132 
133 		return symbol;
134 	}
135 #endif
136 
137 #endif   // SharedLibrary_hpp
138