1a2c1cf09SLang Hames //===--- SimpleExecutorDylibManager.cpp - Executor-side dylib management --===//
2a2c1cf09SLang Hames //
3a2c1cf09SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a2c1cf09SLang Hames // See https://llvm.org/LICENSE.txt for license information.
5a2c1cf09SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a2c1cf09SLang Hames //
7a2c1cf09SLang Hames //===----------------------------------------------------------------------===//
8a2c1cf09SLang Hames
9a2c1cf09SLang Hames #include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
10a2c1cf09SLang Hames
11a2c1cf09SLang Hames #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12a2c1cf09SLang Hames #include "llvm/Support/FormatVariadic.h"
13a2c1cf09SLang Hames
14a2c1cf09SLang Hames #define DEBUG_TYPE "orc"
15a2c1cf09SLang Hames
16a2c1cf09SLang Hames namespace llvm {
17a2c1cf09SLang Hames namespace orc {
18a2c1cf09SLang Hames namespace rt_bootstrap {
19a2c1cf09SLang Hames
~SimpleExecutorDylibManager()20a2c1cf09SLang Hames SimpleExecutorDylibManager::~SimpleExecutorDylibManager() {
21a2c1cf09SLang Hames assert(Dylibs.empty() && "shutdown not called?");
22a2c1cf09SLang Hames }
23a2c1cf09SLang Hames
24a2c1cf09SLang Hames Expected<tpctypes::DylibHandle>
open(const std::string & Path,uint64_t Mode)25a2c1cf09SLang Hames SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
26a2c1cf09SLang Hames if (Mode != 0)
27a2c1cf09SLang Hames return make_error<StringError>("open: non-zero mode bits not yet supported",
28a2c1cf09SLang Hames inconvertibleErrorCode());
29a2c1cf09SLang Hames
30a2c1cf09SLang Hames const char *PathCStr = Path.empty() ? nullptr : Path.c_str();
31a2c1cf09SLang Hames std::string ErrMsg;
32a2c1cf09SLang Hames
33a2c1cf09SLang Hames auto DL = sys::DynamicLibrary::getPermanentLibrary(PathCStr, &ErrMsg);
34a2c1cf09SLang Hames if (!DL.isValid())
35a2c1cf09SLang Hames return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
36a2c1cf09SLang Hames
37a2c1cf09SLang Hames std::lock_guard<std::mutex> Lock(M);
38a2c1cf09SLang Hames Dylibs[NextId] = std::move(DL);
39a2c1cf09SLang Hames return NextId++;
40a2c1cf09SLang Hames }
41a2c1cf09SLang Hames
42ef391df2SLang Hames Expected<std::vector<ExecutorAddr>>
lookup(tpctypes::DylibHandle H,const RemoteSymbolLookupSet & L)43a2c1cf09SLang Hames SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
44a2c1cf09SLang Hames const RemoteSymbolLookupSet &L) {
45ef391df2SLang Hames std::vector<ExecutorAddr> Result;
46a2c1cf09SLang Hames
47a2c1cf09SLang Hames std::lock_guard<std::mutex> Lock(M);
48a2c1cf09SLang Hames auto I = Dylibs.find(H);
49a2c1cf09SLang Hames if (I == Dylibs.end())
50a2c1cf09SLang Hames return make_error<StringError>("No dylib for handle " + formatv("{0:x}", H),
51a2c1cf09SLang Hames inconvertibleErrorCode());
52a2c1cf09SLang Hames auto &DL = I->second;
53a2c1cf09SLang Hames
54a2c1cf09SLang Hames for (const auto &E : L) {
55a2c1cf09SLang Hames
56a2c1cf09SLang Hames if (E.Name.empty()) {
57a2c1cf09SLang Hames if (E.Required)
58a2c1cf09SLang Hames return make_error<StringError>("Required address for empty symbol \"\"",
59a2c1cf09SLang Hames inconvertibleErrorCode());
60a2c1cf09SLang Hames else
61ef391df2SLang Hames Result.push_back(ExecutorAddr());
62a2c1cf09SLang Hames } else {
63a2c1cf09SLang Hames
64a2c1cf09SLang Hames const char *DemangledSymName = E.Name.c_str();
65a2c1cf09SLang Hames #ifdef __APPLE__
66a2c1cf09SLang Hames if (E.Name.front() != '_')
67a2c1cf09SLang Hames return make_error<StringError>(Twine("MachO symbol \"") + E.Name +
68a2c1cf09SLang Hames "\" missing leading '_'",
69a2c1cf09SLang Hames inconvertibleErrorCode());
70a2c1cf09SLang Hames ++DemangledSymName;
71a2c1cf09SLang Hames #endif
72a2c1cf09SLang Hames
73a2c1cf09SLang Hames void *Addr = DL.getAddressOfSymbol(DemangledSymName);
74a2c1cf09SLang Hames if (!Addr && E.Required)
75a2c1cf09SLang Hames return make_error<StringError>(Twine("Missing definition for ") +
76a2c1cf09SLang Hames DemangledSymName,
77a2c1cf09SLang Hames inconvertibleErrorCode());
78a2c1cf09SLang Hames
79ef391df2SLang Hames Result.push_back(ExecutorAddr::fromPtr(Addr));
80a2c1cf09SLang Hames }
81a2c1cf09SLang Hames }
82a2c1cf09SLang Hames
83a2c1cf09SLang Hames return Result;
84a2c1cf09SLang Hames }
85a2c1cf09SLang Hames
shutdown()86a2c1cf09SLang Hames Error SimpleExecutorDylibManager::shutdown() {
87a2c1cf09SLang Hames
88a2c1cf09SLang Hames DylibsMap DM;
89a2c1cf09SLang Hames {
90a2c1cf09SLang Hames std::lock_guard<std::mutex> Lock(M);
91a2c1cf09SLang Hames std::swap(DM, Dylibs);
92a2c1cf09SLang Hames }
93a2c1cf09SLang Hames
94a2c1cf09SLang Hames // There is no removal of dylibs at the moment, so nothing to do here.
95a2c1cf09SLang Hames return Error::success();
96a2c1cf09SLang Hames }
97a2c1cf09SLang Hames
addBootstrapSymbols(StringMap<ExecutorAddr> & M)98a2c1cf09SLang Hames void SimpleExecutorDylibManager::addBootstrapSymbols(
99ef391df2SLang Hames StringMap<ExecutorAddr> &M) {
100ef391df2SLang Hames M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(this);
101a2c1cf09SLang Hames M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
102ef391df2SLang Hames ExecutorAddr::fromPtr(&openWrapper);
103a2c1cf09SLang Hames M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
104ef391df2SLang Hames ExecutorAddr::fromPtr(&lookupWrapper);
105a2c1cf09SLang Hames }
106a2c1cf09SLang Hames
107*213666f8SLang Hames llvm::orc::shared::CWrapperFunctionResult
openWrapper(const char * ArgData,size_t ArgSize)108a2c1cf09SLang Hames SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
109a2c1cf09SLang Hames return shared::
110a2c1cf09SLang Hames WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
111a2c1cf09SLang Hames ArgData, ArgSize,
112a2c1cf09SLang Hames shared::makeMethodWrapperHandler(
113a2c1cf09SLang Hames &SimpleExecutorDylibManager::open))
114a2c1cf09SLang Hames .release();
115a2c1cf09SLang Hames }
116a2c1cf09SLang Hames
117*213666f8SLang Hames llvm::orc::shared::CWrapperFunctionResult
lookupWrapper(const char * ArgData,size_t ArgSize)118a2c1cf09SLang Hames SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
119a2c1cf09SLang Hames return shared::
120a2c1cf09SLang Hames WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
121a2c1cf09SLang Hames ArgData, ArgSize,
122a2c1cf09SLang Hames shared::makeMethodWrapperHandler(
123a2c1cf09SLang Hames &SimpleExecutorDylibManager::lookup))
124a2c1cf09SLang Hames .release();
125a2c1cf09SLang Hames }
126a2c1cf09SLang Hames
127a2c1cf09SLang Hames } // namespace rt_bootstrap
128a2c1cf09SLang Hames } // end namespace orc
129a2c1cf09SLang Hames } // end namespace llvm
130