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