Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
 
20
#include "llvm/ExecutionEngine/JITSymbol.h"
21
#include "llvm/Support/Error.h"
22
#include "llvm/Support/ErrorHandling.h"
23
#include "llvm/Support/MathExtras.h"
24
#include <cstdint>
25
 
26
namespace llvm {
27
namespace orc {
28
 
29
struct IndirectStubsAllocationSizes {
30
  uint64_t StubBytes = 0;
31
  uint64_t PointerBytes = 0;
32
  unsigned NumStubs = 0;
33
};
34
 
35
template <typename ORCABI>
36
IndirectStubsAllocationSizes
37
getIndirectStubsBlockSizes(unsigned MinStubs, unsigned RoundToMultipleOf = 0) {
38
  assert(
39
      (RoundToMultipleOf == 0 || (RoundToMultipleOf % ORCABI::StubSize == 0)) &&
40
      "RoundToMultipleOf is not a multiple of stub size");
41
  uint64_t StubBytes = MinStubs * ORCABI::StubSize;
42
  if (RoundToMultipleOf)
43
    StubBytes = alignTo(StubBytes, RoundToMultipleOf);
44
  unsigned NumStubs = StubBytes / ORCABI::StubSize;
45
  uint64_t PointerBytes = NumStubs * ORCABI::PointerSize;
46
  return {StubBytes, PointerBytes, NumStubs};
47
}
48
 
49
/// Generic ORC ABI support.
50
///
51
/// This class can be substituted as the target architecture support class for
52
/// ORC templates that require one (e.g. IndirectStubsManagers). It does not
53
/// support lazy JITing however, and any attempt to use that functionality
54
/// will result in execution of an llvm_unreachable.
55
class OrcGenericABI {
56
public:
57
  static constexpr unsigned PointerSize = sizeof(uintptr_t);
58
  static constexpr unsigned TrampolineSize = 1;
59
  static constexpr unsigned StubSize = 1;
60
  static constexpr unsigned StubToPointerMaxDisplacement = 1;
61
  static constexpr unsigned ResolverCodeSize = 1;
62
 
63
  static void writeResolverCode(char *ResolveWorkingMem,
64
                                JITTargetAddress ResolverTargetAddr,
65
                                JITTargetAddress ReentryFnAddr,
66
                                JITTargetAddress ReentryCtxAddr) {
67
    llvm_unreachable("writeResolverCode is not supported by the generic host "
68
                     "support class");
69
  }
70
 
71
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
72
                               JITTargetAddress TrampolineBlockTargetAddr,
73
                               JITTargetAddress ResolverAddr,
74
                               unsigned NumTrampolines) {
75
    llvm_unreachable("writeTrampolines is not supported by the generic host "
76
                     "support class");
77
  }
78
 
79
  static void writeIndirectStubsBlock(
80
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
81
      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) {
82
    llvm_unreachable(
83
        "writeIndirectStubsBlock is not supported by the generic host "
84
        "support class");
85
  }
86
};
87
 
88
class OrcAArch64 {
89
public:
90
  static constexpr unsigned PointerSize = 8;
91
  static constexpr unsigned TrampolineSize = 12;
92
  static constexpr unsigned StubSize = 8;
93
  static constexpr unsigned StubToPointerMaxDisplacement = 1U << 27;
94
  static constexpr unsigned ResolverCodeSize = 0x120;
95
 
96
  /// Write the resolver code into the given memory. The user is
97
  /// responsible for allocating the memory and setting permissions.
98
  ///
99
  /// ReentryFnAddr should be the address of a function whose signature matches
100
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
101
  /// argument of writeResolverCode will be passed as the second argument to
102
  /// the function at ReentryFnAddr.
103
  static void writeResolverCode(char *ResolverWorkingMem,
104
                                JITTargetAddress ResolverTargetAddress,
105
                                JITTargetAddress ReentryFnAddr,
106
                                JITTargetAddress RentryCtxAddr);
107
 
108
  /// Write the requested number of trampolines into the given memory,
109
  /// which must be big enough to hold 1 pointer, plus NumTrampolines
110
  /// trampolines.
111
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
112
                               JITTargetAddress TrampolineBlockTargetAddress,
113
                               JITTargetAddress ResolverAddr,
114
                               unsigned NumTrampolines);
115
 
116
  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
117
  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
118
  /// Nth stub using the Nth pointer in memory starting at
119
  /// PointersBlockTargetAddress.
120
  static void writeIndirectStubsBlock(
121
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
122
      JITTargetAddress PointersBlockTargetAddress, unsigned MinStubs);
123
};
124
 
