96 const unsigned ReentryFnAddrOffset = 0x110;
97 const unsigned CallbackMgrAddrOffset = 0x118;
99 memcpy(ResolverMem, ResolverCode,
sizeof(ResolverCode));
100 memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn,
sizeof(ReentryFn));
101 memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
102 sizeof(CallbackMgr));
106 unsigned NumTrampolines) {
110 memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr,
sizeof(
void *));
119 Trampolines[3 *
I + 0] = 0xaa1e03f1;
120 Trampolines[3 *
I + 1] = 0x58000010 | (OffsetToPtr << 3);
121 Trampolines[3 *
I + 2] = 0xd63f0200;
128 void *InitialPtrVal) {
153 unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize;
154 unsigned NumStubs = (NumPages *
PageSize) / StubSize;
159 2 * NumPages * PageSize,
nullptr,
169 NumPages * PageSize);
172 uint64_t *Stub =
reinterpret_cast<uint64_t *
>(StubsBlock.base());
173 uint64_t PtrOffsetField =
static_cast<uint64_t
>(NumPages *
PageSize)
176 for (
unsigned I = 0;
I < NumStubs; ++
I)
177 Stub[
I] = 0xd61f020058000010 | PtrOffsetField;
184 void **
Ptr =
reinterpret_cast<void **
>(PtrsBlock.base());
185 for (
unsigned I = 0;
I < NumStubs; ++
I)
186 Ptr[
I] = InitialPtrVal;
195 unsigned NumTrampolines) {
199 memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr,
sizeof(
void *));
201 uint64_t *Trampolines =
reinterpret_cast<uint64_t *
>(TrampolineMem);
202 uint64_t CallIndirPCRel = 0xf1c40000000015ff;
205 Trampolines[
I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16);
210 void *InitialPtrVal) {
235 unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize;
236 unsigned NumStubs = (NumPages *
PageSize) / StubSize;
241 2 * NumPages * PageSize,
nullptr,
251 NumPages * PageSize);
254 uint64_t *Stub =
reinterpret_cast<uint64_t *
>(StubsBlock.base());
255 uint64_t PtrOffsetField =
static_cast<uint64_t
>(NumPages * PageSize - 6)
257 for (
unsigned I = 0;
I < NumStubs; ++
I)
258 Stub[
I] = 0xF1C40000000025ff | PtrOffsetField;
265 void **
Ptr =
reinterpret_cast<void **
>(PtrsBlock.base());
266 for (
unsigned I = 0;
I < NumStubs; ++
I)
267 Ptr[
I] = InitialPtrVal;
275 JITReentryFn ReentryFn,
278 const uint8_t ResolverCode[] = {
296 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
297 0x48, 0x0f, 0xae, 0x04, 0x24,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x48, 0x8b, 0x75, 0x08,
304 0x48, 0x83, 0xee, 0x06,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x48, 0x89, 0x45, 0x08,
312 0x48, 0x0f, 0xae, 0x0c, 0x24,
313 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
332 const unsigned ReentryFnAddrOffset = 0x3a;
333 const unsigned CallbackMgrAddrOffset = 0x28;
335 memcpy(ResolverMem, ResolverCode,
sizeof(ResolverCode));
336 memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn,
sizeof(ReentryFn));
337 memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
338 sizeof(CallbackMgr));
342 JITReentryFn ReentryFn,
347 const uint8_t ResolverCode[] = {
365 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
366 0x48, 0x0f, 0xae, 0x04, 0x24,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x48, 0x8B, 0x55, 0x08,
373 0x48, 0x83, 0xea, 0x06,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x48, 0x83, 0xEC, 0x20,
384 0x48, 0x83, 0xC4, 0x20,
386 0x48, 0x89, 0x45, 0x08,
387 0x48, 0x0f, 0xae, 0x0c, 0x24,
388 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
408 const unsigned ReentryFnAddrOffset = 0x3a;
409 const unsigned CallbackMgrAddrOffset = 0x28;
411 memcpy(ResolverMem, ResolverCode,
sizeof(ResolverCode));
412 memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn,
sizeof(ReentryFn));
413 memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
414 sizeof(CallbackMgr));
420 const uint8_t ResolverCode[] = {
432 0x81, 0xec, 0x18, 0x02, 0x00, 0x00,
433 0x0f, 0xae, 0x44, 0x24, 0x10,
436 0x89, 0x74, 0x24, 0x04,
437 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00,
439 0xb8, 0x00, 0x00, 0x00, 0x00,
442 0x0f, 0xae, 0x4c, 0x24, 0x10,
443 0x81, 0xc4, 0x18, 0x02, 0x00, 0x00,
455 const unsigned ReentryFnAddrOffset = 0x2a;
456 const unsigned CallbackMgrAddrOffset = 0x25;
458 memcpy(ResolverMem, ResolverCode,
sizeof(ResolverCode));
459 memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn,
sizeof(ReentryFn));
460 memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
461 sizeof(CallbackMgr));
465 unsigned NumTrampolines) {
467 uint64_t CallRelImm = 0xF1C4C400000000e8;
468 uint64_t Resolver =
reinterpret_cast<uint64_t
>(ResolverAddr);
469 uint64_t ResolverRel =
470 Resolver -
reinterpret_cast<uint64_t
>(TrampolineMem) - 5;
472 uint64_t *Trampolines =
reinterpret_cast<uint64_t *
>(TrampolineMem);
474 Trampolines[
I] = CallRelImm | (ResolverRel << 8);
478 unsigned MinStubs,
void *InitialPtrVal) {
503 unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize;
504 unsigned NumStubs = (NumPages *
PageSize) / StubSize;
509 2 * NumPages * PageSize,
nullptr,
519 NumPages * PageSize);
522 uint64_t *Stub =
reinterpret_cast<uint64_t *
>(StubsBlock.base());
523 uint64_t PtrAddr =
reinterpret_cast<uint64_t
>(PtrsBlock.base());
524 for (
unsigned I = 0;
I < NumStubs; ++
I, PtrAddr += 4)
525 Stub[
I] = 0xF1C40000000025ff | (PtrAddr << 16);
532 void **
Ptr =
reinterpret_cast<void **
>(PtrsBlock.base());
533 for (
unsigned I = 0;
I < NumStubs; ++
I)
534 Ptr[
I] = InitialPtrVal;
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr)
Write the resolver code into the given memory.
static const unsigned StubSize
Provide information about stub blocks generated by the makeIndirectStubsBlock function.
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr)
Write the resolver code into the given memory.
static MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)
This method allocates a block of memory that is suitable for loading dynamically generated code (e...
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, unsigned MinStubs, void *InitialPtrVal)
Emit at least MinStubs worth of indirect call stubs, rounded out to the nearest page size...
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr)
Write the resolver code into the given memory.
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096))
static const unsigned TrampolineSize
static const unsigned TrampolineSize
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, unsigned MinStubs, void *InitialPtrVal)
Emit at least MinStubs worth of indirect call stubs, rounded out to the nearest page size...
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static const unsigned TrampolineSize
static unsigned getPageSize()
static ErrorSuccess success()
Create a success value.
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, unsigned NumTrampolines)
Write the requsted number of trampolines into the given memory, which must be big enough to hold 1 po...
This class encapsulates the notion of a memory block which has an address and a size.
GenericIndirectStubsInfo< 8 > IndirectStubsInfo
Owning version of MemoryBlock.
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr)
Write the resolver code into the given memory.
GenericIndirectStubsInfo< 8 > IndirectStubsInfo
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, unsigned NumTrampolines)
Write the requsted number of trampolines into the given memory, which must be big enough to hold 1 po...
Provides a library for accessing information about this process and other processes on the operating ...
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, unsigned NumTrampolines)
Write the requsted number of trampolines into the given memory, which must be big enough to hold 1 po...
Lightweight error class with error context and mandatory checking.
GenericIndirectStubsInfo< 8 > IndirectStubsInfo
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, unsigned MinStubs, void *InitialPtrVal)
Emit at least MinStubs worth of indirect call stubs, rounded out to the nearest page size...
static std::error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)
This method sets the protection flags for a block of memory to the state specified by /p Flags...