1321369Sdim//===- OrcRemoteTargetServer.h - Orc Remote-target Server -------*- C++ -*-===//
2293838Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6293838Sdim//
7293838Sdim//===----------------------------------------------------------------------===//
8293838Sdim//
9293838Sdim// This file defines the OrcRemoteTargetServer class. It can be used to build a
10293838Sdim// JIT server that can execute code sent from an OrcRemoteTargetClient.
11293838Sdim//
12293838Sdim//===----------------------------------------------------------------------===//
13293838Sdim
14293838Sdim#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
15293838Sdim#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
16293838Sdim
17314564Sdim#include "llvm/ExecutionEngine/JITSymbol.h"
18314564Sdim#include "llvm/ExecutionEngine/Orc/OrcError.h"
19321369Sdim#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
20293838Sdim#include "llvm/Support/Debug.h"
21314564Sdim#include "llvm/Support/Error.h"
22293838Sdim#include "llvm/Support/Format.h"
23314564Sdim#include "llvm/Support/Host.h"
24314564Sdim#include "llvm/Support/Memory.h"
25293838Sdim#include "llvm/Support/Process.h"
26293838Sdim#include "llvm/Support/raw_ostream.h"
27314564Sdim#include <algorithm>
28314564Sdim#include <cassert>
29314564Sdim#include <cstddef>
30314564Sdim#include <cstdint>
31314564Sdim#include <functional>
32293838Sdim#include <map>
33314564Sdim#include <memory>
34314564Sdim#include <string>
35314564Sdim#include <system_error>
36314564Sdim#include <tuple>
37314564Sdim#include <type_traits>
38314564Sdim#include <vector>
39293838Sdim
40293838Sdim#define DEBUG_TYPE "orc-remote"
41293838Sdim
42293838Sdimnamespace llvm {
43293838Sdimnamespace orc {
44293838Sdimnamespace remote {
45293838Sdim
46293838Sdimtemplate <typename ChannelT, typename TargetT>
47327952Sdimclass OrcRemoteTargetServer
48327952Sdim    : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
49293838Sdimpublic:
50321369Sdim  using SymbolLookupFtor =
51321369Sdim      std::function<JITTargetAddress(const std::string &Name)>;
52293838Sdim
53321369Sdim  using EHFrameRegistrationFtor =
54321369Sdim      std::function<void(uint8_t *Addr, uint32_t Size)>;
55293838Sdim
56309124Sdim  OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup,
57309124Sdim                        EHFrameRegistrationFtor EHFramesRegister,
58309124Sdim                        EHFrameRegistrationFtor EHFramesDeregister)
59327952Sdim      : rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>(Channel, true),
60327952Sdim        SymbolLookup(std::move(SymbolLookup)),
61309124Sdim        EHFramesRegister(std::move(EHFramesRegister)),
62321369Sdim        EHFramesDeregister(std::move(EHFramesDeregister)) {
63314564Sdim    using ThisT = typename std::remove_reference<decltype(*this)>::type;
64327952Sdim    addHandler<exec::CallIntVoid>(*this, &ThisT::handleCallIntVoid);
65327952Sdim    addHandler<exec::CallMain>(*this, &ThisT::handleCallMain);
66327952Sdim    addHandler<exec::CallVoidVoid>(*this, &ThisT::handleCallVoidVoid);
67327952Sdim    addHandler<mem::CreateRemoteAllocator>(*this,
68327952Sdim                                           &ThisT::handleCreateRemoteAllocator);
69327952Sdim    addHandler<mem::DestroyRemoteAllocator>(
70327952Sdim        *this, &ThisT::handleDestroyRemoteAllocator);
71327952Sdim    addHandler<mem::ReadMem>(*this, &ThisT::handleReadMem);
72327952Sdim    addHandler<mem::ReserveMem>(*this, &ThisT::handleReserveMem);
73327952Sdim    addHandler<mem::SetProtections>(*this, &ThisT::handleSetProtections);
74327952Sdim    addHandler<mem::WriteMem>(*this, &ThisT::handleWriteMem);
75327952Sdim    addHandler<mem::WritePtr>(*this, &ThisT::handleWritePtr);
76327952Sdim    addHandler<eh::RegisterEHFrames>(*this, &ThisT::handleRegisterEHFrames);
77327952Sdim    addHandler<eh::DeregisterEHFrames>(*this, &ThisT::handleDeregisterEHFrames);
78327952Sdim    addHandler<stubs::CreateIndirectStubsOwner>(
79314564Sdim        *this, &ThisT::handleCreateIndirectStubsOwner);
80327952Sdim    addHandler<stubs::DestroyIndirectStubsOwner>(
81314564Sdim        *this, &ThisT::handleDestroyIndirectStubsOwner);
82327952Sdim    addHandler<stubs::EmitIndirectStubs>(*this,
83327952Sdim                                         &ThisT::handleEmitIndirectStubs);
84327952Sdim    addHandler<stubs::EmitResolverBlock>(*this,
85327952Sdim                                         &ThisT::handleEmitResolverBlock);
86327952Sdim    addHandler<stubs::EmitTrampolineBlock>(*this,
87327952Sdim                                           &ThisT::handleEmitTrampolineBlock);
88327952Sdim    addHandler<utils::GetSymbolAddress>(*this, &ThisT::handleGetSymbolAddress);
89327952Sdim    addHandler<utils::GetRemoteInfo>(*this, &ThisT::handleGetRemoteInfo);
90327952Sdim    addHandler<utils::TerminateSession>(*this, &ThisT::handleTerminateSession);
91314564Sdim  }
92314564Sdim
93309124Sdim  // FIXME: Remove move/copy ops once MSVC supports synthesizing move ops.
94309124Sdim  OrcRemoteTargetServer(const OrcRemoteTargetServer &) = delete;
95309124Sdim  OrcRemoteTargetServer &operator=(const OrcRemoteTargetServer &) = delete;
96309124Sdim
97314564Sdim  OrcRemoteTargetServer(OrcRemoteTargetServer &&Other) = default;
98309124Sdim  OrcRemoteTargetServer &operator=(OrcRemoteTargetServer &&) = delete;
99309124Sdim
100314564Sdim  Expected<JITTargetAddress> requestCompile(JITTargetAddress TrampolineAddr) {
101327952Sdim    return callB<utils::RequestCompile>(TrampolineAddr);
102293838Sdim  }
103293838Sdim
104314564Sdim  bool receivedTerminate() const { return TerminateFlag; }
105293838Sdim
106293838Sdimprivate:
107293838Sdim  struct Allocator {
108293838Sdim    Allocator() = default;
109293838Sdim    Allocator(Allocator &&Other) : Allocs(std::move(Other.Allocs)) {}
110321369Sdim
111293838Sdim    Allocator &operator=(Allocator &&Other) {
112293838Sdim      Allocs = std::move(Other.Allocs);
113293838Sdim      return *this;
114293838Sdim    }
115293838Sdim
116293838Sdim    ~Allocator() {
117293838Sdim      for (auto &Alloc : Allocs)
118293838Sdim        sys::Memory::releaseMappedMemory(Alloc.second);
119293838Sdim    }
120293838Sdim
121309124Sdim    Error allocate(void *&Addr, size_t Size, uint32_t Align) {
122293838Sdim      std::error_code EC;
123293838Sdim      sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(
124293838Sdim          Size, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC);
125293838Sdim      if (EC)
126309124Sdim        return errorCodeToError(EC);
127293838Sdim
128293838Sdim      Addr = MB.base();
129293838Sdim      assert(Allocs.find(MB.base()) == Allocs.end() && "Duplicate alloc");
130293838Sdim      Allocs[MB.base()] = std::move(MB);
131309124Sdim      return Error::success();
132293838Sdim    }
133293838Sdim
134309124Sdim    Error setProtections(void *block, unsigned Flags) {
135293838Sdim      auto I = Allocs.find(block);
136293838Sdim      if (I == Allocs.end())
137321369Sdim        return errorCodeToError(orcError(OrcErrorCode::RemoteMProtectAddrUnrecognized));
138309124Sdim      return errorCodeToError(
139309124Sdim          sys::Memory::protectMappedMemory(I->second, Flags));
140293838Sdim    }
141293838Sdim
142293838Sdim  private:
143293838Sdim    std::map<void *, sys::MemoryBlock> Allocs;
144293838Sdim  };
145293838Sdim
146309124Sdim  static Error doNothing() { return Error::success(); }
147293838Sdim
148314564Sdim  static JITTargetAddress reenter(void *JITTargetAddr, void *TrampolineAddr) {
149293838Sdim    auto T = static_cast<OrcRemoteTargetServer *>(JITTargetAddr);
150314564Sdim    auto AddrOrErr = T->requestCompile(static_cast<JITTargetAddress>(
151309124Sdim        reinterpret_cast<uintptr_t>(TrampolineAddr)));
152309124Sdim    // FIXME: Allow customizable failure substitution functions.
153309124Sdim    assert(AddrOrErr && "Compile request failed");
154309124Sdim    return *AddrOrErr;
155293838Sdim  }
156293838Sdim
157314564Sdim  Expected<int32_t> handleCallIntVoid(JITTargetAddress Addr) {
158321369Sdim    using IntVoidFnTy = int (*)();
159321369Sdim
160293838Sdim    IntVoidFnTy Fn =
161293838Sdim        reinterpret_cast<IntVoidFnTy>(static_cast<uintptr_t>(Addr));
162293838Sdim
163341825Sdim    LLVM_DEBUG(dbgs() << "  Calling " << format("0x%016x", Addr) << "\n");
164293838Sdim    int Result = Fn();
165341825Sdim    LLVM_DEBUG(dbgs() << "  Result = " << Result << "\n");
166293838Sdim
167309124Sdim    return Result;
168293838Sdim  }
169293838Sdim
170314564Sdim  Expected<int32_t> handleCallMain(JITTargetAddress Addr,
171309124Sdim                                   std::vector<std::string> Args) {
172321369Sdim    using MainFnTy = int (*)(int, const char *[]);
173293838Sdim
174293838Sdim    MainFnTy Fn = reinterpret_cast<MainFnTy>(static_cast<uintptr_t>(Addr));
175293838Sdim    int ArgC = Args.size() + 1;
176293838Sdim    int Idx = 1;
177293838Sdim    std::unique_ptr<const char *[]> ArgV(new const char *[ArgC + 1]);
178293838Sdim    ArgV[0] = "<jit process>";
179293838Sdim    for (auto &Arg : Args)
180293838Sdim      ArgV[Idx++] = Arg.c_str();
181321369Sdim    ArgV[ArgC] = 0;
182341825Sdim    LLVM_DEBUG(for (int Idx = 0; Idx < ArgC; ++Idx) {
183341825Sdim      llvm::dbgs() << "Arg " << Idx << ": " << ArgV[Idx] << "\n";
184341825Sdim    });
185293838Sdim
186341825Sdim    LLVM_DEBUG(dbgs() << "  Calling " << format("0x%016x", Addr) << "\n");
187293838Sdim    int Result = Fn(ArgC, ArgV.get());
188341825Sdim    LLVM_DEBUG(dbgs() << "  Result = " << Result << "\n");
189293838Sdim
190309124Sdim    return Result;
191293838Sdim  }
192293838Sdim
193314564Sdim  Error handleCallVoidVoid(JITTargetAddress Addr) {
194321369Sdim    using VoidVoidFnTy = void (*)();
195321369Sdim
196293838Sdim    VoidVoidFnTy Fn =
197293838Sdim        reinterpret_cast<VoidVoidFnTy>(static_cast<uintptr_t>(Addr));
198293838Sdim
199341825Sdim    LLVM_DEBUG(dbgs() << "  Calling " << format("0x%016x", Addr) << "\n");
200293838Sdim    Fn();
201341825Sdim    LLVM_DEBUG(dbgs() << "  Complete.\n");
202293838Sdim
203309124Sdim    return Error::success();
204293838Sdim  }
205293838Sdim
206309124Sdim  Error handleCreateRemoteAllocator(ResourceIdMgr::ResourceId Id) {
207293838Sdim    auto I = Allocators.find(Id);
208293838Sdim    if (I != Allocators.end())
209321369Sdim      return errorCodeToError(
210321369Sdim               orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse));
211341825Sdim    LLVM_DEBUG(dbgs() << "  Created allocator " << Id << "\n");
212293838Sdim    Allocators[Id] = Allocator();
213309124Sdim    return Error::success();
214293838Sdim  }
215293838Sdim
216309124Sdim  Error handleCreateIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {
217293838Sdim    auto I = IndirectStubsOwners.find(Id);
218293838Sdim    if (I != IndirectStubsOwners.end())
219321369Sdim      return errorCodeToError(
220321369Sdim               orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse));
221341825Sdim    LLVM_DEBUG(dbgs() << "  Create indirect stubs owner " << Id << "\n");
222293838Sdim    IndirectStubsOwners[Id] = ISBlockOwnerList();
223309124Sdim    return Error::success();
224293838Sdim  }
225293838Sdim
226314564Sdim  Error handleDeregisterEHFrames(JITTargetAddress TAddr, uint32_t Size) {
227309124Sdim    uint8_t *Addr = reinterpret_cast<uint8_t *>(static_cast<uintptr_t>(TAddr));
228341825Sdim    LLVM_DEBUG(dbgs() << "  Registering EH frames at "
229341825Sdim                      << format("0x%016x", TAddr) << ", Size = " << Size
230341825Sdim                      << " bytes\n");
231309124Sdim    EHFramesDeregister(Addr, Size);
232309124Sdim    return Error::success();
233309124Sdim  }
234309124Sdim
235309124Sdim  Error handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId Id) {
236293838Sdim    auto I = Allocators.find(Id);
237293838Sdim    if (I == Allocators.end())
238321369Sdim      return errorCodeToError(
239321369Sdim               orcError(OrcErrorCode::RemoteAllocatorDoesNotExist));
240293838Sdim    Allocators.erase(I);
241341825Sdim    LLVM_DEBUG(dbgs() << "  Destroyed allocator " << Id << "\n");
242309124Sdim    return Error::success();
243293838Sdim  }
244293838Sdim
245309124Sdim  Error handleDestroyIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {
246293838Sdim    auto I = IndirectStubsOwners.find(Id);
247293838Sdim    if (I == IndirectStubsOwners.end())
248321369Sdim      return errorCodeToError(
249321369Sdim               orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist));
250293838Sdim    IndirectStubsOwners.erase(I);
251309124Sdim    return Error::success();
252293838Sdim  }
253293838Sdim
254314564Sdim  Expected<std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>>
255309124Sdim  handleEmitIndirectStubs(ResourceIdMgr::ResourceId Id,
256309124Sdim                          uint32_t NumStubsRequired) {
257341825Sdim    LLVM_DEBUG(dbgs() << "  ISMgr " << Id << " request " << NumStubsRequired
258341825Sdim                      << " stubs.\n");
259293838Sdim
260293838Sdim    auto StubOwnerItr = IndirectStubsOwners.find(Id);
261293838Sdim    if (StubOwnerItr == IndirectStubsOwners.end())
262321369Sdim      return errorCodeToError(
263321369Sdim               orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist));
264293838Sdim
265293838Sdim    typename TargetT::IndirectStubsInfo IS;
266309124Sdim    if (auto Err =
267293838Sdim            TargetT::emitIndirectStubsBlock(IS, NumStubsRequired, nullptr))
268309124Sdim      return std::move(Err);
269293838Sdim
270314564Sdim    JITTargetAddress StubsBase = static_cast<JITTargetAddress>(
271314564Sdim        reinterpret_cast<uintptr_t>(IS.getStub(0)));
272314564Sdim    JITTargetAddress PtrsBase = static_cast<JITTargetAddress>(
273314564Sdim        reinterpret_cast<uintptr_t>(IS.getPtr(0)));
274293838Sdim    uint32_t NumStubsEmitted = IS.getNumStubs();
275293838Sdim
276293838Sdim    auto &BlockList = StubOwnerItr->second;
277293838Sdim    BlockList.push_back(std::move(IS));
278293838Sdim
279309124Sdim    return std::make_tuple(StubsBase, PtrsBase, NumStubsEmitted);
280293838Sdim  }
281293838Sdim
282309124Sdim  Error handleEmitResolverBlock() {
283293838Sdim    std::error_code EC;
284293838Sdim    ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
285293838Sdim        TargetT::ResolverCodeSize, nullptr,
286293838Sdim        sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
287293838Sdim    if (EC)
288309124Sdim      return errorCodeToError(EC);
289293838Sdim
290293838Sdim    TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
291293838Sdim                               &reenter, this);
292293838Sdim
293309124Sdim    return errorCodeToError(sys::Memory::protectMappedMemory(
294309124Sdim        ResolverBlock.getMemoryBlock(),
295309124Sdim        sys::Memory::MF_READ | sys::Memory::MF_EXEC));
296293838Sdim  }
297293838Sdim
298314564Sdim  Expected<std::tuple<JITTargetAddress, uint32_t>> handleEmitTrampolineBlock() {
299293838Sdim    std::error_code EC;
300293838Sdim    auto TrampolineBlock =
301293838Sdim        sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
302353358Sdim            sys::Process::getPageSizeEstimate(), nullptr,
303293838Sdim            sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
304293838Sdim    if (EC)
305309124Sdim      return errorCodeToError(EC);
306293838Sdim
307309124Sdim    uint32_t NumTrampolines =
308353358Sdim        (sys::Process::getPageSizeEstimate() - TargetT::PointerSize) /
309293838Sdim        TargetT::TrampolineSize;
310293838Sdim
311293838Sdim    uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
312293838Sdim    TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(),
313293838Sdim                              NumTrampolines);
314293838Sdim
315293838Sdim    EC = sys::Memory::protectMappedMemory(TrampolineBlock.getMemoryBlock(),
316293838Sdim                                          sys::Memory::MF_READ |
317293838Sdim                                              sys::Memory::MF_EXEC);
318293838Sdim
319293838Sdim    TrampolineBlocks.push_back(std::move(TrampolineBlock));
320293838Sdim
321314564Sdim    auto TrampolineBaseAddr = static_cast<JITTargetAddress>(
322314564Sdim        reinterpret_cast<uintptr_t>(TrampolineMem));
323309124Sdim
324309124Sdim    return std::make_tuple(TrampolineBaseAddr, NumTrampolines);
325293838Sdim  }
326293838Sdim
327314564Sdim  Expected<JITTargetAddress> handleGetSymbolAddress(const std::string &Name) {
328314564Sdim    JITTargetAddress Addr = SymbolLookup(Name);
329341825Sdim    LLVM_DEBUG(dbgs() << "  Symbol '" << Name
330341825Sdim                      << "' =  " << format("0x%016x", Addr) << "\n");
331309124Sdim    return Addr;
332293838Sdim  }
333293838Sdim
334309124Sdim  Expected<std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>>
335309124Sdim  handleGetRemoteInfo() {
336293838Sdim    std::string ProcessTriple = sys::getProcessTriple();
337293838Sdim    uint32_t PointerSize = TargetT::PointerSize;
338353358Sdim    uint32_t PageSize = sys::Process::getPageSizeEstimate();
339293838Sdim    uint32_t TrampolineSize = TargetT::TrampolineSize;
340293838Sdim    uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize;
341341825Sdim    LLVM_DEBUG(dbgs() << "  Remote info:\n"
342341825Sdim                      << "    triple             = '" << ProcessTriple << "'\n"
343341825Sdim                      << "    pointer size       = " << PointerSize << "\n"
344341825Sdim                      << "    page size          = " << PageSize << "\n"
345341825Sdim                      << "    trampoline size    = " << TrampolineSize << "\n"
346341825Sdim                      << "    indirect stub size = " << IndirectStubSize
347341825Sdim                      << "\n");
348309124Sdim    return std::make_tuple(ProcessTriple, PointerSize, PageSize, TrampolineSize,
349309124Sdim                           IndirectStubSize);
350293838Sdim  }
351293838Sdim
352314564Sdim  Expected<std::vector<uint8_t>> handleReadMem(JITTargetAddress RSrc,
353314564Sdim                                               uint64_t Size) {
354314564Sdim    uint8_t *Src = reinterpret_cast<uint8_t *>(static_cast<uintptr_t>(RSrc));
355293838Sdim
356341825Sdim    LLVM_DEBUG(dbgs() << "  Reading " << Size << " bytes from "
357341825Sdim                      << format("0x%016x", RSrc) << "\n");
358293838Sdim
359314564Sdim    std::vector<uint8_t> Buffer;
360309124Sdim    Buffer.resize(Size);
361314564Sdim    for (uint8_t *P = Src; Size != 0; --Size)
362309124Sdim      Buffer.push_back(*P++);
363293838Sdim
364309124Sdim    return Buffer;
365309124Sdim  }
366293838Sdim
367314564Sdim  Error handleRegisterEHFrames(JITTargetAddress TAddr, uint32_t Size) {
368309124Sdim    uint8_t *Addr = reinterpret_cast<uint8_t *>(static_cast<uintptr_t>(TAddr));
369341825Sdim    LLVM_DEBUG(dbgs() << "  Registering EH frames at "
370341825Sdim                      << format("0x%016x", TAddr) << ", Size = " << Size
371341825Sdim                      << " bytes\n");
372309124Sdim    EHFramesRegister(Addr, Size);
373309124Sdim    return Error::success();
374293838Sdim  }
375293838Sdim
376314564Sdim  Expected<JITTargetAddress> handleReserveMem(ResourceIdMgr::ResourceId Id,
377314564Sdim                                              uint64_t Size, uint32_t Align) {
378293838Sdim    auto I = Allocators.find(Id);
379293838Sdim    if (I == Allocators.end())
380321369Sdim      return errorCodeToError(
381321369Sdim               orcError(OrcErrorCode::RemoteAllocatorDoesNotExist));
382293838Sdim    auto &Allocator = I->second;
383293838Sdim    void *LocalAllocAddr = nullptr;
384309124Sdim    if (auto Err = Allocator.allocate(LocalAllocAddr, Size, Align))
385309124Sdim      return std::move(Err);
386293838Sdim
387341825Sdim    LLVM_DEBUG(dbgs() << "  Allocator " << Id << " reserved " << LocalAllocAddr
388341825Sdim                      << " (" << Size << " bytes, alignment " << Align
389341825Sdim                      << ")\n");
390293838Sdim
391314564Sdim    JITTargetAddress AllocAddr = static_cast<JITTargetAddress>(
392314564Sdim        reinterpret_cast<uintptr_t>(LocalAllocAddr));
393293838Sdim
394309124Sdim    return AllocAddr;
395293838Sdim  }
396293838Sdim
397314564Sdim  Error handleSetProtections(ResourceIdMgr::ResourceId Id,
398314564Sdim                             JITTargetAddress Addr, uint32_t Flags) {
399293838Sdim    auto I = Allocators.find(Id);
400293838Sdim    if (I == Allocators.end())
401321369Sdim      return errorCodeToError(
402321369Sdim               orcError(OrcErrorCode::RemoteAllocatorDoesNotExist));
403293838Sdim    auto &Allocator = I->second;
404293838Sdim    void *LocalAddr = reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
405341825Sdim    LLVM_DEBUG(dbgs() << "  Allocator " << Id << " set permissions on "
406341825Sdim                      << LocalAddr << " to "
407341825Sdim                      << (Flags & sys::Memory::MF_READ ? 'R' : '-')
408341825Sdim                      << (Flags & sys::Memory::MF_WRITE ? 'W' : '-')
409341825Sdim                      << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n");
410293838Sdim    return Allocator.setProtections(LocalAddr, Flags);
411293838Sdim  }
412293838Sdim
413314564Sdim  Error handleTerminateSession() {
414314564Sdim    TerminateFlag = true;
415314564Sdim    return Error::success();
416314564Sdim  }
417314564Sdim
418309124Sdim  Error handleWriteMem(DirectBufferWriter DBW) {
419341825Sdim    LLVM_DEBUG(dbgs() << "  Writing " << DBW.getSize() << " bytes to "
420341825Sdim                      << format("0x%016x", DBW.getDst()) << "\n");
421309124Sdim    return Error::success();
422293838Sdim  }
423293838Sdim
424314564Sdim  Error handleWritePtr(JITTargetAddress Addr, JITTargetAddress PtrVal) {
425341825Sdim    LLVM_DEBUG(dbgs() << "  Writing pointer *" << format("0x%016x", Addr)
426341825Sdim                      << " = " << format("0x%016x", PtrVal) << "\n");
427293838Sdim    uintptr_t *Ptr =
428293838Sdim        reinterpret_cast<uintptr_t *>(static_cast<uintptr_t>(Addr));
429293838Sdim    *Ptr = static_cast<uintptr_t>(PtrVal);
430309124Sdim    return Error::success();
431293838Sdim  }
432293838Sdim
433293838Sdim  SymbolLookupFtor SymbolLookup;
434309124Sdim  EHFrameRegistrationFtor EHFramesRegister, EHFramesDeregister;
435293838Sdim  std::map<ResourceIdMgr::ResourceId, Allocator> Allocators;
436321369Sdim  using ISBlockOwnerList = std::vector<typename TargetT::IndirectStubsInfo>;
437293838Sdim  std::map<ResourceIdMgr::ResourceId, ISBlockOwnerList> IndirectStubsOwners;
438293838Sdim  sys::OwningMemoryBlock ResolverBlock;
439293838Sdim  std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
440321369Sdim  bool TerminateFlag = false;
441293838Sdim};
442293838Sdim
443293838Sdim} // end namespace remote
444293838Sdim} // end namespace orc
445293838Sdim} // end namespace llvm
446293838Sdim
447293838Sdim#undef DEBUG_TYPE
448293838Sdim
449321369Sdim#endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
450