xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1*349cc55cSDimitry Andric //===------- SimpleRemoteEPC.cpp -- Simple remote executor control --------===//
2*349cc55cSDimitry Andric //
3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*349cc55cSDimitry Andric //
7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8*349cc55cSDimitry Andric 
9*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
10*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
11*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
12*349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
13*349cc55cSDimitry Andric #include "llvm/Support/FormatVariadic.h"
14*349cc55cSDimitry Andric 
15*349cc55cSDimitry Andric #define DEBUG_TYPE "orc"
16*349cc55cSDimitry Andric 
17*349cc55cSDimitry Andric namespace llvm {
18*349cc55cSDimitry Andric namespace orc {
19*349cc55cSDimitry Andric 
20*349cc55cSDimitry Andric SimpleRemoteEPC::~SimpleRemoteEPC() {
21*349cc55cSDimitry Andric #ifndef NDEBUG
22*349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
23*349cc55cSDimitry Andric   assert(Disconnected && "Destroyed without disconnection");
24*349cc55cSDimitry Andric #endif // NDEBUG
25*349cc55cSDimitry Andric }
26*349cc55cSDimitry Andric 
27*349cc55cSDimitry Andric Expected<tpctypes::DylibHandle>
28*349cc55cSDimitry Andric SimpleRemoteEPC::loadDylib(const char *DylibPath) {
29*349cc55cSDimitry Andric   return DylibMgr->open(DylibPath, 0);
30*349cc55cSDimitry Andric }
31*349cc55cSDimitry Andric 
32*349cc55cSDimitry Andric Expected<std::vector<tpctypes::LookupResult>>
33*349cc55cSDimitry Andric SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) {
34*349cc55cSDimitry Andric   std::vector<tpctypes::LookupResult> Result;
35*349cc55cSDimitry Andric 
36*349cc55cSDimitry Andric   for (auto &Element : Request) {
37*349cc55cSDimitry Andric     if (auto R = DylibMgr->lookup(Element.Handle, Element.Symbols)) {
38*349cc55cSDimitry Andric       Result.push_back({});
39*349cc55cSDimitry Andric       Result.back().reserve(R->size());
40*349cc55cSDimitry Andric       for (auto Addr : *R)
41*349cc55cSDimitry Andric         Result.back().push_back(Addr.getValue());
42*349cc55cSDimitry Andric     } else
43*349cc55cSDimitry Andric       return R.takeError();
44*349cc55cSDimitry Andric   }
45*349cc55cSDimitry Andric   return std::move(Result);
46*349cc55cSDimitry Andric }
47*349cc55cSDimitry Andric 
48*349cc55cSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsMain(ExecutorAddr MainFnAddr,
49*349cc55cSDimitry Andric                                              ArrayRef<std::string> Args) {
50*349cc55cSDimitry Andric   int64_t Result = 0;
51*349cc55cSDimitry Andric   if (auto Err = callSPSWrapper<rt::SPSRunAsMainSignature>(
52*349cc55cSDimitry Andric           RunAsMainAddr, Result, ExecutorAddr(MainFnAddr), Args))
53*349cc55cSDimitry Andric     return std::move(Err);
54*349cc55cSDimitry Andric   return Result;
55*349cc55cSDimitry Andric }
56*349cc55cSDimitry Andric 
57*349cc55cSDimitry Andric void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr,
58*349cc55cSDimitry Andric                                        IncomingWFRHandler OnComplete,
59*349cc55cSDimitry Andric                                        ArrayRef<char> ArgBuffer) {
60*349cc55cSDimitry Andric   uint64_t SeqNo;
61*349cc55cSDimitry Andric   {
62*349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
63*349cc55cSDimitry Andric     SeqNo = getNextSeqNo();
64*349cc55cSDimitry Andric     assert(!PendingCallWrapperResults.count(SeqNo) && "SeqNo already in use");
65*349cc55cSDimitry Andric     PendingCallWrapperResults[SeqNo] = std::move(OnComplete);
66*349cc55cSDimitry Andric   }
67*349cc55cSDimitry Andric 
68*349cc55cSDimitry Andric   if (auto Err = sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo,
69*349cc55cSDimitry Andric                              WrapperFnAddr, ArgBuffer)) {
70*349cc55cSDimitry Andric     IncomingWFRHandler H;
71*349cc55cSDimitry Andric 
72*349cc55cSDimitry Andric     // We just registered OnComplete, but there may be a race between this
73*349cc55cSDimitry Andric     // thread returning from sendMessage and handleDisconnect being called from
74*349cc55cSDimitry Andric     // the transport's listener thread. If handleDisconnect gets there first
75*349cc55cSDimitry Andric     // then it will have failed 'H' for us. If we get there first (or if
76*349cc55cSDimitry Andric     // handleDisconnect already ran) then we need to take care of it.
77*349cc55cSDimitry Andric     {
78*349cc55cSDimitry Andric       std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
79*349cc55cSDimitry Andric       auto I = PendingCallWrapperResults.find(SeqNo);
80*349cc55cSDimitry Andric       if (I != PendingCallWrapperResults.end()) {
81*349cc55cSDimitry Andric         H = std::move(I->second);
82*349cc55cSDimitry Andric         PendingCallWrapperResults.erase(I);
83*349cc55cSDimitry Andric       }
84*349cc55cSDimitry Andric     }
85*349cc55cSDimitry Andric 
86*349cc55cSDimitry Andric     if (H)
87*349cc55cSDimitry Andric       H(shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
88*349cc55cSDimitry Andric 
89*349cc55cSDimitry Andric     getExecutionSession().reportError(std::move(Err));
90*349cc55cSDimitry Andric   }
91*349cc55cSDimitry Andric }
92*349cc55cSDimitry Andric 
93*349cc55cSDimitry Andric Error SimpleRemoteEPC::disconnect() {
94*349cc55cSDimitry Andric   T->disconnect();
95*349cc55cSDimitry Andric   D->shutdown();
96*349cc55cSDimitry Andric   std::unique_lock<std::mutex> Lock(SimpleRemoteEPCMutex);
97*349cc55cSDimitry Andric   DisconnectCV.wait(Lock, [this] { return Disconnected; });
98*349cc55cSDimitry Andric   return std::move(DisconnectErr);
99*349cc55cSDimitry Andric }
100*349cc55cSDimitry Andric 
101*349cc55cSDimitry Andric Expected<SimpleRemoteEPCTransportClient::HandleMessageAction>
102*349cc55cSDimitry Andric SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
103*349cc55cSDimitry Andric                                ExecutorAddr TagAddr,
104*349cc55cSDimitry Andric                                SimpleRemoteEPCArgBytesVector ArgBytes) {
105*349cc55cSDimitry Andric 
106*349cc55cSDimitry Andric   LLVM_DEBUG({
107*349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC::handleMessage: opc = ";
108*349cc55cSDimitry Andric     switch (OpC) {
109*349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Setup:
110*349cc55cSDimitry Andric       dbgs() << "Setup";
111*349cc55cSDimitry Andric       assert(SeqNo == 0 && "Non-zero SeqNo for Setup?");
112*349cc55cSDimitry Andric       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Setup?");
113*349cc55cSDimitry Andric       break;
114*349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Hangup:
115*349cc55cSDimitry Andric       dbgs() << "Hangup";
116*349cc55cSDimitry Andric       assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");
117*349cc55cSDimitry Andric       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Hangup?");
118*349cc55cSDimitry Andric       break;
119*349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Result:
120*349cc55cSDimitry Andric       dbgs() << "Result";
121*349cc55cSDimitry Andric       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Result?");
122*349cc55cSDimitry Andric       break;
123*349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::CallWrapper:
124*349cc55cSDimitry Andric       dbgs() << "CallWrapper";
125*349cc55cSDimitry Andric       break;
126*349cc55cSDimitry Andric     }
127*349cc55cSDimitry Andric     dbgs() << ", seqno = " << SeqNo
128*349cc55cSDimitry Andric            << ", tag-addr = " << formatv("{0:x}", TagAddr.getValue())
129*349cc55cSDimitry Andric            << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())
130*349cc55cSDimitry Andric            << " bytes\n";
131*349cc55cSDimitry Andric   });
132*349cc55cSDimitry Andric 
133*349cc55cSDimitry Andric   using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>;
134*349cc55cSDimitry Andric   if (static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC))
135*349cc55cSDimitry Andric     return make_error<StringError>("Unexpected opcode",
136*349cc55cSDimitry Andric                                    inconvertibleErrorCode());
137*349cc55cSDimitry Andric 
138*349cc55cSDimitry Andric   switch (OpC) {
139*349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::Setup:
140*349cc55cSDimitry Andric     if (auto Err = handleSetup(SeqNo, TagAddr, std::move(ArgBytes)))
141*349cc55cSDimitry Andric       return std::move(Err);
142*349cc55cSDimitry Andric     break;
143*349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::Hangup:
144*349cc55cSDimitry Andric     T->disconnect();
145*349cc55cSDimitry Andric     if (auto Err = handleHangup(std::move(ArgBytes)))
146*349cc55cSDimitry Andric       return std::move(Err);
147*349cc55cSDimitry Andric     return EndSession;
148*349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::Result:
149*349cc55cSDimitry Andric     if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))
150*349cc55cSDimitry Andric       return std::move(Err);
151*349cc55cSDimitry Andric     break;
152*349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::CallWrapper:
153*349cc55cSDimitry Andric     handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes));
154*349cc55cSDimitry Andric     break;
155*349cc55cSDimitry Andric   }
156*349cc55cSDimitry Andric   return ContinueSession;
157*349cc55cSDimitry Andric }
158*349cc55cSDimitry Andric 
159*349cc55cSDimitry Andric void SimpleRemoteEPC::handleDisconnect(Error Err) {
160*349cc55cSDimitry Andric   LLVM_DEBUG({
161*349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC::handleDisconnect: "
162*349cc55cSDimitry Andric            << (Err ? "failure" : "success") << "\n";
163*349cc55cSDimitry Andric   });
164*349cc55cSDimitry Andric 
165*349cc55cSDimitry Andric   PendingCallWrapperResultsMap TmpPending;
166*349cc55cSDimitry Andric 
167*349cc55cSDimitry Andric   {
168*349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
169*349cc55cSDimitry Andric     std::swap(TmpPending, PendingCallWrapperResults);
170*349cc55cSDimitry Andric   }
171*349cc55cSDimitry Andric 
172*349cc55cSDimitry Andric   for (auto &KV : TmpPending)
173*349cc55cSDimitry Andric     KV.second(
174*349cc55cSDimitry Andric         shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
175*349cc55cSDimitry Andric 
176*349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
177*349cc55cSDimitry Andric   DisconnectErr = joinErrors(std::move(DisconnectErr), std::move(Err));
178*349cc55cSDimitry Andric   Disconnected = true;
179*349cc55cSDimitry Andric   DisconnectCV.notify_all();
180*349cc55cSDimitry Andric }
181*349cc55cSDimitry Andric 
182*349cc55cSDimitry Andric Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
183*349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryManager(SimpleRemoteEPC &SREPC) {
184*349cc55cSDimitry Andric   EPCGenericJITLinkMemoryManager::SymbolAddrs SAs;
185*349cc55cSDimitry Andric   if (auto Err = SREPC.getBootstrapSymbols(
186*349cc55cSDimitry Andric           {{SAs.Allocator, rt::SimpleExecutorMemoryManagerInstanceName},
187*349cc55cSDimitry Andric            {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
188*349cc55cSDimitry Andric            {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
189*349cc55cSDimitry Andric            {SAs.Deallocate,
190*349cc55cSDimitry Andric             rt::SimpleExecutorMemoryManagerDeallocateWrapperName}}))
191*349cc55cSDimitry Andric     return std::move(Err);
192*349cc55cSDimitry Andric 
193*349cc55cSDimitry Andric   return std::make_unique<EPCGenericJITLinkMemoryManager>(SREPC, SAs);
194*349cc55cSDimitry Andric }
195*349cc55cSDimitry Andric 
196*349cc55cSDimitry Andric Expected<std::unique_ptr<ExecutorProcessControl::MemoryAccess>>
197*349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryAccess(SimpleRemoteEPC &SREPC) {
198*349cc55cSDimitry Andric   return nullptr;
199*349cc55cSDimitry Andric }
200*349cc55cSDimitry Andric 
201*349cc55cSDimitry Andric Error SimpleRemoteEPC::sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
202*349cc55cSDimitry Andric                                    ExecutorAddr TagAddr,
203*349cc55cSDimitry Andric                                    ArrayRef<char> ArgBytes) {
204*349cc55cSDimitry Andric   assert(OpC != SimpleRemoteEPCOpcode::Setup &&
205*349cc55cSDimitry Andric          "SimpleRemoteEPC sending Setup message? That's the wrong direction.");
206*349cc55cSDimitry Andric 
207*349cc55cSDimitry Andric   LLVM_DEBUG({
208*349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC::sendMessage: opc = ";
209*349cc55cSDimitry Andric     switch (OpC) {
210*349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Hangup:
211*349cc55cSDimitry Andric       dbgs() << "Hangup";
212*349cc55cSDimitry Andric       assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");
213*349cc55cSDimitry Andric       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Hangup?");
214*349cc55cSDimitry Andric       break;
215*349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Result:
216*349cc55cSDimitry Andric       dbgs() << "Result";
217*349cc55cSDimitry Andric       assert(TagAddr.getValue() == 0 && "Non-zero TagAddr for Result?");
218*349cc55cSDimitry Andric       break;
219*349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::CallWrapper:
220*349cc55cSDimitry Andric       dbgs() << "CallWrapper";
221*349cc55cSDimitry Andric       break;
222*349cc55cSDimitry Andric     default:
223*349cc55cSDimitry Andric       llvm_unreachable("Invalid opcode");
224*349cc55cSDimitry Andric     }
225*349cc55cSDimitry Andric     dbgs() << ", seqno = " << SeqNo
226*349cc55cSDimitry Andric            << ", tag-addr = " << formatv("{0:x}", TagAddr.getValue())
227*349cc55cSDimitry Andric            << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())
228*349cc55cSDimitry Andric            << " bytes\n";
229*349cc55cSDimitry Andric   });
230*349cc55cSDimitry Andric   auto Err = T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes);
231*349cc55cSDimitry Andric   LLVM_DEBUG({
232*349cc55cSDimitry Andric     if (Err)
233*349cc55cSDimitry Andric       dbgs() << "  \\--> SimpleRemoteEPC::sendMessage failed\n";
234*349cc55cSDimitry Andric   });
235*349cc55cSDimitry Andric   return Err;
236*349cc55cSDimitry Andric }
237*349cc55cSDimitry Andric 
238*349cc55cSDimitry Andric Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
239*349cc55cSDimitry Andric                                    SimpleRemoteEPCArgBytesVector ArgBytes) {
240*349cc55cSDimitry Andric   if (SeqNo != 0)
241*349cc55cSDimitry Andric     return make_error<StringError>("Setup packet SeqNo not zero",
242*349cc55cSDimitry Andric                                    inconvertibleErrorCode());
243*349cc55cSDimitry Andric 
244*349cc55cSDimitry Andric   if (TagAddr)
245*349cc55cSDimitry Andric     return make_error<StringError>("Setup packet TagAddr not zero",
246*349cc55cSDimitry Andric                                    inconvertibleErrorCode());
247*349cc55cSDimitry Andric 
248*349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
249*349cc55cSDimitry Andric   auto I = PendingCallWrapperResults.find(0);
250*349cc55cSDimitry Andric   assert(PendingCallWrapperResults.size() == 1 &&
251*349cc55cSDimitry Andric          I != PendingCallWrapperResults.end() &&
252*349cc55cSDimitry Andric          "Setup message handler not connectly set up");
253*349cc55cSDimitry Andric   auto SetupMsgHandler = std::move(I->second);
254*349cc55cSDimitry Andric   PendingCallWrapperResults.erase(I);
255*349cc55cSDimitry Andric 
256*349cc55cSDimitry Andric   auto WFR =
257*349cc55cSDimitry Andric       shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
258*349cc55cSDimitry Andric   SetupMsgHandler(std::move(WFR));
259*349cc55cSDimitry Andric   return Error::success();
260*349cc55cSDimitry Andric }
261*349cc55cSDimitry Andric 
262*349cc55cSDimitry Andric Error SimpleRemoteEPC::setup(Setup S) {
263*349cc55cSDimitry Andric   using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;
264*349cc55cSDimitry Andric 
265*349cc55cSDimitry Andric   std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP;
266*349cc55cSDimitry Andric   auto EIF = EIP.get_future();
267*349cc55cSDimitry Andric 
268*349cc55cSDimitry Andric   // Prepare a handler for the setup packet.
269*349cc55cSDimitry Andric   PendingCallWrapperResults[0] =
270*349cc55cSDimitry Andric     RunInPlace()(
271*349cc55cSDimitry Andric       [&](shared::WrapperFunctionResult SetupMsgBytes) {
272*349cc55cSDimitry Andric         if (const char *ErrMsg = SetupMsgBytes.getOutOfBandError()) {
273*349cc55cSDimitry Andric           EIP.set_value(
274*349cc55cSDimitry Andric               make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
275*349cc55cSDimitry Andric           return;
276*349cc55cSDimitry Andric         }
277*349cc55cSDimitry Andric         using SPSSerialize =
278*349cc55cSDimitry Andric             shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>;
279*349cc55cSDimitry Andric         shared::SPSInputBuffer IB(SetupMsgBytes.data(), SetupMsgBytes.size());
280*349cc55cSDimitry Andric         SimpleRemoteEPCExecutorInfo EI;
281*349cc55cSDimitry Andric         if (SPSSerialize::deserialize(IB, EI))
282*349cc55cSDimitry Andric           EIP.set_value(EI);
283*349cc55cSDimitry Andric         else
284*349cc55cSDimitry Andric           EIP.set_value(make_error<StringError>(
285*349cc55cSDimitry Andric               "Could not deserialize setup message", inconvertibleErrorCode()));
286*349cc55cSDimitry Andric       });
287*349cc55cSDimitry Andric 
288*349cc55cSDimitry Andric   // Start the transport.
289*349cc55cSDimitry Andric   if (auto Err = T->start())
290*349cc55cSDimitry Andric     return Err;
291*349cc55cSDimitry Andric 
292*349cc55cSDimitry Andric   // Wait for setup packet to arrive.
293*349cc55cSDimitry Andric   auto EI = EIF.get();
294*349cc55cSDimitry Andric   if (!EI) {
295*349cc55cSDimitry Andric     T->disconnect();
296*349cc55cSDimitry Andric     return EI.takeError();
297*349cc55cSDimitry Andric   }
298*349cc55cSDimitry Andric 
299*349cc55cSDimitry Andric   LLVM_DEBUG({
300*349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC received setup message:\n"
301*349cc55cSDimitry Andric            << "  Triple: " << EI->TargetTriple << "\n"
302*349cc55cSDimitry Andric            << "  Page size: " << EI->PageSize << "\n"
303*349cc55cSDimitry Andric            << "  Bootstrap symbols:\n";
304*349cc55cSDimitry Andric     for (const auto &KV : EI->BootstrapSymbols)
305*349cc55cSDimitry Andric       dbgs() << "    " << KV.first() << ": "
306*349cc55cSDimitry Andric              << formatv("{0:x16}", KV.second.getValue()) << "\n";
307*349cc55cSDimitry Andric   });
308*349cc55cSDimitry Andric   TargetTriple = Triple(EI->TargetTriple);
309*349cc55cSDimitry Andric   PageSize = EI->PageSize;
310*349cc55cSDimitry Andric   BootstrapSymbols = std::move(EI->BootstrapSymbols);
311*349cc55cSDimitry Andric 
312*349cc55cSDimitry Andric   if (auto Err = getBootstrapSymbols(
313*349cc55cSDimitry Andric           {{JDI.JITDispatchContext, ExecutorSessionObjectName},
314*349cc55cSDimitry Andric            {JDI.JITDispatchFunction, DispatchFnName},
315*349cc55cSDimitry Andric            {RunAsMainAddr, rt::RunAsMainWrapperName}}))
316*349cc55cSDimitry Andric     return Err;
317*349cc55cSDimitry Andric 
318*349cc55cSDimitry Andric   if (auto DM =
319*349cc55cSDimitry Andric           EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this))
320*349cc55cSDimitry Andric     DylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM));
321*349cc55cSDimitry Andric   else
322*349cc55cSDimitry Andric     return DM.takeError();
323*349cc55cSDimitry Andric 
324*349cc55cSDimitry Andric   // Set a default CreateMemoryManager if none is specified.
325*349cc55cSDimitry Andric   if (!S.CreateMemoryManager)
326*349cc55cSDimitry Andric     S.CreateMemoryManager = createDefaultMemoryManager;
327*349cc55cSDimitry Andric 
328*349cc55cSDimitry Andric   if (auto MemMgr = S.CreateMemoryManager(*this)) {
329*349cc55cSDimitry Andric     OwnedMemMgr = std::move(*MemMgr);
330*349cc55cSDimitry Andric     this->MemMgr = OwnedMemMgr.get();
331*349cc55cSDimitry Andric   } else
332*349cc55cSDimitry Andric     return MemMgr.takeError();
333*349cc55cSDimitry Andric 
334*349cc55cSDimitry Andric   // Set a default CreateMemoryAccess if none is specified.
335*349cc55cSDimitry Andric   if (!S.CreateMemoryAccess)
336*349cc55cSDimitry Andric     S.CreateMemoryAccess = createDefaultMemoryAccess;
337*349cc55cSDimitry Andric 
338*349cc55cSDimitry Andric   if (auto MemAccess = S.CreateMemoryAccess(*this)) {
339*349cc55cSDimitry Andric     OwnedMemAccess = std::move(*MemAccess);
340*349cc55cSDimitry Andric     this->MemAccess = OwnedMemAccess.get();
341*349cc55cSDimitry Andric   } else
342*349cc55cSDimitry Andric     return MemAccess.takeError();
343*349cc55cSDimitry Andric 
344*349cc55cSDimitry Andric   return Error::success();
345*349cc55cSDimitry Andric }
346*349cc55cSDimitry Andric 
347*349cc55cSDimitry Andric Error SimpleRemoteEPC::handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
348*349cc55cSDimitry Andric                                     SimpleRemoteEPCArgBytesVector ArgBytes) {
349*349cc55cSDimitry Andric   IncomingWFRHandler SendResult;
350*349cc55cSDimitry Andric 
351*349cc55cSDimitry Andric   if (TagAddr)
352*349cc55cSDimitry Andric     return make_error<StringError>("Unexpected TagAddr in result message",
353*349cc55cSDimitry Andric                                    inconvertibleErrorCode());
354*349cc55cSDimitry Andric 
355*349cc55cSDimitry Andric   {
356*349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
357*349cc55cSDimitry Andric     auto I = PendingCallWrapperResults.find(SeqNo);
358*349cc55cSDimitry Andric     if (I == PendingCallWrapperResults.end())
359*349cc55cSDimitry Andric       return make_error<StringError>("No call for sequence number " +
360*349cc55cSDimitry Andric                                          Twine(SeqNo),
361*349cc55cSDimitry Andric                                      inconvertibleErrorCode());
362*349cc55cSDimitry Andric     SendResult = std::move(I->second);
363*349cc55cSDimitry Andric     PendingCallWrapperResults.erase(I);
364*349cc55cSDimitry Andric     releaseSeqNo(SeqNo);
365*349cc55cSDimitry Andric   }
366*349cc55cSDimitry Andric 
367*349cc55cSDimitry Andric   auto WFR =
368*349cc55cSDimitry Andric       shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
369*349cc55cSDimitry Andric   SendResult(std::move(WFR));
370*349cc55cSDimitry Andric   return Error::success();
371*349cc55cSDimitry Andric }
372*349cc55cSDimitry Andric 
373*349cc55cSDimitry Andric void SimpleRemoteEPC::handleCallWrapper(
374*349cc55cSDimitry Andric     uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
375*349cc55cSDimitry Andric     SimpleRemoteEPCArgBytesVector ArgBytes) {
376*349cc55cSDimitry Andric   assert(ES && "No ExecutionSession attached");
377*349cc55cSDimitry Andric   D->dispatch(makeGenericNamedTask(
378*349cc55cSDimitry Andric       [this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() {
379*349cc55cSDimitry Andric         ES->runJITDispatchHandler(
380*349cc55cSDimitry Andric             [this, RemoteSeqNo](shared::WrapperFunctionResult WFR) {
381*349cc55cSDimitry Andric               if (auto Err =
382*349cc55cSDimitry Andric                       sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo,
383*349cc55cSDimitry Andric                                   ExecutorAddr(), {WFR.data(), WFR.size()}))
384*349cc55cSDimitry Andric                 getExecutionSession().reportError(std::move(Err));
385*349cc55cSDimitry Andric             },
386*349cc55cSDimitry Andric             TagAddr.getValue(), ArgBytes);
387*349cc55cSDimitry Andric       },
388*349cc55cSDimitry Andric       "callWrapper task"));
389*349cc55cSDimitry Andric }
390*349cc55cSDimitry Andric 
391*349cc55cSDimitry Andric Error SimpleRemoteEPC::handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes) {
392*349cc55cSDimitry Andric   using namespace llvm::orc::shared;
393*349cc55cSDimitry Andric   auto WFR = WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
394*349cc55cSDimitry Andric   if (const char *ErrMsg = WFR.getOutOfBandError())
395*349cc55cSDimitry Andric     return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
396*349cc55cSDimitry Andric 
397*349cc55cSDimitry Andric   detail::SPSSerializableError Info;
398*349cc55cSDimitry Andric   SPSInputBuffer IB(WFR.data(), WFR.size());
399*349cc55cSDimitry Andric   if (!SPSArgList<SPSError>::deserialize(IB, Info))
400*349cc55cSDimitry Andric     return make_error<StringError>("Could not deserialize hangup info",
401*349cc55cSDimitry Andric                                    inconvertibleErrorCode());
402*349cc55cSDimitry Andric   return fromSPSSerializable(std::move(Info));
403*349cc55cSDimitry Andric }
404*349cc55cSDimitry Andric 
405*349cc55cSDimitry Andric } // end namespace orc
406*349cc55cSDimitry Andric } // end namespace llvm
407