Botan 3.8.1
Crypto and TLS for C&
dyn_load.cpp
Go to the documentation of this file.
1/*
2* Dynamically Loaded Object
3* (C) 2010 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/dyn_load.h>
9
10#include <botan/exceptn.h>
11#include <botan/internal/fmt.h>
12#include <botan/internal/target_info.h>
13#include <sstream>
14
15#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
16 #include <dlfcn.h>
17#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
18 #define NOMINMAX 1
19 #define _WINSOCKAPI_ // stop windows.h including winsock.h
20 #include <windows.h>
21#endif
22
23namespace Botan {
24
25namespace {
26
27void raise_runtime_loader_exception(std::string_view lib_name, const char* msg) {
28 std::ostringstream err;
29 err << "Failed to load " << lib_name << ": ";
30 if(msg) {
31 err << msg;
32 } else {
33 err << "Unknown error";
34 }
35
36 throw System_Error(err.str(), 0);
37}
38
39} // namespace
40
41Dynamically_Loaded_Library::Dynamically_Loaded_Library(std::string_view library) : m_lib_name(library), m_lib(nullptr) {
42#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
43 m_lib = ::dlopen(m_lib_name.c_str(), RTLD_LAZY);
44
45 if(!m_lib) {
46 raise_runtime_loader_exception(m_lib_name, ::dlerror());
47 }
48
49#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
50 m_lib = ::LoadLibraryA(m_lib_name.c_str());
51
52 if(!m_lib)
53 raise_runtime_loader_exception(m_lib_name, "LoadLibrary failed");
54#endif
55
56 if(!m_lib) {
57 raise_runtime_loader_exception(m_lib_name, "Dynamic load not supported");
58 }
59}
60
62#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
63 ::dlclose(m_lib);
64#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
65 ::FreeLibrary(reinterpret_cast<HMODULE>(m_lib));
66#endif
67}
68
69void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) {
70 void* addr = nullptr;
71
72#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
73 addr = ::dlsym(m_lib, symbol.c_str());
74#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
75 addr = reinterpret_cast<void*>(::GetProcAddress(reinterpret_cast<HMODULE>(m_lib), symbol.c_str()));
76#endif
77
78 if(!addr) {
79 throw Invalid_Argument(fmt("Failed to resolve symbol {} in {}", symbol, m_lib_name));
80 }
81
82 return addr;
83}
84
85} // namespace Botan
Dynamically_Loaded_Library(std::string_view lib_name)
Definition dyn_load.cpp:41
void * resolve_symbol(const std::string &symbol)
Definition dyn_load.cpp:69
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53