13#define DEBUG_TYPE "orc"
18template <
typename ORCABI>
19[[maybe_unused]]
static bool
22 constexpr unsigned MaxDisp = ORCABI::StubToPointerMaxDisplacement;
24 ExecutorAddr LastStub = FirstStub + ((NumStubs - 1) * ORCABI::StubSize);
26 ExecutorAddr LastPointer = FirstPointer + ((NumStubs - 1) * ORCABI::StubSize);
28 if (FirstStub < FirstPointer) {
29 if (LastStub >= FirstPointer)
31 return (FirstPointer - FirstStub <= MaxDisp) &&
32 (LastPointer - LastStub <= MaxDisp);
35 if (LastPointer >= FirstStub)
38 return (FirstStub - FirstPointer <= MaxDisp) &&
39 (LastStub - LastPointer <= MaxDisp);
126 const unsigned ReentryFnAddrOffset = 0x110;
127 const unsigned ReentryCtxAddrOffset = 0x118;
129 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
130 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
132 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
139 unsigned NumTrampolines) {
143 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
151 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
154 Trampolines[3 *
I + 0] = 0xaa1e03f1;
155 Trampolines[3 *
I + 1] = 0x58000010 | (OffsetToPtr << 3);
156 Trampolines[3 *
I + 2] = 0xd63f0200;
161 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
162 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
184 "Pointer and stub size must match for algorithm below");
186 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
187 "PointersBlock is out of range");
188 uint64_t PtrDisplacement =
189 PointersBlockTargetAddress - StubsBlockTargetAddress;
190 assert((PtrDisplacement % 8 == 0) &&
191 "Displacement to pointer is not a multiple of 8");
192 uint64_t *Stub =
reinterpret_cast<uint64_t *
>(StubsBlockWorkingMem);
193 uint64_t PtrOffsetField = ((PtrDisplacement >> 2) & 0x7ffff) << 5;
195 for (
unsigned I = 0;
I < NumStubs; ++
I)
196 Stub[
I] = 0xd61f020058000010 | PtrOffsetField;
202 unsigned NumTrampolines) {
206 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
209 uint64_t *Trampolines =
210 reinterpret_cast<uint64_t *
>(TrampolineBlockWorkingMem);
211 uint64_t CallIndirPCRel = 0xf1c40000000015ff;
214 Trampolines[
I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16);
218 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
219 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
242 "Pointer and stub size must match for algorithm below");
244 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
245 "PointersBlock is out of range");
246 uint64_t *Stub =
reinterpret_cast<uint64_t *
>(StubsBlockWorkingMem);
247 uint64_t PtrOffsetField =
248 (PointersBlockTargetAddress - StubsBlockTargetAddress - 6) << 16;
249 for (
unsigned I = 0;
I < NumStubs; ++
I)
250 Stub[
I] = 0xF1C40000000025ff | PtrOffsetField;
259 dbgs() <<
"Writing resolver code to "
260 <<
formatv(
"{0:x16}", ResolverTargetAddress) <<
"\n";
263 const uint8_t ResolverCode[] = {
281 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
282 0x48, 0x0f, 0xae, 0x04, 0x24,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x48, 0x8b, 0x75, 0x08,
289 0x48, 0x83, 0xee, 0x06,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x48, 0x89, 0x45, 0x08,
297 0x48, 0x0f, 0xae, 0x0c, 0x24,
298 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
317 const unsigned ReentryFnAddrOffset = 0x3a;
318 const unsigned ReentryCtxAddrOffset = 0x28;
320 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
321 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
323 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
335 const uint8_t ResolverCode[] = {
353 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
354 0x48, 0x0f, 0xae, 0x04, 0x24,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x48, 0x8B, 0x55, 0x08,
361 0x48, 0x83, 0xea, 0x06,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x48, 0x83, 0xEC, 0x20,
372 0x48, 0x83, 0xC4, 0x20,
374 0x48, 0x89, 0x45, 0x08,
375 0x48, 0x0f, 0xae, 0x0c, 0x24,
376 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
395 const unsigned ReentryFnAddrOffset = 0x3a;
396 const unsigned ReentryCtxAddrOffset = 0x28;
398 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
399 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
401 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
410 assert((ReentryFnAddr.
getValue() >> 32) == 0 &&
"ReentryFnAddr out of range");
412 "ReentryCtxAddr out of range");
414 const uint8_t ResolverCode[] = {
426 0x81, 0xec, 0x18, 0x02, 0x00, 0x00,
427 0x0f, 0xae, 0x44, 0x24, 0x10,
430 0x89, 0x74, 0x24, 0x04,
431 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00,
433 0xb8, 0x00, 0x00, 0x00, 0x00,
436 0x0f, 0xae, 0x4c, 0x24, 0x10,
437 0x81, 0xc4, 0x18, 0x02, 0x00, 0x00,
449 const unsigned ReentryFnAddrOffset = 0x2a;
450 const unsigned ReentryCtxAddrOffset = 0x25;
452 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
453 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
455 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
462 unsigned NumTrampolines) {
463 assert((ResolverAddr.
getValue() >> 32) == 0 &&
"ResolverAddr out of range");
465 uint64_t CallRelImm = 0xF1C4C400000000e8;
466 uint64_t ResolverRel = ResolverAddr - TrampolineBlockTargetAddress - 5;
468 uint64_t *Trampolines =
reinterpret_cast<uint64_t *
>(TrampolineWorkingMem);
470 Trampolines[
I] = CallRelImm | (ResolverRel << 8);
478 "StubsBlockTargetAddress is out of range");
480 "PointersBlockTargetAddress is out of range");
503 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
504 "PointersBlock is out of range");
506 uint64_t *Stub =
reinterpret_cast<uint64_t *
>(StubsBlockWorkingMem);
507 uint64_t PtrAddr = PointersBlockTargetAddress.
getValue();
508 for (
unsigned I = 0;
I < NumStubs; ++
I, PtrAddr += 4)
509 Stub[
I] = 0xF1C40000000025ff | (PtrAddr << 16);
593 const unsigned ReentryFnAddrOffset = 0x7c;
594 const unsigned ReentryCtxAddrOffset = 0x6c;
595 const unsigned MoveLandingAddrOffset = 0xf8;
598 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
602 memcpy(ResolverWorkingMem + MoveLandingAddrOffset, &MoveVxT9,
606 0x3c040000 | (((ReentryCtxAddr.
getValue() + 0x8000) >> 16) & 0xFFFF);
607 uint32_t ReentryCtxADDiu = 0x24840000 | (ReentryCtxAddr.
getValue() & 0xFFFF);
608 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxLUi,
609 sizeof(ReentryCtxLUi));
610 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset + 4, &ReentryCtxADDiu,
611 sizeof(ReentryCtxADDiu));
614 0x3c190000 | (((ReentryFnAddr.
getValue() + 0x8000) >> 16) & 0xFFFF);
616 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnLUi,
617 sizeof(ReentryFnLUi));
618 memcpy(ResolverWorkingMem + ReentryFnAddrOffset + 4, &ReentryFnADDiu,
619 sizeof(ReentryFnADDiu));
625 unsigned NumTrampolines) {
627 assert((ResolverAddr.
getValue() >> 32) == 0 &&
"ResolverAddr out of range");
630 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
633 for (
unsigned I = 0;
I < NumTrampolines; ++
I) {
639 Trampolines[5 *
I + 0] = 0x03e0c025;
640 Trampolines[5 *
I + 1] = 0x3c190000 | (RHiAddr & 0xFFFF);
641 Trampolines[5 *
I + 2] = 0x27390000 | (ResolverAddr.
getValue() & 0xFFFF);
642 Trampolines[5 *
I + 3] = 0x0320f809;
643 Trampolines[5 *
I + 4] = 0x00000000;
648 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
649 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
651 "InitialPtrVal is out of range");
676 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
677 "PointersBlock is out of range");
681 uint64_t PtrAddr = PointersBlockTargetAddress.
getValue();
683 for (
unsigned I = 0;
I < NumStubs; ++
I) {
684 uint32_t HiAddr = ((PtrAddr + 0x8000) >> 16);
685 Stub[4 *
I + 0] = 0x3c190000 | (HiAddr & 0xFFFF);
686 Stub[4 *
I + 1] = 0x8f390000 | (PtrAddr & 0xFFFF);
687 Stub[4 *
I + 2] = 0x03200008;
688 Stub[4 *
I + 3] = 0x00000000;
780 const unsigned ReentryFnAddrOffset = 0x8c;
781 const unsigned ReentryCtxAddrOffset = 0x6c;
784 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
788 (((ReentryCtxAddr.
getValue() + 0x800080008000) >> 48) & 0xFFFF);
790 0x64840000 | (((ReentryCtxAddr.
getValue() + 0x80008000) >> 32) & 0xFFFF);
791 uint32_t ReentryCtxDSLL = 0x00042438;
793 0x64840000 | ((((ReentryCtxAddr.
getValue() + 0x8000) >> 16) & 0xFFFF));
794 uint32_t ReentryCtxDSLL2 = 0x00042438;
796 0x64840000 | (ReentryCtxAddr.
getValue() & 0xFFFF);
798 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxLUi,
799 sizeof(ReentryCtxLUi));
800 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 4), &ReentryCtxDADDiu,
801 sizeof(ReentryCtxDADDiu));
802 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 8), &ReentryCtxDSLL,
803 sizeof(ReentryCtxDSLL));
804 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 12), &ReentryCtxDADDiu2,
805 sizeof(ReentryCtxDADDiu2));
806 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 16), &ReentryCtxDSLL2,
807 sizeof(ReentryCtxDSLL2));
808 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 20), &ReentryCtxDADDiu3,
809 sizeof(ReentryCtxDADDiu3));
813 (((ReentryFnAddr.
getValue() + 0x800080008000) >> 48) & 0xFFFF);
816 0x67390000 | (((ReentryFnAddr.
getValue() + 0x80008000) >> 32) & 0xFFFF);
818 uint32_t ReentryFnDSLL = 0x0019cc38;
821 0x67390000 | (((ReentryFnAddr.
getValue() + 0x8000) >> 16) & 0xFFFF);
823 uint32_t ReentryFnDSLL2 = 0x0019cc38;
825 uint32_t ReentryFnDADDiu3 = 0x67390000 | (ReentryFnAddr.
getValue() & 0xFFFF);
827 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnLUi,
828 sizeof(ReentryFnLUi));
829 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 4), &ReentryFnDADDiu,
830 sizeof(ReentryFnDADDiu));
831 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 8), &ReentryFnDSLL,
832 sizeof(ReentryFnDSLL));
833 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 12), &ReentryFnDADDiu2,
834 sizeof(ReentryFnDADDiu2));
835 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 16), &ReentryFnDSLL2,
836 sizeof(ReentryFnDSLL2));
837 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 20), &ReentryFnDADDiu3,
838 sizeof(ReentryFnDADDiu3));
844 unsigned NumTrampolines) {
847 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
849 uint64_t HeighestAddr = ((ResolverAddr.
getValue() + 0x800080008000) >> 48);
850 uint64_t HeigherAddr = ((ResolverAddr.
getValue() + 0x80008000) >> 32);
851 uint64_t HiAddr = ((ResolverAddr.
getValue() + 0x8000) >> 16);
853 for (
unsigned I = 0;
I < NumTrampolines; ++
I) {
854 Trampolines[10 *
I + 0] = 0x03e0c025;
855 Trampolines[10 *
I + 1] = 0x3c190000 | (HeighestAddr & 0xFFFF);
856 Trampolines[10 *
I + 2] = 0x67390000 | (HeigherAddr & 0xFFFF);
857 Trampolines[10 *
I + 3] = 0x0019cc38;
858 Trampolines[10 *
I + 4] = 0x67390000 | (HiAddr & 0xFFFF);
859 Trampolines[10 *
I + 5] = 0x0019cc38;
860 Trampolines[10 *
I + 6] = 0x67390000 | (ResolverAddr.
getValue() &
862 Trampolines[10 *
I + 7] = 0x0320f809;
863 Trampolines[10 *
I + 8] = 0x00000000;
864 Trampolines[10 *
I + 9] = 0x00000000;
901 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
902 "PointersBlock is out of range");
906 uint64_t PtrAddr = PointersBlockTargetAddress.
getValue();
908 for (
unsigned I = 0;
I < NumStubs; ++
I, PtrAddr += 8) {
909 uint64_t HeighestAddr = ((PtrAddr + 0x800080008000) >> 48);
910 uint64_t HeigherAddr = ((PtrAddr + 0x80008000) >> 32);
911 uint64_t HiAddr = ((PtrAddr + 0x8000) >> 16);
912 Stub[8 *
I + 0] = 0x3c190000 | (HeighestAddr & 0xFFFF);
913 Stub[8 *
I + 1] = 0x67390000 | (HeigherAddr & 0xFFFF);
914 Stub[8 *
I + 2] = 0x0019cc38;
915 Stub[8 *
I + 3] = 0x67390000 | (HiAddr & 0xFFFF);
916 Stub[8 *
I + 4] = 0x0019cc38;
917 Stub[8 *
I + 5] = 0xdf390000 | (PtrAddr & 0xFFFF);
918 Stub[8 *
I + 6] = 0x03200008;
919 Stub[8 *
I + 7] = 0x00000000;
1013 const unsigned ReentryCtxAddrOffset = 0x138;
1014 const unsigned ReentryFnAddrOffset = 0x140;
1016 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
1017 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
1019 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
1026 unsigned NumTrampolines) {
1030 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
1034 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
1036 uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xFFFFF000;
1037 uint32_t Lo12 = OffsetToPtr - Hi20;
1038 Trampolines[4 *
I + 0] = 0x00000297 | Hi20;
1039 Trampolines[4 *
I + 1] =
1040 0x0002b283 | ((Lo12 & 0xFFF) << 20);
1041 Trampolines[4 *
I + 2] = 0x00028367;
1042 Trampolines[4 *
I + 3] = 0xdeadface;
1047 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
1048 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
1074 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
1075 "PointersBlock is out of range");
1079 for (
unsigned I = 0;
I < NumStubs; ++
I) {
1080 uint64_t PtrDisplacement =
1081 PointersBlockTargetAddress - StubsBlockTargetAddress;
1082 uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xFFFFF000;
1083 uint32_t Lo12 = PtrDisplacement - Hi20;
1084 Stub[4 *
I + 0] = 0x00000297 | Hi20;
1085 Stub[4 *
I + 1] = 0x0002b283 | ((Lo12 & 0xFFF) << 20);
1086 Stub[4 *
I + 2] = 0x00028067;
1087 Stub[4 *
I + 3] = 0xfeedbeef;
1089 StubsBlockTargetAddress +=
StubSize;
1099 dbgs() <<
"Writing resolver code to "
1100 <<
formatv(
"{0:x16}", ResolverTargetAddress) <<
"\n";
1156 const unsigned ReentryCtxAddrOffset = 0xb8;
1157 const unsigned ReentryFnAddrOffset = 0xc0;
1159 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
1160 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
1162 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
1169 unsigned NumTrampolines) {
1172 dbgs() <<
"Writing trampoline code to "
1173 <<
formatv(
"{0:x16}", TrampolineBlockTargetAddress) <<
"\n";
1178 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
1182 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
1184 uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xfffff000;
1185 uint32_t Lo12 = OffsetToPtr - Hi20;
1186 Trampolines[4 *
I + 0] =
1188 (((Hi20 >> 12) & 0xfffff) << 5);
1189 Trampolines[4 *
I + 1] =
1190 0x28c0018c | ((Lo12 & 0xfff) << 10);
1191 Trampolines[4 *
I + 2] = 0x4c00018d;
1192 Trampolines[4 *
I + 3] = 0x0;
1197 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
1198 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
1221 dbgs() <<
"Writing stubs code to "
1222 <<
formatv(
"{0:x16}", StubsBlockTargetAddress) <<
"\n";
1225 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
1226 "PointersBlock is out of range");
1230 for (
unsigned I = 0;
I < NumStubs; ++
I) {
1231 uint64_t PtrDisplacement =
1232 PointersBlockTargetAddress - StubsBlockTargetAddress;
1233 uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xfffff000;
1234 uint32_t Lo12 = PtrDisplacement - Hi20;
1235 Stub[4 *
I + 0] = 0x1c00000c | (((Hi20 >> 12) & 0xfffff)
1238 0x28c0018c | ((Lo12 & 0xfff) << 10);
1239 Stub[4 *
I + 2] = 0x4c000180;
1240 Stub[4 *
I + 3] = 0x0;
1242 StubsBlockTargetAddress +=
StubSize;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
static bool stubAndPointerRangesOk(ExecutorAddr StubBlockAddr, ExecutorAddr PointerBlockAddr, unsigned NumStubs)
Represents an address in the executor process.
uint64_t getValue() const
static constexpr unsigned PointerSize
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr RentryCtxAddr)
Write the resolver code into the given memory.
static LLVM_ABI void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static constexpr unsigned TrampolineSize
static constexpr unsigned StubSize
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned MinStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static LLVM_ABI void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static constexpr unsigned TrampolineSize
static constexpr unsigned StubSize
static constexpr unsigned PointerSize
static constexpr unsigned TrampolineSize
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static LLVM_ABI void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverFnAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static LLVM_ABI void writeResolverCode(char *ResolverBlockWorkingMem, ExecutorAddr ResolverBlockTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr, bool isBigEndian)
Write the resolver code into the given memory.
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static LLVM_ABI void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static constexpr unsigned ResolverCodeSize
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static constexpr unsigned ResolverCodeSize
static LLVM_ABI void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverFnAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static constexpr unsigned StubSize
static constexpr unsigned TrampolineSize
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static LLVM_ABI void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverFnAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static constexpr unsigned PointerSize
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static constexpr unsigned PointerSize
static constexpr unsigned StubSize
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static LLVM_ABI void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static constexpr unsigned TrampolineSize
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.