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