OrcRemoteTargetServer.h revision 309124
1293838Sdim//===---- OrcRemoteTargetServer.h - Orc Remote-target Server ----*- C++ -*-===//
2293838Sdim//
3293838Sdim//                     The LLVM Compiler Infrastructure
4293838Sdim//
5293838Sdim// This file is distributed under the University of Illinois Open Source
6293838Sdim// License. See LICENSE.TXT for details.
7293838Sdim//
8293838Sdim//===----------------------------------------------------------------------===//
9293838Sdim//
10293838Sdim// This file defines the OrcRemoteTargetServer class. It can be used to build a
11293838Sdim// JIT server that can execute code sent from an OrcRemoteTargetClient.
12293838Sdim//
13293838Sdim//===----------------------------------------------------------------------===//
14293838Sdim
15293838Sdim#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
16293838Sdim#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
17293838Sdim
18293838Sdim#include "OrcRemoteTargetRPCAPI.h"
19293838Sdim#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
20293838Sdim#include "llvm/Support/Debug.h"
21293838Sdim#include "llvm/Support/Format.h"
22293838Sdim#include "llvm/Support/Process.h"
23293838Sdim#include "llvm/Support/raw_ostream.h"
24293838Sdim#include <map>
25293838Sdim
26293838Sdim#define DEBUG_TYPE "orc-remote"
27293838Sdim
28293838Sdimnamespace llvm {
29293838Sdimnamespace orc {
30293838Sdimnamespace remote {
31293838Sdim
32293838Sdimtemplate <typename ChannelT, typename TargetT>
33293838Sdimclass OrcRemoteTargetServer : public OrcRemoteTargetRPCAPI {
34293838Sdimpublic:
35293838Sdim  typedef std::function<TargetAddress(const std::string &Name)>
36293838Sdim      SymbolLookupFtor;
37293838Sdim
38309124Sdim  typedef std::function<void(uint8_t *Addr, uint32_t Size)>
39309124Sdim      EHFrameRegistrationFtor;
40293838Sdim
41309124Sdim  OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup,
42309124Sdim                        EHFrameRegistrationFtor EHFramesRegister,
43309124Sdim                        EHFrameRegistrationFtor EHFramesDeregister)
44309124Sdim      : Channel(Channel), SymbolLookup(std::move(SymbolLookup)),
45309124Sdim        EHFramesRegister(std::move(EHFramesRegister)),
46309124Sdim        EHFramesDeregister(std::move(EHFramesDeregister)) {}
47293838Sdim
48309124Sdim  // FIXME: Remove move/copy ops once MSVC supports synthesizing move ops.
49309124Sdim  OrcRemoteTargetServer(const OrcRemoteTargetServer &) = delete;
50309124Sdim  OrcRemoteTargetServer &operator=(const OrcRemoteTargetServer &) = delete;
51309124Sdim
52309124Sdim  OrcRemoteTargetServer(OrcRemoteTargetServer &&Other)
53309124Sdim      : Channel(Other.Channel), SymbolLookup(std::move(Other.SymbolLookup)),
54309124Sdim        EHFramesRegister(std::move(Other.EHFramesRegister)),
55309124Sdim        EHFramesDeregister(std::move(Other.EHFramesDeregister)) {}
56309124Sdim
57309124Sdim  OrcRemoteTargetServer &operator=(OrcRemoteTargetServer &&) = delete;
58309124Sdim
59309124Sdim  Error handleKnownFunction(JITFuncId Id) {
60293838Sdim    typedef OrcRemoteTargetServer ThisT;
61293838Sdim
62309124Sdim    DEBUG(dbgs() << "Handling known proc: " << getJITFuncIdName(Id) << "\n");
63293838Sdim
64293838Sdim    switch (Id) {
65293838Sdim    case CallIntVoidId:
66293838Sdim      return handle<CallIntVoid>(Channel, *this, &ThisT::handleCallIntVoid);
67293838Sdim    case CallMainId:
68293838Sdim      return handle<CallMain>(Channel, *this, &ThisT::handleCallMain);
69293838Sdim    case CallVoidVoidId:
70293838Sdim      return handle<CallVoidVoid>(Channel, *this, &ThisT::handleCallVoidVoid);
71293838Sdim    case CreateRemoteAllocatorId:
72293838Sdim      return handle<CreateRemoteAllocator>(Channel, *this,
73293838Sdim                                           &ThisT::handleCreateRemoteAllocator);
74293838Sdim    case CreateIndirectStubsOwnerId:
75293838Sdim      return handle<CreateIndirectStubsOwner>(
76293838Sdim          Channel, *this, &ThisT::handleCreateIndirectStubsOwner);
77309124Sdim    case DeregisterEHFramesId:
78309124Sdim      return handle<DeregisterEHFrames>(Channel, *this,
79309124Sdim                                        &ThisT::handleDeregisterEHFrames);
80293838Sdim    case DestroyRemoteAllocatorId:
81293838Sdim      return handle<DestroyRemoteAllocator>(
82293838Sdim          Channel, *this, &ThisT::handleDestroyRemoteAllocator);
83293838Sdim    case DestroyIndirectStubsOwnerId:
84293838Sdim      return handle<DestroyIndirectStubsOwner>(
85293838Sdim          Channel, *this, &ThisT::handleDestroyIndirectStubsOwner);
86293838Sdim    case EmitIndirectStubsId:
87293838Sdim      return handle<EmitIndirectStubs>(Channel, *this,
88293838Sdim                                       &ThisT::handleEmitIndirectStubs);
89293838Sdim    case EmitResolverBlockId:
90293838Sdim      return handle<EmitResolverBlock>(Channel, *this,
91293838Sdim                                       &ThisT::handleEmitResolverBlock);
92293838Sdim    case EmitTrampolineBlockId:
93293838Sdim      return handle<EmitTrampolineBlock>(Channel, *this,
94293838Sdim                                         &ThisT::handleEmitTrampolineBlock);
95293838Sdim    case GetSymbolAddressId:
96293838Sdim      return handle<GetSymbolAddress>(Channel, *this,
97293838Sdim                                      &ThisT::handleGetSymbolAddress);
98293838Sdim    case GetRemoteInfoId:
99293838Sdim      return handle<GetRemoteInfo>(Channel, *this, &ThisT::handleGetRemoteInfo);
100293838Sdim    case ReadMemId:
101293838Sdim      return handle<ReadMem>(Channel, *this, &ThisT::handleReadMem);
102309124Sdim    case RegisterEHFramesId:
103309124Sdim      return handle<RegisterEHFrames>(Channel, *this,
104309124Sdim                                      &ThisT::handleRegisterEHFrames);
105293838Sdim    case ReserveMemId:
106293838Sdim      return handle<ReserveMem>(Channel, *this, &ThisT::handleReserveMem);
107293838Sdim    case SetProtectionsId:
108293838Sdim      return handle<SetProtections>(Channel, *this,
109293838Sdim                                    &ThisT::handleSetProtections);
110293838Sdim    case WriteMemId:
111293838Sdim      return handle<WriteMem>(Channel, *this, &ThisT::handleWriteMem);
112293838Sdim    case WritePtrId:
113293838Sdim      return handle<WritePtr>(Channel, *this, &ThisT::handleWritePtr);
114293838Sdim    default:
115293838Sdim      return orcError(OrcErrorCode::UnexpectedRPCCall);
116293838Sdim    }
117293838Sdim
118293838Sdim    llvm_unreachable("Unhandled JIT RPC procedure Id.");
119293838Sdim  }
120293838Sdim
121309124Sdim  Expected<TargetAddress> requestCompile(TargetAddress TrampolineAddr) {
122309124Sdim    auto Listen = [&](RPCChannel &C, uint32_t Id) {
123309124Sdim      return handleKnownFunction(static_cast<JITFuncId>(Id));
124309124Sdim    };
125293838Sdim
126309124Sdim    return callSTHandling<RequestCompile>(Channel, Listen, TrampolineAddr);
127309124Sdim  }
128293838Sdim
129309124Sdim  Error handleTerminateSession() {
130309124Sdim    return handle<TerminateSession>(Channel, []() { return Error::success(); });
131293838Sdim  }
132293838Sdim
133293838Sdimprivate:
134293838Sdim  struct Allocator {
135293838Sdim    Allocator() = default;
136293838Sdim    Allocator(Allocator &&Other) : Allocs(std::move(Other.Allocs)) {}
137293838Sdim    Allocator &operator=(Allocator &&Other) {
138293838Sdim      Allocs = std::move(Other.Allocs);
139293838Sdim      return *this;
140293838Sdim    }
141293838Sdim
142293838Sdim    ~Allocator() {
143293838Sdim      for (auto &Alloc : Allocs)
144293838Sdim        sys::Memory::releaseMappedMemory(Alloc.second);
145293838Sdim    }
146293838Sdim
147309124Sdim    Error allocate(void *&Addr, size_t Size, uint32_t Align) {
148293838Sdim      std::error_code EC;
149293838Sdim      sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(
150293838Sdim          Size, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC);
151293838Sdim      if (EC)
152309124Sdim        return errorCodeToError(EC);
153293838Sdim
154293838Sdim      Addr = MB.base();
155293838Sdim      assert(Allocs.find(MB.base()) == Allocs.end() && "Duplicate alloc");
156293838Sdim      Allocs[MB.base()] = std::move(MB);
157309124Sdim      return Error::success();
158293838Sdim    }
159293838Sdim
160309124Sdim    Error setProtections(void *block, unsigned Flags) {
161293838Sdim      auto I = Allocs.find(block);
162293838Sdim      if (I == Allocs.end())
163293838Sdim        return orcError(OrcErrorCode::RemoteMProtectAddrUnrecognized);
164309124Sdim      return errorCodeToError(
165309124Sdim          sys::Memory::protectMappedMemory(I->second, Flags));
166293838Sdim    }
167293838Sdim
168293838Sdim  private:
169293838Sdim    std::map<void *, sys::MemoryBlock> Allocs;
170293838Sdim  };
171293838Sdim
172309124Sdim  static Error doNothing() { return Error::success(); }
173293838Sdim
174293838Sdim  static TargetAddress reenter(void *JITTargetAddr, void *TrampolineAddr) {
175293838Sdim    auto T = static_cast<OrcRemoteTargetServer *>(JITTargetAddr);
176309124Sdim    auto AddrOrErr = T->requestCompile(static_cast<TargetAddress>(
177309124Sdim        reinterpret_cast<uintptr_t>(TrampolineAddr)));
178309124Sdim    // FIXME: Allow customizable failure substitution functions.
179309124Sdim    assert(AddrOrErr && "Compile request failed");
180309124Sdim    return *AddrOrErr;
181293838Sdim  }
182293838Sdim
183309124Sdim  Expected<int32_t> handleCallIntVoid(TargetAddress Addr) {
184293838Sdim    typedef int (*IntVoidFnTy)();
185293838Sdim    IntVoidFnTy Fn =
186293838Sdim        reinterpret_cast<IntVoidFnTy>(static_cast<uintptr_t>(Addr));
187293838Sdim
188309124Sdim    DEBUG(dbgs() << "  Calling " << format("0x%016x", Addr) << "\n");
189293838Sdim    int Result = Fn();
190293838Sdim    DEBUG(dbgs() << "  Result = " << Result << "\n");
191293838Sdim
192309124Sdim    return Result;
193293838Sdim  }
194293838Sdim
195309124Sdim  Expected<int32_t> handleCallMain(TargetAddress Addr,
196309124Sdim                                   std::vector<std::string> Args) {
197293838Sdim    typedef int (*MainFnTy)(int, const char *[]);
198293838Sdim
199293838Sdim    MainFnTy Fn = reinterpret_cast<MainFnTy>(static_cast<uintptr_t>(Addr));
200293838Sdim    int ArgC = Args.size() + 1;
201293838Sdim    int Idx = 1;
202293838Sdim    std::unique_ptr<const char *[]> ArgV(new const char *[ArgC + 1]);
203293838Sdim    ArgV[0] = "<jit process>";
204293838Sdim    for (auto &Arg : Args)
205293838Sdim      ArgV[Idx++] = Arg.c_str();
206293838Sdim
207309124Sdim    DEBUG(dbgs() << "  Calling " << format("0x%016x", Addr) << "\n");
208293838Sdim    int Result = Fn(ArgC, ArgV.get());
209293838Sdim    DEBUG(dbgs() << "  Result = " << Result << "\n");
210293838Sdim
211309124Sdim    return Result;
212293838Sdim  }
213293838Sdim
214309124Sdim  Error handleCallVoidVoid(TargetAddress Addr) {
215293838Sdim    typedef void (*VoidVoidFnTy)();
216293838Sdim    VoidVoidFnTy Fn =
217293838Sdim        reinterpret_cast<VoidVoidFnTy>(static_cast<uintptr_t>(Addr));
218293838Sdim
219309124Sdim    DEBUG(dbgs() << "  Calling " << format("0x%016x", Addr) << "\n");
220293838Sdim    Fn();
221293838Sdim    DEBUG(dbgs() << "  Complete.\n");
222293838Sdim
223309124Sdim    return Error::success();
224293838Sdim  }
225293838Sdim
226309124Sdim  Error handleCreateRemoteAllocator(ResourceIdMgr::ResourceId Id) {
227293838Sdim    auto I = Allocators.find(Id);
228293838Sdim    if (I != Allocators.end())
229293838Sdim      return orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse);
230293838Sdim    DEBUG(dbgs() << "  Created allocator " << Id << "\n");
231293838Sdim    Allocators[Id] = Allocator();
232309124Sdim    return Error::success();
233293838Sdim  }
234293838Sdim
235309124Sdim  Error handleCreateIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {
236293838Sdim    auto I = IndirectStubsOwners.find(Id);
237293838Sdim    if (I != IndirectStubsOwners.end())
238293838Sdim      return orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse);
239293838Sdim    DEBUG(dbgs() << "  Create indirect stubs owner " << Id << "\n");
240293838Sdim    IndirectStubsOwners[Id] = ISBlockOwnerList();
241309124Sdim    return Error::success();
242293838Sdim  }
243293838Sdim
244309124Sdim  Error handleDeregisterEHFrames(TargetAddress TAddr, uint32_t Size) {
245309124Sdim    uint8_t *Addr = reinterpret_cast<uint8_t *>(static_cast<uintptr_t>(TAddr));
246309124Sdim    DEBUG(dbgs() << "  Registering EH frames at " << format("0x%016x", TAddr)
247309124Sdim                 << ", Size = " << Size << " bytes\n");
248309124Sdim    EHFramesDeregister(Addr, Size);
249309124Sdim    return Error::success();
250309124Sdim  }
251309124Sdim
252309124Sdim  Error handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId Id) {
253293838Sdim    auto I = Allocators.find(Id);
254293838Sdim    if (I == Allocators.end())
255293838Sdim      return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);
256293838Sdim    Allocators.erase(I);
257293838Sdim    DEBUG(dbgs() << "  Destroyed allocator " << Id << "\n");
258309124Sdim    return Error::success();
259293838Sdim  }
260293838Sdim
261309124Sdim  Error handleDestroyIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {
262293838Sdim    auto I = IndirectStubsOwners.find(Id);
263293838Sdim    if (I == IndirectStubsOwners.end())
264293838Sdim      return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist);
265293838Sdim    IndirectStubsOwners.erase(I);
266309124Sdim    return Error::success();
267293838Sdim  }
268293838Sdim
269309124Sdim  Expected<std::tuple<TargetAddress, TargetAddress, uint32_t>>
270309124Sdim  handleEmitIndirectStubs(ResourceIdMgr::ResourceId Id,
271309124Sdim                          uint32_t NumStubsRequired) {
272293838Sdim    DEBUG(dbgs() << "  ISMgr " << Id << " request " << NumStubsRequired
273293838Sdim                 << " stubs.\n");
274293838Sdim
275293838Sdim    auto StubOwnerItr = IndirectStubsOwners.find(Id);
276293838Sdim    if (StubOwnerItr == IndirectStubsOwners.end())
277293838Sdim      return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist);
278293838Sdim
279293838Sdim    typename TargetT::IndirectStubsInfo IS;
280309124Sdim    if (auto Err =
281293838Sdim            TargetT::emitIndirectStubsBlock(IS, NumStubsRequired, nullptr))
282309124Sdim      return std::move(Err);
283293838Sdim
284293838Sdim    TargetAddress StubsBase =
285293838Sdim        static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(IS.getStub(0)));
286293838Sdim    TargetAddress PtrsBase =
287293838Sdim        static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(IS.getPtr(0)));
288293838Sdim    uint32_t NumStubsEmitted = IS.getNumStubs();
289293838Sdim
290293838Sdim    auto &BlockList = StubOwnerItr->second;
291293838Sdim    BlockList.push_back(std::move(IS));
292293838Sdim
293309124Sdim    return std::make_tuple(StubsBase, PtrsBase, NumStubsEmitted);
294293838Sdim  }
295293838Sdim
296309124Sdim  Error handleEmitResolverBlock() {
297293838Sdim    std::error_code EC;
298293838Sdim    ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
299293838Sdim        TargetT::ResolverCodeSize, nullptr,
300293838Sdim        sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
301293838Sdim    if (EC)
302309124Sdim      return errorCodeToError(EC);
303293838Sdim
304293838Sdim    TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
305293838Sdim                               &reenter, this);
306293838Sdim
307309124Sdim    return errorCodeToError(sys::Memory::protectMappedMemory(
308309124Sdim        ResolverBlock.getMemoryBlock(),
309309124Sdim        sys::Memory::MF_READ | sys::Memory::MF_EXEC));
310293838Sdim  }
311293838Sdim
312309124Sdim  Expected<std::tuple<TargetAddress, uint32_t>> handleEmitTrampolineBlock() {
313293838Sdim    std::error_code EC;
314293838Sdim    auto TrampolineBlock =
315293838Sdim        sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
316293838Sdim            sys::Process::getPageSize(), nullptr,
317293838Sdim            sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
318293838Sdim    if (EC)
319309124Sdim      return errorCodeToError(EC);
320293838Sdim
321309124Sdim    uint32_t NumTrampolines =
322293838Sdim        (sys::Process::getPageSize() - TargetT::PointerSize) /
323293838Sdim        TargetT::TrampolineSize;
324293838Sdim
325293838Sdim    uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
326293838Sdim    TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(),
327293838Sdim                              NumTrampolines);
328293838Sdim
329293838Sdim    EC = sys::Memory::protectMappedMemory(TrampolineBlock.getMemoryBlock(),
330293838Sdim                                          sys::Memory::MF_READ |
331293838Sdim                                              sys::Memory::MF_EXEC);
332293838Sdim
333293838Sdim    TrampolineBlocks.push_back(std::move(TrampolineBlock));
334293838Sdim
335309124Sdim    auto TrampolineBaseAddr =
336309124Sdim        static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(TrampolineMem));
337309124Sdim
338309124Sdim    return std::make_tuple(TrampolineBaseAddr, NumTrampolines);
339293838Sdim  }
340293838Sdim
341309124Sdim  Expected<TargetAddress> handleGetSymbolAddress(const std::string &Name) {
342293838Sdim    TargetAddress Addr = SymbolLookup(Name);
343293838Sdim    DEBUG(dbgs() << "  Symbol '" << Name << "' =  " << format("0x%016x", Addr)
344293838Sdim                 << "\n");
345309124Sdim    return Addr;
346293838Sdim  }
347293838Sdim
348309124Sdim  Expected<std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>>
349309124Sdim  handleGetRemoteInfo() {
350293838Sdim    std::string ProcessTriple = sys::getProcessTriple();
351293838Sdim    uint32_t PointerSize = TargetT::PointerSize;
352293838Sdim    uint32_t PageSize = sys::Process::getPageSize();
353293838Sdim    uint32_t TrampolineSize = TargetT::TrampolineSize;
354293838Sdim    uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize;
355293838Sdim    DEBUG(dbgs() << "  Remote info:\n"
356293838Sdim                 << "    triple             = '" << ProcessTriple << "'\n"
357293838Sdim                 << "    pointer size       = " << PointerSize << "\n"
358293838Sdim                 << "    page size          = " << PageSize << "\n"
359293838Sdim                 << "    trampoline size    = " << TrampolineSize << "\n"
360293838Sdim                 << "    indirect stub size = " << IndirectStubSize << "\n");
361309124Sdim    return std::make_tuple(ProcessTriple, PointerSize, PageSize, TrampolineSize,
362309124Sdim                           IndirectStubSize);
363293838Sdim  }
364293838Sdim
365309124Sdim  Expected<std::vector<char>> handleReadMem(TargetAddress RSrc, uint64_t Size) {
366293838Sdim    char *Src = reinterpret_cast<char *>(static_cast<uintptr_t>(RSrc));
367293838Sdim
368293838Sdim    DEBUG(dbgs() << "  Reading " << Size << " bytes from "
369309124Sdim                 << format("0x%016x", RSrc) << "\n");
370293838Sdim
371309124Sdim    std::vector<char> Buffer;
372309124Sdim    Buffer.resize(Size);
373309124Sdim    for (char *P = Src; Size != 0; --Size)
374309124Sdim      Buffer.push_back(*P++);
375293838Sdim
376309124Sdim    return Buffer;
377309124Sdim  }
378293838Sdim
379309124Sdim  Error handleRegisterEHFrames(TargetAddress TAddr, uint32_t Size) {
380309124Sdim    uint8_t *Addr = reinterpret_cast<uint8_t *>(static_cast<uintptr_t>(TAddr));
381309124Sdim    DEBUG(dbgs() << "  Registering EH frames at " << format("0x%016x", TAddr)
382309124Sdim                 << ", Size = " << Size << " bytes\n");
383309124Sdim    EHFramesRegister(Addr, Size);
384309124Sdim    return Error::success();
385293838Sdim  }
386293838Sdim
387309124Sdim  Expected<TargetAddress> handleReserveMem(ResourceIdMgr::ResourceId Id,
388309124Sdim                                           uint64_t Size, uint32_t Align) {
389293838Sdim    auto I = Allocators.find(Id);
390293838Sdim    if (I == Allocators.end())
391293838Sdim      return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);
392293838Sdim    auto &Allocator = I->second;
393293838Sdim    void *LocalAllocAddr = nullptr;
394309124Sdim    if (auto Err = Allocator.allocate(LocalAllocAddr, Size, Align))
395309124Sdim      return std::move(Err);
396293838Sdim
397293838Sdim    DEBUG(dbgs() << "  Allocator " << Id << " reserved " << LocalAllocAddr
398293838Sdim                 << " (" << Size << " bytes, alignment " << Align << ")\n");
399293838Sdim
400293838Sdim    TargetAddress AllocAddr =
401293838Sdim        static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(LocalAllocAddr));
402293838Sdim
403309124Sdim    return AllocAddr;
404293838Sdim  }
405293838Sdim
406309124Sdim  Error handleSetProtections(ResourceIdMgr::ResourceId Id, TargetAddress Addr,
407309124Sdim                             uint32_t Flags) {
408293838Sdim    auto I = Allocators.find(Id);
409293838Sdim    if (I == Allocators.end())
410293838Sdim      return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);
411293838Sdim    auto &Allocator = I->second;
412293838Sdim    void *LocalAddr = reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
413293838Sdim    DEBUG(dbgs() << "  Allocator " << Id << " set permissions on " << LocalAddr
414293838Sdim                 << " to " << (Flags & sys::Memory::MF_READ ? 'R' : '-')
415293838Sdim                 << (Flags & sys::Memory::MF_WRITE ? 'W' : '-')
416293838Sdim                 << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n");
417293838Sdim    return Allocator.setProtections(LocalAddr, Flags);
418293838Sdim  }
419293838Sdim
420309124Sdim  Error handleWriteMem(DirectBufferWriter DBW) {
421309124Sdim    DEBUG(dbgs() << "  Writing " << DBW.getSize() << " bytes to "
422309124Sdim                 << format("0x%016x", DBW.getDst()) << "\n");
423309124Sdim    return Error::success();
424293838Sdim  }
425293838Sdim
426309124Sdim  Error handleWritePtr(TargetAddress Addr, TargetAddress PtrVal) {
427293838Sdim    DEBUG(dbgs() << "  Writing pointer *" << format("0x%016x", Addr) << " = "
428293838Sdim                 << format("0x%016x", PtrVal) << "\n");
429293838Sdim    uintptr_t *Ptr =
430293838Sdim        reinterpret_cast<uintptr_t *>(static_cast<uintptr_t>(Addr));
431293838Sdim    *Ptr = static_cast<uintptr_t>(PtrVal);
432309124Sdim    return Error::success();
433293838Sdim  }
434293838Sdim
435293838Sdim  ChannelT &Channel;
436293838Sdim  SymbolLookupFtor SymbolLookup;
437309124Sdim  EHFrameRegistrationFtor EHFramesRegister, EHFramesDeregister;
438293838Sdim  std::map<ResourceIdMgr::ResourceId, Allocator> Allocators;
439293838Sdim  typedef std::vector<typename TargetT::IndirectStubsInfo> ISBlockOwnerList;
440293838Sdim  std::map<ResourceIdMgr::ResourceId, ISBlockOwnerList> IndirectStubsOwners;
441293838Sdim  sys::OwningMemoryBlock ResolverBlock;
442293838Sdim  std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
443293838Sdim};
444293838Sdim
445293838Sdim} // end namespace remote
446293838Sdim} // end namespace orc
447293838Sdim} // end namespace llvm
448293838Sdim
449293838Sdim#undef DEBUG_TYPE
450293838Sdim
451293838Sdim#endif
452