• 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 
31 template<int n>
loadLibrary(const std::string & libraryDirectory,const char * (& names)[n],const char * mustContainSymbol=nullptr)32 void *loadLibrary(const std::string &libraryDirectory, const char *(&names)[n], const char *mustContainSymbol = nullptr)
33 {
34 	for(const char *libraryName : names)
35 	{
36 		std::string libraryPath = libraryDirectory + libraryName;
37 		void *library = getLibraryHandle(libraryPath.c_str());
38 
39 		if(library)
40 		{
41 			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
42 			{
43 				return library;
44 			}
45 
46 			freeLibrary(library);
47 		}
48 	}
49 
50 	for(const char *libraryName : names)
51 	{
52 		std::string libraryPath = libraryDirectory + libraryName;
53 		void *library = loadLibrary(libraryPath.c_str());
54 
55 		if(library)
56 		{
57 			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
58 			{
59 				return library;
60 			}
61 
62 			freeLibrary(library);
63 		}
64 	}
65 
66 	return nullptr;
67 }
68 
69 #if defined(_WIN32)
loadLibrary(const char * path)70 inline void *loadLibrary(const char *path)
71 {
72 	return (void *)LoadLibrary(path);
73 }
74 
getLibraryHandle(const char * path)75 inline void *getLibraryHandle(const char *path)
76 {
77 	HMODULE module = NULL;
78 	GetModuleHandleEx(0, path, &module);
79 	return (void *)module;
80 }
81 
freeLibrary(void * library)82 inline void freeLibrary(void *library)
83 {
84 	FreeLibrary((HMODULE)library);
85 }
86 
getProcAddress(void * library,const char * name)87 inline void *getProcAddress(void *library, const char *name)
88 {
89 	return (void *)GetProcAddress((HMODULE)library, name);
90 }
91 #else
loadLibrary(const char * path)92 inline void *loadLibrary(const char *path)
93 {
94 	return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
95 }
96 
getLibraryHandle(const char * path)97 inline void *getLibraryHandle(const char *path)
98 {
99 #	ifdef __ANDROID__
100 	// bionic doesn't support RTLD_NOLOAD before L
101 	return dlopen(path, RTLD_NOW | RTLD_LOCAL);
102 #	else
103 	void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD | RTLD_LOCAL);
104 
105 	if(resident)
106 	{
107 		return dlopen(path, RTLD_LAZY | RTLD_LOCAL);  // Increment reference count
108 	}
109 
110 	return nullptr;
111 #	endif
112 }
113 
freeLibrary(void * library)114 inline void freeLibrary(void *library)
115 {
116 	if(library)
117 	{
118 		dlclose(library);
119 	}
120 }
121 
getProcAddress(void * library,const char * name)122 inline void *getProcAddress(void *library, const char *name)
123 {
124 	void *symbol = dlsym(library, name);
125 
126 	if(!symbol)
127 	{
128 		const char *reason = dlerror();  // Silence the error
129 		(void)reason;
130 	}
131 
132 	return symbol;
133 }
134 #endif
135 
136 #endif  // SharedLibrary_hpp
137