1//===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Utilities for remote-JITing with LLI.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
14#define LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
15
16#include "llvm/ExecutionEngine/Orc/Core.h"
17#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManagerSPS.h"
18#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
19#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
20
21namespace llvm {
22
23// ForwardingMM - Adapter to connect MCJIT to Orc's Remote
24// memory manager.
25class ForwardingMemoryManager : public llvm::RTDyldMemoryManager {
26public:
27 void setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr) {
28 this->MemMgr = std::move(MemMgr);
29 }
30
31 void setResolver(std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
32 this->Resolver = std::move(Resolver);
33 }
34
35 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
36 unsigned SectionID,
37 StringRef SectionName) override {
38 return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName);
39 }
40
41 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
42 unsigned SectionID, StringRef SectionName,
43 bool IsReadOnly) override {
44 return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName,
45 IsReadOnly);
46 }
47
48 void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign,
49 uintptr_t RODataSize, Align RODataAlign,
50 uintptr_t RWDataSize,
51 Align RWDataAlign) override {
52 MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,
53 RWDataSize, RWDataAlign);
54 }
55
56 bool needsToReserveAllocationSpace() override {
57 return MemMgr->needsToReserveAllocationSpace();
58 }
59
60 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
61 size_t Size) override {
62 MemMgr->registerEHFrames(Addr, LoadAddr, Size);
63 }
64
65 void deregisterEHFrames() override { MemMgr->deregisterEHFrames(); }
66
67 bool finalizeMemory(std::string *ErrMsg = nullptr) override {
68 return MemMgr->finalizeMemory(ErrMsg);
69 }
70
71 void notifyObjectLoaded(RuntimeDyld &RTDyld,
72 const object::ObjectFile &Obj) override {
73 MemMgr->notifyObjectLoaded(RTDyld, Obj);
74 }
75
76 // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager.
77 using RTDyldMemoryManager::notifyObjectLoaded;
78
79 JITSymbol findSymbol(const std::string &Name) override {
80 return Resolver->findSymbol(Name);
81 }
82
83 JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
84 return Resolver->findSymbolInLogicalDylib(Name);
85 }
86
87private:
88 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr;
89 std::shared_ptr<LegacyJITSymbolResolver> Resolver;
90};
91
92class RemoteResolver : public LegacyJITSymbolResolver {
93public:
94 static Expected<std::unique_ptr<RemoteResolver>>
95 Create(orc::ExecutionSession &ES) {
96 auto DylibMgr = orc::sps::createEPCGenericDylibManager(ES);
97 if (!DylibMgr)
98 return DylibMgr.takeError();
99 auto H = (*DylibMgr)->open(Path: "", Mode: 0);
100 if (!H)
101 return H.takeError();
102 return std::make_unique<RemoteResolver>(args&: ES, args: std::move(*DylibMgr),
103 args: std::move(*H));
104 }
105
106 JITSymbol findSymbol(const std::string &Name) override {
107 orc::SymbolLookupSet LS(ES.intern(SymName: Name),
108 orc::SymbolLookupFlags::WeaklyReferencedSymbol);
109 if (auto Syms = DylibMgr->lookup(H, Lookup: LS)) {
110 if (Syms->size() != 1)
111 return make_error<StringError>(Args: "Unexpected remote lookup result",
112 Args: inconvertibleErrorCode());
113 if (!Syms->front())
114 return make_error<StringError>(Args: "Expected valid address",
115 Args: inconvertibleErrorCode());
116 return JITSymbol(Syms->front()->getValue(), JITSymbolFlags::Exported);
117 } else
118 return Syms.takeError();
119 }
120
121 JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
122 return nullptr;
123 }
124
125public:
126 RemoteResolver(orc::ExecutionSession &ES,
127 std::unique_ptr<orc::EPCGenericDylibManager> DylibMgr,
128 orc::tpctypes::DylibHandle H)
129 : ES(ES), DylibMgr(std::move(DylibMgr)), H(std::move(H)) {}
130
131 orc::ExecutionSession &ES;
132 std::unique_ptr<orc::EPCGenericDylibManager> DylibMgr;
133 orc::tpctypes::DylibHandle H;
134};
135} // namespace llvm
136
137#endif // LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
138