LLVM  7.0.0svn
OrcRemoteTargetClient.h
Go to the documentation of this file.
1 //===- OrcRemoteTargetClient.h - Orc Remote-target Client -------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the OrcRemoteTargetClient class and helpers. This class
11 // can be used to communicate over an RawByteChannel with an
12 // OrcRemoteTargetServer instance to support remote-JITing.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H
17 #define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H
18 
19 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringRef.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/Error.h"
30 #include "llvm/Support/Format.h"
32 #include "llvm/Support/Memory.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstdint>
37 #include <memory>
38 #include <string>
39 #include <tuple>
40 #include <utility>
41 #include <vector>
42 
43 #define DEBUG_TYPE "orc-remote"
44 
45 namespace llvm {
46 namespace orc {
47 namespace remote {
48 
49 /// This class provides utilities (including memory manager, indirect stubs
50 /// manager, and compile callback manager types) that support remote JITing
51 /// in ORC.
52 ///
53 /// Each of the utility classes talks to a JIT server (an instance of the
54 /// OrcRemoteTargetServer class) via an RPC system (see RPCUtils.h) to carry out
55 /// its actions.
57  : public rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel> {
58 public:
59  /// Remote-mapped RuntimeDyld-compatible memory manager.
61  friend class OrcRemoteTargetClient;
62 
63  public:
65  Client.destroyRemoteAllocator(Id);
66  LLVM_DEBUG(dbgs() << "Destroyed remote allocator " << Id << "\n");
67  }
68 
71  operator=(const RemoteRTDyldMemoryManager &) = delete;
75 
76  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
77  unsigned SectionID,
78  StringRef SectionName) override {
79  Unmapped.back().CodeAllocs.emplace_back(Size, Alignment);
80  uint8_t *Alloc = reinterpret_cast<uint8_t *>(
81  Unmapped.back().CodeAllocs.back().getLocalAddress());
82  LLVM_DEBUG(dbgs() << "Allocator " << Id << " allocated code for "
83  << SectionName << ": " << Alloc << " (" << Size
84  << " bytes, alignment " << Alignment << ")\n");
85  return Alloc;
86  }
87 
88  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
89  unsigned SectionID, StringRef SectionName,
90  bool IsReadOnly) override {
91  if (IsReadOnly) {
92  Unmapped.back().RODataAllocs.emplace_back(Size, Alignment);
93  uint8_t *Alloc = reinterpret_cast<uint8_t *>(
94  Unmapped.back().RODataAllocs.back().getLocalAddress());
95  LLVM_DEBUG(dbgs() << "Allocator " << Id << " allocated ro-data for "
96  << SectionName << ": " << Alloc << " (" << Size
97  << " bytes, alignment " << Alignment << ")\n");
98  return Alloc;
99  } // else...
100 
101  Unmapped.back().RWDataAllocs.emplace_back(Size, Alignment);
102  uint8_t *Alloc = reinterpret_cast<uint8_t *>(
103  Unmapped.back().RWDataAllocs.back().getLocalAddress());
104  LLVM_DEBUG(dbgs() << "Allocator " << Id << " allocated rw-data for "
105  << SectionName << ": " << Alloc << " (" << Size
106  << " bytes, alignment " << Alignment << ")\n");
107  return Alloc;
108  }
109 
110  void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
111  uintptr_t RODataSize, uint32_t RODataAlign,
112  uintptr_t RWDataSize,
113  uint32_t RWDataAlign) override {
114  Unmapped.push_back(ObjectAllocs());
115 
116  LLVM_DEBUG(dbgs() << "Allocator " << Id << " reserved:\n");
117 
118  if (CodeSize != 0) {
119  Unmapped.back().RemoteCodeAddr =
120  Client.reserveMem(Id, CodeSize, CodeAlign);
121 
122  LLVM_DEBUG(dbgs() << " code: "
123  << format("0x%016x", Unmapped.back().RemoteCodeAddr)
124  << " (" << CodeSize << " bytes, alignment "
125  << CodeAlign << ")\n");
126  }
127 
128  if (RODataSize != 0) {
129  Unmapped.back().RemoteRODataAddr =
130  Client.reserveMem(Id, RODataSize, RODataAlign);
131 
132  LLVM_DEBUG(dbgs() << " ro-data: "
133  << format("0x%016x", Unmapped.back().RemoteRODataAddr)
134  << " (" << RODataSize << " bytes, alignment "
135  << RODataAlign << ")\n");
136  }
137 
138  if (RWDataSize != 0) {
139  Unmapped.back().RemoteRWDataAddr =
140  Client.reserveMem(Id, RWDataSize, RWDataAlign);
141 
142  LLVM_DEBUG(dbgs() << " rw-data: "
143  << format("0x%016x", Unmapped.back().RemoteRWDataAddr)
144  << " (" << RWDataSize << " bytes, alignment "
145  << RWDataAlign << ")\n");
146  }
147  }
148 
149  bool needsToReserveAllocationSpace() override { return true; }
150 
151  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
152  size_t Size) override {
153  UnfinalizedEHFrames.push_back({LoadAddr, Size});
154  }
155 
156  void deregisterEHFrames() override {
157  for (auto &Frame : RegisteredEHFrames) {
158  // FIXME: Add error poll.
159  Client.deregisterEHFrames(Frame.Addr, Frame.Size);
160  }
161  }
162 
164  const object::ObjectFile &Obj) override {
165  LLVM_DEBUG(dbgs() << "Allocator " << Id << " applied mappings:\n");
166  for (auto &ObjAllocs : Unmapped) {
167  mapAllocsToRemoteAddrs(Dyld, ObjAllocs.CodeAllocs,
168  ObjAllocs.RemoteCodeAddr);
169  mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RODataAllocs,
170  ObjAllocs.RemoteRODataAddr);
171  mapAllocsToRemoteAddrs(Dyld, ObjAllocs.RWDataAllocs,
172  ObjAllocs.RemoteRWDataAddr);
173  Unfinalized.push_back(std::move(ObjAllocs));
174  }
175  Unmapped.clear();
176  }
177 
178  bool finalizeMemory(std::string *ErrMsg = nullptr) override {
179  LLVM_DEBUG(dbgs() << "Allocator " << Id << " finalizing:\n");
180 
181  for (auto &ObjAllocs : Unfinalized) {
182  if (copyAndProtect(ObjAllocs.CodeAllocs, ObjAllocs.RemoteCodeAddr,
184  return true;
185 
186  if (copyAndProtect(ObjAllocs.RODataAllocs, ObjAllocs.RemoteRODataAddr,
188  return true;
189 
190  if (copyAndProtect(ObjAllocs.RWDataAllocs, ObjAllocs.RemoteRWDataAddr,
192  return true;
193  }
194  Unfinalized.clear();
195 
196  for (auto &EHFrame : UnfinalizedEHFrames) {
197  if (auto Err = Client.registerEHFrames(EHFrame.Addr, EHFrame.Size)) {
198  // FIXME: Replace this once finalizeMemory can return an Error.
199  handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
200  if (ErrMsg) {
201  raw_string_ostream ErrOut(*ErrMsg);
202  EIB.log(ErrOut);
203  }
204  });
205  return false;
206  }
207  }
208  RegisteredEHFrames = std::move(UnfinalizedEHFrames);
209  UnfinalizedEHFrames = {};
210 
211  return false;
212  }
213 
214  private:
215  class Alloc {
216  public:
217  Alloc(uint64_t Size, unsigned Align)
218  : Size(Size), Align(Align), Contents(new char[Size + Align - 1]) {}
219 
220  Alloc(const Alloc &) = delete;
221  Alloc &operator=(const Alloc &) = delete;
222  Alloc(Alloc &&) = default;
223  Alloc &operator=(Alloc &&) = default;
224 
225  uint64_t getSize() const { return Size; }
226 
227  unsigned getAlign() const { return Align; }
228 
229  char *getLocalAddress() const {
230  uintptr_t LocalAddr = reinterpret_cast<uintptr_t>(Contents.get());
231  LocalAddr = alignTo(LocalAddr, Align);
232  return reinterpret_cast<char *>(LocalAddr);
233  }
234 
235  void setRemoteAddress(JITTargetAddress RemoteAddr) {
236  this->RemoteAddr = RemoteAddr;
237  }
238 
239  JITTargetAddress getRemoteAddress() const { return RemoteAddr; }
240 
241  private:
242  uint64_t Size;
243  unsigned Align;
244  std::unique_ptr<char[]> Contents;
245  JITTargetAddress RemoteAddr = 0;
246  };
247 
248  struct ObjectAllocs {
249  ObjectAllocs() = default;
250  ObjectAllocs(const ObjectAllocs &) = delete;
251  ObjectAllocs &operator=(const ObjectAllocs &) = delete;
252  ObjectAllocs(ObjectAllocs &&) = default;
253  ObjectAllocs &operator=(ObjectAllocs &&) = default;
254 
255  JITTargetAddress RemoteCodeAddr = 0;
256  JITTargetAddress RemoteRODataAddr = 0;
257  JITTargetAddress RemoteRWDataAddr = 0;
258  std::vector<Alloc> CodeAllocs, RODataAllocs, RWDataAllocs;
259  };
260 
263  : Client(Client), Id(Id) {
264  LLVM_DEBUG(dbgs() << "Created remote allocator " << Id << "\n");
265  }
266 
267  // Maps all allocations in Allocs to aligned blocks
268  void mapAllocsToRemoteAddrs(RuntimeDyld &Dyld, std::vector<Alloc> &Allocs,
269  JITTargetAddress NextAddr) {
270  for (auto &Alloc : Allocs) {
271  NextAddr = alignTo(NextAddr, Alloc.getAlign());
272  Dyld.mapSectionAddress(Alloc.getLocalAddress(), NextAddr);
273  LLVM_DEBUG(dbgs() << " "
274  << static_cast<void *>(Alloc.getLocalAddress())
275  << " -> " << format("0x%016x", NextAddr) << "\n");
276  Alloc.setRemoteAddress(NextAddr);
277 
278  // Only advance NextAddr if it was non-null to begin with,
279  // otherwise leave it as null.
280  if (NextAddr)
281  NextAddr += Alloc.getSize();
282  }
283  }
284 
285  // Copies data for each alloc in the list, then set permissions on the
286  // segment.
287  bool copyAndProtect(const std::vector<Alloc> &Allocs,
288  JITTargetAddress RemoteSegmentAddr,
289  unsigned Permissions) {
290  if (RemoteSegmentAddr) {
291  assert(!Allocs.empty() && "No sections in allocated segment");
292 
293  for (auto &Alloc : Allocs) {
294  LLVM_DEBUG(dbgs() << " copying section: "
295  << static_cast<void *>(Alloc.getLocalAddress())
296  << " -> "
297  << format("0x%016x", Alloc.getRemoteAddress())
298  << " (" << Alloc.getSize() << " bytes)\n";);
299 
300  if (Client.writeMem(Alloc.getRemoteAddress(), Alloc.getLocalAddress(),
301  Alloc.getSize()))
302  return true;
303  }
304 
305  LLVM_DEBUG(dbgs() << " setting "
306  << (Permissions & sys::Memory::MF_READ ? 'R' : '-')
307  << (Permissions & sys::Memory::MF_WRITE ? 'W' : '-')
308  << (Permissions & sys::Memory::MF_EXEC ? 'X' : '-')
309  << " permissions on block: "
310  << format("0x%016x", RemoteSegmentAddr) << "\n");
311  if (Client.setProtections(Id, RemoteSegmentAddr, Permissions))
312  return true;
313  }
314  return false;
315  }
316 
317  OrcRemoteTargetClient &Client;
319  std::vector<ObjectAllocs> Unmapped;
320  std::vector<ObjectAllocs> Unfinalized;
321 
322  struct EHFrame {
323  JITTargetAddress Addr;
324  uint64_t Size;
325  };
326  std::vector<EHFrame> UnfinalizedEHFrames;
327  std::vector<EHFrame> RegisteredEHFrames;
328  };
329 
330  /// Remote indirect stubs manager.
332  public:
335  : Client(Client), Id(Id) {}
336 
338  Client.destroyIndirectStubsManager(Id);
339  }
340 
342  JITSymbolFlags StubFlags) override {
343  if (auto Err = reserveStubs(1))
344  return Err;
345 
346  return createStubInternal(StubName, StubAddr, StubFlags);
347  }
348 
349  Error createStubs(const StubInitsMap &StubInits) override {
350  if (auto Err = reserveStubs(StubInits.size()))
351  return Err;
352 
353  for (auto &Entry : StubInits)
354  if (auto Err = createStubInternal(Entry.first(), Entry.second.first,
355  Entry.second.second))
356  return Err;
357 
358  return Error::success();
359  }
360 
361  JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override {
362  auto I = StubIndexes.find(Name);
363  if (I == StubIndexes.end())
364  return nullptr;
365  auto Key = I->second.first;
366  auto Flags = I->second.second;
367  auto StubSymbol = JITEvaluatedSymbol(getStubAddr(Key), Flags);
368  if (ExportedStubsOnly && !StubSymbol.getFlags().isExported())
369  return nullptr;
370  return StubSymbol;
371  }
372 
374  auto I = StubIndexes.find(Name);
375  if (I == StubIndexes.end())
376  return nullptr;
377  auto Key = I->second.first;
378  auto Flags = I->second.second;
379  return JITEvaluatedSymbol(getPtrAddr(Key), Flags);
380  }
381 
383  auto I = StubIndexes.find(Name);
384  assert(I != StubIndexes.end() && "No stub pointer for symbol");
385  auto Key = I->second.first;
386  return Client.writePointer(getPtrAddr(Key), NewAddr);
387  }
388 
389  private:
390  struct RemoteIndirectStubsInfo {
391  JITTargetAddress StubBase;
392  JITTargetAddress PtrBase;
393  unsigned NumStubs;
394  };
395 
396  using StubKey = std::pair<uint16_t, uint16_t>;
397 
398  Error reserveStubs(unsigned NumStubs) {
399  if (NumStubs <= FreeStubs.size())
400  return Error::success();
401 
402  unsigned NewStubsRequired = NumStubs - FreeStubs.size();
403  JITTargetAddress StubBase;
404  JITTargetAddress PtrBase;
405  unsigned NumStubsEmitted;
406 
407  if (auto StubInfoOrErr = Client.emitIndirectStubs(Id, NewStubsRequired))
408  std::tie(StubBase, PtrBase, NumStubsEmitted) = *StubInfoOrErr;
409  else
410  return StubInfoOrErr.takeError();
411 
412  unsigned NewBlockId = RemoteIndirectStubsInfos.size();
413  RemoteIndirectStubsInfos.push_back({StubBase, PtrBase, NumStubsEmitted});
414 
415  for (unsigned I = 0; I < NumStubsEmitted; ++I)
416  FreeStubs.push_back(std::make_pair(NewBlockId, I));
417 
418  return Error::success();
419  }
420 
421  Error createStubInternal(StringRef StubName, JITTargetAddress InitAddr,
422  JITSymbolFlags StubFlags) {
423  auto Key = FreeStubs.back();
424  FreeStubs.pop_back();
425  StubIndexes[StubName] = std::make_pair(Key, StubFlags);
426  return Client.writePointer(getPtrAddr(Key), InitAddr);
427  }
428 
429  JITTargetAddress getStubAddr(StubKey K) {
430  assert(RemoteIndirectStubsInfos[K.first].StubBase != 0 &&
431  "Missing stub address");
432  return RemoteIndirectStubsInfos[K.first].StubBase +
433  K.second * Client.getIndirectStubSize();
434  }
435 
436  JITTargetAddress getPtrAddr(StubKey K) {
437  assert(RemoteIndirectStubsInfos[K.first].PtrBase != 0 &&
438  "Missing pointer address");
439  return RemoteIndirectStubsInfos[K.first].PtrBase +
440  K.second * Client.getPointerSize();
441  }
442 
443  OrcRemoteTargetClient &Client;
445  std::vector<RemoteIndirectStubsInfo> RemoteIndirectStubsInfos;
446  std::vector<StubKey> FreeStubs;
448  };
449 
450  /// Remote compile callback manager.
452  public:
454  ExecutionSession &ES,
455  JITTargetAddress ErrorHandlerAddress)
456  : JITCompileCallbackManager(ES, ErrorHandlerAddress), Client(Client) {}
457 
458  private:
459  Error grow() override {
460  JITTargetAddress BlockAddr = 0;
461  uint32_t NumTrampolines = 0;
462  if (auto TrampolineInfoOrErr = Client.emitTrampolineBlock())
463  std::tie(BlockAddr, NumTrampolines) = *TrampolineInfoOrErr;
464  else
465  return TrampolineInfoOrErr.takeError();
466 
467  uint32_t TrampolineSize = Client.getTrampolineSize();
468  for (unsigned I = 0; I < NumTrampolines; ++I)
469  this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
470 
471  return Error::success();
472  }
473 
474  OrcRemoteTargetClient &Client;
475  };
476 
477  /// Create an OrcRemoteTargetClient.
478  /// Channel is the ChannelT instance to communicate on. It is assumed that
479  /// the channel is ready to be read from and written to.
482  Error Err = Error::success();
483  auto Client = std::unique_ptr<OrcRemoteTargetClient>(
484  new OrcRemoteTargetClient(Channel, ES, Err));
485  if (Err)
486  return std::move(Err);
487  return std::move(Client);
488  }
489 
490  /// Call the int(void) function at the given address in the target and return
491  /// its result.
493  LLVM_DEBUG(dbgs() << "Calling int(*)(void) " << format("0x%016x", Addr)
494  << "\n");
495  return callB<exec::CallIntVoid>(Addr);
496  }
497 
498  /// Call the int(int, char*[]) function at the given address in the target and
499  /// return its result.
501  const std::vector<std::string> &Args) {
502  LLVM_DEBUG(dbgs() << "Calling int(*)(int, char*[]) "
503  << format("0x%016x", Addr) << "\n");
504  return callB<exec::CallMain>(Addr, Args);
505  }
506 
507  /// Call the void() function at the given address in the target and wait for
508  /// it to finish.
510  LLVM_DEBUG(dbgs() << "Calling void(*)(void) " << format("0x%016x", Addr)
511  << "\n");
512  return callB<exec::CallVoidVoid>(Addr);
513  }
514 
515  /// Create an RCMemoryManager which will allocate its memory on the remote
516  /// target.
519  auto Id = AllocatorIds.getNext();
520  if (auto Err = callB<mem::CreateRemoteAllocator>(Id))
521  return std::move(Err);
522  return std::unique_ptr<RemoteRTDyldMemoryManager>(
523  new RemoteRTDyldMemoryManager(*this, Id));
524  }
525 
526  /// Create an RCIndirectStubsManager that will allocate stubs on the remote
527  /// target.
530  auto Id = IndirectStubOwnerIds.getNext();
531  if (auto Err = callB<stubs::CreateIndirectStubsOwner>(Id))
532  return std::move(Err);
533  return llvm::make_unique<RemoteIndirectStubsManager>(*this, Id);
534  }
535 
538  assert(!CallbackManager && "CallbackManager already obtained");
539 
540  // Emit the resolver block on the JIT server.
541  if (auto Err = callB<stubs::EmitResolverBlock>())
542  return std::move(Err);
543 
544  // Create the callback manager.
545  CallbackManager.emplace(*this, ES, ErrorHandlerAddress);
546  RemoteCompileCallbackManager &Mgr = *CallbackManager;
547  return Mgr;
548  }
549 
550  /// Search for symbols in the remote process. Note: This should be used by
551  /// symbol resolvers *after* they've searched the local symbol table in the
552  /// JIT stack.
554  return callB<utils::GetSymbolAddress>(Name);
555  }
556 
557  /// Get the triple for the remote target.
558  const std::string &getTargetTriple() const { return RemoteTargetTriple; }
559 
560  Error terminateSession() { return callB<utils::TerminateSession>(); }
561 
562 private:
564  Error &Err)
566  ES(ES) {
567  ErrorAsOutParameter EAO(&Err);
568 
569  addHandler<utils::RequestCompile>(
570  [this](JITTargetAddress Addr) -> JITTargetAddress {
571  if (CallbackManager)
572  return CallbackManager->executeCompileCallback(Addr);
573  return 0;
574  });
575 
576  if (auto RIOrErr = callB<utils::GetRemoteInfo>()) {
577  std::tie(RemoteTargetTriple, RemotePointerSize, RemotePageSize,
578  RemoteTrampolineSize, RemoteIndirectStubSize) = *RIOrErr;
579  Err = Error::success();
580  } else
581  Err = RIOrErr.takeError();
582  }
583 
585  if (auto Err = callB<eh::RegisterEHFrames>(Addr, Size))
586  ES.reportError(std::move(Err));
587  }
588 
589  void destroyRemoteAllocator(ResourceIdMgr::ResourceId Id) {
590  if (auto Err = callB<mem::DestroyRemoteAllocator>(Id)) {
591  // FIXME: This will be triggered by a removeModuleSet call: Propagate
592  // error return up through that.
593  llvm_unreachable("Failed to destroy remote allocator.");
594  AllocatorIds.release(Id);
595  }
596  }
597 
598  void destroyIndirectStubsManager(ResourceIdMgr::ResourceId Id) {
599  IndirectStubOwnerIds.release(Id);
600  if (auto Err = callB<stubs::DestroyIndirectStubsOwner>(Id))
601  ES.reportError(std::move(Err));
602  }
603 
605  emitIndirectStubs(ResourceIdMgr::ResourceId Id, uint32_t NumStubsRequired) {
606  return callB<stubs::EmitIndirectStubs>(Id, NumStubsRequired);
607  }
608 
609  Expected<std::tuple<JITTargetAddress, uint32_t>> emitTrampolineBlock() {
610  return callB<stubs::EmitTrampolineBlock>();
611  }
612 
613  uint32_t getIndirectStubSize() const { return RemoteIndirectStubSize; }
614  uint32_t getPageSize() const { return RemotePageSize; }
615  uint32_t getPointerSize() const { return RemotePointerSize; }
616 
617  uint32_t getTrampolineSize() const { return RemoteTrampolineSize; }
618 
619  Expected<std::vector<uint8_t>> readMem(char *Dst, JITTargetAddress Src,
620  uint64_t Size) {
621  return callB<mem::ReadMem>(Src, Size);
622  }
623 
625  // FIXME: Duplicate error and report it via ReportError too?
626  return callB<eh::RegisterEHFrames>(RAddr, Size);
627  }
628 
629  JITTargetAddress reserveMem(ResourceIdMgr::ResourceId Id, uint64_t Size,
630  uint32_t Align) {
631  if (auto AddrOrErr = callB<mem::ReserveMem>(Id, Size, Align))
632  return *AddrOrErr;
633  else {
634  ES.reportError(AddrOrErr.takeError());
635  return 0;
636  }
637  }
638 
639  bool setProtections(ResourceIdMgr::ResourceId Id,
640  JITTargetAddress RemoteSegAddr, unsigned ProtFlags) {
641  if (auto Err = callB<mem::SetProtections>(Id, RemoteSegAddr, ProtFlags)) {
642  ES.reportError(std::move(Err));
643  return true;
644  } else
645  return false;
646  }
647 
648  bool writeMem(JITTargetAddress Addr, const char *Src, uint64_t Size) {
649  if (auto Err = callB<mem::WriteMem>(DirectBufferWriter(Src, Addr, Size))) {
650  ES.reportError(std::move(Err));
651  return true;
652  } else
653  return false;
654  }
655 
656  Error writePointer(JITTargetAddress Addr, JITTargetAddress PtrVal) {
657  return callB<mem::WritePtr>(Addr, PtrVal);
658  }
659 
660  static Error doNothing() { return Error::success(); }
661 
662  ExecutionSession &ES;
663  std::function<void(Error)> ReportError;
664  std::string RemoteTargetTriple;
665  uint32_t RemotePointerSize = 0;
666  uint32_t RemotePageSize = 0;
667  uint32_t RemoteTrampolineSize = 0;
668  uint32_t RemoteIndirectStubSize = 0;
669  ResourceIdMgr AllocatorIds, IndirectStubOwnerIds;
671 };
672 
673 } // end namespace remote
674 } // end namespace orc
675 } // end namespace llvm
676 
677 #undef DEBUG_TYPE
678 
679 #endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H
bool needsToReserveAllocationSpace() override
Override to return true to enable the reserveAllocationSpace callback.
Error createStubs(const StubInitsMap &StubInits) override
Create StubInits.size() stubs with the given names, target addresses, and flags.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Base class for managing collections of named indirect stubs.
bool getAlign(const Function &F, unsigned index, unsigned &align)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
Interface for byte-streams to be used with RPC.
Expected< std::unique_ptr< RemoteRTDyldMemoryManager > > createRemoteMemoryManager()
Create an RCMemoryManager which will allocate its memory on the remote target.
This class is the base class for all object file types.
Definition: ObjectFile.h:190
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:683
RemoteRTDyldMemoryManager(const RemoteRTDyldMemoryManager &)=delete
void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, uintptr_t RODataSize, uint32_t RODataAlign, uintptr_t RWDataSize, uint32_t RWDataAlign) override
Inform the memory manager about the total amount of memory required to allocate all sections to be lo...
Base class for error info classes.
Definition: Error.h:47
uint8_t * allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly) override
Allocate a memory block of (at least) the given size suitable for data.
JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override
Find the stub with the given name.
Target-independent base class for compile callback management.
void notifyObjectLoaded(RuntimeDyld &Dyld, const object::ObjectFile &Obj) override
This method is called after an object has been loaded into memory but before relocations are applied ...
Expected< int > callMain(JITTargetAddress Addr, const std::vector< std::string > &Args)
Call the int(int, char*[]) function at the given address in the target and return its result...
Error createStub(StringRef StubName, JITTargetAddress StubAddr, JITSymbolFlags StubFlags) override
Create a single stub with the given name, target address and flags.
unsigned size() const
Definition: StringMap.h:112
RemoteCompileCallbackManager(OrcRemoteTargetClient &Client, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress)
virtual void log(raw_ostream &OS) const =0
Print an error message to an output stream.
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
Error callVoidVoid(JITTargetAddress Addr)
Call the void() function at the given address in the target and wait for it to finish.
Key
PAL metadata keys.
Expected< JITTargetAddress > getSymbolAddress(StringRef Name)
Search for symbols in the remote process.
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:40
void reportError(Error Err)
Report a error for this execution session.
Definition: Core.h:289
const std::string & getTargetTriple() const
Get the triple for the remote target.
This class provides utilities (including memory manager, indirect stubs manager, and compile callback...
Flags for symbols in the JIT.
Definition: JITSymbol.h:43
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:889
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override
Change the value of the implementation pointer for the stub.
bool finalizeMemory(std::string *ErrMsg=nullptr) override
This method is called when object loading is complete and section page permissions can be applied...
An ExecutionSession represents a running JIT program.
Definition: Core.h:625
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:220
Expected< RemoteCompileCallbackManager & > enableCompileCallbacks(JITTargetAddress ErrorHandlerAddress)
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:157
Helper for Errors used as out-parameters.
Definition: Error.h:1002
RemoteRTDyldMemoryManager & operator=(const RemoteRTDyldMemoryManager &)=delete
#define I(x, y, z)
Definition: MD5.cpp:58
uint8_t * allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) override
Allocate a memory block of (at least) the given size suitable for executable code.
Expected< int > callIntVoid(JITTargetAddress Addr)
Call the int(void) function at the given address in the target and return its result.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
JITEvaluatedSymbol findPointer(StringRef Name) override
Find the implementation-pointer for the stub.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:477
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Remote-mapped RuntimeDyld-compatible memory manager.
static Expected< std::unique_ptr< OrcRemoteTargetClient > > Create(rpc::RawByteChannel &Channel, ExecutionSession &ES)
Create an OrcRemoteTargetClient.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
Map a section to its target address space value.
#define LLVM_DEBUG(X)
Definition: Debug.h:119
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override
Register the EH frames with the runtime so that c++ exceptions work.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Expected< std::unique_ptr< RemoteIndirectStubsManager > > createIndirectStubsManager()
Create an RCIndirectStubsManager that will allocate stubs on the remote target.
RemoteIndirectStubsManager(OrcRemoteTargetClient &Client, ResourceIdMgr::ResourceId Id)