125
/// X86_64 code that's common to all ABIs.
126
///
127
/// X86_64 supports lazy JITing.
128
class OrcX86_64_Base {
129
public:
130
  static constexpr unsigned PointerSize = 8;
131
  static constexpr unsigned TrampolineSize = 8;
132
  static constexpr unsigned StubSize = 8;
133
  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
134
 
135
  /// Write the requested number of trampolines into the given memory,
136
  /// which must be big enough to hold 1 pointer, plus NumTrampolines
137
  /// trampolines.
138
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
139
                               JITTargetAddress TrampolineBlockTargetAddress,
140
                               JITTargetAddress ResolverAddr,
141
                               unsigned NumTrampolines);
142
 
143
  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
144
  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
145
  /// Nth stub using the Nth pointer in memory starting at
146
  /// PointersBlockTargetAddress.
147
  static void writeIndirectStubsBlock(
148
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
149
      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
150
};
151
 
152
/// X86_64 support for SysV ABI (Linux, MacOSX).
153
///
154
/// X86_64_SysV supports lazy JITing.
155
class OrcX86_64_SysV : public OrcX86_64_Base {
156
public:
157
  static constexpr unsigned ResolverCodeSize = 0x6C;
158
 
159
  /// Write the resolver code into the given memory. The user is
160
  /// responsible for allocating the memory and setting permissions.
161
  ///
162
  /// ReentryFnAddr should be the address of a function whose signature matches
163
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
164
  /// argument of writeResolverCode will be passed as the second argument to
165
  /// the function at ReentryFnAddr.
166
  static void writeResolverCode(char *ResolverWorkingMem,
167
                                JITTargetAddress ResolverTargetAddress,
168
                                JITTargetAddress ReentryFnAddr,
169
                                JITTargetAddress ReentryCtxAddr);
170
};
171
 
172
/// X86_64 support for Win32.
173
///
174
/// X86_64_Win32 supports lazy JITing.
175
class OrcX86_64_Win32 : public OrcX86_64_Base {
176
public:
177
  static constexpr unsigned ResolverCodeSize = 0x74;
178
 
179
  /// Write the resolver code into the given memory. The user is
180
  /// responsible for allocating the memory and setting permissions.
181
  ///
182
  /// ReentryFnAddr should be the address of a function whose signature matches
183
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
184
  /// argument of writeResolverCode will be passed as the second argument to
185
  /// the function at ReentryFnAddr.
186
  static void writeResolverCode(char *ResolverWorkingMem,
187
                                JITTargetAddress ResolverTargetAddress,
188
                                JITTargetAddress ReentryFnAddr,
189
                                JITTargetAddress ReentryCtxAddr);
190
};
191
 
192
/// I386 support.
193
///
194
/// I386 supports lazy JITing.
195
class OrcI386 {
196
public:
197
  static constexpr unsigned PointerSize = 4;
198
  static constexpr unsigned TrampolineSize = 8;
199
  static constexpr unsigned StubSize = 8;
200
  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
201
  static constexpr unsigned ResolverCodeSize = 0x4a;
202
 
203
  /// Write the resolver code into the given memory. The user is
204
  /// responsible for allocating the memory and setting permissions.
205
  ///
206
  /// ReentryFnAddr should be the address of a function whose signature matches
207
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
208
  /// argument of writeResolverCode will be passed as the second argument to
209
  /// the function at ReentryFnAddr.
210
  static void writeResolverCode(char *ResolverWorkingMem,
211
                                JITTargetAddress ResolverTargetAddress,
212
                                JITTargetAddress ReentryFnAddr,
213
                                JITTargetAddress ReentryCtxAddr);
214
 
215
  /// Write the requested number of trampolines into the given memory,
216
  /// which must be big enough to hold 1 pointer, plus NumTrampolines
217
  /// trampolines.
218
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
219
                               JITTargetAddress TrampolineBlockTargetAddress,
220
                               JITTargetAddress ResolverAddr,
221
                               unsigned NumTrampolines);
