1349cc55cSDimitry Andric //===--- SimpleExecutorDylibManager.cpp - Executor-side dylib management --===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
10349cc55cSDimitry Andric 
11349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12349cc55cSDimitry Andric #include "llvm/Support/FormatVariadic.h"
13349cc55cSDimitry Andric 
14349cc55cSDimitry Andric #define DEBUG_TYPE "orc"
15349cc55cSDimitry Andric 
16349cc55cSDimitry Andric namespace llvm {
17349cc55cSDimitry Andric namespace orc {
18349cc55cSDimitry Andric namespace rt_bootstrap {
19349cc55cSDimitry Andric 
~SimpleExecutorDylibManager()20349cc55cSDimitry Andric SimpleExecutorDylibManager::~SimpleExecutorDylibManager() {
21349cc55cSDimitry Andric   assert(Dylibs.empty() && "shutdown not called?");
22349cc55cSDimitry Andric }
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric Expected<tpctypes::DylibHandle>
open(const std::string & Path,uint64_t Mode)25349cc55cSDimitry Andric SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
26349cc55cSDimitry Andric   if (Mode != 0)
27349cc55cSDimitry Andric     return make_error<StringError>("open: non-zero mode bits not yet supported",
28349cc55cSDimitry Andric                                    inconvertibleErrorCode());
29349cc55cSDimitry Andric 
30349cc55cSDimitry Andric   const char *PathCStr = Path.empty() ? nullptr : Path.c_str();
31349cc55cSDimitry Andric   std::string ErrMsg;
32349cc55cSDimitry Andric 
33349cc55cSDimitry Andric   auto DL = sys::DynamicLibrary::getPermanentLibrary(PathCStr, &ErrMsg);
34349cc55cSDimitry Andric   if (!DL.isValid())
35349cc55cSDimitry Andric     return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
36349cc55cSDimitry Andric 
37349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(M);
38bdd1243dSDimitry Andric   auto H = ExecutorAddr::fromPtr(DL.getOSSpecificHandle());
39bdd1243dSDimitry Andric   Dylibs.insert(DL.getOSSpecificHandle());
40bdd1243dSDimitry Andric   return H;
41349cc55cSDimitry Andric }
42349cc55cSDimitry Andric 
43*1db9f3b2SDimitry Andric Expected<std::vector<ExecutorSymbolDef>>
lookup(tpctypes::DylibHandle H,const RemoteSymbolLookupSet & L)44349cc55cSDimitry Andric SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
45349cc55cSDimitry Andric                                    const RemoteSymbolLookupSet &L) {
46*1db9f3b2SDimitry Andric   std::vector<ExecutorSymbolDef> Result;
47bdd1243dSDimitry Andric   auto DL = sys::DynamicLibrary(H.toPtr<void *>());
48349cc55cSDimitry Andric 
49349cc55cSDimitry Andric   for (const auto &E : L) {
50349cc55cSDimitry Andric     if (E.Name.empty()) {
51349cc55cSDimitry Andric       if (E.Required)
52349cc55cSDimitry Andric         return make_error<StringError>("Required address for empty symbol \"\"",
53349cc55cSDimitry Andric                                        inconvertibleErrorCode());
54349cc55cSDimitry Andric       else
55*1db9f3b2SDimitry Andric         Result.push_back(ExecutorSymbolDef());
56349cc55cSDimitry Andric     } else {
57349cc55cSDimitry Andric 
58349cc55cSDimitry Andric       const char *DemangledSymName = E.Name.c_str();
59349cc55cSDimitry Andric #ifdef __APPLE__
60349cc55cSDimitry Andric       if (E.Name.front() != '_')
61349cc55cSDimitry Andric         return make_error<StringError>(Twine("MachO symbol \"") + E.Name +
62349cc55cSDimitry Andric                                            "\" missing leading '_'",
63349cc55cSDimitry Andric                                        inconvertibleErrorCode());
64349cc55cSDimitry Andric       ++DemangledSymName;
65349cc55cSDimitry Andric #endif
66349cc55cSDimitry Andric 
67349cc55cSDimitry Andric       void *Addr = DL.getAddressOfSymbol(DemangledSymName);
68349cc55cSDimitry Andric       if (!Addr && E.Required)
69349cc55cSDimitry Andric         return make_error<StringError>(Twine("Missing definition for ") +
70349cc55cSDimitry Andric                                            DemangledSymName,
71349cc55cSDimitry Andric                                        inconvertibleErrorCode());
72349cc55cSDimitry Andric 
73*1db9f3b2SDimitry Andric       // FIXME: determine accurate JITSymbolFlags.
74*1db9f3b2SDimitry Andric       Result.push_back({ExecutorAddr::fromPtr(Addr), JITSymbolFlags::Exported});
75349cc55cSDimitry Andric     }
76349cc55cSDimitry Andric   }
77349cc55cSDimitry Andric 
78349cc55cSDimitry Andric   return Result;
79349cc55cSDimitry Andric }
80349cc55cSDimitry Andric 
shutdown()81349cc55cSDimitry Andric Error SimpleExecutorDylibManager::shutdown() {
82349cc55cSDimitry Andric 
83bdd1243dSDimitry Andric   DylibSet DS;
84349cc55cSDimitry Andric   {
85349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(M);
86bdd1243dSDimitry Andric     std::swap(DS, Dylibs);
87349cc55cSDimitry Andric   }
88349cc55cSDimitry Andric 
89349cc55cSDimitry Andric   // There is no removal of dylibs at the moment, so nothing to do here.
90349cc55cSDimitry Andric   return Error::success();
91349cc55cSDimitry Andric }
92349cc55cSDimitry Andric 
addBootstrapSymbols(StringMap<ExecutorAddr> & M)93349cc55cSDimitry Andric void SimpleExecutorDylibManager::addBootstrapSymbols(
94349cc55cSDimitry Andric     StringMap<ExecutorAddr> &M) {
95349cc55cSDimitry Andric   M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(this);
96349cc55cSDimitry Andric   M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
97349cc55cSDimitry Andric       ExecutorAddr::fromPtr(&openWrapper);
98349cc55cSDimitry Andric   M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
99349cc55cSDimitry Andric       ExecutorAddr::fromPtr(&lookupWrapper);
100349cc55cSDimitry Andric }
101349cc55cSDimitry Andric 
102349cc55cSDimitry Andric llvm::orc::shared::CWrapperFunctionResult
openWrapper(const char * ArgData,size_t ArgSize)103349cc55cSDimitry Andric SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
104349cc55cSDimitry Andric   return shared::
105349cc55cSDimitry Andric       WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
106349cc55cSDimitry Andric              ArgData, ArgSize,
107349cc55cSDimitry Andric              shared::makeMethodWrapperHandler(
108349cc55cSDimitry Andric                  &SimpleExecutorDylibManager::open))
109349cc55cSDimitry Andric           .release();
110349cc55cSDimitry Andric }
111349cc55cSDimitry Andric 
112349cc55cSDimitry Andric llvm::orc::shared::CWrapperFunctionResult
lookupWrapper(const char * ArgData,size_t ArgSize)113349cc55cSDimitry Andric SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
114349cc55cSDimitry Andric   return shared::
115349cc55cSDimitry Andric       WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
116349cc55cSDimitry Andric              ArgData, ArgSize,
117349cc55cSDimitry Andric              shared::makeMethodWrapperHandler(
118349cc55cSDimitry Andric                  &SimpleExecutorDylibManager::lookup))
119349cc55cSDimitry Andric           .release();
120349cc55cSDimitry Andric }
121349cc55cSDimitry Andric 
122349cc55cSDimitry Andric } // namespace rt_bootstrap
123349cc55cSDimitry Andric } // end namespace orc
124349cc55cSDimitry Andric } // end namespace llvm
125