diff options
author | lloyd <[email protected]> | 2010-07-27 20:58:47 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-07-27 20:58:47 +0000 |
commit | 2f3414c1bb2af4db4b03282b47decddf4f3e27e9 (patch) | |
tree | 8205bd36d88ec3f1168abda69ca87b5588edf335 /src/utils/dyn_load | |
parent | b910f61fd17fabdf96140f921dc90ca8dbd364d3 (diff) |
Add a new utility class Dynamically_Loaded_Library which wraps around
the system dynamic linker (if any). Currently it only supports dlopen,
and is only enabled on Linux. It will almost certainly work on BSDs
and Solaris as well, though, and should be easy to extend to support
Win32-style dynamic loading.
Also add a new engine, Dynamically_Loaded_Engine, which loads up a new
Engine object from a shared library/DLL.
Diffstat (limited to 'src/utils/dyn_load')
-rw-r--r-- | src/utils/dyn_load/dyn_load.cpp | 53 | ||||
-rw-r--r-- | src/utils/dyn_load/dyn_load.h | 56 | ||||
-rw-r--r-- | src/utils/dyn_load/info.txt | 13 |
3 files changed, 122 insertions, 0 deletions
diff --git a/src/utils/dyn_load/dyn_load.cpp b/src/utils/dyn_load/dyn_load.cpp new file mode 100644 index 000000000..621737d0c --- /dev/null +++ b/src/utils/dyn_load/dyn_load.cpp @@ -0,0 +1,53 @@ +/** +* Dynamically Loaded Object +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/dyn_load.h> +#include <botan/build.h> +#include <stdexcept> + +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + #include <dlfcn.h> +#endif + +namespace Botan { + +Dynamically_Loaded_Library::Dynamically_Loaded_Library( + const std::string& library) : + lib_name(library), lib(0) + { +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + lib = ::dlopen(lib_name.c_str(), RTLD_LAZY); + + if(!lib) + throw std::runtime_error("Failed to load engine " + lib_name); +#endif + + } + +Dynamically_Loaded_Library::~Dynamically_Loaded_Library() + { +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + ::dlclose(lib); +#endif + } + +void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) + { + void* addr = 0; + +#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) + addr = ::dlsym(lib, symbol.c_str()); +#endif + + if(!addr) + throw std::runtime_error("Failed to resolve symbol " + symbol + + " in " + lib_name); + + return addr; + } + +} diff --git a/src/utils/dyn_load/dyn_load.h b/src/utils/dyn_load/dyn_load.h new file mode 100644 index 000000000..d5476b389 --- /dev/null +++ b/src/utils/dyn_load/dyn_load.h @@ -0,0 +1,56 @@ +/** +* Dynamically Loaded Object +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_DYNAMIC_LOADER_H__ +#define BOTAN_DYNAMIC_LOADER_H__ + +#include <string> + +namespace Botan { + +class Dynamically_Loaded_Library + { + public: + /** + * Load a DLL (or fail with an exception) + * @param lib_name name or path to a library + */ + Dynamically_Loaded_Library(const std::string& lib_name); + + /** + * Unload the DLL + * @warning Any pointers returned by resolve()/resolve_symbol() + * should not be used after this destructor runs. + */ + ~Dynamically_Loaded_Library(); + + /** + * Load a symbol (or fail with an exception) + * @param symbol names the symbol to load + * @return address of the loaded symbol + */ + void* resolve_symbol(const std::string& symbol); + + /** + * Convenience function for casting symbol to the right type + * @param symbol names the symbol to load + * @return address of the loaded symbol + */ + template<typename T> + T resolve(const std::string& symbol) + { + return reinterpret_cast<T>(resolve_symbol(symbol)); + } + + private: + std::string lib_name; + void* lib; + }; + +} + +#endif diff --git a/src/utils/dyn_load/info.txt b/src/utils/dyn_load/info.txt new file mode 100644 index 000000000..208870dac --- /dev/null +++ b/src/utils/dyn_load/info.txt @@ -0,0 +1,13 @@ +define DYNAMIC_LOADER + +<libs> +linux -> dl +</libs> + +<source> +dyn_load.cpp +</source> + +<header:internal> +dyn_load.h +</header:internal> |