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#include "llvm/Support/FormatVariadic.h"
13
14#define DEBUG_TYPE "orc"
15
16namespace llvm {
17namespace orc {
18namespace rt_bootstrap {
19
20SimpleExecutorDylibManager::~SimpleExecutorDylibManager() {
21 assert(Dylibs.empty() && "shutdown not called?");
22}
23
24Expected<tpctypes::DylibHandle>
25SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
26 if (Mode != 0)
27 return make_error<StringError>(Args: "open: non-zero mode bits not yet supported",
28 Args: inconvertibleErrorCode());
29
30 const char *PathCStr = Path.empty() ? nullptr : Path.c_str();
31 std::string ErrMsg;
32
33 auto DL = sys::DynamicLibrary::getPermanentLibrary(filename: PathCStr, errMsg: &ErrMsg);
34 if (!DL.isValid())
35 return make_error<StringError>(Args: std::move(ErrMsg), Args: inconvertibleErrorCode());
36
37 std::lock_guard<std::mutex> Lock(M);
38 auto H = ExecutorAddr::fromPtr(Ptr: DL.getOSSpecificHandle());
39 Dylibs.insert(V: DL.getOSSpecificHandle());
40 return H;
41}
42
43Expected<std::vector<ExecutorSymbolDef>>
44SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
45 const RemoteSymbolLookupSet &L) {
46 std::vector<ExecutorSymbolDef> Result;
47 auto DL = sys::DynamicLibrary(H.toPtr<void *>());
48
49 for (const auto &E : L) {
50 if (E.Name.empty()) {
51 if (E.Required)
52 return make_error<StringError>(Args: "Required address for empty symbol \"\"",
53 Args: inconvertibleErrorCode());
54 else
55 Result.push_back(x: ExecutorSymbolDef());
56 } else {
57
58 const char *DemangledSymName = E.Name.c_str();
59#ifdef __APPLE__
60 if (E.Name.front() != '_')
61 return make_error<StringError>(Twine("MachO symbol \"") + E.Name +
62 "\" missing leading '_'",
63 inconvertibleErrorCode());
64 ++DemangledSymName;
65#endif
66
67 void *Addr = DL.getAddressOfSymbol(symbolName: DemangledSymName);
68 if (!Addr && E.Required)
69 return make_error<StringError>(Args: Twine("Missing definition for ") +
70 DemangledSymName,
71 Args: inconvertibleErrorCode());
72
73 // FIXME: determine accurate JITSymbolFlags.
74 Result.push_back(x: {ExecutorAddr::fromPtr(Ptr: Addr), JITSymbolFlags::Exported});
75 }
76 }
77
78 return Result;
79}
80
81Error SimpleExecutorDylibManager::shutdown() {
82
83 DylibSet DS;
84 {
85 std::lock_guard<std::mutex> Lock(M);
86 std::swap(a&: DS, b&: Dylibs);
87 }
88
89 // There is no removal of dylibs at the moment, so nothing to do here.
90 return Error::success();
91}
92
93void SimpleExecutorDylibManager::addBootstrapSymbols(
94 StringMap<ExecutorAddr> &M) {
95 M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(Ptr: this);
96 M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
97 ExecutorAddr::fromPtr(Ptr: &openWrapper);
98 M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
99 ExecutorAddr::fromPtr(Ptr: &lookupWrapper);
100}
101
102llvm::orc::shared::CWrapperFunctionResult
103SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
104 return shared::
105 WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
106 ArgData, ArgSize,
107 Handler: shared::makeMethodWrapperHandler(
108 Method: &SimpleExecutorDylibManager::open))
109 .release();
110}
111
112llvm::orc::shared::CWrapperFunctionResult
113SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
114 return shared::
115 WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
116 ArgData, ArgSize,
117 Handler: shared::makeMethodWrapperHandler(
118 Method: &SimpleExecutorDylibManager::lookup))
119 .release();
120}
121
122} // namespace rt_bootstrap
123} // end namespace orc
124} // end namespace llvm
125