aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.cpp
blob: 8da6d1b0237724b658782813148b35f6b9c15308 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//===--- SimpleExecutorDylibManager.cpp - Executor-side dylib management --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"

#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"

#include "llvm/Support/MSVCErrorWorkarounds.h"

#include <future>

#define DEBUG_TYPE "orc"

namespace llvm {
namespace orc {
namespace rt_bootstrap {

SimpleExecutorDylibManager::~SimpleExecutorDylibManager() {
  assert(Dylibs.empty() && "shutdown not called?");
}

Expected<tpctypes::DylibHandle>
SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) {
  if (Mode != 0)
    return make_error<StringError>("open: non-zero mode bits not yet supported",
                                   inconvertibleErrorCode());

  const char *PathCStr = Path.empty() ? nullptr : Path.c_str();
  std::string ErrMsg;

  auto DL = sys::DynamicLibrary::getPermanentLibrary(PathCStr, &ErrMsg);
  if (!DL.isValid())
    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());

  std::lock_guard<std::mutex> Lock(M);
  auto H = ExecutorAddr::fromPtr(DL.getOSSpecificHandle());
  Resolvers.push_back(std::make_unique<DylibSymbolResolver>(H));
  Dylibs.insert(DL.getOSSpecificHandle());
  return ExecutorAddr::fromPtr(Resolvers.back().get());
}

Error SimpleExecutorDylibManager::shutdown() {

  DylibSet DS;
  {
    std::lock_guard<std::mutex> Lock(M);
    std::swap(DS, Dylibs);
  }

  // There is no removal of dylibs at the moment, so nothing to do here.
  return Error::success();
}

void SimpleExecutorDylibManager::addBootstrapSymbols(
    StringMap<ExecutorAddr> &M) {
  M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(this);
  M[rt::SimpleExecutorDylibManagerOpenWrapperName] =
      ExecutorAddr::fromPtr(&openWrapper);
  M[rt::SimpleExecutorDylibManagerResolveWrapperName] =
      ExecutorAddr::fromPtr(&resolveWrapper);
}

llvm::orc::shared::CWrapperFunctionBuffer
SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) {
  return shared::
      WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle(
             ArgData, ArgSize,
             shared::makeMethodWrapperHandler(
                 &SimpleExecutorDylibManager::open))
          .release();
}

llvm::orc::shared::CWrapperFunctionBuffer
SimpleExecutorDylibManager::resolveWrapper(const char *ArgData,
                                           size_t ArgSize) {
  using ResolveResult = ExecutorResolver::ResolveResult;
  return shared::WrapperFunction<
             rt::SPSSimpleExecutorDylibManagerResolveSignature>::
      handle(ArgData, ArgSize,
             [](ExecutorAddr Obj, RemoteSymbolLookupSet L) -> ResolveResult {
               using TmpResult =
                   MSVCPExpected<std::vector<std::optional<ExecutorSymbolDef>>>;
               std::promise<TmpResult> P;
               auto F = P.get_future();
               Obj.toPtr<ExecutorResolver *>()->resolveAsync(
                   std::move(L),
                   [&](TmpResult R) { P.set_value(std::move(R)); });
               return F.get();
             })
          .release();
}

} // namespace rt_bootstrap
} // end namespace orc
} // end namespace llvm