1//===--- SimpleExecutorDylibManager.cpp - Executor-side dylib management --===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
10
11#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12
13#include "llvm/Support/MSVCErrorWorkarounds.h"
14
15#include <future>
16
17#define DEBUG_TYPE "orc"
18
19namespace llvm {
20namespace orc {
21namespace rt_bootstrap {
22
23SimpleExecutorDylibManager::~SimpleExecutorDylibManager() {
24 assert(Dylibs.empty() && "shutdown not called?");
25}
26
27Expected<tpctypes::DylibHandle>
28SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
29 if (Mode != 0)
30 return make_error<StringError>(Args: "open: non-zero mode bits not yet supported",
31 Args: inconvertibleErrorCode());
32
33 const char *PathCStr = Path.empty() ? nullptr : Path.c_str();
34 std::string ErrMsg;
35
36 auto DL = sys::DynamicLibrary::getPermanentLibrary(filename: PathCStr, errMsg: &ErrMsg);
37 if (!DL.isValid())
38 return make_error<StringError>(Args: std::move(ErrMsg), Args: inconvertibleErrorCode());
39
40 std::lock_guard<std::mutex> Lock(M);
41 auto H = ExecutorAddr::fromPtr(Ptr: DL.getOSSpecificHandle());
42 Resolvers.push_back(x: std::make_unique<DylibSymbolResolver>(args&: H));
43 Dylibs.insert(V: DL.getOSSpecificHandle());
44 return ExecutorAddr::fromPtr(Ptr: Resolvers.back().get());
45}
46
47ExecutorResolver::ResolveResult
48SimpleExecutorDylibManager::resolve(ExecutorAddr Resolver,
49 RemoteSymbolLookupSet Lookup) {
50 using TmpResult = MSVCPExpected<std::vector<std::optional<ExecutorAddr>>>;
51 std::promise<TmpResult> P;
52 auto F = P.get_future();
53 Resolver.toPtr<ExecutorResolver *>()->resolveAsync(
54 L: std::move(Lookup), OnResolve: [&](TmpResult R) { P.set_value(std::move(R)); });
55 return F.get();
56}
57
58Error SimpleExecutorDylibManager::shutdown() {
59
60 DylibSet DS;
61 {
62 std::lock_guard<std::mutex> Lock(M);
63 std::swap(a&: DS, b&: Dylibs);
64 }
65
66 // There is no removal of dylibs at the moment, so nothing to do here.
67 return Error::success();
68}
69
70void SimpleExecutorDylibManager::addBootstrapSymbols(
71 StringMap<ExecutorAddr> &M) {
72 M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(Ptr: this);
73 M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
74 ExecutorAddr::fromPtr(Ptr: &openWrapper);
75 M[rt::SimpleExecutorDylibManagerResolveWrapperName] =
76 ExecutorAddr::fromPtr(Ptr: &resolveWrapper);
77
78 {
79 // Also provide NativeDylibManager symbols for compatibility with
80 // controllers configured to use the ORC runtime's NativeDylibManager
81 // interface.
82 // FIXME: We should codify a "simple" dylib manager interface and make
83 // SimpleExecutorDylibManager its LLVM-based implementation, and
84 // NativeDylibManager its ORC-runtime implementation.
85 const auto &SNs = rt::orc_rt_NativeDylibManagerSPSSymbols;
86 M[SNs.InstanceName] = ExecutorAddr::fromPtr(Ptr: this);
87 M[SNs.OpenName] = ExecutorAddr::fromPtr(Ptr: &openWrapper);
88 M[SNs.ResolveName] = ExecutorAddr::fromPtr(Ptr: &resolveWrapper);
89 }
90}
91
92llvm::orc::shared::CWrapperFunctionBuffer
93SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
94 return shared::
95 WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
96 ArgData, ArgSize,
97 Handler: shared::makeMethodWrapperHandler(
98 Method: &SimpleExecutorDylibManager::open))
99 .release();
100}
101
102llvm::orc::shared::CWrapperFunctionBuffer
103SimpleExecutorDylibManager::resolveWrapper(const char *ArgData,
104 size_t ArgSize) {
105 return shared::WrapperFunction<
106 rt::SPSSimpleExecutorDylibManagerResolveSignature>::
107 handle(ArgData, ArgSize,
108 Handler: shared::makeMethodWrapperHandler(
109 Method: &SimpleExecutorDylibManager::resolve))
110 .release();
111}
112
113} // namespace rt_bootstrap
114} // end namespace orc
115} // end namespace llvm
116