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