Botan 3.5.0
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 <sstream>
13
14#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
15 #include <dlfcn.h>
16#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
17 #define NOMINMAX 1
18 #define _WINSOCKAPI_ // stop windows.h including winsock.h
19 #include <windows.h>
20#endif
21
22namespace Botan {
23
24namespace {
25
26void raise_runtime_loader_exception(std::string_view lib_name, const char* msg) {
27 std::ostringstream err;
28 err << "Failed to load " << lib_name << ": ";
29 if(msg) {
30 err << msg;
31 } else {
32 err << "Unknown error";
33 }
34
35 throw System_Error(err.str(), 0);
36}
37
38} // namespace
39
40Dynamically_Loaded_Library::Dynamically_Loaded_Library(std::string_view library) : m_lib_name(library), m_lib(nullptr) {
41#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
42 m_lib = ::dlopen(m_lib_name.c_str(), RTLD_LAZY);
43
44 if(!m_lib) {
45 raise_runtime_loader_exception(m_lib_name, ::dlerror());
46 }
47
48#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
49 m_lib = ::LoadLibraryA(m_lib_name.c_str());
50
51 if(!m_lib)
52 raise_runtime_loader_exception(m_lib_name, "LoadLibrary failed");
53#endif
54
55 if(!m_lib) {
56 raise_runtime_loader_exception(m_lib_name, "Dynamic load not supported");
57 }
58}
59
61#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
62 ::dlclose(m_lib);
63#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
64 ::FreeLibrary(reinterpret_cast<HMODULE>(m_lib));
65#endif
66}
67
68void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) {
69 void* addr = nullptr;
70
71#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
72 addr = ::dlsym(m_lib, symbol.c_str());
73#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
74 addr = reinterpret_cast<void*>(::GetProcAddress(reinterpret_cast<HMODULE>(m_lib), symbol.c_str()));
75#endif
76
77 if(!addr) {
78 throw Invalid_Argument(fmt("Failed to resolve symbol {} in {}", symbol, m_lib_name));
79 }
80
81 return addr;
82}
83
84} // namespace Botan
Dynamically_Loaded_Library(std::string_view lib_name)
Definition dyn_load.cpp:40
void * resolve_symbol(const std::string &symbol)
Definition dyn_load.cpp:68
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53