Botan
1.11.15
|
00001 /** 00002 * Dynamically Loaded Object 00003 * (C) 2010 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/dyn_load.h> 00009 #include <botan/build.h> 00010 #include <stdexcept> 00011 00012 #if defined(BOTAN_TARGET_OS_HAS_DLOPEN) 00013 #include <dlfcn.h> 00014 #elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) 00015 #include <windows.h> 00016 #endif 00017 00018 namespace Botan { 00019 00020 namespace { 00021 00022 void raise_runtime_loader_exception(const std::string& lib_name, 00023 const char* msg) 00024 { 00025 throw std::runtime_error("Failed to load " + lib_name + ": " + 00026 (msg ? msg : "Unknown error")); 00027 } 00028 00029 } 00030 00031 Dynamically_Loaded_Library::Dynamically_Loaded_Library( 00032 const std::string& library) : 00033 lib_name(library), lib(nullptr) 00034 { 00035 #if defined(BOTAN_TARGET_OS_HAS_DLOPEN) 00036 lib = ::dlopen(lib_name.c_str(), RTLD_LAZY); 00037 00038 if(!lib) 00039 raise_runtime_loader_exception(lib_name, dlerror()); 00040 00041 #elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) 00042 lib = ::LoadLibraryA(lib_name.c_str()); 00043 00044 if(!lib) 00045 raise_runtime_loader_exception(lib_name, "LoadLibrary failed"); 00046 #endif 00047 00048 if(!lib) 00049 raise_runtime_loader_exception(lib_name, "Dynamic load not supported"); 00050 } 00051 00052 Dynamically_Loaded_Library::~Dynamically_Loaded_Library() 00053 { 00054 #if defined(BOTAN_TARGET_OS_HAS_DLOPEN) 00055 ::dlclose(lib); 00056 #elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) 00057 ::FreeLibrary((HMODULE)lib); 00058 #endif 00059 } 00060 00061 void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) 00062 { 00063 void* addr = nullptr; 00064 00065 #if defined(BOTAN_TARGET_OS_HAS_DLOPEN) 00066 addr = ::dlsym(lib, symbol.c_str()); 00067 #elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) 00068 addr = reinterpret_cast<void*>(::GetProcAddress((HMODULE)lib, 00069 symbol.c_str())); 00070 #endif 00071 00072 if(!addr) 00073 throw std::runtime_error("Failed to resolve symbol " + symbol + 00074 " in " + lib_name); 00075 00076 return addr; 00077 } 00078 00079 }