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