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: |
25 | void setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr) { |
26 | this->MemMgr = std::move(MemMgr); |
27 | } |
28 | |
29 | void setResolver(std::shared_ptr<LegacyJITSymbolResolver> Resolver) { |
30 | this->Resolver = std::move(Resolver); |
31 | } |
32 | |
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 | |
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 | |
46 | void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign, |
47 | uintptr_t RODataSize, Align RODataAlign, |
48 | uintptr_t RWDataSize, |
49 | Align RWDataAlign) override { |
50 | MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign, |
51 | RWDataSize, RWDataAlign); |
52 | } |
53 | |
54 | bool needsToReserveAllocationSpace() override { |
55 | return MemMgr->needsToReserveAllocationSpace(); |
56 | } |
57 | |
58 | void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, |
59 | size_t Size) override { |
60 | MemMgr->registerEHFrames(Addr, LoadAddr, Size); |
61 | } |
62 | |
63 | void deregisterEHFrames() override { MemMgr->deregisterEHFrames(); } |
64 | |
65 | bool finalizeMemory(std::string *ErrMsg = nullptr) override { |
66 | return MemMgr->finalizeMemory(ErrMsg); |
67 | } |
68 | |
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 | |
77 | JITSymbol findSymbol(const std::string &Name) override { |
78 | return Resolver->findSymbol(Name); |
79 | } |
80 | |
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>> |
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(Path: "" , Mode: 0); |
99 | if (!H) |
100 | return H.takeError(); |
101 | return std::make_unique<RemoteResolver>(args: std::move(*DylibMgr), |
102 | args: std::move(*H)); |
103 | } |
104 | |
105 | JITSymbol findSymbol(const std::string &Name) override { |
106 | orc::RemoteSymbolLookupSet R; |
107 | R.push_back(x: {.Name: std::move(Name), .Required: false}); |
108 | if (auto Syms = DylibMgr.lookup(H, Lookup: R)) { |
109 | if (Syms->size() != 1) |
110 | return make_error<StringError>(Args: "Unexpected remote lookup result" , |
111 | Args: inconvertibleErrorCode()); |
112 | return JITSymbol(Syms->front().getAddress().getValue(), |
113 | Syms->front().getFlags()); |
114 | } else |
115 | return Syms.takeError(); |
116 | } |
117 | |
118 | JITSymbol findSymbolInLogicalDylib(const std::string &Name) override { |
119 | return nullptr; |
120 | } |
121 | |
122 | public: |
123 | RemoteResolver(orc::EPCGenericDylibManager DylibMgr, |
124 | orc::tpctypes::DylibHandle H) |
125 | : DylibMgr(std::move(DylibMgr)), H(std::move(H)) {} |
126 | |
127 | orc::EPCGenericDylibManager DylibMgr; |
128 | orc::tpctypes::DylibHandle H; |
129 | }; |
130 | } // namespace llvm |
131 | |
132 | #endif // LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H |
133 | |