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 32*0fca6ea1SDimitry Andric /// Async helper to chain together calls to DylibMgr::lookupAsync to fulfill all 33*0fca6ea1SDimitry Andric /// all the requests. 34*0fca6ea1SDimitry Andric /// FIXME: The dylib manager should support multiple LookupRequests natively. 35*0fca6ea1SDimitry Andric static void 36*0fca6ea1SDimitry Andric lookupSymbolsAsyncHelper(EPCGenericDylibManager &DylibMgr, 37*0fca6ea1SDimitry Andric ArrayRef<SimpleRemoteEPC::LookupRequest> Request, 38*0fca6ea1SDimitry Andric std::vector<tpctypes::LookupResult> Result, 39*0fca6ea1SDimitry Andric SimpleRemoteEPC::SymbolLookupCompleteFn Complete) { 40*0fca6ea1SDimitry Andric if (Request.empty()) 41*0fca6ea1SDimitry Andric return Complete(std::move(Result)); 42349cc55cSDimitry Andric 43*0fca6ea1SDimitry Andric auto &Element = Request.front(); 44*0fca6ea1SDimitry Andric DylibMgr.lookupAsync(Element.Handle, Element.Symbols, 45*0fca6ea1SDimitry Andric [&DylibMgr, Request, Complete = std::move(Complete), 46*0fca6ea1SDimitry Andric Result = std::move(Result)](auto R) mutable { 47*0fca6ea1SDimitry Andric if (!R) 48*0fca6ea1SDimitry Andric return Complete(R.takeError()); 49349cc55cSDimitry Andric Result.push_back({}); 50349cc55cSDimitry Andric Result.back().reserve(R->size()); 51349cc55cSDimitry Andric for (auto Addr : *R) 52bdd1243dSDimitry Andric Result.back().push_back(Addr); 53*0fca6ea1SDimitry Andric 54*0fca6ea1SDimitry Andric lookupSymbolsAsyncHelper( 55*0fca6ea1SDimitry Andric DylibMgr, Request.drop_front(), std::move(Result), 56*0fca6ea1SDimitry Andric std::move(Complete)); 57*0fca6ea1SDimitry Andric }); 58349cc55cSDimitry Andric } 59*0fca6ea1SDimitry Andric 60*0fca6ea1SDimitry Andric void SimpleRemoteEPC::lookupSymbolsAsync(ArrayRef<LookupRequest> Request, 61*0fca6ea1SDimitry Andric SymbolLookupCompleteFn Complete) { 62*0fca6ea1SDimitry Andric lookupSymbolsAsyncHelper(*DylibMgr, Request, {}, std::move(Complete)); 63349cc55cSDimitry Andric } 64349cc55cSDimitry Andric 65349cc55cSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsMain(ExecutorAddr MainFnAddr, 66349cc55cSDimitry Andric ArrayRef<std::string> Args) { 67349cc55cSDimitry Andric int64_t Result = 0; 68349cc55cSDimitry Andric if (auto Err = callSPSWrapper<rt::SPSRunAsMainSignature>( 6906c3fb27SDimitry Andric RunAsMainAddr, Result, MainFnAddr, Args)) 70349cc55cSDimitry Andric return std::move(Err); 71349cc55cSDimitry Andric return Result; 72349cc55cSDimitry Andric } 73349cc55cSDimitry Andric 74bdd1243dSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsVoidFunction(ExecutorAddr VoidFnAddr) { 75bdd1243dSDimitry Andric int32_t Result = 0; 76bdd1243dSDimitry Andric if (auto Err = callSPSWrapper<rt::SPSRunAsVoidFunctionSignature>( 7706c3fb27SDimitry Andric RunAsVoidFunctionAddr, Result, VoidFnAddr)) 78bdd1243dSDimitry Andric return std::move(Err); 79bdd1243dSDimitry Andric return Result; 80bdd1243dSDimitry Andric } 81bdd1243dSDimitry Andric 82bdd1243dSDimitry Andric Expected<int32_t> SimpleRemoteEPC::runAsIntFunction(ExecutorAddr IntFnAddr, 83bdd1243dSDimitry Andric int Arg) { 84bdd1243dSDimitry Andric int32_t Result = 0; 85bdd1243dSDimitry Andric if (auto Err = callSPSWrapper<rt::SPSRunAsIntFunctionSignature>( 8606c3fb27SDimitry Andric RunAsIntFunctionAddr, Result, IntFnAddr, Arg)) 87bdd1243dSDimitry Andric return std::move(Err); 88bdd1243dSDimitry Andric return Result; 89bdd1243dSDimitry Andric } 90bdd1243dSDimitry Andric 91349cc55cSDimitry Andric void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr, 92349cc55cSDimitry Andric IncomingWFRHandler OnComplete, 93349cc55cSDimitry Andric ArrayRef<char> ArgBuffer) { 94349cc55cSDimitry Andric uint64_t SeqNo; 95349cc55cSDimitry Andric { 96349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 97349cc55cSDimitry Andric SeqNo = getNextSeqNo(); 98349cc55cSDimitry Andric assert(!PendingCallWrapperResults.count(SeqNo) && "SeqNo already in use"); 99349cc55cSDimitry Andric PendingCallWrapperResults[SeqNo] = std::move(OnComplete); 100349cc55cSDimitry Andric } 101349cc55cSDimitry Andric 102349cc55cSDimitry Andric if (auto Err = sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo, 103349cc55cSDimitry Andric WrapperFnAddr, ArgBuffer)) { 104349cc55cSDimitry Andric IncomingWFRHandler H; 105349cc55cSDimitry Andric 106349cc55cSDimitry Andric // We just registered OnComplete, but there may be a race between this 107349cc55cSDimitry Andric // thread returning from sendMessage and handleDisconnect being called from 108349cc55cSDimitry Andric // the transport's listener thread. If handleDisconnect gets there first 109349cc55cSDimitry Andric // then it will have failed 'H' for us. If we get there first (or if 110349cc55cSDimitry Andric // handleDisconnect already ran) then we need to take care of it. 111349cc55cSDimitry Andric { 112349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 113349cc55cSDimitry Andric auto I = PendingCallWrapperResults.find(SeqNo); 114349cc55cSDimitry Andric if (I != PendingCallWrapperResults.end()) { 115349cc55cSDimitry Andric H = std::move(I->second); 116349cc55cSDimitry Andric PendingCallWrapperResults.erase(I); 117349cc55cSDimitry Andric } 118349cc55cSDimitry Andric } 119349cc55cSDimitry Andric 120349cc55cSDimitry Andric if (H) 121349cc55cSDimitry Andric H(shared::WrapperFunctionResult::createOutOfBandError("disconnecting")); 122349cc55cSDimitry Andric 123349cc55cSDimitry Andric getExecutionSession().reportError(std::move(Err)); 124349cc55cSDimitry Andric } 125349cc55cSDimitry Andric } 126349cc55cSDimitry Andric 127349cc55cSDimitry Andric Error SimpleRemoteEPC::disconnect() { 128349cc55cSDimitry Andric T->disconnect(); 129349cc55cSDimitry Andric D->shutdown(); 130349cc55cSDimitry Andric std::unique_lock<std::mutex> Lock(SimpleRemoteEPCMutex); 131349cc55cSDimitry Andric DisconnectCV.wait(Lock, [this] { return Disconnected; }); 132349cc55cSDimitry Andric return std::move(DisconnectErr); 133349cc55cSDimitry Andric } 134349cc55cSDimitry Andric 135349cc55cSDimitry Andric Expected<SimpleRemoteEPCTransportClient::HandleMessageAction> 136349cc55cSDimitry Andric SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 137349cc55cSDimitry Andric ExecutorAddr TagAddr, 138349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 139349cc55cSDimitry Andric 140349cc55cSDimitry Andric LLVM_DEBUG({ 141349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC::handleMessage: opc = "; 142349cc55cSDimitry Andric switch (OpC) { 143349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Setup: 144349cc55cSDimitry Andric dbgs() << "Setup"; 145349cc55cSDimitry Andric assert(SeqNo == 0 && "Non-zero SeqNo for Setup?"); 14606c3fb27SDimitry Andric assert(!TagAddr && "Non-zero TagAddr for Setup?"); 147349cc55cSDimitry Andric break; 148349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Hangup: 149349cc55cSDimitry Andric dbgs() << "Hangup"; 150349cc55cSDimitry Andric assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?"); 15106c3fb27SDimitry Andric assert(!TagAddr && "Non-zero TagAddr for Hangup?"); 152349cc55cSDimitry Andric break; 153349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Result: 154349cc55cSDimitry Andric dbgs() << "Result"; 15506c3fb27SDimitry Andric assert(!TagAddr && "Non-zero TagAddr for Result?"); 156349cc55cSDimitry Andric break; 157349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::CallWrapper: 158349cc55cSDimitry Andric dbgs() << "CallWrapper"; 159349cc55cSDimitry Andric break; 160349cc55cSDimitry Andric } 16106c3fb27SDimitry Andric dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr 162349cc55cSDimitry Andric << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size()) 163349cc55cSDimitry Andric << " bytes\n"; 164349cc55cSDimitry Andric }); 165349cc55cSDimitry Andric 166349cc55cSDimitry Andric using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>; 167349cc55cSDimitry Andric if (static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC)) 168349cc55cSDimitry Andric return make_error<StringError>("Unexpected opcode", 169349cc55cSDimitry Andric inconvertibleErrorCode()); 170349cc55cSDimitry Andric 171349cc55cSDimitry Andric switch (OpC) { 172349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Setup: 173349cc55cSDimitry Andric if (auto Err = handleSetup(SeqNo, TagAddr, std::move(ArgBytes))) 174349cc55cSDimitry Andric return std::move(Err); 175349cc55cSDimitry Andric break; 176349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Hangup: 177349cc55cSDimitry Andric T->disconnect(); 178349cc55cSDimitry Andric if (auto Err = handleHangup(std::move(ArgBytes))) 179349cc55cSDimitry Andric return std::move(Err); 180349cc55cSDimitry Andric return EndSession; 181349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Result: 182349cc55cSDimitry Andric if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes))) 183349cc55cSDimitry Andric return std::move(Err); 184349cc55cSDimitry Andric break; 185349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::CallWrapper: 186349cc55cSDimitry Andric handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes)); 187349cc55cSDimitry Andric break; 188349cc55cSDimitry Andric } 189349cc55cSDimitry Andric return ContinueSession; 190349cc55cSDimitry Andric } 191349cc55cSDimitry Andric 192349cc55cSDimitry Andric void SimpleRemoteEPC::handleDisconnect(Error Err) { 193349cc55cSDimitry Andric LLVM_DEBUG({ 194349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC::handleDisconnect: " 195349cc55cSDimitry Andric << (Err ? "failure" : "success") << "\n"; 196349cc55cSDimitry Andric }); 197349cc55cSDimitry Andric 198349cc55cSDimitry Andric PendingCallWrapperResultsMap TmpPending; 199349cc55cSDimitry Andric 200349cc55cSDimitry Andric { 201349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 202349cc55cSDimitry Andric std::swap(TmpPending, PendingCallWrapperResults); 203349cc55cSDimitry Andric } 204349cc55cSDimitry Andric 205349cc55cSDimitry Andric for (auto &KV : TmpPending) 206349cc55cSDimitry Andric KV.second( 207349cc55cSDimitry Andric shared::WrapperFunctionResult::createOutOfBandError("disconnecting")); 208349cc55cSDimitry Andric 209349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 210349cc55cSDimitry Andric DisconnectErr = joinErrors(std::move(DisconnectErr), std::move(Err)); 211349cc55cSDimitry Andric Disconnected = true; 212349cc55cSDimitry Andric DisconnectCV.notify_all(); 213349cc55cSDimitry Andric } 214349cc55cSDimitry Andric 215349cc55cSDimitry Andric Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>> 216349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryManager(SimpleRemoteEPC &SREPC) { 217349cc55cSDimitry Andric EPCGenericJITLinkMemoryManager::SymbolAddrs SAs; 218349cc55cSDimitry Andric if (auto Err = SREPC.getBootstrapSymbols( 219349cc55cSDimitry Andric {{SAs.Allocator, rt::SimpleExecutorMemoryManagerInstanceName}, 220349cc55cSDimitry Andric {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName}, 221349cc55cSDimitry Andric {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName}, 222349cc55cSDimitry Andric {SAs.Deallocate, 223349cc55cSDimitry Andric rt::SimpleExecutorMemoryManagerDeallocateWrapperName}})) 224349cc55cSDimitry Andric return std::move(Err); 225349cc55cSDimitry Andric 226349cc55cSDimitry Andric return std::make_unique<EPCGenericJITLinkMemoryManager>(SREPC, SAs); 227349cc55cSDimitry Andric } 228349cc55cSDimitry Andric 229349cc55cSDimitry Andric Expected<std::unique_ptr<ExecutorProcessControl::MemoryAccess>> 230349cc55cSDimitry Andric SimpleRemoteEPC::createDefaultMemoryAccess(SimpleRemoteEPC &SREPC) { 231349cc55cSDimitry Andric return nullptr; 232349cc55cSDimitry Andric } 233349cc55cSDimitry Andric 234349cc55cSDimitry Andric Error SimpleRemoteEPC::sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 235349cc55cSDimitry Andric ExecutorAddr TagAddr, 236349cc55cSDimitry Andric ArrayRef<char> ArgBytes) { 237349cc55cSDimitry Andric assert(OpC != SimpleRemoteEPCOpcode::Setup && 238349cc55cSDimitry Andric "SimpleRemoteEPC sending Setup message? That's the wrong direction."); 239349cc55cSDimitry Andric 240349cc55cSDimitry Andric LLVM_DEBUG({ 241349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC::sendMessage: opc = "; 242349cc55cSDimitry Andric switch (OpC) { 243349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Hangup: 244349cc55cSDimitry Andric dbgs() << "Hangup"; 245349cc55cSDimitry Andric assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?"); 24606c3fb27SDimitry Andric assert(!TagAddr && "Non-zero TagAddr for Hangup?"); 247349cc55cSDimitry Andric break; 248349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::Result: 249349cc55cSDimitry Andric dbgs() << "Result"; 25006c3fb27SDimitry Andric assert(!TagAddr && "Non-zero TagAddr for Result?"); 251349cc55cSDimitry Andric break; 252349cc55cSDimitry Andric case SimpleRemoteEPCOpcode::CallWrapper: 253349cc55cSDimitry Andric dbgs() << "CallWrapper"; 254349cc55cSDimitry Andric break; 255349cc55cSDimitry Andric default: 256349cc55cSDimitry Andric llvm_unreachable("Invalid opcode"); 257349cc55cSDimitry Andric } 25806c3fb27SDimitry Andric dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr 259349cc55cSDimitry Andric << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size()) 260349cc55cSDimitry Andric << " bytes\n"; 261349cc55cSDimitry Andric }); 262349cc55cSDimitry Andric auto Err = T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes); 263349cc55cSDimitry Andric LLVM_DEBUG({ 264349cc55cSDimitry Andric if (Err) 265349cc55cSDimitry Andric dbgs() << " \\--> SimpleRemoteEPC::sendMessage failed\n"; 266349cc55cSDimitry Andric }); 267349cc55cSDimitry Andric return Err; 268349cc55cSDimitry Andric } 269349cc55cSDimitry Andric 270349cc55cSDimitry Andric Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr, 271349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 272349cc55cSDimitry Andric if (SeqNo != 0) 273349cc55cSDimitry Andric return make_error<StringError>("Setup packet SeqNo not zero", 274349cc55cSDimitry Andric inconvertibleErrorCode()); 275349cc55cSDimitry Andric 276349cc55cSDimitry Andric if (TagAddr) 277349cc55cSDimitry Andric return make_error<StringError>("Setup packet TagAddr not zero", 278349cc55cSDimitry Andric inconvertibleErrorCode()); 279349cc55cSDimitry Andric 280349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 281349cc55cSDimitry Andric auto I = PendingCallWrapperResults.find(0); 282349cc55cSDimitry Andric assert(PendingCallWrapperResults.size() == 1 && 283349cc55cSDimitry Andric I != PendingCallWrapperResults.end() && 284349cc55cSDimitry Andric "Setup message handler not connectly set up"); 285349cc55cSDimitry Andric auto SetupMsgHandler = std::move(I->second); 286349cc55cSDimitry Andric PendingCallWrapperResults.erase(I); 287349cc55cSDimitry Andric 288349cc55cSDimitry Andric auto WFR = 289349cc55cSDimitry Andric shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 290349cc55cSDimitry Andric SetupMsgHandler(std::move(WFR)); 291349cc55cSDimitry Andric return Error::success(); 292349cc55cSDimitry Andric } 293349cc55cSDimitry Andric 294349cc55cSDimitry Andric Error SimpleRemoteEPC::setup(Setup S) { 295349cc55cSDimitry Andric using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames; 296349cc55cSDimitry Andric 297349cc55cSDimitry Andric std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP; 298349cc55cSDimitry Andric auto EIF = EIP.get_future(); 299349cc55cSDimitry Andric 300349cc55cSDimitry Andric // Prepare a handler for the setup packet. 301349cc55cSDimitry Andric PendingCallWrapperResults[0] = 302349cc55cSDimitry Andric RunInPlace()( 303349cc55cSDimitry Andric [&](shared::WrapperFunctionResult SetupMsgBytes) { 304349cc55cSDimitry Andric if (const char *ErrMsg = SetupMsgBytes.getOutOfBandError()) { 305349cc55cSDimitry Andric EIP.set_value( 306349cc55cSDimitry Andric make_error<StringError>(ErrMsg, inconvertibleErrorCode())); 307349cc55cSDimitry Andric return; 308349cc55cSDimitry Andric } 309349cc55cSDimitry Andric using SPSSerialize = 310349cc55cSDimitry Andric shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>; 311349cc55cSDimitry Andric shared::SPSInputBuffer IB(SetupMsgBytes.data(), SetupMsgBytes.size()); 312349cc55cSDimitry Andric SimpleRemoteEPCExecutorInfo EI; 313349cc55cSDimitry Andric if (SPSSerialize::deserialize(IB, EI)) 314349cc55cSDimitry Andric EIP.set_value(EI); 315349cc55cSDimitry Andric else 316349cc55cSDimitry Andric EIP.set_value(make_error<StringError>( 317349cc55cSDimitry Andric "Could not deserialize setup message", inconvertibleErrorCode())); 318349cc55cSDimitry Andric }); 319349cc55cSDimitry Andric 320349cc55cSDimitry Andric // Start the transport. 321349cc55cSDimitry Andric if (auto Err = T->start()) 322349cc55cSDimitry Andric return Err; 323349cc55cSDimitry Andric 324349cc55cSDimitry Andric // Wait for setup packet to arrive. 325349cc55cSDimitry Andric auto EI = EIF.get(); 326349cc55cSDimitry Andric if (!EI) { 327349cc55cSDimitry Andric T->disconnect(); 328349cc55cSDimitry Andric return EI.takeError(); 329349cc55cSDimitry Andric } 330349cc55cSDimitry Andric 331349cc55cSDimitry Andric LLVM_DEBUG({ 332349cc55cSDimitry Andric dbgs() << "SimpleRemoteEPC received setup message:\n" 333349cc55cSDimitry Andric << " Triple: " << EI->TargetTriple << "\n" 334349cc55cSDimitry Andric << " Page size: " << EI->PageSize << "\n" 33506c3fb27SDimitry Andric << " Bootstrap map" << (EI->BootstrapMap.empty() ? " empty" : ":") 33606c3fb27SDimitry Andric << "\n"; 33706c3fb27SDimitry Andric for (const auto &KV : EI->BootstrapMap) 33806c3fb27SDimitry Andric dbgs() << " " << KV.first() << ": " << KV.second.size() 33906c3fb27SDimitry Andric << "-byte SPS encoded buffer\n"; 34006c3fb27SDimitry Andric dbgs() << " Bootstrap symbols" 34106c3fb27SDimitry Andric << (EI->BootstrapSymbols.empty() ? " empty" : ":") << "\n"; 342349cc55cSDimitry Andric for (const auto &KV : EI->BootstrapSymbols) 34306c3fb27SDimitry Andric dbgs() << " " << KV.first() << ": " << KV.second << "\n"; 344349cc55cSDimitry Andric }); 345349cc55cSDimitry Andric TargetTriple = Triple(EI->TargetTriple); 346349cc55cSDimitry Andric PageSize = EI->PageSize; 34706c3fb27SDimitry Andric BootstrapMap = std::move(EI->BootstrapMap); 348349cc55cSDimitry Andric BootstrapSymbols = std::move(EI->BootstrapSymbols); 349349cc55cSDimitry Andric 350349cc55cSDimitry Andric if (auto Err = getBootstrapSymbols( 351349cc55cSDimitry Andric {{JDI.JITDispatchContext, ExecutorSessionObjectName}, 352349cc55cSDimitry Andric {JDI.JITDispatchFunction, DispatchFnName}, 353bdd1243dSDimitry Andric {RunAsMainAddr, rt::RunAsMainWrapperName}, 354bdd1243dSDimitry Andric {RunAsVoidFunctionAddr, rt::RunAsVoidFunctionWrapperName}, 355bdd1243dSDimitry Andric {RunAsIntFunctionAddr, rt::RunAsIntFunctionWrapperName}})) 356349cc55cSDimitry Andric return Err; 357349cc55cSDimitry Andric 358349cc55cSDimitry Andric if (auto DM = 359349cc55cSDimitry Andric EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this)) 360349cc55cSDimitry Andric DylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM)); 361349cc55cSDimitry Andric else 362349cc55cSDimitry Andric return DM.takeError(); 363349cc55cSDimitry Andric 364349cc55cSDimitry Andric // Set a default CreateMemoryManager if none is specified. 365349cc55cSDimitry Andric if (!S.CreateMemoryManager) 366349cc55cSDimitry Andric S.CreateMemoryManager = createDefaultMemoryManager; 367349cc55cSDimitry Andric 368349cc55cSDimitry Andric if (auto MemMgr = S.CreateMemoryManager(*this)) { 369349cc55cSDimitry Andric OwnedMemMgr = std::move(*MemMgr); 370349cc55cSDimitry Andric this->MemMgr = OwnedMemMgr.get(); 371349cc55cSDimitry Andric } else 372349cc55cSDimitry Andric return MemMgr.takeError(); 373349cc55cSDimitry Andric 374349cc55cSDimitry Andric // Set a default CreateMemoryAccess if none is specified. 375349cc55cSDimitry Andric if (!S.CreateMemoryAccess) 376349cc55cSDimitry Andric S.CreateMemoryAccess = createDefaultMemoryAccess; 377349cc55cSDimitry Andric 378349cc55cSDimitry Andric if (auto MemAccess = S.CreateMemoryAccess(*this)) { 379349cc55cSDimitry Andric OwnedMemAccess = std::move(*MemAccess); 380349cc55cSDimitry Andric this->MemAccess = OwnedMemAccess.get(); 381349cc55cSDimitry Andric } else 382349cc55cSDimitry Andric return MemAccess.takeError(); 383349cc55cSDimitry Andric 384349cc55cSDimitry Andric return Error::success(); 385349cc55cSDimitry Andric } 386349cc55cSDimitry Andric 387349cc55cSDimitry Andric Error SimpleRemoteEPC::handleResult(uint64_t SeqNo, ExecutorAddr TagAddr, 388349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 389349cc55cSDimitry Andric IncomingWFRHandler SendResult; 390349cc55cSDimitry Andric 391349cc55cSDimitry Andric if (TagAddr) 392349cc55cSDimitry Andric return make_error<StringError>("Unexpected TagAddr in result message", 393349cc55cSDimitry Andric inconvertibleErrorCode()); 394349cc55cSDimitry Andric 395349cc55cSDimitry Andric { 396349cc55cSDimitry Andric std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 397349cc55cSDimitry Andric auto I = PendingCallWrapperResults.find(SeqNo); 398349cc55cSDimitry Andric if (I == PendingCallWrapperResults.end()) 399349cc55cSDimitry Andric return make_error<StringError>("No call for sequence number " + 400349cc55cSDimitry Andric Twine(SeqNo), 401349cc55cSDimitry Andric inconvertibleErrorCode()); 402349cc55cSDimitry Andric SendResult = std::move(I->second); 403349cc55cSDimitry Andric PendingCallWrapperResults.erase(I); 404349cc55cSDimitry Andric releaseSeqNo(SeqNo); 405349cc55cSDimitry Andric } 406349cc55cSDimitry Andric 407349cc55cSDimitry Andric auto WFR = 408349cc55cSDimitry Andric shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 409349cc55cSDimitry Andric SendResult(std::move(WFR)); 410349cc55cSDimitry Andric return Error::success(); 411349cc55cSDimitry Andric } 412349cc55cSDimitry Andric 413349cc55cSDimitry Andric void SimpleRemoteEPC::handleCallWrapper( 414349cc55cSDimitry Andric uint64_t RemoteSeqNo, ExecutorAddr TagAddr, 415349cc55cSDimitry Andric SimpleRemoteEPCArgBytesVector ArgBytes) { 416349cc55cSDimitry Andric assert(ES && "No ExecutionSession attached"); 417349cc55cSDimitry Andric D->dispatch(makeGenericNamedTask( 418349cc55cSDimitry Andric [this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() { 419349cc55cSDimitry Andric ES->runJITDispatchHandler( 420349cc55cSDimitry Andric [this, RemoteSeqNo](shared::WrapperFunctionResult WFR) { 421349cc55cSDimitry Andric if (auto Err = 422349cc55cSDimitry Andric sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo, 423349cc55cSDimitry Andric ExecutorAddr(), {WFR.data(), WFR.size()})) 424349cc55cSDimitry Andric getExecutionSession().reportError(std::move(Err)); 425349cc55cSDimitry Andric }, 42606c3fb27SDimitry Andric TagAddr, ArgBytes); 427349cc55cSDimitry Andric }, 428349cc55cSDimitry Andric "callWrapper task")); 429349cc55cSDimitry Andric } 430349cc55cSDimitry Andric 431349cc55cSDimitry Andric Error SimpleRemoteEPC::handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes) { 432349cc55cSDimitry Andric using namespace llvm::orc::shared; 433349cc55cSDimitry Andric auto WFR = WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 434349cc55cSDimitry Andric if (const char *ErrMsg = WFR.getOutOfBandError()) 435349cc55cSDimitry Andric return make_error<StringError>(ErrMsg, inconvertibleErrorCode()); 436349cc55cSDimitry Andric 437349cc55cSDimitry Andric detail::SPSSerializableError Info; 438349cc55cSDimitry Andric SPSInputBuffer IB(WFR.data(), WFR.size()); 439349cc55cSDimitry Andric if (!SPSArgList<SPSError>::deserialize(IB, Info)) 440349cc55cSDimitry Andric return make_error<StringError>("Could not deserialize hangup info", 441349cc55cSDimitry Andric inconvertibleErrorCode()); 442349cc55cSDimitry Andric return fromSPSSerializable(std::move(Info)); 443349cc55cSDimitry Andric } 444349cc55cSDimitry Andric 445349cc55cSDimitry Andric } // end namespace orc 446349cc55cSDimitry Andric } // end namespace llvm 447