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   Dylibs[NextId] = std::move(DL);
39   return NextId++;
40 }
41 
42 Expected<std::vector<ExecutorAddress>>
43 SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
44                                    const RemoteSymbolLookupSet &L) {
45   std::vector<ExecutorAddress> Result;
46 
47   std::lock_guard<std::mutex> Lock(M);
48   auto I = Dylibs.find(H);
49   if (I == Dylibs.end())
50     return make_error<StringError>("No dylib for handle " + formatv("{0:x}", H),
51                                    inconvertibleErrorCode());
52   auto &DL = I->second;
53 
54   for (const auto &E : L) {
55 
56     if (E.Name.empty()) {
57       if (E.Required)
58         return make_error<StringError>("Required address for empty symbol \"\"",
59                                        inconvertibleErrorCode());
60       else
61         Result.push_back(ExecutorAddress());
62     } else {
63 
64       const char *DemangledSymName = E.Name.c_str();
65 #ifdef __APPLE__
66       if (E.Name.front() != '_')
67         return make_error<StringError>(Twine("MachO symbol \"") + E.Name +
68                                            "\" missing leading '_'",
69                                        inconvertibleErrorCode());
70       ++DemangledSymName;
71 #endif
72 
73       void *Addr = DL.getAddressOfSymbol(DemangledSymName);
74       if (!Addr && E.Required)
75         return make_error<StringError>(Twine("Missing definition for ") +
76                                            DemangledSymName,
77                                        inconvertibleErrorCode());
78 
79       Result.push_back(ExecutorAddress::fromPtr(Addr));
80     }
81   }
82 
83   return Result;
84 }
85 
86 Error SimpleExecutorDylibManager::shutdown() {
87 
88   DylibsMap DM;
89   {
90     std::lock_guard<std::mutex> Lock(M);
91     std::swap(DM, Dylibs);
92   }
93 
94   // There is no removal of dylibs at the moment, so nothing to do here.
95   return Error::success();
96 }
97 
98 void SimpleExecutorDylibManager::addBootstrapSymbols(
99     StringMap<ExecutorAddress> &M) {
100   M[rt::SimpleExecutorDylibManagerInstanceName] =
101       ExecutorAddress::fromPtr(this);
102   M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
103       ExecutorAddress::fromPtr(&openWrapper);
104   M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
105       ExecutorAddress::fromPtr(&lookupWrapper);
106 }
107 
108 llvm::orc::shared::detail::CWrapperFunctionResult
109 SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
110   return shared::
111       WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
112              ArgData, ArgSize,
113              shared::makeMethodWrapperHandler(
114                  &SimpleExecutorDylibManager::open))
115           .release();
116 }
117 
118 llvm::orc::shared::detail::CWrapperFunctionResult
119 SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
120   return shared::
121       WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
122              ArgData, ArgSize,
123              shared::makeMethodWrapperHandler(
124                  &SimpleExecutorDylibManager::lookup))
125           .release();
126 }
127 
128 } // namespace rt_bootstrap
129 } // end namespace orc
130 } // end namespace llvm
131