222
 
223
  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
224
  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
225
  /// Nth stub using the Nth pointer in memory starting at
226
  /// PointersBlockTargetAddress.
227
  static void writeIndirectStubsBlock(
228
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
229
      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
230
};
231
 
232
// @brief Mips32 support.
233
//
234
// Mips32 supports lazy JITing.
235
class OrcMips32_Base {
236
public:
237
  static constexpr unsigned PointerSize = 4;
238
  static constexpr unsigned TrampolineSize = 20;
239
  static constexpr unsigned StubSize = 8;
240
  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
241
  static constexpr unsigned ResolverCodeSize = 0xfc;
242
 
243
  /// Write the requested number of trampolines into the given memory,
244
  /// which must be big enough to hold 1 pointer, plus NumTrampolines
245
  /// trampolines.
246
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
247
                               JITTargetAddress TrampolineBlockTargetAddress,
248
                               JITTargetAddress ResolverAddr,
249
                               unsigned NumTrampolines);
250
 
251
  /// Write the resolver code into the given memory. The user is
252
  /// responsible for allocating the memory and setting permissions.
253
  ///
254
  /// ReentryFnAddr should be the address of a function whose signature matches
255
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
256
  /// argument of writeResolverCode will be passed as the second argument to
257
  /// the function at ReentryFnAddr.
258
  static void writeResolverCode(char *ResolverBlockWorkingMem,
259
                                JITTargetAddress ResolverBlockTargetAddress,
260
                                JITTargetAddress ReentryFnAddr,
261
                                JITTargetAddress ReentryCtxAddr,
262
                                bool isBigEndian);
263
  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
264
  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
265
  /// Nth stub using the Nth pointer in memory starting at
266
  /// PointersBlockTargetAddress.
267
  static void writeIndirectStubsBlock(
268
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
269
      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
270
};
271
 
272
class OrcMips32Le : public OrcMips32_Base {
273
public:
274
  static void writeResolverCode(char *ResolverWorkingMem,
275
                                JITTargetAddress ResolverTargetAddress,
276
                                JITTargetAddress ReentryFnAddr,
277
                                JITTargetAddress ReentryCtxAddr) {
278
    OrcMips32_Base::writeResolverCode(ResolverWorkingMem, ResolverTargetAddress,
279
                                      ReentryFnAddr, ReentryCtxAddr, false);
280
  }
281
};
282
 
283
class OrcMips32Be : public OrcMips32_Base {
284
public:
285
  static void writeResolverCode(char *ResolverWorkingMem,
286
                                JITTargetAddress ResolverTargetAddress,
287
                                JITTargetAddress ReentryFnAddr,
288
                                JITTargetAddress ReentryCtxAddr) {
289
    OrcMips32_Base::writeResolverCode(ResolverWorkingMem, ResolverTargetAddress,
290
                                      ReentryFnAddr, ReentryCtxAddr, true);
291
  }
292
};
293
 
294
// @brief Mips64 support.
295
//
296
// Mips64 supports lazy JITing.
297
class OrcMips64 {
298
public:
299
  static constexpr unsigned PointerSize = 8;
300
  static constexpr unsigned TrampolineSize = 40;
301
  static constexpr unsigned StubSize = 32;
302
  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
303
  static constexpr unsigned ResolverCodeSize = 0x120;
304
 
305
  /// Write the resolver code into the given memory. The user is
306
  /// responsible for allocating the memory and setting permissions.
307
  ///
308
  /// ReentryFnAddr should be the address of a function whose signature matches
309
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
310
  /// argument of writeResolverCode will be passed as the second argument to
311
  /// the function at ReentryFnAddr.
312
  static void writeResolverCode(char *ResolverWorkingMem,
313
                                JITTargetAddress ResolverTargetAddress,
314
                                JITTargetAddress ReentryFnAddr,
315
                                JITTargetAddress ReentryCtxAddr);
316
 
317
  /// Write the requested number of trampolines into the given memory,
318
  /// which must be big enough to hold 1 pointer, plus NumTrampolines
319
  /// trampolines.
320
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
321
                               JITTargetAddress TrampolineBlockTargetAddress,
322
                               JITTargetAddress ResolverFnAddr,
323
                               unsigned NumTrampolines);
