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