Home | History | Annotate | Download | only in Common
      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 void *getLibraryHandle(const char *path);
     25 void *loadLibrary(const char *path);
     26 void freeLibrary(void *library);
     27 void *getProcAddress(void *library, const char *name);
     28 
     29 template<int n>
     30 void *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 nullptr;
     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 = NULL;
     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 nullptr;
    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
    133