1bb72f073SLang Hames //===------- SimpleRemoteEPC.cpp -- Simple remote executor control --------===// 2bb72f073SLang Hames // 3bb72f073SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bb72f073SLang Hames // See https://llvm.org/LICENSE.txt for license information. 5bb72f073SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bb72f073SLang Hames // 7bb72f073SLang Hames //===----------------------------------------------------------------------===// 8bb72f073SLang Hames 9bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h" 10bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h" 112c8e7849SLang Hames #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" 12bb72f073SLang Hames #include "llvm/Support/FormatVariadic.h" 13bb72f073SLang Hames 14bb72f073SLang Hames #define DEBUG_TYPE "orc" 15bb72f073SLang Hames 16bb72f073SLang Hames namespace llvm { 17bb72f073SLang Hames namespace orc { 18bb72f073SLang Hames 19bb72f073SLang Hames SimpleRemoteEPC::~SimpleRemoteEPC() { 20320832ccSLang Hames #ifndef NDEBUG 21320832ccSLang Hames std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 22bb72f073SLang Hames assert(Disconnected && "Destroyed without disconnection"); 23320832ccSLang Hames #endif // NDEBUG 24bb72f073SLang Hames } 25bb72f073SLang Hames 26bb72f073SLang Hames Expected<tpctypes::DylibHandle> 27bb72f073SLang Hames SimpleRemoteEPC::loadDylib(const char *DylibPath) { 28db21bd4fSLang Hames return EPCDylibMgr->open(DylibPath, 0); 29bb72f073SLang Hames } 30bb72f073SLang Hames 3154226e23SBen Langmuir /// Async helper to chain together calls to DylibMgr::lookupAsync to fulfill all 3254226e23SBen Langmuir /// all the requests. 3354226e23SBen Langmuir /// FIXME: The dylib manager should support multiple LookupRequests natively. 3454226e23SBen Langmuir static void 3554226e23SBen Langmuir lookupSymbolsAsyncHelper(EPCGenericDylibManager &DylibMgr, 36db21bd4fSLang Hames ArrayRef<DylibManager::LookupRequest> Request, 3754226e23SBen Langmuir std::vector<tpctypes::LookupResult> Result, 38db21bd4fSLang Hames DylibManager::SymbolLookupCompleteFn Complete) { 3954226e23SBen Langmuir if (Request.empty()) 4054226e23SBen Langmuir return Complete(std::move(Result)); 41bb72f073SLang Hames 4254226e23SBen Langmuir auto &Element = Request.front(); 4354226e23SBen Langmuir DylibMgr.lookupAsync(Element.Handle, Element.Symbols, 4454226e23SBen Langmuir [&DylibMgr, Request, Complete = std::move(Complete), 4554226e23SBen Langmuir Result = std::move(Result)](auto R) mutable { 4654226e23SBen Langmuir if (!R) 4754226e23SBen Langmuir return Complete(R.takeError()); 48a2c1cf09SLang Hames Result.push_back({}); 49a2c1cf09SLang Hames Result.back().reserve(R->size()); 50a2c1cf09SLang Hames for (auto Addr : *R) 516613f4afSLang Hames Result.back().push_back(Addr); 5254226e23SBen Langmuir 5354226e23SBen Langmuir lookupSymbolsAsyncHelper( 5454226e23SBen Langmuir DylibMgr, Request.drop_front(), std::move(Result), 5554226e23SBen Langmuir std::move(Complete)); 5654226e23SBen Langmuir }); 57a2c1cf09SLang Hames } 5854226e23SBen Langmuir 5954226e23SBen Langmuir void SimpleRemoteEPC::lookupSymbolsAsync(ArrayRef<LookupRequest> Request, 6054226e23SBen Langmuir SymbolLookupCompleteFn Complete) { 61db21bd4fSLang Hames lookupSymbolsAsyncHelper(*EPCDylibMgr, Request, {}, std::move(Complete)); 62bb72f073SLang Hames } 63bb72f073SLang Hames 6421a06254SLang Hames Expected<int32_t> SimpleRemoteEPC::runAsMain(ExecutorAddr MainFnAddr, 65bb72f073SLang Hames ArrayRef<std::string> Args) { 66bb72f073SLang Hames int64_t Result = 0; 672c8e7849SLang Hames if (auto Err = callSPSWrapper<rt::SPSRunAsMainSignature>( 685baaf0c2SLang Hames RunAsMainAddr, Result, MainFnAddr, Args)) 69bb72f073SLang Hames return std::move(Err); 70bb72f073SLang Hames return Result; 71bb72f073SLang Hames } 72bb72f073SLang Hames 737260cdd2SSunho Kim Expected<int32_t> SimpleRemoteEPC::runAsVoidFunction(ExecutorAddr VoidFnAddr) { 747260cdd2SSunho Kim int32_t Result = 0; 757260cdd2SSunho Kim if (auto Err = callSPSWrapper<rt::SPSRunAsVoidFunctionSignature>( 765baaf0c2SLang Hames RunAsVoidFunctionAddr, Result, VoidFnAddr)) 777260cdd2SSunho Kim return std::move(Err); 787260cdd2SSunho Kim return Result; 797260cdd2SSunho Kim } 807260cdd2SSunho Kim 817260cdd2SSunho Kim Expected<int32_t> SimpleRemoteEPC::runAsIntFunction(ExecutorAddr IntFnAddr, 827260cdd2SSunho Kim int Arg) { 837260cdd2SSunho Kim int32_t Result = 0; 847260cdd2SSunho Kim if (auto Err = callSPSWrapper<rt::SPSRunAsIntFunctionSignature>( 855baaf0c2SLang Hames RunAsIntFunctionAddr, Result, IntFnAddr, Arg)) 867260cdd2SSunho Kim return std::move(Err); 877260cdd2SSunho Kim return Result; 887260cdd2SSunho Kim } 897260cdd2SSunho Kim 90da7f993aSLang Hames void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr, 914d7cea3dSLang Hames IncomingWFRHandler OnComplete, 92bb72f073SLang Hames ArrayRef<char> ArgBuffer) { 93bb72f073SLang Hames uint64_t SeqNo; 94bb72f073SLang Hames { 95bb72f073SLang Hames std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 96bb72f073SLang Hames SeqNo = getNextSeqNo(); 97bb72f073SLang Hames assert(!PendingCallWrapperResults.count(SeqNo) && "SeqNo already in use"); 98bb72f073SLang Hames PendingCallWrapperResults[SeqNo] = std::move(OnComplete); 99bb72f073SLang Hames } 100bb72f073SLang Hames 101175c1a39SLang Hames if (auto Err = sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo, 10221a06254SLang Hames WrapperFnAddr, ArgBuffer)) { 10317a0858fSLang Hames IncomingWFRHandler H; 10417a0858fSLang Hames 10517a0858fSLang Hames // We just registered OnComplete, but there may be a race between this 10617a0858fSLang Hames // thread returning from sendMessage and handleDisconnect being called from 10717a0858fSLang Hames // the transport's listener thread. If handleDisconnect gets there first 10817a0858fSLang Hames // then it will have failed 'H' for us. If we get there first (or if 10917a0858fSLang Hames // handleDisconnect already ran) then we need to take care of it. 11017a0858fSLang Hames { 11117a0858fSLang Hames std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 11217a0858fSLang Hames auto I = PendingCallWrapperResults.find(SeqNo); 11317a0858fSLang Hames if (I != PendingCallWrapperResults.end()) { 11417a0858fSLang Hames H = std::move(I->second); 11517a0858fSLang Hames PendingCallWrapperResults.erase(I); 11617a0858fSLang Hames } 11717a0858fSLang Hames } 11817a0858fSLang Hames 11917a0858fSLang Hames if (H) 12017a0858fSLang Hames H(shared::WrapperFunctionResult::createOutOfBandError("disconnecting")); 12117a0858fSLang Hames 122bb72f073SLang Hames getExecutionSession().reportError(std::move(Err)); 123bb72f073SLang Hames } 124bb72f073SLang Hames } 125bb72f073SLang Hames 126bb72f073SLang Hames Error SimpleRemoteEPC::disconnect() { 127bb72f073SLang Hames T->disconnect(); 1282815ed57SLang Hames D->shutdown(); 129320832ccSLang Hames std::unique_lock<std::mutex> Lock(SimpleRemoteEPCMutex); 130320832ccSLang Hames DisconnectCV.wait(Lock, [this] { return Disconnected; }); 131320832ccSLang Hames return std::move(DisconnectErr); 132bb72f073SLang Hames } 133bb72f073SLang Hames 134bb72f073SLang Hames Expected<SimpleRemoteEPCTransportClient::HandleMessageAction> 135bb72f073SLang Hames SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 136ef391df2SLang Hames ExecutorAddr TagAddr, 137bb72f073SLang Hames SimpleRemoteEPCArgBytesVector ArgBytes) { 138175c1a39SLang Hames 139175c1a39SLang Hames LLVM_DEBUG({ 140175c1a39SLang Hames dbgs() << "SimpleRemoteEPC::handleMessage: opc = "; 141175c1a39SLang Hames switch (OpC) { 142175c1a39SLang Hames case SimpleRemoteEPCOpcode::Setup: 143175c1a39SLang Hames dbgs() << "Setup"; 144175c1a39SLang Hames assert(SeqNo == 0 && "Non-zero SeqNo for Setup?"); 145577f316cSLang Hames assert(!TagAddr && "Non-zero TagAddr for Setup?"); 146175c1a39SLang Hames break; 147175c1a39SLang Hames case SimpleRemoteEPCOpcode::Hangup: 148175c1a39SLang Hames dbgs() << "Hangup"; 149175c1a39SLang Hames assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?"); 150577f316cSLang Hames assert(!TagAddr && "Non-zero TagAddr for Hangup?"); 151175c1a39SLang Hames break; 152175c1a39SLang Hames case SimpleRemoteEPCOpcode::Result: 153175c1a39SLang Hames dbgs() << "Result"; 154577f316cSLang Hames assert(!TagAddr && "Non-zero TagAddr for Result?"); 155175c1a39SLang Hames break; 156175c1a39SLang Hames case SimpleRemoteEPCOpcode::CallWrapper: 157175c1a39SLang Hames dbgs() << "CallWrapper"; 158175c1a39SLang Hames break; 159175c1a39SLang Hames } 160577f316cSLang Hames dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr 161175c1a39SLang Hames << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size()) 162175c1a39SLang Hames << " bytes\n"; 163175c1a39SLang Hames }); 164175c1a39SLang Hames 165bb72f073SLang Hames using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>; 166d11a0c5dSLang Hames if (static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC)) 167bb72f073SLang Hames return make_error<StringError>("Unexpected opcode", 168bb72f073SLang Hames inconvertibleErrorCode()); 169bb72f073SLang Hames 170bb72f073SLang Hames switch (OpC) { 171bb72f073SLang Hames case SimpleRemoteEPCOpcode::Setup: 172bb72f073SLang Hames if (auto Err = handleSetup(SeqNo, TagAddr, std::move(ArgBytes))) 173bb72f073SLang Hames return std::move(Err); 174bb72f073SLang Hames break; 175bb72f073SLang Hames case SimpleRemoteEPCOpcode::Hangup: 176a6c95063SStefan Gränitz T->disconnect(); 177a6c95063SStefan Gränitz if (auto Err = handleHangup(std::move(ArgBytes))) 178a6c95063SStefan Gränitz return std::move(Err); 179a6c95063SStefan Gränitz return EndSession; 180bb72f073SLang Hames case SimpleRemoteEPCOpcode::Result: 181bb72f073SLang Hames if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes))) 182bb72f073SLang Hames return std::move(Err); 183bb72f073SLang Hames break; 184bb72f073SLang Hames case SimpleRemoteEPCOpcode::CallWrapper: 185bb72f073SLang Hames handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes)); 186bb72f073SLang Hames break; 187bb72f073SLang Hames } 188bb72f073SLang Hames return ContinueSession; 189bb72f073SLang Hames } 190bb72f073SLang Hames 191bb72f073SLang Hames void SimpleRemoteEPC::handleDisconnect(Error Err) { 192175c1a39SLang Hames LLVM_DEBUG({ 193175c1a39SLang Hames dbgs() << "SimpleRemoteEPC::handleDisconnect: " 194175c1a39SLang Hames << (Err ? "failure" : "success") << "\n"; 195175c1a39SLang Hames }); 196175c1a39SLang Hames 197bb72f073SLang Hames PendingCallWrapperResultsMap TmpPending; 198bb72f073SLang Hames 199bb72f073SLang Hames { 200bb72f073SLang Hames std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 201bb72f073SLang Hames std::swap(TmpPending, PendingCallWrapperResults); 202bb72f073SLang Hames } 203bb72f073SLang Hames 204bb72f073SLang Hames for (auto &KV : TmpPending) 205bb72f073SLang Hames KV.second( 206bb72f073SLang Hames shared::WrapperFunctionResult::createOutOfBandError("disconnecting")); 207bb72f073SLang Hames 208320832ccSLang Hames std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 209320832ccSLang Hames DisconnectErr = joinErrors(std::move(DisconnectErr), std::move(Err)); 210320832ccSLang Hames Disconnected = true; 211320832ccSLang Hames DisconnectCV.notify_all(); 212bb72f073SLang Hames } 213bb72f073SLang Hames 214b64fc0afSLang Hames Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>> 2154fcc0ac1SLang Hames SimpleRemoteEPC::createDefaultMemoryManager(SimpleRemoteEPC &SREPC) { 21678b083dbSLang Hames EPCGenericJITLinkMemoryManager::SymbolAddrs SAs; 2174fcc0ac1SLang Hames if (auto Err = SREPC.getBootstrapSymbols( 21878b083dbSLang Hames {{SAs.Allocator, rt::SimpleExecutorMemoryManagerInstanceName}, 21978b083dbSLang Hames {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName}, 22078b083dbSLang Hames {SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName}, 22178b083dbSLang Hames {SAs.Deallocate, 22278b083dbSLang Hames rt::SimpleExecutorMemoryManagerDeallocateWrapperName}})) 223b64fc0afSLang Hames return std::move(Err); 224bb72f073SLang Hames 2254fcc0ac1SLang Hames return std::make_unique<EPCGenericJITLinkMemoryManager>(SREPC, SAs); 226bb72f073SLang Hames } 227bb72f073SLang Hames 228b64fc0afSLang Hames Expected<std::unique_ptr<ExecutorProcessControl::MemoryAccess>> 2294fcc0ac1SLang Hames SimpleRemoteEPC::createDefaultMemoryAccess(SimpleRemoteEPC &SREPC) { 230*8201ae2aSLang Hames EPCGenericMemoryAccess::FuncAddrs FAs; 231*8201ae2aSLang Hames if (auto Err = SREPC.getBootstrapSymbols( 232*8201ae2aSLang Hames {{FAs.WriteUInt8s, rt::MemoryWriteUInt8sWrapperName}, 233*8201ae2aSLang Hames {FAs.WriteUInt16s, rt::MemoryWriteUInt16sWrapperName}, 234*8201ae2aSLang Hames {FAs.WriteUInt32s, rt::MemoryWriteUInt32sWrapperName}, 235*8201ae2aSLang Hames {FAs.WriteUInt64s, rt::MemoryWriteUInt64sWrapperName}, 236*8201ae2aSLang Hames {FAs.WriteBuffers, rt::MemoryWriteBuffersWrapperName}, 237*8201ae2aSLang Hames {FAs.WritePointers, rt::MemoryWritePointersWrapperName}})) 238*8201ae2aSLang Hames return std::move(Err); 239*8201ae2aSLang Hames 240*8201ae2aSLang Hames return std::make_unique<EPCGenericMemoryAccess>(SREPC, FAs); 241bb72f073SLang Hames } 242bb72f073SLang Hames 243175c1a39SLang Hames Error SimpleRemoteEPC::sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 244175c1a39SLang Hames ExecutorAddr TagAddr, 245175c1a39SLang Hames ArrayRef<char> ArgBytes) { 246175c1a39SLang Hames assert(OpC != SimpleRemoteEPCOpcode::Setup && 247175c1a39SLang Hames "SimpleRemoteEPC sending Setup message? That's the wrong direction."); 248175c1a39SLang Hames 249175c1a39SLang Hames LLVM_DEBUG({ 250175c1a39SLang Hames dbgs() << "SimpleRemoteEPC::sendMessage: opc = "; 251175c1a39SLang Hames switch (OpC) { 252175c1a39SLang Hames case SimpleRemoteEPCOpcode::Hangup: 253175c1a39SLang Hames dbgs() << "Hangup"; 254175c1a39SLang Hames assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?"); 255577f316cSLang Hames assert(!TagAddr && "Non-zero TagAddr for Hangup?"); 256175c1a39SLang Hames break; 257175c1a39SLang Hames case SimpleRemoteEPCOpcode::Result: 258175c1a39SLang Hames dbgs() << "Result"; 259577f316cSLang Hames assert(!TagAddr && "Non-zero TagAddr for Result?"); 260175c1a39SLang Hames break; 261175c1a39SLang Hames case SimpleRemoteEPCOpcode::CallWrapper: 262175c1a39SLang Hames dbgs() << "CallWrapper"; 263175c1a39SLang Hames break; 264175c1a39SLang Hames default: 265175c1a39SLang Hames llvm_unreachable("Invalid opcode"); 266175c1a39SLang Hames } 267577f316cSLang Hames dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr 268175c1a39SLang Hames << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size()) 269175c1a39SLang Hames << " bytes\n"; 270175c1a39SLang Hames }); 271175c1a39SLang Hames auto Err = T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes); 272175c1a39SLang Hames LLVM_DEBUG({ 273175c1a39SLang Hames if (Err) 274175c1a39SLang Hames dbgs() << " \\--> SimpleRemoteEPC::sendMessage failed\n"; 275175c1a39SLang Hames }); 276175c1a39SLang Hames return Err; 277175c1a39SLang Hames } 278175c1a39SLang Hames 279ef391df2SLang Hames Error SimpleRemoteEPC::handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr, 280bb72f073SLang Hames SimpleRemoteEPCArgBytesVector ArgBytes) { 281bb72f073SLang Hames if (SeqNo != 0) 282bb72f073SLang Hames return make_error<StringError>("Setup packet SeqNo not zero", 283bb72f073SLang Hames inconvertibleErrorCode()); 284bb72f073SLang Hames 285bb72f073SLang Hames if (TagAddr) 286bb72f073SLang Hames return make_error<StringError>("Setup packet TagAddr not zero", 287bb72f073SLang Hames inconvertibleErrorCode()); 288bb72f073SLang Hames 289bb72f073SLang Hames std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 290bb72f073SLang Hames auto I = PendingCallWrapperResults.find(0); 291bb72f073SLang Hames assert(PendingCallWrapperResults.size() == 1 && 292bb72f073SLang Hames I != PendingCallWrapperResults.end() && 293bb72f073SLang Hames "Setup message handler not connectly set up"); 294bb72f073SLang Hames auto SetupMsgHandler = std::move(I->second); 295bb72f073SLang Hames PendingCallWrapperResults.erase(I); 296bb72f073SLang Hames 297bb72f073SLang Hames auto WFR = 298bb72f073SLang Hames shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 299bb72f073SLang Hames SetupMsgHandler(std::move(WFR)); 300bb72f073SLang Hames return Error::success(); 301bb72f073SLang Hames } 302bb72f073SLang Hames 3034fcc0ac1SLang Hames Error SimpleRemoteEPC::setup(Setup S) { 3044b37462aSLang Hames using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames; 3054b37462aSLang Hames 3064b37462aSLang Hames std::promise<MSVCPExpected<SimpleRemoteEPCExecutorInfo>> EIP; 3074b37462aSLang Hames auto EIF = EIP.get_future(); 3084b37462aSLang Hames 3094b37462aSLang Hames // Prepare a handler for the setup packet. 310bb72f073SLang Hames PendingCallWrapperResults[0] = 3114d7cea3dSLang Hames RunInPlace()( 312bb72f073SLang Hames [&](shared::WrapperFunctionResult SetupMsgBytes) { 313bb72f073SLang Hames if (const char *ErrMsg = SetupMsgBytes.getOutOfBandError()) { 3144b37462aSLang Hames EIP.set_value( 315bb72f073SLang Hames make_error<StringError>(ErrMsg, inconvertibleErrorCode())); 316bb72f073SLang Hames return; 317bb72f073SLang Hames } 318bb72f073SLang Hames using SPSSerialize = 319bb72f073SLang Hames shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>; 320bb72f073SLang Hames shared::SPSInputBuffer IB(SetupMsgBytes.data(), SetupMsgBytes.size()); 321bb72f073SLang Hames SimpleRemoteEPCExecutorInfo EI; 322bb72f073SLang Hames if (SPSSerialize::deserialize(IB, EI)) 3234b37462aSLang Hames EIP.set_value(EI); 324bb72f073SLang Hames else 3254b37462aSLang Hames EIP.set_value(make_error<StringError>( 326bb72f073SLang Hames "Could not deserialize setup message", inconvertibleErrorCode())); 3274d7cea3dSLang Hames }); 3284b37462aSLang Hames 3294b37462aSLang Hames // Start the transport. 3304b37462aSLang Hames if (auto Err = T->start()) 3314b37462aSLang Hames return Err; 3324b37462aSLang Hames 3334b37462aSLang Hames // Wait for setup packet to arrive. 3344b37462aSLang Hames auto EI = EIF.get(); 3354b37462aSLang Hames if (!EI) { 3364b37462aSLang Hames T->disconnect(); 3374b37462aSLang Hames return EI.takeError(); 338bb72f073SLang Hames } 339bb72f073SLang Hames 340b64fc0afSLang Hames LLVM_DEBUG({ 341b64fc0afSLang Hames dbgs() << "SimpleRemoteEPC received setup message:\n" 3424b37462aSLang Hames << " Triple: " << EI->TargetTriple << "\n" 3434b37462aSLang Hames << " Page size: " << EI->PageSize << "\n" 344060319a2SLang Hames << " Bootstrap map" << (EI->BootstrapMap.empty() ? " empty" : ":") 345060319a2SLang Hames << "\n"; 346060319a2SLang Hames for (const auto &KV : EI->BootstrapMap) 347060319a2SLang Hames dbgs() << " " << KV.first() << ": " << KV.second.size() 348060319a2SLang Hames << "-byte SPS encoded buffer\n"; 349060319a2SLang Hames dbgs() << " Bootstrap symbols" 350060319a2SLang Hames << (EI->BootstrapSymbols.empty() ? " empty" : ":") << "\n"; 3514b37462aSLang Hames for (const auto &KV : EI->BootstrapSymbols) 352577f316cSLang Hames dbgs() << " " << KV.first() << ": " << KV.second << "\n"; 353b64fc0afSLang Hames }); 3544b37462aSLang Hames TargetTriple = Triple(EI->TargetTriple); 3554b37462aSLang Hames PageSize = EI->PageSize; 356060319a2SLang Hames BootstrapMap = std::move(EI->BootstrapMap); 3574b37462aSLang Hames BootstrapSymbols = std::move(EI->BootstrapSymbols); 358b64fc0afSLang Hames 359b64fc0afSLang Hames if (auto Err = getBootstrapSymbols( 360ef391df2SLang Hames {{JDI.JITDispatchContext, ExecutorSessionObjectName}, 361ef391df2SLang Hames {JDI.JITDispatchFunction, DispatchFnName}, 3627260cdd2SSunho Kim {RunAsMainAddr, rt::RunAsMainWrapperName}, 3637260cdd2SSunho Kim {RunAsVoidFunctionAddr, rt::RunAsVoidFunctionWrapperName}, 3647260cdd2SSunho Kim {RunAsIntFunctionAddr, rt::RunAsIntFunctionWrapperName}})) 365b64fc0afSLang Hames return Err; 366b64fc0afSLang Hames 367a2c1cf09SLang Hames if (auto DM = 368a2c1cf09SLang Hames EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(*this)) 369db21bd4fSLang Hames EPCDylibMgr = std::make_unique<EPCGenericDylibManager>(std::move(*DM)); 370a2c1cf09SLang Hames else 371a2c1cf09SLang Hames return DM.takeError(); 372a2c1cf09SLang Hames 3734fcc0ac1SLang Hames // Set a default CreateMemoryManager if none is specified. 3744fcc0ac1SLang Hames if (!S.CreateMemoryManager) 3754fcc0ac1SLang Hames S.CreateMemoryManager = createDefaultMemoryManager; 3764fcc0ac1SLang Hames 3774fcc0ac1SLang Hames if (auto MemMgr = S.CreateMemoryManager(*this)) { 378b64fc0afSLang Hames OwnedMemMgr = std::move(*MemMgr); 379b64fc0afSLang Hames this->MemMgr = OwnedMemMgr.get(); 380b64fc0afSLang Hames } else 381b64fc0afSLang Hames return MemMgr.takeError(); 382b64fc0afSLang Hames 3834fcc0ac1SLang Hames // Set a default CreateMemoryAccess if none is specified. 3844fcc0ac1SLang Hames if (!S.CreateMemoryAccess) 3854fcc0ac1SLang Hames S.CreateMemoryAccess = createDefaultMemoryAccess; 3864fcc0ac1SLang Hames 3874fcc0ac1SLang Hames if (auto MemAccess = S.CreateMemoryAccess(*this)) { 388b64fc0afSLang Hames OwnedMemAccess = std::move(*MemAccess); 389b64fc0afSLang Hames this->MemAccess = OwnedMemAccess.get(); 390b64fc0afSLang Hames } else 391b64fc0afSLang Hames return MemAccess.takeError(); 392b64fc0afSLang Hames 393b64fc0afSLang Hames return Error::success(); 394b64fc0afSLang Hames } 395b64fc0afSLang Hames 396ef391df2SLang Hames Error SimpleRemoteEPC::handleResult(uint64_t SeqNo, ExecutorAddr TagAddr, 397bb72f073SLang Hames SimpleRemoteEPCArgBytesVector ArgBytes) { 3984d7cea3dSLang Hames IncomingWFRHandler SendResult; 399bb72f073SLang Hames 400bb72f073SLang Hames if (TagAddr) 401bb72f073SLang Hames return make_error<StringError>("Unexpected TagAddr in result message", 402bb72f073SLang Hames inconvertibleErrorCode()); 403bb72f073SLang Hames 404bb72f073SLang Hames { 405bb72f073SLang Hames std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex); 406bb72f073SLang Hames auto I = PendingCallWrapperResults.find(SeqNo); 407bb72f073SLang Hames if (I == PendingCallWrapperResults.end()) 408bb72f073SLang Hames return make_error<StringError>("No call for sequence number " + 409bb72f073SLang Hames Twine(SeqNo), 410bb72f073SLang Hames inconvertibleErrorCode()); 411bb72f073SLang Hames SendResult = std::move(I->second); 412bb72f073SLang Hames PendingCallWrapperResults.erase(I); 413bb72f073SLang Hames releaseSeqNo(SeqNo); 414bb72f073SLang Hames } 415bb72f073SLang Hames 416bb72f073SLang Hames auto WFR = 417bb72f073SLang Hames shared::WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 418bb72f073SLang Hames SendResult(std::move(WFR)); 419bb72f073SLang Hames return Error::success(); 420bb72f073SLang Hames } 421bb72f073SLang Hames 422bb72f073SLang Hames void SimpleRemoteEPC::handleCallWrapper( 423ef391df2SLang Hames uint64_t RemoteSeqNo, ExecutorAddr TagAddr, 424bb72f073SLang Hames SimpleRemoteEPCArgBytesVector ArgBytes) { 425bb72f073SLang Hames assert(ES && "No ExecutionSession attached"); 426e9014d97SLang Hames D->dispatch(makeGenericNamedTask( 427e9014d97SLang Hames [this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() { 428bb72f073SLang Hames ES->runJITDispatchHandler( 429bb72f073SLang Hames [this, RemoteSeqNo](shared::WrapperFunctionResult WFR) { 430e9014d97SLang Hames if (auto Err = 431e9014d97SLang Hames sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo, 432ef391df2SLang Hames ExecutorAddr(), {WFR.data(), WFR.size()})) 433bb72f073SLang Hames getExecutionSession().reportError(std::move(Err)); 434bb72f073SLang Hames }, 4358b1771bdSLang Hames TagAddr, ArgBytes); 436e9014d97SLang Hames }, 437e9014d97SLang Hames "callWrapper task")); 438bb72f073SLang Hames } 439bb72f073SLang Hames 440a6c95063SStefan Gränitz Error SimpleRemoteEPC::handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes) { 441a6c95063SStefan Gränitz using namespace llvm::orc::shared; 442a6c95063SStefan Gränitz auto WFR = WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size()); 443a6c95063SStefan Gränitz if (const char *ErrMsg = WFR.getOutOfBandError()) 444a6c95063SStefan Gränitz return make_error<StringError>(ErrMsg, inconvertibleErrorCode()); 445a6c95063SStefan Gränitz 446a6c95063SStefan Gränitz detail::SPSSerializableError Info; 447a6c95063SStefan Gränitz SPSInputBuffer IB(WFR.data(), WFR.size()); 448a6c95063SStefan Gränitz if (!SPSArgList<SPSError>::deserialize(IB, Info)) 449a6c95063SStefan Gränitz return make_error<StringError>("Could not deserialize hangup info", 450a6c95063SStefan Gränitz inconvertibleErrorCode()); 451a6c95063SStefan Gränitz return fromSPSSerializable(std::move(Info)); 452a6c95063SStefan Gränitz } 453a6c95063SStefan Gränitz 454bb72f073SLang Hames } // end namespace orc 455bb72f073SLang Hames } // end namespace llvm 456