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<ExecutorAddr>>
43  SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H,
44                                     const RemoteSymbolLookupSet &L) {
45    std::vector<ExecutorAddr> 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(ExecutorAddr());
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(ExecutorAddr::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<ExecutorAddr> &M) {
100    M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(this);
101    M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
102        ExecutorAddr::fromPtr(&openWrapper);
103    M[rt::SimpleExecutorDylibManagerLookupWrapperName] =
104        ExecutorAddr::fromPtr(&lookupWrapper);
105  }
106  
107  llvm::orc::shared::CWrapperFunctionResult
108  SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
109    return shared::
110        WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
111               ArgData, ArgSize,
112               shared::makeMethodWrapperHandler(
113                   &SimpleExecutorDylibManager::open))
114            .release();
115  }
116  
117  llvm::orc::shared::CWrapperFunctionResult
118  SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) {
119    return shared::
120        WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle(
121               ArgData, ArgSize,
122               shared::makeMethodWrapperHandler(
123                   &SimpleExecutorDylibManager::lookup))
124            .release();
125  }
126  
127  } // namespace rt_bootstrap
128  } // end namespace orc
129  } // end namespace llvm
130