324
  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
325
  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
326
  /// Nth stub using the Nth pointer in memory starting at
327
  /// PointersBlockTargetAddress.
328
  static void writeIndirectStubsBlock(
329
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
330
      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
331
};
332
 
333
// @brief riscv64 support.
334
//
335
// RISC-V 64 supports lazy JITing.
336
class OrcRiscv64 {
337
public:
338
  static constexpr unsigned PointerSize = 8;
339
  static constexpr unsigned TrampolineSize = 16;
340
  static constexpr unsigned StubSize = 16;
341
  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
342
  static constexpr unsigned ResolverCodeSize = 0x148;
343
 
344
  /// Write the resolver code into the given memory. The user is
345
  /// responsible for allocating the memory and setting permissions.
346
  ///
347
  /// ReentryFnAddr should be the address of a function whose signature matches
348
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
349
  /// argument of writeResolverCode will be passed as the second argument to
350
  /// the function at ReentryFnAddr.
351
  static void writeResolverCode(char *ResolverWorkingMem,
352
                                JITTargetAddress ResolverTargetAddress,
353
                                JITTargetAddress ReentryFnAddr,
354
                                JITTargetAddress ReentryCtxAddr);
355
 
356
  /// Write the requested number of trampolines into the given memory,
357
  /// which must be big enough to hold 1 pointer, plus NumTrampolines
358
  /// trampolines.
359
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
360
                               JITTargetAddress TrampolineBlockTargetAddress,
361
                               JITTargetAddress ResolverFnAddr,
362
                               unsigned NumTrampolines);
363
  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
364
  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
365
  /// Nth stub using the Nth pointer in memory starting at
366
  /// PointersBlockTargetAddress.
367
  static void writeIndirectStubsBlock(
368
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
369
      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
370
};
371
 
372
// @brief loongarch64 support.
373
//
374
// LoongArch 64 supports lazy JITing.
375
class OrcLoongArch64 {
376
public:
377
  static constexpr unsigned PointerSize = 8;
378
  static constexpr unsigned TrampolineSize = 16;
379
  static constexpr unsigned StubSize = 16;
380
  static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
381
  static constexpr unsigned ResolverCodeSize = 0xc8;
382
 
383
  /// Write the resolver code into the given memory. The user is
384
  /// responsible for allocating the memory and setting permissions.
385
  ///
386
  /// ReentryFnAddr should be the address of a function whose signature matches
387
  /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
388
  /// argument of writeResolverCode will be passed as the second argument to
389
  /// the function at ReentryFnAddr.
390
  static void writeResolverCode(char *ResolverWorkingMem,
391
                                JITTargetAddress ResolverTargetAddress,
392
                                JITTargetAddress ReentryFnAddr,
393
                                JITTargetAddress ReentryCtxAddr);
394
 
395
  /// Write the requested number of trampolines into the given memory,
396
  /// which must be big enough to hold 1 pointer, plus NumTrampolines
397
  /// trampolines.
398
  static void writeTrampolines(char *TrampolineBlockWorkingMem,
399
                               JITTargetAddress TrampolineBlockTargetAddress,
400
                               JITTargetAddress ResolverFnAddr,
401
                               unsigned NumTrampolines);
402
 
403
  /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
404
  /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
405
  /// Nth stub using the Nth pointer in memory starting at
406
  /// PointersBlockTargetAddress.
407
  static void writeIndirectStubsBlock(
408
      char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
409
      JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
410
};
411
 
412
} // end namespace orc
413
} // end namespace llvm
414
 
415
#endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H