xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1349cc55cSDimitry Andric //===------- SimpleRemoteEPC.cpp -- Simple remote executor control --------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
10349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
11349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
12349cc55cSDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
13349cc55cSDimitry Andric #include "llvm/Support/FormatVariadic.h"
14349cc55cSDimitry Andric 
15349cc55cSDimitry Andric #define DEBUG_TYPE "orc"
16349cc55cSDimitry Andric 
17349cc55cSDimitry Andric namespace llvm {
18349cc55cSDimitry Andric namespace orc {
19349cc55cSDimitry Andric 
20349cc55cSDimitry Andric SimpleRemoteEPC::~SimpleRemoteEPC() {
21349cc55cSDimitry Andric #ifndef NDEBUG
22349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
23349cc55cSDimitry Andric   assert(Disconnected && "Destroyed without disconnection");
24349cc55cSDimitry Andric #endif // NDEBUG
25349cc55cSDimitry Andric }
26349cc55cSDimitry Andric 
27349cc55cSDimitry Andric Expected<tpctypes::DylibHandle>
28349cc55cSDimitry Andric SimpleRemoteEPC::loadDylib(const char *DylibPath) {
29349cc55cSDimitry Andric   return DylibMgr->open(DylibPath, 0);
30349cc55cSDimitry Andric }
31349cc55cSDimitry Andric 
32349cc55cSDimitry Andric Expected<std::vector<tpctypes::LookupResult>>
33349cc55cSDimitry Andric SimpleRemoteEPC::lookupSymbols(ArrayRef<LookupRequest> Request) {
34349cc55cSDimitry Andric   std::vector<tpctypes::LookupResult> Result;
35349cc55cSDimitry Andric 
36349cc55cSDimitry Andric   for (auto &Element : Request) {
37349cc55cSDimitry Andric     if (auto R = DylibMgr->lookup(Element.Handle, Element.Symbols)) {
38349cc55cSDimitry Andric       Result.push_back({});
39349cc55cSDimitry Andric       Result.back().reserve(R->size());
40349cc55cSDimitry Andric       for (auto Addr : *R)
41bdd1243dSDimitry Andric         Result.back().push_back(Addr);
42349cc55cSDimitry Andric     } else
43349cc55cSDimitry Andric       return R.takeError();
44349cc55cSDimitry Andric   }
45349cc55cSDimitry Andric   return std::move(Result);
46349cc55cSDimitry Andric }
47349cc55cSDimitry Andric 
48349cc55cSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsMain(ExecutorAddr MainFnAddr,
49349cc55cSDimitry Andric                                              ArrayRef<std::string> Args) {
50349cc55cSDimitry Andric   int64_t Result = 0;
51349cc55cSDimitry Andric   if (auto Err = callSPSWrapper<rt::SPSRunAsMainSignature>(
52*06c3fb27SDimitry Andric           RunAsMainAddr, Result, MainFnAddr, Args))
53349cc55cSDimitry Andric     return std::move(Err);
54349cc55cSDimitry Andric   return Result;
55349cc55cSDimitry Andric }
56349cc55cSDimitry Andric 
57bdd1243dSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsVoidFunction(ExecutorAddr VoidFnAddr) {
58bdd1243dSDimitry Andric   int32_t Result = 0;
59bdd1243dSDimitry Andric   if (auto Err = callSPSWrapper<rt::SPSRunAsVoidFunctionSignature>(
60*06c3fb27SDimitry Andric           RunAsVoidFunctionAddr, Result, VoidFnAddr))
61bdd1243dSDimitry Andric     return std::move(Err);
62bdd1243dSDimitry Andric   return Result;
63bdd1243dSDimitry Andric }
64bdd1243dSDimitry Andric 
65bdd1243dSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsIntFunction(ExecutorAddr IntFnAddr,
66bdd1243dSDimitry Andric                                                     int Arg) {
67bdd1243dSDimitry Andric   int32_t Result = 0;
68bdd1243dSDimitry Andric   if (auto Err = callSPSWrapper<rt::SPSRunAsIntFunctionSignature>(
69*06c3fb27SDimitry Andric           RunAsIntFunctionAddr, Result, IntFnAddr, Arg))
70bdd1243dSDimitry Andric     return std::move(Err);
71bdd1243dSDimitry Andric   return Result;
72bdd1243dSDimitry Andric }
73bdd1243dSDimitry Andric 
74349cc55cSDimitry Andric void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr,
75349cc55cSDimitry Andric                                        IncomingWFRHandler OnComplete,
76349cc55cSDimitry Andric                                        ArrayRef<char> ArgBuffer) {
77349cc55cSDimitry Andric   uint64_t SeqNo;
78349cc55cSDimitry Andric   {
79349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
80349cc55cSDimitry Andric     SeqNo = getNextSeqNo();
81349cc55cSDimitry Andric     assert(!PendingCallWrapperResults.count(SeqNo) && "SeqNo already in use");
82349cc55cSDimitry Andric     PendingCallWrapperResults[SeqNo] = std::move(OnComplete);
83349cc55cSDimitry Andric   }
84349cc55cSDimitry Andric 
85349cc55cSDimitry Andric   if (auto Err = sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo,
86349cc55cSDimitry Andric                              WrapperFnAddr, ArgBuffer)) {
87349cc55cSDimitry Andric     IncomingWFRHandler H;
88349cc55cSDimitry Andric 
89349cc55cSDimitry Andric     // We just registered OnComplete, but there may be a race between this
90349cc55cSDimitry Andric     // thread returning from sendMessage and handleDisconnect being called from
91349cc55cSDimitry Andric     // the transport's listener thread. If handleDisconnect gets there first
92349cc55cSDimitry Andric     // then it will have failed 'H' for us. If we get there first (or if
93349cc55cSDimitry Andric     // handleDisconnect already ran) then we need to take care of it.
94349cc55cSDimitry Andric     {
95349cc55cSDimitry Andric       std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
96349cc55cSDimitry Andric       auto I = PendingCallWrapperResults.find(SeqNo);
97349cc55cSDimitry Andric       if (I != PendingCallWrapperResults.end()) {
98349cc55cSDimitry Andric         H = std::move(I->second);
99349cc55cSDimitry Andric         PendingCallWrapperResults.erase(I);
100349cc55cSDimitry Andric       }
101349cc55cSDimitry Andric     }
102349cc55cSDimitry Andric 
103349cc55cSDimitry Andric     if (H)
104349cc55cSDimitry Andric       H(shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
105349cc55cSDimitry Andric 
106349cc55cSDimitry Andric     getExecutionSession().reportError(std::move(Err));
107349cc55cSDimitry Andric   }
108349cc55cSDimitry Andric }
109349cc55cSDimitry Andric 
110349cc55cSDimitry Andric Error SimpleRemoteEPC::disconnect() {
111349cc55cSDimitry Andric   T->disconnect();
112349cc55cSDimitry Andric   D->shutdown();
113349cc55cSDimitry Andric   std::unique_lock<std::mutex> Lock(SimpleRemoteEPCMutex);
114349cc55cSDimitry Andric   DisconnectCV.wait(Lock, [this] { return Disconnected; });
115349cc55cSDimitry Andric   return std::move(DisconnectErr);
116349cc55cSDimitry Andric }
117349cc55cSDimitry Andric 
118349cc55cSDimitry Andric Expected<SimpleRemoteEPCTransportClient::HandleMessageAction>
119349cc55cSDimitry Andric SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
120349cc55cSDimitry Andric                                ExecutorAddr TagAddr,
121349cc55cSDimitry Andric                                SimpleRemoteEPCArgBytesVector ArgBytes) {
122349cc55cSDimitry Andric 
123349cc55cSDimitry Andric   LLVM_DEBUG({
124349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC::handleMessage: opc = ";
125349cc55cSDimitry Andric     switch (OpC) {
126349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Setup:
127349cc55cSDimitry Andric       dbgs() << "Setup";
128349cc55cSDimitry Andric       assert(SeqNo == 0 && "Non-zero SeqNo for Setup?");
129*06c3fb27SDimitry Andric       assert(!TagAddr && "Non-zero TagAddr for Setup?");
130349cc55cSDimitry Andric       break;
131349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Hangup:
132349cc55cSDimitry Andric       dbgs() << "Hangup";
133349cc55cSDimitry Andric       assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");
134*06c3fb27SDimitry Andric       assert(!TagAddr && "Non-zero TagAddr for Hangup?");
135349cc55cSDimitry Andric       break;
136349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Result:
137349cc55cSDimitry Andric       dbgs() << "Result";
138*06c3fb27SDimitry Andric       assert(!TagAddr && "Non-zero TagAddr for Result?");
139349cc55cSDimitry Andric       break;
140349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::CallWrapper:
141349cc55cSDimitry Andric       dbgs() << "CallWrapper";
142349cc55cSDimitry Andric       break;
143349cc55cSDimitry Andric     }
144*06c3fb27SDimitry Andric     dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr
145349cc55cSDimitry Andric            << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())
146349cc55cSDimitry Andric            << " bytes\n";
147349cc55cSDimitry Andric   });
148349cc55cSDimitry Andric 
149349cc55cSDimitry Andric   using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>;
150349cc55cSDimitry Andric   if (static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC))
151349cc55cSDimitry Andric     return make_error<StringError>("Unexpected opcode",
152349cc55cSDimitry Andric                                    inconvertibleErrorCode());
153349cc55cSDimitry Andric 
154349cc55cSDimitry Andric   switch (OpC) {
155349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::Setup:
156349cc55cSDimitry Andric     if (auto Err = handleSetup(SeqNo, TagAddr, std::move(ArgBytes)))
157349cc55cSDimitry Andric       return std::move(Err);
158349cc55cSDimitry Andric     break;
159349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::Hangup:
160349cc55cSDimitry Andric     T->disconnect();
161349cc55cSDimitry Andric     if (auto Err = handleHangup(std::move(ArgBytes)))
162349cc55cSDimitry Andric       return std::move(Err);
163349cc55cSDimitry Andric     return EndSession;
164349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::Result:
165349cc55cSDimitry Andric     if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))
166349cc55cSDimitry Andric       return std::move(Err);
167349cc55cSDimitry Andric     break;
168349cc55cSDimitry Andric   case SimpleRemoteEPCOpcode::CallWrapper:
169349cc55cSDimitry Andric     handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes));
170349cc55cSDimitry Andric     break;
171349cc55cSDimitry Andric   }
172349cc55cSDimitry Andric   return ContinueSession;
173349cc55cSDimitry Andric }
174349cc55cSDimitry Andric 
175349cc55cSDimitry Andric void SimpleRemoteEPC::handleDisconnect(Error Err) {
176349cc55cSDimitry Andric   LLVM_DEBUG({
177349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC::handleDisconnect: "
178349cc55cSDimitry Andric            << (Err ? "failure" : "success") << "\n";
179349cc55cSDimitry Andric   });
180349cc55cSDimitry Andric 
181349cc55cSDimitry Andric   PendingCallWrapperResultsMap TmpPending;
182349cc55cSDimitry Andric 
183349cc55cSDimitry Andric   {
184349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
185349cc55cSDimitry Andric     std::swap(TmpPending, PendingCallWrapperResults);
186349cc55cSDimitry Andric   }
187349cc55cSDimitry Andric 
188349cc55cSDimitry Andric   for (auto &KV : TmpPending)
189349cc55cSDimitry Andric     KV.second(
190349cc55cSDimitry Andric         shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));
191349cc55cSDimitry Andric 
192349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
193349cc55cSDimitry Andric   DisconnectErr = joinErrors(std::move(DisconnectErr), std::move(Err));
194349cc55cSDimitry Andric   Disconnected = true;
195349cc55cSDimitry Andric   DisconnectCV.notify_all();
196349cc55cSDimitry Andric }
197349cc55cSDimitry Andric 
198349cc55cSDimitry Andric Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
199349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryManager(SimpleRemoteEPC &SREPC) {
200349cc55cSDimitry Andric   EPCGenericJITLinkMemoryManager::SymbolAddrs SAs;
201349cc55cSDimitry Andric   if (auto Err = SREPC.getBootstrapSymbols(
202349cc55cSDimitry Andric           {{SAs.Allocator, rt::SimpleExecutorMemoryManagerInstanceName},
203349cc55cSDimitry Andric            {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
204349cc55cSDimitry Andric            {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
205349cc55cSDimitry Andric            {SAs.Deallocate,
206349cc55cSDimitry Andric             rt::SimpleExecutorMemoryManagerDeallocateWrapperName}}))
207349cc55cSDimitry Andric     return std::move(Err);
208349cc55cSDimitry Andric 
209349cc55cSDimitry Andric   return std::make_unique<EPCGenericJITLinkMemoryManager>(SREPC, SAs);
210349cc55cSDimitry Andric }
211349cc55cSDimitry Andric 
212349cc55cSDimitry Andric Expected<std::unique_ptr<ExecutorProcessControl::MemoryAccess>>
213349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryAccess(SimpleRemoteEPC &SREPC) {
214349cc55cSDimitry Andric   return nullptr;
215349cc55cSDimitry Andric }
216349cc55cSDimitry Andric 
217349cc55cSDimitry Andric Error SimpleRemoteEPC::sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
218349cc55cSDimitry Andric                                    ExecutorAddr TagAddr,
219349cc55cSDimitry Andric                                    ArrayRef<char> ArgBytes) {
220349cc55cSDimitry Andric   assert(OpC != SimpleRemoteEPCOpcode::Setup &&
221349cc55cSDimitry Andric          "SimpleRemoteEPC sending Setup message? That's the wrong direction.");
222349cc55cSDimitry Andric 
223349cc55cSDimitry Andric   LLVM_DEBUG({
224349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC::sendMessage: opc = ";
225349cc55cSDimitry Andric     switch (OpC) {
226349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Hangup:
227349cc55cSDimitry Andric       dbgs() << "Hangup";
228349cc55cSDimitry Andric       assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");
229*06c3fb27SDimitry Andric       assert(!TagAddr && "Non-zero TagAddr for Hangup?");
230349cc55cSDimitry Andric       break;
231349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::Result:
232349cc55cSDimitry Andric       dbgs() << "Result";
233*06c3fb27SDimitry Andric       assert(!TagAddr && "Non-zero TagAddr for Result?");
234349cc55cSDimitry Andric       break;
235349cc55cSDimitry Andric     case SimpleRemoteEPCOpcode::CallWrapper:
236349cc55cSDimitry Andric       dbgs() << "CallWrapper";
237349cc55cSDimitry Andric       break;
238349cc55cSDimitry Andric     default:
239349cc55cSDimitry Andric       llvm_unreachable("Invalid opcode");
240349cc55cSDimitry Andric     }
241*06c3fb27SDimitry Andric     dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr
242349cc55cSDimitry Andric            << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())
243349cc55cSDimitry Andric            << " bytes\n";
244349cc55cSDimitry Andric   });
245349cc55cSDimitry Andric   auto Err = T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes);
246349cc55cSDimitry Andric   LLVM_DEBUG({
247349cc55cSDimitry Andric     if (Err)
248349cc55cSDimitry Andric       dbgs() << "  \\--> SimpleRemoteEPC::sendMessage failed\n";
249349cc55cSDimitry Andric   });
250349cc55cSDimitry Andric   return Err;
251349cc55cSDimitry Andric }
252349cc55cSDimitry Andric 
253349cc55cSDimitry Andric Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
254349cc55cSDimitry Andric                                    SimpleRemoteEPCArgBytesVector ArgBytes) {
255349cc55cSDimitry Andric   if (SeqNo != 0)
256349cc55cSDimitry Andric     return make_error<StringError>("Setup packet SeqNo not zero",
257349cc55cSDimitry Andric                                    inconvertibleErrorCode());
258349cc55cSDimitry Andric 
259349cc55cSDimitry Andric   if (TagAddr)
260349cc55cSDimitry Andric     return make_error<StringError>("Setup packet TagAddr not zero",
261349cc55cSDimitry Andric                                    inconvertibleErrorCode());
262349cc55cSDimitry Andric 
263349cc55cSDimitry Andric   std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
264349cc55cSDimitry Andric   auto I = PendingCallWrapperResults.find(0);
265349cc55cSDimitry Andric   assert(PendingCallWrapperResults.size() == 1 &&
266349cc55cSDimitry Andric          I != PendingCallWrapperResults.end() &&
267349cc55cSDimitry Andric          "Setup message handler not connectly set up");
268349cc55cSDimitry Andric   auto SetupMsgHandler = std::move(I->second);
269349cc55cSDimitry Andric   PendingCallWrapperResults.erase(I);
270349cc55cSDimitry Andric 
271349cc55cSDimitry Andric   auto WFR =
272349cc55cSDimitry Andric       shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
273349cc55cSDimitry Andric   SetupMsgHandler(std::move(WFR));
274349cc55cSDimitry Andric   return Error::success();
275349cc55cSDimitry Andric }
276349cc55cSDimitry Andric 
277349cc55cSDimitry Andric Error SimpleRemoteEPC::setup(Setup S) {
278349cc55cSDimitry Andric   using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;
279349cc55cSDimitry Andric 
280349cc55cSDimitry Andric   std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP;
281349cc55cSDimitry Andric   auto EIF = EIP.get_future();
282349cc55cSDimitry Andric 
283349cc55cSDimitry Andric   // Prepare a handler for the setup packet.
284349cc55cSDimitry Andric   PendingCallWrapperResults[0] =
285349cc55cSDimitry Andric     RunInPlace()(
286349cc55cSDimitry Andric       [&](shared::WrapperFunctionResult SetupMsgBytes) {
287349cc55cSDimitry Andric         if (const char *ErrMsg = SetupMsgBytes.getOutOfBandError()) {
288349cc55cSDimitry Andric           EIP.set_value(
289349cc55cSDimitry Andric               make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
290349cc55cSDimitry Andric           return;
291349cc55cSDimitry Andric         }
292349cc55cSDimitry Andric         using SPSSerialize =
293349cc55cSDimitry Andric             shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>;
294349cc55cSDimitry Andric         shared::SPSInputBuffer IB(SetupMsgBytes.data(), SetupMsgBytes.size());
295349cc55cSDimitry Andric         SimpleRemoteEPCExecutorInfo EI;
296349cc55cSDimitry Andric         if (SPSSerialize::deserialize(IB, EI))
297349cc55cSDimitry Andric           EIP.set_value(EI);
298349cc55cSDimitry Andric         else
299349cc55cSDimitry Andric           EIP.set_value(make_error<StringError>(
300349cc55cSDimitry Andric               "Could not deserialize setup message", inconvertibleErrorCode()));
301349cc55cSDimitry Andric       });
302349cc55cSDimitry Andric 
303349cc55cSDimitry Andric   // Start the transport.
304349cc55cSDimitry Andric   if (auto Err = T->start())
305349cc55cSDimitry Andric     return Err;
306349cc55cSDimitry Andric 
307349cc55cSDimitry Andric   // Wait for setup packet to arrive.
308349cc55cSDimitry Andric   auto EI = EIF.get();
309349cc55cSDimitry Andric   if (!EI) {
310349cc55cSDimitry Andric     T->disconnect();
311349cc55cSDimitry Andric     return EI.takeError();
312349cc55cSDimitry Andric   }
313349cc55cSDimitry Andric 
314349cc55cSDimitry Andric   LLVM_DEBUG({
315349cc55cSDimitry Andric     dbgs() << "SimpleRemoteEPC received setup message:\n"
316349cc55cSDimitry Andric            << "  Triple: " << EI->TargetTriple << "\n"
317349cc55cSDimitry Andric            << "  Page size: " << EI->PageSize << "\n"
318*06c3fb27SDimitry Andric            << "  Bootstrap map" << (EI->BootstrapMap.empty() ? " empty" : ":")
319*06c3fb27SDimitry Andric            << "\n";
320*06c3fb27SDimitry Andric     for (const auto &KV : EI->BootstrapMap)
321*06c3fb27SDimitry Andric       dbgs() << "    " << KV.first() << ": " << KV.second.size()
322*06c3fb27SDimitry Andric              << "-byte SPS encoded buffer\n";
323*06c3fb27SDimitry Andric     dbgs() << "  Bootstrap symbols"
324*06c3fb27SDimitry Andric            << (EI->BootstrapSymbols.empty() ? " empty" : ":") << "\n";
325349cc55cSDimitry Andric     for (const auto &KV : EI->BootstrapSymbols)
326*06c3fb27SDimitry Andric       dbgs() << "    " << KV.first() << ": " << KV.second << "\n";
327349cc55cSDimitry Andric   });
328349cc55cSDimitry Andric   TargetTriple = Triple(EI->TargetTriple);
329349cc55cSDimitry Andric   PageSize = EI->PageSize;
330*06c3fb27SDimitry Andric   BootstrapMap = std::move(EI->BootstrapMap);
331349cc55cSDimitry Andric   BootstrapSymbols = std::move(EI->BootstrapSymbols);
332349cc55cSDimitry Andric 
333349cc55cSDimitry Andric   if (auto Err = getBootstrapSymbols(
334349cc55cSDimitry Andric           {{JDI.JITDispatchContext, ExecutorSessionObjectName},
335349cc55cSDimitry Andric            {JDI.JITDispatchFunction, DispatchFnName},
336bdd1243dSDimitry Andric            {RunAsMainAddr, rt::RunAsMainWrapperName},
337bdd1243dSDimitry Andric            {RunAsVoidFunctionAddr, rt::RunAsVoidFunctionWrapperName},
338bdd1243dSDimitry Andric            {RunAsIntFunctionAddr, rt::RunAsIntFunctionWrapperName}}))
339349cc55cSDimitry Andric     return Err;
340349cc55cSDimitry Andric 
341349cc55cSDimitry Andric   if (auto DM =
342349cc55cSDimitry Andric           EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this))
343349cc55cSDimitry Andric     DylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM));
344349cc55cSDimitry Andric   else
345349cc55cSDimitry Andric     return DM.takeError();
346349cc55cSDimitry Andric 
347349cc55cSDimitry Andric   // Set a default CreateMemoryManager if none is specified.
348349cc55cSDimitry Andric   if (!S.CreateMemoryManager)
349349cc55cSDimitry Andric     S.CreateMemoryManager = createDefaultMemoryManager;
350349cc55cSDimitry Andric 
351349cc55cSDimitry Andric   if (auto MemMgr = S.CreateMemoryManager(*this)) {
352349cc55cSDimitry Andric     OwnedMemMgr = std::move(*MemMgr);
353349cc55cSDimitry Andric     this->MemMgr = OwnedMemMgr.get();
354349cc55cSDimitry Andric   } else
355349cc55cSDimitry Andric     return MemMgr.takeError();
356349cc55cSDimitry Andric 
357349cc55cSDimitry Andric   // Set a default CreateMemoryAccess if none is specified.
358349cc55cSDimitry Andric   if (!S.CreateMemoryAccess)
359349cc55cSDimitry Andric     S.CreateMemoryAccess = createDefaultMemoryAccess;
360349cc55cSDimitry Andric 
361349cc55cSDimitry Andric   if (auto MemAccess = S.CreateMemoryAccess(*this)) {
362349cc55cSDimitry Andric     OwnedMemAccess = std::move(*MemAccess);
363349cc55cSDimitry Andric     this->MemAccess = OwnedMemAccess.get();
364349cc55cSDimitry Andric   } else
365349cc55cSDimitry Andric     return MemAccess.takeError();
366349cc55cSDimitry Andric 
367349cc55cSDimitry Andric   return Error::success();
368349cc55cSDimitry Andric }
369349cc55cSDimitry Andric 
370349cc55cSDimitry Andric Error SimpleRemoteEPC::handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
371349cc55cSDimitry Andric                                     SimpleRemoteEPCArgBytesVector ArgBytes) {
372349cc55cSDimitry Andric   IncomingWFRHandler SendResult;
373349cc55cSDimitry Andric 
374349cc55cSDimitry Andric   if (TagAddr)
375349cc55cSDimitry Andric     return make_error<StringError>("Unexpected TagAddr in result message",
376349cc55cSDimitry Andric                                    inconvertibleErrorCode());
377349cc55cSDimitry Andric 
378349cc55cSDimitry Andric   {
379349cc55cSDimitry Andric     std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
380349cc55cSDimitry Andric     auto I = PendingCallWrapperResults.find(SeqNo);
381349cc55cSDimitry Andric     if (I == PendingCallWrapperResults.end())
382349cc55cSDimitry Andric       return make_error<StringError>("No call for sequence number " +
383349cc55cSDimitry Andric                                          Twine(SeqNo),
384349cc55cSDimitry Andric                                      inconvertibleErrorCode());
385349cc55cSDimitry Andric     SendResult = std::move(I->second);
386349cc55cSDimitry Andric     PendingCallWrapperResults.erase(I);
387349cc55cSDimitry Andric     releaseSeqNo(SeqNo);
388349cc55cSDimitry Andric   }
389349cc55cSDimitry Andric 
390349cc55cSDimitry Andric   auto WFR =
391349cc55cSDimitry Andric       shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
392349cc55cSDimitry Andric   SendResult(std::move(WFR));
393349cc55cSDimitry Andric   return Error::success();
394349cc55cSDimitry Andric }
395349cc55cSDimitry Andric 
396349cc55cSDimitry Andric void SimpleRemoteEPC::handleCallWrapper(
397349cc55cSDimitry Andric     uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
398349cc55cSDimitry Andric     SimpleRemoteEPCArgBytesVector ArgBytes) {
399349cc55cSDimitry Andric   assert(ES && "No ExecutionSession attached");
400349cc55cSDimitry Andric   D->dispatch(makeGenericNamedTask(
401349cc55cSDimitry Andric       [this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() {
402349cc55cSDimitry Andric         ES->runJITDispatchHandler(
403349cc55cSDimitry Andric             [this, RemoteSeqNo](shared::WrapperFunctionResult WFR) {
404349cc55cSDimitry Andric               if (auto Err =
405349cc55cSDimitry Andric                       sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo,
406349cc55cSDimitry Andric                                   ExecutorAddr(), {WFR.data(), WFR.size()}))
407349cc55cSDimitry Andric                 getExecutionSession().reportError(std::move(Err));
408349cc55cSDimitry Andric             },
409*06c3fb27SDimitry Andric             TagAddr, ArgBytes);
410349cc55cSDimitry Andric       },
411349cc55cSDimitry Andric       "callWrapper task"));
412349cc55cSDimitry Andric }
413349cc55cSDimitry Andric 
414349cc55cSDimitry Andric Error SimpleRemoteEPC::handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes) {
415349cc55cSDimitry Andric   using namespace llvm::orc::shared;
416349cc55cSDimitry Andric   auto WFR = WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
417349cc55cSDimitry Andric   if (const char *ErrMsg = WFR.getOutOfBandError())
418349cc55cSDimitry Andric     return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
419349cc55cSDimitry Andric 
420349cc55cSDimitry Andric   detail::SPSSerializableError Info;
421349cc55cSDimitry Andric   SPSInputBuffer IB(WFR.data(), WFR.size());
422349cc55cSDimitry Andric   if (!SPSArgList<SPSError>::deserialize(IB, Info))
423349cc55cSDimitry Andric     return make_error<StringError>("Could not deserialize hangup info",
424349cc55cSDimitry Andric                                    inconvertibleErrorCode());
425349cc55cSDimitry Andric   return fromSPSSerializable(std::move(Info));
426349cc55cSDimitry Andric }
427349cc55cSDimitry Andric 
428349cc55cSDimitry Andric } // end namespace orc
429349cc55cSDimitry Andric } // end namespace llvm
430