Botan 3.9.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 <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
27[[noreturn]] void 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 != nullptr) {
31 err << msg;
32 } else {
33 err << "Unknown error";
34 }
35
36 throw System_Error(err.str(), 0);
37}
38
39void* open_shared_library(const std::string& library) {
40#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
41 void* lib = ::dlopen(library.c_str(), RTLD_LAZY);
42
43 if(lib != nullptr) {
44 return lib;
45 } else {
46 raise_runtime_loader_exception(library, ::dlerror());
47 }
48
49#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
50 void* lib = ::LoadLibraryA(library.c_str());
51
52 if(lib != nullptr) {
53 return lib;
54 } else {
55 raise_runtime_loader_exception(library, "LoadLibrary failed");
56 }
57#else
58 raise_runtime_loader_exception(library, "Dynamic loading not supported");
59#endif
60}
61
62} // namespace
63
65 m_lib_name(library), m_lib(open_shared_library(m_lib_name)) {}
66
68#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
69 ::dlclose(m_lib);
70#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
71 ::FreeLibrary(reinterpret_cast<HMODULE>(m_lib));
72#endif
73}
74
75void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) {
76 void* addr = nullptr;
77
78#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
79 addr = ::dlsym(m_lib, symbol.c_str());
80#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
81 addr = reinterpret_cast<void*>(::GetProcAddress(reinterpret_cast<HMODULE>(m_lib), symbol.c_str()));
82#endif
83
84 if(addr == nullptr) {
85 throw Invalid_Argument(fmt("Failed to resolve symbol {} in {}", symbol, m_lib_name));
86 }
87
88 return addr;
89}
90
91} // namespace Botan
Dynamically_Loaded_Library(std::string_view lib_name)
Definition dyn_load.cpp:64
void * resolve_symbol(const std::string &symbol)
Definition dyn_load.cpp:75
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53