/src/WasmEdge/lib/loader/shared_library.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // SPDX-FileCopyrightText: 2019-2024 Second State INC |
3 | | |
4 | | #include "loader/shared_library.h" |
5 | | #include "common/spdlog.h" |
6 | | |
7 | | #include <algorithm> |
8 | | #include <cerrno> |
9 | | #include <cstdint> |
10 | | #include <cstring> |
11 | | #include <tuple> |
12 | | #include <utility> |
13 | | |
14 | | #if WASMEDGE_OS_WINDOWS |
15 | | #include "system/winapi.h" |
16 | | #elif WASMEDGE_OS_LINUX || WASMEDGE_OS_MACOS |
17 | | #include <dlfcn.h> |
18 | | #else |
19 | | #error Unsupported os! |
20 | | #endif |
21 | | |
22 | | using namespace std::literals; |
23 | | |
24 | | namespace WasmEdge::Loader { |
25 | | |
26 | | // Open so file. See "include/loader/shared_library.h". |
27 | 0 | Expect<void> SharedLibrary::load(const std::filesystem::path &Path) noexcept { |
28 | | #if WASMEDGE_OS_WINDOWS |
29 | | Handle = winapi::LoadLibraryExW(Path.c_str(), nullptr, 0); |
30 | | #else |
31 | 0 | Handle = ::dlopen(Path.c_str(), RTLD_LAZY | RTLD_LOCAL); |
32 | 0 | #endif |
33 | 0 | if (!Handle) { |
34 | 0 | spdlog::error(ErrCode::Value::IllegalPath); |
35 | | #if WASMEDGE_OS_WINDOWS |
36 | | const auto Code = winapi::GetLastError(); |
37 | | winapi::LPSTR_ ErrorText = nullptr; |
38 | | if (winapi::FormatMessageA(winapi::FORMAT_MESSAGE_FROM_SYSTEM_ | |
39 | | winapi::FORMAT_MESSAGE_ALLOCATE_BUFFER_ | |
40 | | winapi::FORMAT_MESSAGE_IGNORE_INSERTS_, |
41 | | nullptr, Code, |
42 | | winapi::MAKELANGID_(winapi::LANG_NEUTRAL_, |
43 | | winapi::SUBLANG_DEFAULT_), |
44 | | reinterpret_cast<winapi::LPSTR_>(&ErrorText), 0, |
45 | | nullptr)) { |
46 | | spdlog::error(" load library failed:{}"sv, ErrorText); |
47 | | winapi::LocalFree(ErrorText); |
48 | | } else { |
49 | | spdlog::error(" load library failed:{:x}"sv, Code); |
50 | | } |
51 | | #else |
52 | 0 | spdlog::error(" load library failed:{}"sv, ::dlerror()); |
53 | 0 | #endif |
54 | 0 | return Unexpect(ErrCode::Value::IllegalPath); |
55 | 0 | } |
56 | 0 | return {}; |
57 | 0 | } |
58 | | |
59 | 0 | void SharedLibrary::unload() noexcept { |
60 | 0 | if (Handle) { |
61 | | #if WASMEDGE_OS_WINDOWS |
62 | | winapi::FreeLibrary(Handle); |
63 | | #else |
64 | 0 | ::dlclose(Handle); |
65 | 0 | #endif |
66 | 0 | Handle = NativeHandle{}; |
67 | 0 | } |
68 | 0 | } |
69 | | |
70 | 0 | void *SharedLibrary::getSymbolAddr(const char *Name) const noexcept { |
71 | 0 | if (!Handle) { |
72 | 0 | return nullptr; |
73 | 0 | } |
74 | | #if WASMEDGE_OS_WINDOWS |
75 | | return reinterpret_cast<void *>(winapi::GetProcAddress(Handle, Name)); |
76 | | #else |
77 | 0 | return ::dlsym(Handle, Name); |
78 | 0 | #endif |
79 | 0 | } |
80 | | |
81 | | } // namespace WasmEdge::Loader |