1*bb72f073SLang Hames //===------- SimpleEPCServer.cpp - EPC over simple abstract channel -------===// 2*bb72f073SLang Hames // 3*bb72f073SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bb72f073SLang Hames // See https://llvm.org/LICENSE.txt for license information. 5*bb72f073SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bb72f073SLang Hames // 7*bb72f073SLang Hames //===----------------------------------------------------------------------===// 8*bb72f073SLang Hames 9*bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h" 10*bb72f073SLang Hames 11*bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h" 12*bb72f073SLang Hames #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h" 13*bb72f073SLang Hames #include "llvm/Support/FormatVariadic.h" 14*bb72f073SLang Hames #include "llvm/Support/Host.h" 15*bb72f073SLang Hames #include "llvm/Support/Process.h" 16*bb72f073SLang Hames 17*bb72f073SLang Hames #define DEBUG_TYPE "orc" 18*bb72f073SLang Hames 19*bb72f073SLang Hames using namespace llvm::orc::shared; 20*bb72f073SLang Hames 21*bb72f073SLang Hames namespace llvm { 22*bb72f073SLang Hames namespace orc { 23*bb72f073SLang Hames 24*bb72f073SLang Hames static llvm::orc::shared::detail::CWrapperFunctionResult 25*bb72f073SLang Hames reserveWrapper(const char *ArgData, size_t ArgSize) { 26*bb72f073SLang Hames return WrapperFunction<SPSOrcTargetProcessAllocate>::handle( 27*bb72f073SLang Hames ArgData, ArgSize, 28*bb72f073SLang Hames [](uint64_t Size) -> Expected<ExecutorAddress> { 29*bb72f073SLang Hames std::error_code EC; 30*bb72f073SLang Hames auto MB = sys::Memory::allocateMappedMemory( 31*bb72f073SLang Hames Size, 0, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC); 32*bb72f073SLang Hames if (EC) 33*bb72f073SLang Hames return errorCodeToError(EC); 34*bb72f073SLang Hames return ExecutorAddress::fromPtr(MB.base()); 35*bb72f073SLang Hames }) 36*bb72f073SLang Hames .release(); 37*bb72f073SLang Hames } 38*bb72f073SLang Hames 39*bb72f073SLang Hames static llvm::orc::shared::detail::CWrapperFunctionResult 40*bb72f073SLang Hames finalizeWrapper(const char *ArgData, size_t ArgSize) { 41*bb72f073SLang Hames return WrapperFunction<SPSOrcTargetProcessFinalize>::handle( 42*bb72f073SLang Hames ArgData, ArgSize, 43*bb72f073SLang Hames [](const tpctypes::FinalizeRequest &FR) -> Error { 44*bb72f073SLang Hames for (auto &Seg : FR) { 45*bb72f073SLang Hames char *Mem = Seg.Addr.toPtr<char *>(); 46*bb72f073SLang Hames memcpy(Mem, Seg.Content.data(), Seg.Content.size()); 47*bb72f073SLang Hames memset(Mem + Seg.Content.size(), 0, 48*bb72f073SLang Hames Seg.Size - Seg.Content.size()); 49*bb72f073SLang Hames assert(Seg.Size <= std::numeric_limits<size_t>::max()); 50*bb72f073SLang Hames if (auto EC = sys::Memory::protectMappedMemory( 51*bb72f073SLang Hames {Mem, static_cast<size_t>(Seg.Size)}, 52*bb72f073SLang Hames tpctypes::fromWireProtectionFlags(Seg.Prot))) 53*bb72f073SLang Hames return errorCodeToError(EC); 54*bb72f073SLang Hames if (Seg.Prot & tpctypes::WPF_Exec) 55*bb72f073SLang Hames sys::Memory::InvalidateInstructionCache(Mem, Seg.Size); 56*bb72f073SLang Hames } 57*bb72f073SLang Hames return Error::success(); 58*bb72f073SLang Hames }) 59*bb72f073SLang Hames .release(); 60*bb72f073SLang Hames } 61*bb72f073SLang Hames 62*bb72f073SLang Hames static llvm::orc::shared::detail::CWrapperFunctionResult 63*bb72f073SLang Hames deallocateWrapper(const char *ArgData, size_t ArgSize) { 64*bb72f073SLang Hames return WrapperFunction<SPSOrcTargetProcessDeallocate>::handle( 65*bb72f073SLang Hames ArgData, ArgSize, 66*bb72f073SLang Hames [](ExecutorAddress Base, uint64_t Size) -> Error { 67*bb72f073SLang Hames sys::MemoryBlock MB(Base.toPtr<void *>(), Size); 68*bb72f073SLang Hames if (auto EC = sys::Memory::releaseMappedMemory(MB)) 69*bb72f073SLang Hames return errorCodeToError(EC); 70*bb72f073SLang Hames return Error::success(); 71*bb72f073SLang Hames }) 72*bb72f073SLang Hames .release(); 73*bb72f073SLang Hames } 74*bb72f073SLang Hames 75*bb72f073SLang Hames template <typename WriteT, typename SPSWriteT> 76*bb72f073SLang Hames static llvm::orc::shared::detail::CWrapperFunctionResult 77*bb72f073SLang Hames writeUIntsWrapper(const char *ArgData, size_t ArgSize) { 78*bb72f073SLang Hames return WrapperFunction<void(SPSSequence<SPSWriteT>)>::handle( 79*bb72f073SLang Hames ArgData, ArgSize, 80*bb72f073SLang Hames [](std::vector<WriteT> Ws) { 81*bb72f073SLang Hames for (auto &W : Ws) 82*bb72f073SLang Hames *jitTargetAddressToPointer<decltype(W.Value) *>(W.Address) = 83*bb72f073SLang Hames W.Value; 84*bb72f073SLang Hames }) 85*bb72f073SLang Hames .release(); 86*bb72f073SLang Hames } 87*bb72f073SLang Hames 88*bb72f073SLang Hames static llvm::orc::shared::detail::CWrapperFunctionResult 89*bb72f073SLang Hames writeBuffersWrapper(const char *ArgData, size_t ArgSize) { 90*bb72f073SLang Hames return WrapperFunction<void(SPSSequence<SPSMemoryAccessBufferWrite>)>::handle( 91*bb72f073SLang Hames ArgData, ArgSize, 92*bb72f073SLang Hames [](std::vector<tpctypes::BufferWrite> Ws) { 93*bb72f073SLang Hames for (auto &W : Ws) 94*bb72f073SLang Hames memcpy(jitTargetAddressToPointer<char *>(W.Address), 95*bb72f073SLang Hames W.Buffer.data(), W.Buffer.size()); 96*bb72f073SLang Hames }) 97*bb72f073SLang Hames .release(); 98*bb72f073SLang Hames } 99*bb72f073SLang Hames 100*bb72f073SLang Hames static llvm::orc::shared::detail::CWrapperFunctionResult 101*bb72f073SLang Hames runAsMainWrapper(const char *ArgData, size_t ArgSize) { 102*bb72f073SLang Hames return WrapperFunction<SPSRunAsMainSignature>::handle( 103*bb72f073SLang Hames ArgData, ArgSize, 104*bb72f073SLang Hames [](ExecutorAddress MainAddr, 105*bb72f073SLang Hames std::vector<std::string> Args) -> int64_t { 106*bb72f073SLang Hames return runAsMain(MainAddr.toPtr<int (*)(int, char *[])>(), Args); 107*bb72f073SLang Hames }) 108*bb72f073SLang Hames .release(); 109*bb72f073SLang Hames } 110*bb72f073SLang Hames 111*bb72f073SLang Hames SimpleRemoteEPCServer::Dispatcher::~Dispatcher() {} 112*bb72f073SLang Hames 113*bb72f073SLang Hames #if LLVM_ENABLE_THREADS 114*bb72f073SLang Hames void SimpleRemoteEPCServer::ThreadDispatcher::dispatch( 115*bb72f073SLang Hames unique_function<void()> Work) { 116*bb72f073SLang Hames { 117*bb72f073SLang Hames std::lock_guard<std::mutex> Lock(DispatchMutex); 118*bb72f073SLang Hames if (!Running) 119*bb72f073SLang Hames return; 120*bb72f073SLang Hames ++Outstanding; 121*bb72f073SLang Hames } 122*bb72f073SLang Hames 123*bb72f073SLang Hames std::thread([this, Work = std::move(Work)]() mutable { 124*bb72f073SLang Hames Work(); 125*bb72f073SLang Hames std::lock_guard<std::mutex> Lock(DispatchMutex); 126*bb72f073SLang Hames --Outstanding; 127*bb72f073SLang Hames OutstandingCV.notify_all(); 128*bb72f073SLang Hames }).detach(); 129*bb72f073SLang Hames } 130*bb72f073SLang Hames 131*bb72f073SLang Hames void SimpleRemoteEPCServer::ThreadDispatcher::shutdown() { 132*bb72f073SLang Hames std::unique_lock<std::mutex> Lock(DispatchMutex); 133*bb72f073SLang Hames Running = false; 134*bb72f073SLang Hames OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; }); 135*bb72f073SLang Hames } 136*bb72f073SLang Hames #endif 137*bb72f073SLang Hames 138*bb72f073SLang Hames StringMap<ExecutorAddress> SimpleRemoteEPCServer::defaultBootstrapSymbols() { 139*bb72f073SLang Hames StringMap<ExecutorAddress> DBS; 140*bb72f073SLang Hames 141*bb72f073SLang Hames DBS["__llvm_orc_memory_reserve"] = ExecutorAddress::fromPtr(&reserveWrapper); 142*bb72f073SLang Hames DBS["__llvm_orc_memory_finalize"] = 143*bb72f073SLang Hames ExecutorAddress::fromPtr(&finalizeWrapper); 144*bb72f073SLang Hames DBS["__llvm_orc_memory_deallocate"] = 145*bb72f073SLang Hames ExecutorAddress::fromPtr(&deallocateWrapper); 146*bb72f073SLang Hames DBS["__llvm_orc_memory_write_uint8s"] = ExecutorAddress::fromPtr( 147*bb72f073SLang Hames &writeUIntsWrapper<tpctypes::UInt8Write, 148*bb72f073SLang Hames shared::SPSMemoryAccessUInt8Write>); 149*bb72f073SLang Hames DBS["__llvm_orc_memory_write_uint16s"] = ExecutorAddress::fromPtr( 150*bb72f073SLang Hames &writeUIntsWrapper<tpctypes::UInt16Write, 151*bb72f073SLang Hames shared::SPSMemoryAccessUInt16Write>); 152*bb72f073SLang Hames DBS["__llvm_orc_memory_write_uint32s"] = ExecutorAddress::fromPtr( 153*bb72f073SLang Hames &writeUIntsWrapper<tpctypes::UInt32Write, 154*bb72f073SLang Hames shared::SPSMemoryAccessUInt32Write>); 155*bb72f073SLang Hames DBS["__llvm_orc_memory_write_uint64s"] = ExecutorAddress::fromPtr( 156*bb72f073SLang Hames &writeUIntsWrapper<tpctypes::UInt64Write, 157*bb72f073SLang Hames shared::SPSMemoryAccessUInt64Write>); 158*bb72f073SLang Hames DBS["__llvm_orc_memory_write_buffers"] = 159*bb72f073SLang Hames ExecutorAddress::fromPtr(&writeBuffersWrapper); 160*bb72f073SLang Hames DBS["__llvm_orc_run_as_main"] = ExecutorAddress::fromPtr(&runAsMainWrapper); 161*bb72f073SLang Hames DBS["__llvm_orc_load_dylib"] = ExecutorAddress::fromPtr(&loadDylibWrapper); 162*bb72f073SLang Hames DBS["__llvm_orc_lookup_symbols"] = 163*bb72f073SLang Hames ExecutorAddress::fromPtr(&lookupSymbolsWrapper); 164*bb72f073SLang Hames return DBS; 165*bb72f073SLang Hames } 166*bb72f073SLang Hames 167*bb72f073SLang Hames Expected<SimpleRemoteEPCTransportClient::HandleMessageAction> 168*bb72f073SLang Hames SimpleRemoteEPCServer::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 169*bb72f073SLang Hames ExecutorAddress TagAddr, 170*bb72f073SLang Hames SimpleRemoteEPCArgBytesVector ArgBytes) { 171*bb72f073SLang Hames using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>; 172*bb72f073SLang Hames if (static_cast<UT>(OpC) < static_cast<UT>(SimpleRemoteEPCOpcode::FirstOpC) || 173*bb72f073SLang Hames static_cast<UT>(OpC) > static_cast<UT>(SimpleRemoteEPCOpcode::LastOpC)) 174*bb72f073SLang Hames return make_error<StringError>("Unexpected opcode", 175*bb72f073SLang Hames inconvertibleErrorCode()); 176*bb72f073SLang Hames 177*bb72f073SLang Hames // TODO: Clean detach message? 178*bb72f073SLang Hames switch (OpC) { 179*bb72f073SLang Hames case SimpleRemoteEPCOpcode::Setup: 180*bb72f073SLang Hames return make_error<StringError>("Unexpected Setup opcode", 181*bb72f073SLang Hames inconvertibleErrorCode()); 182*bb72f073SLang Hames case SimpleRemoteEPCOpcode::Hangup: 183*bb72f073SLang Hames return SimpleRemoteEPCTransportClient::EndSession; 184*bb72f073SLang Hames case SimpleRemoteEPCOpcode::Result: 185*bb72f073SLang Hames if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes))) 186*bb72f073SLang Hames return std::move(Err); 187*bb72f073SLang Hames break; 188*bb72f073SLang Hames case SimpleRemoteEPCOpcode::CallWrapper: 189*bb72f073SLang Hames handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes)); 190*bb72f073SLang Hames break; 191*bb72f073SLang Hames } 192*bb72f073SLang Hames return ContinueSession; 193*bb72f073SLang Hames } 194*bb72f073SLang Hames 195*bb72f073SLang Hames Error SimpleRemoteEPCServer::waitForDisconnect() { 196*bb72f073SLang Hames std::unique_lock<std::mutex> Lock(ServerStateMutex); 197*bb72f073SLang Hames ShutdownCV.wait(Lock, [this]() { return RunState == ServerShutDown; }); 198*bb72f073SLang Hames return std::move(ShutdownErr); 199*bb72f073SLang Hames } 200*bb72f073SLang Hames 201*bb72f073SLang Hames void SimpleRemoteEPCServer::handleDisconnect(Error Err) { 202*bb72f073SLang Hames PendingJITDispatchResultsMap TmpPending; 203*bb72f073SLang Hames 204*bb72f073SLang Hames { 205*bb72f073SLang Hames std::lock_guard<std::mutex> Lock(ServerStateMutex); 206*bb72f073SLang Hames std::swap(TmpPending, PendingJITDispatchResults); 207*bb72f073SLang Hames RunState = ServerShuttingDown; 208*bb72f073SLang Hames } 209*bb72f073SLang Hames 210*bb72f073SLang Hames // Send out-of-band errors to any waiting threads. 211*bb72f073SLang Hames for (auto &KV : TmpPending) 212*bb72f073SLang Hames KV.second->set_value( 213*bb72f073SLang Hames shared::WrapperFunctionResult::createOutOfBandError("disconnecting")); 214*bb72f073SLang Hames 215*bb72f073SLang Hames // TODO: Free attached resources. 216*bb72f073SLang Hames // 1. Close libraries in DylibHandles. 217*bb72f073SLang Hames 218*bb72f073SLang Hames // Wait for dispatcher to clear. 219*bb72f073SLang Hames D->shutdown(); 220*bb72f073SLang Hames 221*bb72f073SLang Hames std::lock_guard<std::mutex> Lock(ServerStateMutex); 222*bb72f073SLang Hames ShutdownErr = joinErrors(std::move(ShutdownErr), std::move(Err)); 223*bb72f073SLang Hames RunState = ServerShutDown; 224*bb72f073SLang Hames ShutdownCV.notify_all(); 225*bb72f073SLang Hames } 226*bb72f073SLang Hames 227*bb72f073SLang Hames Error SimpleRemoteEPCServer::sendSetupMessage( 228*bb72f073SLang Hames StringMap<ExecutorAddress> BootstrapSymbols) { 229*bb72f073SLang Hames 230*bb72f073SLang Hames using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames; 231*bb72f073SLang Hames 232*bb72f073SLang Hames std::vector<char> SetupPacket; 233*bb72f073SLang Hames SimpleRemoteEPCExecutorInfo EI; 234*bb72f073SLang Hames EI.TargetTriple = sys::getProcessTriple(); 235*bb72f073SLang Hames if (auto PageSize = sys::Process::getPageSize()) 236*bb72f073SLang Hames EI.PageSize = *PageSize; 237*bb72f073SLang Hames else 238*bb72f073SLang Hames return PageSize.takeError(); 239*bb72f073SLang Hames EI.BootstrapSymbols = std::move(BootstrapSymbols); 240*bb72f073SLang Hames 241*bb72f073SLang Hames assert(!EI.BootstrapSymbols.count(ExecutorSessionObjectName) && 242*bb72f073SLang Hames "Dispatch context name should not be set"); 243*bb72f073SLang Hames assert(!EI.BootstrapSymbols.count(DispatchFnName) && 244*bb72f073SLang Hames "Dispatch function name should not be set"); 245*bb72f073SLang Hames EI.BootstrapSymbols[ExecutorSessionObjectName] = 246*bb72f073SLang Hames ExecutorAddress::fromPtr(this); 247*bb72f073SLang Hames EI.BootstrapSymbols[DispatchFnName] = 248*bb72f073SLang Hames ExecutorAddress::fromPtr(jitDispatchEntry); 249*bb72f073SLang Hames 250*bb72f073SLang Hames using SPSSerialize = 251*bb72f073SLang Hames shared::SPSArgList<shared::SPSSimpleRemoteEPCExecutorInfo>; 252*bb72f073SLang Hames auto SetupPacketBytes = 253*bb72f073SLang Hames shared::WrapperFunctionResult::allocate(SPSSerialize::size(EI)); 254*bb72f073SLang Hames shared::SPSOutputBuffer OB(SetupPacketBytes.data(), SetupPacketBytes.size()); 255*bb72f073SLang Hames if (!SPSSerialize::serialize(OB, EI)) 256*bb72f073SLang Hames return make_error<StringError>("Could not send setup packet", 257*bb72f073SLang Hames inconvertibleErrorCode()); 258*bb72f073SLang Hames 259*bb72f073SLang Hames return T->sendMessage(SimpleRemoteEPCOpcode::Setup, 0, ExecutorAddress(), 260*bb72f073SLang Hames {SetupPacketBytes.data(), SetupPacketBytes.size()}); 261*bb72f073SLang Hames } 262*bb72f073SLang Hames 263*bb72f073SLang Hames Error SimpleRemoteEPCServer::handleResult( 264*bb72f073SLang Hames uint64_t SeqNo, ExecutorAddress TagAddr, 265*bb72f073SLang Hames SimpleRemoteEPCArgBytesVector ArgBytes) { 266*bb72f073SLang Hames std::promise<shared::WrapperFunctionResult> *P = nullptr; 267*bb72f073SLang Hames { 268*bb72f073SLang Hames std::lock_guard<std::mutex> Lock(ServerStateMutex); 269*bb72f073SLang Hames auto I = PendingJITDispatchResults.find(SeqNo); 270*bb72f073SLang Hames if (I == PendingJITDispatchResults.end()) 271*bb72f073SLang Hames return make_error<StringError>("No call for sequence number " + 272*bb72f073SLang Hames Twine(SeqNo), 273*bb72f073SLang Hames inconvertibleErrorCode()); 274*bb72f073SLang Hames P = I->second; 275*bb72f073SLang Hames PendingJITDispatchResults.erase(I); 276*bb72f073SLang Hames releaseSeqNo(SeqNo); 277*bb72f073SLang Hames } 278*bb72f073SLang Hames auto R = shared::WrapperFunctionResult::allocate(ArgBytes.size()); 279*bb72f073SLang Hames memcpy(R.data(), ArgBytes.data(), ArgBytes.size()); 280*bb72f073SLang Hames P->set_value(std::move(R)); 281*bb72f073SLang Hames return Error::success(); 282*bb72f073SLang Hames } 283*bb72f073SLang Hames 284*bb72f073SLang Hames void SimpleRemoteEPCServer::handleCallWrapper( 285*bb72f073SLang Hames uint64_t RemoteSeqNo, ExecutorAddress TagAddr, 286*bb72f073SLang Hames SimpleRemoteEPCArgBytesVector ArgBytes) { 287*bb72f073SLang Hames D->dispatch([this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() { 288*bb72f073SLang Hames using WrapperFnTy = 289*bb72f073SLang Hames shared::detail::CWrapperFunctionResult (*)(const char *, size_t); 290*bb72f073SLang Hames auto *Fn = TagAddr.toPtr<WrapperFnTy>(); 291*bb72f073SLang Hames shared::WrapperFunctionResult ResultBytes( 292*bb72f073SLang Hames Fn(ArgBytes.data(), ArgBytes.size())); 293*bb72f073SLang Hames if (auto Err = T->sendMessage(SimpleRemoteEPCOpcode::Result, RemoteSeqNo, 294*bb72f073SLang Hames ExecutorAddress(), 295*bb72f073SLang Hames {ResultBytes.data(), ResultBytes.size()})) 296*bb72f073SLang Hames ReportError(std::move(Err)); 297*bb72f073SLang Hames }); 298*bb72f073SLang Hames } 299*bb72f073SLang Hames 300*bb72f073SLang Hames shared::detail::CWrapperFunctionResult 301*bb72f073SLang Hames SimpleRemoteEPCServer::loadDylibWrapper(const char *ArgData, size_t ArgSize) { 302*bb72f073SLang Hames return shared::WrapperFunction<shared::SPSLoadDylibSignature>::handle( 303*bb72f073SLang Hames ArgData, ArgSize, 304*bb72f073SLang Hames [](ExecutorAddress ExecutorSessionObj, std::string Path, 305*bb72f073SLang Hames uint64_t Flags) -> Expected<uint64_t> { 306*bb72f073SLang Hames return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>() 307*bb72f073SLang Hames ->loadDylib(Path, Flags); 308*bb72f073SLang Hames }) 309*bb72f073SLang Hames .release(); 310*bb72f073SLang Hames } 311*bb72f073SLang Hames 312*bb72f073SLang Hames shared::detail::CWrapperFunctionResult 313*bb72f073SLang Hames SimpleRemoteEPCServer::lookupSymbolsWrapper(const char *ArgData, 314*bb72f073SLang Hames size_t ArgSize) { 315*bb72f073SLang Hames return shared::WrapperFunction<shared::SPSLookupSymbolsSignature>::handle( 316*bb72f073SLang Hames ArgData, ArgSize, 317*bb72f073SLang Hames [](ExecutorAddress ExecutorSessionObj, 318*bb72f073SLang Hames std::vector<RemoteSymbolLookup> Lookup) { 319*bb72f073SLang Hames return ExecutorSessionObj.toPtr<SimpleRemoteEPCServer *>() 320*bb72f073SLang Hames ->lookupSymbols(Lookup); 321*bb72f073SLang Hames }) 322*bb72f073SLang Hames .release(); 323*bb72f073SLang Hames } 324*bb72f073SLang Hames 325*bb72f073SLang Hames Expected<tpctypes::DylibHandle> 326*bb72f073SLang Hames SimpleRemoteEPCServer::loadDylib(const std::string &Path, uint64_t Mode) { 327*bb72f073SLang Hames std::string ErrMsg; 328*bb72f073SLang Hames const char *P = Path.empty() ? nullptr : Path.c_str(); 329*bb72f073SLang Hames auto DL = sys::DynamicLibrary::getPermanentLibrary(P, &ErrMsg); 330*bb72f073SLang Hames if (!DL.isValid()) 331*bb72f073SLang Hames return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); 332*bb72f073SLang Hames std::lock_guard<std::mutex> Lock(ServerStateMutex); 333*bb72f073SLang Hames uint64_t Id = Dylibs.size(); 334*bb72f073SLang Hames Dylibs.push_back(std::move(DL)); 335*bb72f073SLang Hames return Id; 336*bb72f073SLang Hames } 337*bb72f073SLang Hames 338*bb72f073SLang Hames Expected<std::vector<std::vector<ExecutorAddress>>> 339*bb72f073SLang Hames SimpleRemoteEPCServer::lookupSymbols(const std::vector<RemoteSymbolLookup> &L) { 340*bb72f073SLang Hames std::vector<std::vector<ExecutorAddress>> Result; 341*bb72f073SLang Hames 342*bb72f073SLang Hames for (const auto &E : L) { 343*bb72f073SLang Hames if (E.H >= Dylibs.size()) 344*bb72f073SLang Hames return make_error<StringError>("Unrecognized handle", 345*bb72f073SLang Hames inconvertibleErrorCode()); 346*bb72f073SLang Hames auto &DL = Dylibs[E.H]; 347*bb72f073SLang Hames Result.push_back({}); 348*bb72f073SLang Hames 349*bb72f073SLang Hames for (const auto &Sym : E.Symbols) { 350*bb72f073SLang Hames 351*bb72f073SLang Hames const char *DemangledSymName = Sym.Name.c_str(); 352*bb72f073SLang Hames #ifdef __APPLE__ 353*bb72f073SLang Hames if (*DemangledSymName == '_') 354*bb72f073SLang Hames ++DemangledSymName; 355*bb72f073SLang Hames #endif 356*bb72f073SLang Hames 357*bb72f073SLang Hames void *Addr = DL.getAddressOfSymbol(DemangledSymName); 358*bb72f073SLang Hames if (!Addr && Sym.Required) 359*bb72f073SLang Hames return make_error<StringError>(Twine("Missing definition for ") + 360*bb72f073SLang Hames DemangledSymName, 361*bb72f073SLang Hames inconvertibleErrorCode()); 362*bb72f073SLang Hames 363*bb72f073SLang Hames Result.back().push_back(ExecutorAddress::fromPtr(Addr)); 364*bb72f073SLang Hames } 365*bb72f073SLang Hames } 366*bb72f073SLang Hames 367*bb72f073SLang Hames return std::move(Result); 368*bb72f073SLang Hames } 369*bb72f073SLang Hames 370*bb72f073SLang Hames shared::WrapperFunctionResult 371*bb72f073SLang Hames SimpleRemoteEPCServer::doJITDispatch(const void *FnTag, const char *ArgData, 372*bb72f073SLang Hames size_t ArgSize) { 373*bb72f073SLang Hames uint64_t SeqNo; 374*bb72f073SLang Hames std::promise<shared::WrapperFunctionResult> ResultP; 375*bb72f073SLang Hames auto ResultF = ResultP.get_future(); 376*bb72f073SLang Hames { 377*bb72f073SLang Hames std::lock_guard<std::mutex> Lock(ServerStateMutex); 378*bb72f073SLang Hames if (RunState != ServerRunning) 379*bb72f073SLang Hames return shared::WrapperFunctionResult::createOutOfBandError( 380*bb72f073SLang Hames "jit_dispatch not available (EPC server shut down)"); 381*bb72f073SLang Hames 382*bb72f073SLang Hames SeqNo = getNextSeqNo(); 383*bb72f073SLang Hames assert(!PendingJITDispatchResults.count(SeqNo) && "SeqNo already in use"); 384*bb72f073SLang Hames PendingJITDispatchResults[SeqNo] = &ResultP; 385*bb72f073SLang Hames } 386*bb72f073SLang Hames 387*bb72f073SLang Hames if (auto Err = 388*bb72f073SLang Hames T->sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo, 389*bb72f073SLang Hames ExecutorAddress::fromPtr(FnTag), {ArgData, ArgSize})) 390*bb72f073SLang Hames ReportError(std::move(Err)); 391*bb72f073SLang Hames 392*bb72f073SLang Hames return ResultF.get(); 393*bb72f073SLang Hames } 394*bb72f073SLang Hames 395*bb72f073SLang Hames shared::detail::CWrapperFunctionResult 396*bb72f073SLang Hames SimpleRemoteEPCServer::jitDispatchEntry(void *DispatchCtx, const void *FnTag, 397*bb72f073SLang Hames const char *ArgData, size_t ArgSize) { 398*bb72f073SLang Hames return reinterpret_cast<SimpleRemoteEPCServer *>(DispatchCtx) 399*bb72f073SLang Hames ->doJITDispatch(FnTag, ArgData, ArgSize) 400*bb72f073SLang Hames .release(); 401*bb72f073SLang Hames } 402*bb72f073SLang Hames 403*bb72f073SLang Hames } // end namespace orc 404*bb72f073SLang Hames } // end namespace llvm 405