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