1//===---- EPCGenericRTDyldMemoryManager.h - EPC-based MemMgr ----*- 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// Defines a RuntimeDyld::MemoryManager that uses EPC and the ORC runtime
10// bootstrap functions.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H
15#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H
16
17#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
18#include "llvm/ExecutionEngine/RuntimeDyld.h"
19#include "llvm/Support/Compiler.h"
20
21#define DEBUG_TYPE "orc"
22
23namespace llvm {
24namespace orc {
25
26/// Remote-mapped RuntimeDyld-compatible memory manager.
27class LLVM_ABI EPCGenericRTDyldMemoryManager
28 : public RuntimeDyld::MemoryManager {
29public:
30 /// Symbol addresses for memory access.
31 struct SymbolAddrs {
32 ExecutorAddr Instance;
33 ExecutorAddr Reserve;
34 ExecutorAddr Finalize;
35 ExecutorAddr Deallocate;
36 ExecutorAddr RegisterEHFrame;
37 ExecutorAddr DeregisterEHFrame;
38 };
39
40 /// Create an EPCGenericRTDyldMemoryManager using the given EPC, looking up
41 /// the default symbol names in the bootstrap symbol set.
42 static Expected<std::unique_ptr<EPCGenericRTDyldMemoryManager>>
43 CreateWithDefaultBootstrapSymbols(ExecutorProcessControl &EPC);
44
45 /// Create an EPCGenericRTDyldMemoryManager using the given EPC and symbol
46 /// addrs.
47 EPCGenericRTDyldMemoryManager(ExecutorProcessControl &EPC, SymbolAddrs SAs);
48
49 EPCGenericRTDyldMemoryManager(const EPCGenericRTDyldMemoryManager &) = delete;
50 EPCGenericRTDyldMemoryManager &
51 operator=(const EPCGenericRTDyldMemoryManager &) = delete;
52 EPCGenericRTDyldMemoryManager(EPCGenericRTDyldMemoryManager &&) = delete;
53 EPCGenericRTDyldMemoryManager &
54 operator=(EPCGenericRTDyldMemoryManager &&) = delete;
55 ~EPCGenericRTDyldMemoryManager();
56
57 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
58 unsigned SectionID,
59 StringRef SectionName) override;
60
61 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
62 unsigned SectionID, StringRef SectionName,
63 bool IsReadOnly) override;
64
65 void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign,
66 uintptr_t RODataSize, Align RODataAlign,
67 uintptr_t RWDataSize, Align RWDataAlign) override;
68
69 bool needsToReserveAllocationSpace() override;
70
71 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
72
73 void deregisterEHFrames() override;
74
75 void notifyObjectLoaded(RuntimeDyld &Dyld,
76 const object::ObjectFile &Obj) override;
77
78 bool finalizeMemory(std::string *ErrMsg = nullptr) override;
79
80private:
81 struct SectionAlloc {
82 public:
83 SectionAlloc(uint64_t Size, unsigned Align)
84 : Size(Size), Align(Align),
85 Contents(std::make_unique<uint8_t[]>(num: Size + Align - 1)) {}
86
87 uint64_t Size;
88 unsigned Align;
89 std::unique_ptr<uint8_t[]> Contents;
90 ExecutorAddr RemoteAddr;
91 };
92
93 // Group of section allocations to be allocated together in the executor. The
94 // RemoteCodeAddr will stand in as the id of the group for deallocation
95 // purposes.
96 struct SectionAllocGroup {
97 SectionAllocGroup() = default;
98 SectionAllocGroup(const SectionAllocGroup &) = delete;
99 SectionAllocGroup &operator=(const SectionAllocGroup &) = delete;
100 SectionAllocGroup(SectionAllocGroup &&) = default;
101 SectionAllocGroup &operator=(SectionAllocGroup &&) = default;
102
103 ExecutorAddrRange RemoteCode;
104 ExecutorAddrRange RemoteROData;
105 ExecutorAddrRange RemoteRWData;
106 std::vector<ExecutorAddrRange> UnfinalizedEHFrames;
107 std::vector<SectionAlloc> CodeAllocs, RODataAllocs, RWDataAllocs;
108 };
109
110 // Maps all allocations in SectionAllocs to aligned blocks
111 void mapAllocsToRemoteAddrs(RuntimeDyld &Dyld,
112 std::vector<SectionAlloc> &SecAllocs,
113 ExecutorAddr NextAddr);
114
115 ExecutorProcessControl &EPC;
116 SymbolAddrs SAs;
117
118 std::mutex M;
119 std::vector<SectionAllocGroup> Unmapped;
120 std::vector<SectionAllocGroup> Unfinalized;
121 std::vector<ExecutorAddr> FinalizedAllocs;
122 std::string ErrMsg;
123};
124
125} // end namespace orc
126} // end namespace llvm
127
128#undef DEBUG_TYPE
129
130#endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H
131