LLVM  8.0.1
OrcABISupport.h
Go to the documentation of this file.
1 //===- OrcABISupport.h - ABI support code -----------------------*- 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 // ABI specific code for Orc, e.g. callback assembly.
11 //
12 // ABI classes should be part of the JIT *target* process, not the host
13 // process (except where you're doing hosted JITing and the two are one and the
14 // same).
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
19 #define LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
20 
22 #include "llvm/Support/Error.h"
24 #include "llvm/Support/Memory.h"
25 #include <algorithm>
26 #include <cstdint>
27 
28 namespace llvm {
29 namespace orc {
30 
31 /// Generic ORC ABI support.
32 ///
33 /// This class can be substituted as the target architecure support class for
34 /// ORC templates that require one (e.g. IndirectStubsManagers). It does not
35 /// support lazy JITing however, and any attempt to use that functionality
36 /// will result in execution of an llvm_unreachable.
38 public:
39  static const unsigned PointerSize = sizeof(uintptr_t);
40  static const unsigned TrampolineSize = 1;
41  static const unsigned ResolverCodeSize = 1;
42 
43  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
44  void *TrampolineId);
45 
46  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
47  void *CallbackMgr) {
48  llvm_unreachable("writeResolverCode is not supported by the generic host "
49  "support class");
50  }
51 
52  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
53  unsigned NumTrampolines) {
54  llvm_unreachable("writeTrampolines is not supported by the generic host "
55  "support class");
56  }
57 
59  public:
60  const static unsigned StubSize = 1;
61 
62  unsigned getNumStubs() const { llvm_unreachable("Not supported"); }
63  void *getStub(unsigned Idx) const { llvm_unreachable("Not supported"); }
64  void **getPtr(unsigned Idx) const { llvm_unreachable("Not supported"); }
65  };
66 
68  unsigned MinStubs, void *InitialPtrVal) {
69  llvm_unreachable("emitIndirectStubsBlock is not supported by the generic "
70  "host support class");
71  }
72 };
73 
74 /// Provide information about stub blocks generated by the
75 /// makeIndirectStubsBlock function.
76 template <unsigned StubSizeVal> class GenericIndirectStubsInfo {
77 public:
78  const static unsigned StubSize = StubSizeVal;
79 
80  GenericIndirectStubsInfo() = default;
81  GenericIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
82  : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}
84  : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
85  Other.NumStubs = 0;
86  }
87 
89  NumStubs = Other.NumStubs;
90  Other.NumStubs = 0;
91  StubsMem = std::move(Other.StubsMem);
92  return *this;
93  }
94 
95  /// Number of stubs in this block.
96  unsigned getNumStubs() const { return NumStubs; }
97 
98  /// Get a pointer to the stub at the given index, which must be in
99  /// the range 0 .. getNumStubs() - 1.
100  void *getStub(unsigned Idx) const {
101  return static_cast<char *>(StubsMem.base()) + Idx * StubSize;
102  }
103 
104  /// Get a pointer to the implementation-pointer at the given index,
105  /// which must be in the range 0 .. getNumStubs() - 1.
106  void **getPtr(unsigned Idx) const {
107  char *PtrsBase = static_cast<char *>(StubsMem.base()) + NumStubs * StubSize;
108  return reinterpret_cast<void **>(PtrsBase) + Idx;
109  }
110 
111 private:
112  unsigned NumStubs = 0;
113  sys::OwningMemoryBlock StubsMem;
114 };
115 
116 class OrcAArch64 {
117 public:
118  static const unsigned PointerSize = 8;
119  static const unsigned TrampolineSize = 12;
120  static const unsigned ResolverCodeSize = 0x120;
121 
123 
124  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
125  void *TrampolineId);
126 
127  /// Write the resolver code into the given memory. The user is be
128  /// responsible for allocating the memory and setting permissions.
129  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
130  void *CallbackMgr);
131 
132  /// Write the requsted number of trampolines into the given memory,
133  /// which must be big enough to hold 1 pointer, plus NumTrampolines
134  /// trampolines.
135  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
136  unsigned NumTrampolines);
137 
138  /// Emit at least MinStubs worth of indirect call stubs, rounded out to
139  /// the nearest page size.
140  ///
141  /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
142  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
143  /// will return a block of 1024 (2-pages worth).
145  unsigned MinStubs, void *InitialPtrVal);
146 };
147 
148 /// X86_64 code that's common to all ABIs.
149 ///
150 /// X86_64 supports lazy JITing.
152 public:
153  static const unsigned PointerSize = 8;
154  static const unsigned TrampolineSize = 8;
155 
157 
158  /// Write the requsted number of trampolines into the given memory,
159  /// which must be big enough to hold 1 pointer, plus NumTrampolines
160  /// trampolines.
161  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
162  unsigned NumTrampolines);
163 
164  /// Emit at least MinStubs worth of indirect call stubs, rounded out to
165  /// the nearest page size.
166  ///
167  /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
168  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
169  /// will return a block of 1024 (2-pages worth).
171  unsigned MinStubs, void *InitialPtrVal);
172 };
173 
174 /// X86_64 support for SysV ABI (Linux, MacOSX).
175 ///
176 /// X86_64_SysV supports lazy JITing.
178 public:
179  static const unsigned ResolverCodeSize = 0x6C;
180 
181  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
182  void *TrampolineId);
183 
184  /// Write the resolver code into the given memory. The user is be
185  /// responsible for allocating the memory and setting permissions.
186  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
187  void *CallbackMgr);
188 };
189 
190 /// X86_64 support for Win32.
191 ///
192 /// X86_64_Win32 supports lazy JITing.
194 public:
195  static const unsigned ResolverCodeSize = 0x74;
196 
197  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
198  void *TrampolineId);
199 
200  /// Write the resolver code into the given memory. The user is be
201  /// responsible for allocating the memory and setting permissions.
202  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
203  void *CallbackMgr);
204 };
205 
206 /// I386 support.
207 ///
208 /// I386 supports lazy JITing.
209 class OrcI386 {
210 public:
211  static const unsigned PointerSize = 4;
212  static const unsigned TrampolineSize = 8;
213  static const unsigned ResolverCodeSize = 0x4a;
214 
216 
217  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
218  void *TrampolineId);
219 
220  /// Write the resolver code into the given memory. The user is be
221  /// responsible for allocating the memory and setting permissions.
222  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
223  void *CallbackMgr);
224 
225  /// Write the requsted number of trampolines into the given memory,
226  /// which must be big enough to hold 1 pointer, plus NumTrampolines
227  /// trampolines.
228  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
229  unsigned NumTrampolines);
230 
231  /// Emit at least MinStubs worth of indirect call stubs, rounded out to
232  /// the nearest page size.
233  ///
234  /// E.g. Asking for 4 stubs on i386, where stubs are 8-bytes, with 4k
235  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
236  /// will return a block of 1024 (2-pages worth).
238  unsigned MinStubs, void *InitialPtrVal);
239 };
240 
241 // @brief Mips32 support.
242 //
243 // Mips32 supports lazy JITing.
245 public:
246  static const unsigned PointerSize = 4;
247  static const unsigned TrampolineSize = 20;
248  static const unsigned ResolverCodeSize = 0xfc;
250 
251  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
252  void *TrampolineId);
253  /// @brief Write the requsted number of trampolines into the given memory,
254  /// which must be big enough to hold 1 pointer, plus NumTrampolines
255  /// trampolines.
256  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
257 
258  /// @brief Write the resolver code into the given memory. The user is be
259  /// responsible for allocating the memory and setting permissions.
260  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr, bool isBigEndian);
261  /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
262  /// the nearest page size.
263  ///
264  /// E.g. Asking for 4 stubs on Mips32, where stubs are 8-bytes, with 4k
265  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
266  /// will return a block of 1024 (2-pages worth).
267  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
268 };
269 
270 
271 class OrcMips32Le : public OrcMips32_Base {
272 public:
273  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
274  { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, false); }
275 };
276 
277 class OrcMips32Be : public OrcMips32_Base {
278 public:
279  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
280  { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, true); }
281 };
282 
283 // @brief Mips64 support.
284 //
285 // Mips64 supports lazy JITing.
286 class OrcMips64 {
287 public:
288  static const unsigned PointerSize = 8;
289  static const unsigned TrampolineSize = 40;
290  static const unsigned ResolverCodeSize = 0x120;
291 
293  using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
294  void *TrampolineId);
295  /// @brief Write the resolver code into the given memory. The user is be
296  /// responsible for allocating the memory and setting permissions.
297  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr);
298 
299  /// @brief Write the requsted number of trampolines into the given memory,
300  /// which must be big enough to hold 1 pointer, plus NumTrampolines
301  /// trampolines.
302  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
303 
304  /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
305  /// the nearest page size.
306  ///
307  /// E.g. Asking for 4 stubs on Mips64, where stubs are 8-bytes, with 4k
308  /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
309  /// will return a block of 1024 (2-pages worth).
310  static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
311 };
312 
313  } // end namespace orc
314  } // end namespace llvm
315 #endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
static const unsigned TrampolineSize
Definition: OrcABISupport.h:40
static const unsigned ResolverCodeSize
Definition: OrcABISupport.h:41
Generic ORC ABI support.
Definition: OrcABISupport.h:37
JITTargetAddress(*)(void *CallbackMgr, void *TrampolineId) JITReentryFn
Definition: OrcABISupport.h:44
static const unsigned PointerSize
Definition: OrcABISupport.h:39
This class represents lattice values for constants.
Definition: AllocatorList.h:24
X86_64 code that&#39;s common to all ABIs.
GenericIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
Definition: OrcABISupport.h:81
Provide information about stub blocks generated by the makeIndirectStubsBlock function.
Definition: OrcABISupport.h:76
JITTargetAddress(*)(void *CallbackMgr, void *TrampolineId) JITReentryFn
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, unsigned MinStubs, void *InitialPtrVal)
Definition: OrcABISupport.h:67
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, unsigned NumTrampolines)
Definition: OrcABISupport.h:52
X86_64 support for SysV ABI (Linux, MacOSX).
Definition: BitVector.h:938
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:784
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:41
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr, bool isBigEndian)
Write the resolver code into the given memory.
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr)
JITTargetAddress(*)(void *CallbackMgr, void *TrampolineId) JITReentryFn
GenericIndirectStubsInfo(GenericIndirectStubsInfo &&Other)
Definition: OrcABISupport.h:83
void ** getPtr(unsigned Idx) const
Get a pointer to the implementation-pointer at the given index, which must be in the range 0 ...
X86_64 support for Win32.
unsigned getNumStubs() const
Number of stubs in this block.
Definition: OrcABISupport.h:96
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr)
GenericIndirectStubsInfo & operator=(GenericIndirectStubsInfo &&Other)
Definition: OrcABISupport.h:88
JITTargetAddress(*)(void *CallbackMgr, void *TrampolineId) JITReentryFn
JITTargetAddress(*)(void *CallbackMgr, void *TrampolineId) JITReentryFn
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr)
Definition: OrcABISupport.h:46
I386 support.
JITTargetAddress(*)(void *CallbackMgr, void *TrampolineId) JITReentryFn
Owning version of MemoryBlock.
Definition: Memory.h:119
void * getStub(unsigned Idx) const
Get a pointer to the stub at the given index, which must be in the range 0 .
JITTargetAddress(*)(void *CallbackMgr, void *TrampolineId) JITReentryFn
void ** getPtr(unsigned Idx) const
Definition: OrcABISupport.h:64
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158