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