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