Botan  1.11.15
src/lib/utils/dyn_load/dyn_load.cpp
Go to the documentation of this file.
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 }