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/EPCGenericDylibManager.h"
17 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
18 
19 namespace llvm {
20 
21 // ForwardingMM - Adapter to connect MCJIT to Orc's Remote
22 // memory manager.
23 class ForwardingMemoryManager : public llvm::RTDyldMemoryManager {
24 public:
setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr)25   void setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr) {
26     this->MemMgr = std::move(MemMgr);
27   }
28 
setResolver(std::shared_ptr<LegacyJITSymbolResolver> Resolver)29   void setResolver(std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
30     this->Resolver = std::move(Resolver);
31   }
32 
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)33   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
34                                unsigned SectionID,
35                                StringRef SectionName) override {
36     return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName);
37   }
38 
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)39   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
40                                unsigned SectionID, StringRef SectionName,
41                                bool IsReadOnly) override {
42     return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName,
43                                        IsReadOnly);
44   }
45 
reserveAllocationSpace(uintptr_t CodeSize,uint32_t CodeAlign,uintptr_t RODataSize,uint32_t RODataAlign,uintptr_t RWDataSize,uint32_t RWDataAlign)46   void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
47                               uintptr_t RODataSize, uint32_t RODataAlign,
48                               uintptr_t RWDataSize,
49                               uint32_t RWDataAlign) override {
50     MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,
51                                    RWDataSize, RWDataAlign);
52   }
53 
needsToReserveAllocationSpace()54   bool needsToReserveAllocationSpace() override {
55     return MemMgr->needsToReserveAllocationSpace();
56   }
57 
registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)58   void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
59                         size_t Size) override {
60     MemMgr->registerEHFrames(Addr, LoadAddr, Size);
61   }
62 
deregisterEHFrames()63   void deregisterEHFrames() override { MemMgr->deregisterEHFrames(); }
64 
65   bool finalizeMemory(std::string *ErrMsg = nullptr) override {
66     return MemMgr->finalizeMemory(ErrMsg);
67   }
68 
notifyObjectLoaded(RuntimeDyld & RTDyld,const object::ObjectFile & Obj)69   void notifyObjectLoaded(RuntimeDyld &RTDyld,
70                           const object::ObjectFile &Obj) override {
71     MemMgr->notifyObjectLoaded(RTDyld, Obj);
72   }
73 
74   // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager.
75   using RTDyldMemoryManager::notifyObjectLoaded;
76 
findSymbol(const std::string & Name)77   JITSymbol findSymbol(const std::string &Name) override {
78     return Resolver->findSymbol(Name);
79   }
80 
findSymbolInLogicalDylib(const std::string & Name)81   JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
82     return Resolver->findSymbolInLogicalDylib(Name);
83   }
84 
85 private:
86   std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr;
87   std::shared_ptr<LegacyJITSymbolResolver> Resolver;
88 };
89 
90 class RemoteResolver : public LegacyJITSymbolResolver {
91 public:
92   static Expected<std::unique_ptr<RemoteResolver>>
Create(orc::ExecutorProcessControl & EPC)93   Create(orc::ExecutorProcessControl &EPC) {
94     auto DylibMgr =
95         orc::EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(EPC);
96     if (!DylibMgr)
97       return DylibMgr.takeError();
98     auto H = DylibMgr->open("", 0);
99     if (!H)
100       return H.takeError();
101     return std::unique_ptr<RemoteResolver>(
102         new RemoteResolver(std::move(*DylibMgr), std::move(*H)));
103   }
104 
findSymbol(const std::string & Name)105   JITSymbol findSymbol(const std::string &Name) override {
106     orc::RemoteSymbolLookupSet R;
107     R.push_back({std::move(Name), false});
108     if (auto Addrs = DylibMgr.lookup(H, R)) {
109       if (Addrs->size() != 1)
110         return make_error<StringError>("Unexpected remote lookup result",
111                                        inconvertibleErrorCode());
112       return JITSymbol(Addrs->front().getValue(), JITSymbolFlags::Exported);
113     } else
114       return Addrs.takeError();
115   }
116 
findSymbolInLogicalDylib(const std::string & Name)117   JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
118     return nullptr;
119   }
120 
121 public:
RemoteResolver(orc::EPCGenericDylibManager DylibMgr,orc::tpctypes::DylibHandle H)122   RemoteResolver(orc::EPCGenericDylibManager DylibMgr,
123                  orc::tpctypes::DylibHandle H)
124       : DylibMgr(std::move(DylibMgr)), H(std::move(H)) {}
125 
126   orc::EPCGenericDylibManager DylibMgr;
127   orc::tpctypes::DylibHandle H;
128 };
129 } // namespace llvm
130 
131 #endif // LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
132