LLVM: lib/ExecutionEngine/Orc/OrcABISupport.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
12
13#define DEBUG_TYPE "orc"
14
15using namespace llvm;
17
18template
21 unsigned NumStubs) {
22 constexpr unsigned MaxDisp = ORCABI::StubToPointerMaxDisplacement;
24 ExecutorAddr LastStub = FirstStub + ((NumStubs - 1) * ORCABI::StubSize);
26 ExecutorAddr LastPointer = FirstPointer + ((NumStubs - 1) * ORCABI::StubSize);
27
28 if (FirstStub < FirstPointer) {
29 if (LastStub >= FirstPointer)
30 return false;
31 return (FirstPointer - FirstStub <= MaxDisp) &&
32 (LastPointer - LastStub <= MaxDisp);
33 }
34
35 if (LastPointer >= FirstStub)
36 return false;
37
38 return (FirstStub - FirstPointer <= MaxDisp) &&
39 (LastStub - LastPointer <= MaxDisp);
40}
41
42namespace llvm {
43namespace orc {
44
49
50 const uint32_t ResolverCode[] = {
51
52 0xa9bf47fd,
53 0x910003fd,
54 0xa9bf73fb,
55 0xa9bf6bf9,
56 0xa9bf63f7,
57 0xa9bf5bf5,
58 0xa9bf53f3,
59 0xa9bf3fee,
60 0xa9bf37ec,
61 0xa9bf2fea,
62 0xa9bf27e8,
63 0xa9bf1fe6,
64 0xa9bf17e4,
65 0xa9bf0fe2,
66 0xa9bf07e0,
67 0xadbf7ffe,
68 0xadbf77fc,
69 0xadbf6ffa,
70 0xadbf67f8,
71 0xadbf5ff6,
72 0xadbf57f4,
73 0xadbf4ff2,
74 0xadbf47f0,
75 0xadbf3fee,
76 0xadbf37ec,
77 0xadbf2fea,
78 0xadbf27e8,
79 0xadbf1fe6,
80 0xadbf17e4,
81 0xadbf0fe2,
82 0xadbf07e0,
83 0x580004e0,
84 0xaa1e03e1,
85 0xd1003021,
86 0x58000442,
87 0xd63f0040,
88 0xaa0003f1,
89 0xacc107e0,
90 0xacc10fe2,
91 0xacc117e4,
92 0xacc11fe6,
93 0xacc127e8,
94 0xacc12fea,
95 0xacc137ec,
96 0xacc13fee,
97 0xacc147f0,
98 0xacc14ff2,
99 0xacc157f4,
100 0xacc15ff6,
101 0xacc167f8,
102 0xacc16ffa,
103 0xacc177fc,
104 0xacc17ffe,
105 0xa8c107e0,
106 0xa8c10fe2,
107 0xa8c117e4,
108 0xa8c11fe6,
109 0xa8c127e8,
110 0xa8c12fea,
111 0xa8c137ec,
112 0xa8c13fee,
113 0xa8c153f3,
114 0xa8c15bf5,
115 0xa8c163f7,
116 0xa8c16bf9,
117 0xa8c173fb,
118 0xa8c17bfd,
119 0xd65f0220,
120 0x01234567,
121 0xdeadbeef,
122 0x98765432,
123 0xcafef00d
124 };
125
126 const unsigned ReentryFnAddrOffset = 0x110;
127 const unsigned ReentryCtxAddrOffset = 0x118;
128
129 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
130 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
132 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
134}
135
139 unsigned NumTrampolines) {
140
142
143 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
145
146
147
148 OffsetToPtr -= 4;
149
151 reinterpret_cast<uint32_t *>(TrampolineBlockWorkingMem);
152
153 for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) {
154 Trampolines[3 * I + 0] = 0xaa1e03f1;
155 Trampolines[3 * I + 1] = 0x58000010 | (OffsetToPtr << 3);
156 Trampolines[3 * I + 2] = 0xd63f0200;
157 }
158}
159
161 char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress,
162 ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) {
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
184 "Pointer and stub size must match for algorithm below");
186 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
187 "PointersBlock is out of range");
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;
194
195 for (unsigned I = 0; I < NumStubs; ++I)
196 Stub[I] = 0xd61f020058000010 | PtrOffsetField;
197}
198
202 unsigned NumTrampolines) {
203
204 unsigned OffsetToPtr = NumTrampolines * TrampolineSize;
205
206 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
208
210 reinterpret_cast<uint64_t *>(TrampolineBlockWorkingMem);
211 uint64_t CallIndirPCRel = 0xf1c40000000015ff;
212
213 for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize)
214 Trampolines[I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16);
215}
216
218 char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress,
219 ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) {
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
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);
248 (PointersBlockTargetAddress - StubsBlockTargetAddress - 6) << 16;
249 for (unsigned I = 0; I < NumStubs; ++I)
250 Stub[I] = 0xF1C40000000025ff | PtrOffsetField;
251}
252
257
259 dbgs() << "Writing resolver code to "
260 << formatv("{0:x16}", ResolverTargetAddress) << "\n";
261 });
262
263 const uint8_t ResolverCode[] = {
264
265 0x55,
266 0x48, 0x89, 0xe5,
267 0x50,
268 0x53,
269 0x51,
270 0x52,
271 0x56,
272 0x57,
273 0x41, 0x50,
274 0x41, 0x51,
275 0x41, 0x52,
276 0x41, 0x53,
277 0x41, 0x54,
278 0x41, 0x55,
279 0x41, 0x56,
280 0x41, 0x57,
281 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
282 0x48, 0x0f, 0xae, 0x04, 0x24,
283 0x48, 0xbf,
284
285
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287
288 0x48, 0x8b, 0x75, 0x08,
289 0x48, 0x83, 0xee, 0x06,
290 0x48, 0xb8,
291
292
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294
295 0xff, 0xd0,
296 0x48, 0x89, 0x45, 0x08,
297 0x48, 0x0f, 0xae, 0x0c, 0x24,
298 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
299 0x41, 0x5f,
300 0x41, 0x5e,
301 0x41, 0x5d,
302 0x41, 0x5c,
303 0x41, 0x5b,
304 0x41, 0x5a,
305 0x41, 0x59,
306 0x41, 0x58,
307 0x5f,
308 0x5e,
309 0x5a,
310 0x59,
311 0x5b,
312 0x58,
313 0x5d,
314 0xc3,
315 };
316
317 const unsigned ReentryFnAddrOffset = 0x3a;
318 const unsigned ReentryCtxAddrOffset = 0x28;
319
320 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
321 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
323 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
325}
326
331
332
333
334
335 const uint8_t ResolverCode[] = {
336
337 0x55,
338 0x48, 0x89, 0xe5,
339 0x50,
340 0x53,
341 0x51,
342 0x52,
343 0x56,
344 0x57,
345 0x41, 0x50,
346 0x41, 0x51,
347 0x41, 0x52,
348 0x41, 0x53,
349 0x41, 0x54,
350 0x41, 0x55,
351 0x41, 0x56,
352 0x41, 0x57,
353 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
354 0x48, 0x0f, 0xae, 0x04, 0x24,
355
356 0x48, 0xb9,
357
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359
360 0x48, 0x8B, 0x55, 0x08,
361 0x48, 0x83, 0xea, 0x06,
362
363 0x48, 0xb8,
364
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366
367
368 0x48, 0x83, 0xEC, 0x20,
369 0xff, 0xd0,
370
371
372 0x48, 0x83, 0xC4, 0x20,
373
374 0x48, 0x89, 0x45, 0x08,
375 0x48, 0x0f, 0xae, 0x0c, 0x24,
376 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
377 0x41, 0x5f,
378 0x41, 0x5e,
379 0x41, 0x5d,
380 0x41, 0x5c,
381 0x41, 0x5b,
382 0x41, 0x5a,
383 0x41, 0x59,
384 0x41, 0x58,
385 0x5f,
386 0x5e,
387 0x5a,
388 0x59,
389 0x5b,
390 0x58,
391 0x5d,
392 0xc3,
393 };
394
395 const unsigned ReentryFnAddrOffset = 0x3a;
396 const unsigned ReentryCtxAddrOffset = 0x28;
397
398 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
399 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
401 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
403}
404
409
410 assert((ReentryFnAddr.getValue() >> 32) == 0 && "ReentryFnAddr out of range");
412 "ReentryCtxAddr out of range");
413
414 const uint8_t ResolverCode[] = {
415
416 0x55,
417 0x89, 0xe5,
418 0x54,
419 0x83, 0xe4, 0xf0,
420 0x50,
421 0x53,
422 0x51,
423 0x52,
424 0x56,
425 0x57,
426 0x81, 0xec, 0x18, 0x02, 0x00, 0x00,
427 0x0f, 0xae, 0x44, 0x24, 0x10,
428 0x8b, 0x75, 0x04,
429 0x83, 0xee, 0x05,
430 0x89, 0x74, 0x24, 0x04,
431 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00,
432 0x00,
433 0xb8, 0x00, 0x00, 0x00, 0x00,
434 0xff, 0xd0,
435 0x89, 0x45, 0x04,
436 0x0f, 0xae, 0x4c, 0x24, 0x10,
437 0x81, 0xc4, 0x18, 0x02, 0x00, 0x00,
438 0x5f,
439 0x5e,
440 0x5a,
441 0x59,
442 0x5b,
443 0x58,
444 0x8b, 0x65, 0xfc,
445 0x5d,
446 0xc3
447 };
448
449 const unsigned ReentryFnAddrOffset = 0x2a;
450 const unsigned ReentryCtxAddrOffset = 0x25;
451
452 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
453 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
455 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
457}
458
462 unsigned NumTrampolines) {
463 assert((ResolverAddr.getValue() >> 32) == 0 && "ResolverAddr out of range");
464
465 uint64_t CallRelImm = 0xF1C4C400000000e8;
466 uint64_t ResolverRel = ResolverAddr - TrampolineBlockTargetAddress - 5;
467
468 uint64_t *Trampolines = reinterpret_cast<uint64_t *>(TrampolineWorkingMem);
469 for (unsigned I = 0; I < NumTrampolines; ++I, ResolverRel -= TrampolineSize)
470 Trampolines[I] = CallRelImm | (ResolverRel << 8);
471}
472
476 unsigned NumStubs) {
477 assert((StubsBlockTargetAddress.getValue() >> 32) == 0 &&
478 "StubsBlockTargetAddress is out of range");
479 assert((PointersBlockTargetAddress.getValue() >> 32) == 0 &&
480 "PointersBlockTargetAddress is out of range");
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
503 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
504 "PointersBlock is out of range");
505
506 uint64_t *Stub = reinterpret_cast<uint64_t *>(StubsBlockWorkingMem);
508 for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 4)
509 Stub[I] = 0xF1C40000000025ff | (PtrAddr << 16);
510}
511
517
518 const uint32_t ResolverCode[] = {
519
520 0x27bdff98,
521 0xafa20000,
522 0xafa30004,
523 0xafa40008,
524 0xafa5000c,
525 0xafa60010,
526 0xafa70014,
527 0xafb00018,
528 0xafb1001c,
529 0xafb20020,
530 0xafb30024,
531 0xafb40028,
532 0xafb5002c,
533 0xafb60030,
534 0xafb70034,
535 0xafa80038,
536 0xafa9003c,
537 0xafaa0040,
538 0xafab0044,
539 0xafac0048,
540 0xafad004c,
541 0xafae0050,
542 0xafaf0054,
543 0xafb80058,
544 0xafb9005c,
545 0xafbe0060,
546 0xafbf0064,
547
548
549 0x00000000,
550 0x00000000,
551
552 0x03e02825,
553 0x24a5ffec,
554
555
556 0x00000000,
557 0x00000000,
558
559 0x0320f809,
560 0x00000000,
561 0x8fbf0064,
562 0x8fbe0060,
563 0x8fb9005c,
564 0x8fb80058,
565 0x8faf0054,
566 0x8fae0050,
567 0x8fad004c,
568 0x8fac0048,
569 0x8fab0044,
570 0x8faa0040,
571 0x8fa9003c,
572 0x8fa80038,
573 0x8fb70034,
574 0x8fb60030,
575 0x8fb5002c,
576 0x8fb40028,
577 0x8fb30024,
578 0x8fb20020,
579 0x8fb1001c,
580 0x8fb00018,
581 0x8fa70014,
582 0x8fa60010,
583 0x8fa5000c,
584 0x8fa40008,
585 0x27bd0068,
586 0x0300f825,
587 0x03200008,
588 0x00000000,
589 };
590
591 const unsigned ReentryFnAddrOffset = 0x7c;
592 const unsigned ReentryCtxAddrOffset = 0x6c;
593 const unsigned Offsett = 0xf8;
594
595 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
596
597
599 memcpy(ResolverWorkingMem + Offsett, &MoveVxT9, sizeof(MoveVxT9));
600
602 0x3c040000 | (((ReentryCtxAddr.getValue() + 0x8000) >> 16) & 0xFFFF);
603 uint32_t ReentryCtxADDiu = 0x24840000 | (ReentryCtxAddr.getValue() & 0xFFFF);
604 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxLUi,
605 sizeof(ReentryCtxLUi));
606 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset + 4, &ReentryCtxADDiu,
607 sizeof(ReentryCtxADDiu));
608
610 0x3c190000 | (((ReentryFnAddr.getValue() + 0x8000) >> 16) & 0xFFFF);
611 uint32_t ReentryFnADDiu = 0x27390000 | (ReentryFnAddr.getValue() & 0xFFFF);
612 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnLUi,
613 sizeof(ReentryFnLUi));
614 memcpy(ResolverWorkingMem + ReentryFnAddrOffset + 4, &ReentryFnADDiu,
615 sizeof(ReentryFnADDiu));
616}
617
621 unsigned NumTrampolines) {
622
623 assert((ResolverAddr.getValue() >> 32) == 0 && "ResolverAddr out of range");
624
626 reinterpret_cast<uint32_t *>(TrampolineBlockWorkingMem);
627 uint32_t RHiAddr = ((ResolverAddr.getValue() + 0x8000) >> 16);
628
629 for (unsigned I = 0; I < NumTrampolines; ++I) {
630
631
632
633
634
635 Trampolines[5 * I + 0] = 0x03e0c025;
636 Trampolines[5 * I + 1] = 0x3c190000 | (RHiAddr & 0xFFFF);
637 Trampolines[5 * I + 2] = 0x27390000 | (ResolverAddr.getValue() & 0xFFFF);
638 Trampolines[5 * I + 3] = 0x0320f809;
639 Trampolines[5 * I + 4] = 0x00000000;
640 }
641}
642
644 char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress,
645 ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) {
646 assert((StubsBlockTargetAddress.getValue() >> 32) == 0 &&
647 "InitialPtrVal is out of range");
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
672 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
673 "PointersBlock is out of range");
674
675
676 uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlockWorkingMem);
678
679 for (unsigned I = 0; I < NumStubs; ++I) {
680 uint32_t HiAddr = ((PtrAddr + 0x8000) >> 16);
681 Stub[4 * I + 0] = 0x3c190000 | (HiAddr & 0xFFFF);
682 Stub[4 * I + 1] = 0x8f390000 | (PtrAddr & 0xFFFF);
683 Stub[4 * I + 2] = 0x03200008;
684 Stub[4 * I + 3] = 0x00000000;
685 PtrAddr += 4;
686 }
687}
688
693
694 const uint32_t ResolverCode[] = {
695
696 0x67bdff30,
697 0xffa20000,
698 0xffa30008,
699 0xffa40010,
700 0xffa50018,
701 0xffa60020,
702 0xffa70028,
703 0xffa80030,
704 0xffa90038,
705 0xffaa0040,
706 0xffab0048,
707 0xffac0050,
708 0xffad0058,
709 0xffae0060,
710 0xffaf0068,
711 0xffb00070,
712 0xffb10078,
713 0xffb20080,
714 0xffb30088,
715 0xffb40090,
716 0xffb50098,
717 0xffb600a0,
718 0xffb700a8,
719 0xffb800b0,
720 0xffb900b8,
721 0xffbe00c0,
722 0xffbf00c8,
723
724
725 0x00000000,
726 0x00000000,
727 0x00000000,
728 0x00000000,
729 0x00000000,
730 0x00000000,
731
732 0x03e02825,
733 0x64a5ffdc,
734
735
736 0x00000000,
737 0x00000000,
738 0x00000000,
739 0x00000000,
740 0x00000000,
741 0x00000000,
742 0x0320f809,
743 0x00000000,
744 0xdfbf00c8,
745 0xdfbe00c0,
746 0xdfb900b8,
747 0xdfb800b0,
748 0xdfb700a8,
749 0xdfb600a0,
750 0xdfb50098,
751 0xdfb40090,
752 0xdfb30088,
753 0xdfb20080,
754 0xdfb10078,
755 0xdfb00070,
756 0xdfaf0068,
757 0xdfae0060,
758 0xdfad0058,
759 0xdfac0050,
760 0xdfab0048,
761 0xdfaa0040,
762 0xdfa90038,
763 0xdfa80030,
764 0xdfa70028,
765 0xdfa60020,
766 0xdfa50018,
767 0xdfa40010,
768 0xdfa30008,
769 0x67bd00d0,
770 0x0300f825,
771 0x03200008,
772 0x0040c825,
773 };
774
775 const unsigned ReentryFnAddrOffset = 0x8c;
776 const unsigned ReentryCtxAddrOffset = 0x6c;
777
778 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
779
781 0x3c040000 |
782 (((ReentryCtxAddr.getValue() + 0x800080008000) >> 48) & 0xFFFF);
784 0x64840000 | (((ReentryCtxAddr.getValue() + 0x80008000) >> 32) & 0xFFFF);
785 uint32_t ReentryCtxDSLL = 0x00042438;
787 0x64840000 | ((((ReentryCtxAddr.getValue() + 0x8000) >> 16) & 0xFFFF));
788 uint32_t ReentryCtxDSLL2 = 0x00042438;
790 0x64840000 | (ReentryCtxAddr.getValue() & 0xFFFF);
791
792 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxLUi,
793 sizeof(ReentryCtxLUi));
794 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 4), &ReentryCtxDADDiu,
795 sizeof(ReentryCtxDADDiu));
796 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 8), &ReentryCtxDSLL,
797 sizeof(ReentryCtxDSLL));
798 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 12), &ReentryCtxDADDiu2,
799 sizeof(ReentryCtxDADDiu2));
800 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 16), &ReentryCtxDSLL2,
801 sizeof(ReentryCtxDSLL2));
802 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 20), &ReentryCtxDADDiu3,
803 sizeof(ReentryCtxDADDiu3));
804
806 0x3c190000 |
807 (((ReentryFnAddr.getValue() + 0x800080008000) >> 48) & 0xFFFF);
808
810 0x67390000 | (((ReentryFnAddr.getValue() + 0x80008000) >> 32) & 0xFFFF);
811
812 uint32_t ReentryFnDSLL = 0x0019cc38;
813
815 0x67390000 | (((ReentryFnAddr.getValue() + 0x8000) >> 16) & 0xFFFF);
816
817 uint32_t ReentryFnDSLL2 = 0x0019cc38;
818
819 uint32_t ReentryFnDADDiu3 = 0x67390000 | (ReentryFnAddr.getValue() & 0xFFFF);
820
821 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnLUi,
822 sizeof(ReentryFnLUi));
823 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 4), &ReentryFnDADDiu,
824 sizeof(ReentryFnDADDiu));
825 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 8), &ReentryFnDSLL,
826 sizeof(ReentryFnDSLL));
827 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 12), &ReentryFnDADDiu2,
828 sizeof(ReentryFnDADDiu2));
829 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 16), &ReentryFnDSLL2,
830 sizeof(ReentryFnDSLL2));
831 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 20), &ReentryFnDADDiu3,
832 sizeof(ReentryFnDADDiu3));
833}
834
838 unsigned NumTrampolines) {
839
841 reinterpret_cast<uint32_t *>(TrampolineBlockWorkingMem);
842
843 uint64_t HeighestAddr = ((ResolverAddr.getValue() + 0x800080008000) >> 48);
844 uint64_t HeigherAddr = ((ResolverAddr.getValue() + 0x80008000) >> 32);
845 uint64_t HiAddr = ((ResolverAddr.getValue() + 0x8000) >> 16);
846
847 for (unsigned I = 0; I < NumTrampolines; ++I) {
848 Trampolines[10 * I + 0] = 0x03e0c025;
849 Trampolines[10 * I + 1] = 0x3c190000 | (HeighestAddr & 0xFFFF);
850 Trampolines[10 * I + 2] = 0x67390000 | (HeigherAddr & 0xFFFF);
851 Trampolines[10 * I + 3] = 0x0019cc38;
852 Trampolines[10 * I + 4] = 0x67390000 | (HiAddr & 0xFFFF);
853 Trampolines[10 * I + 5] = 0x0019cc38;
854 Trampolines[10 * I + 6] = 0x67390000 | (ResolverAddr.getValue() &
855 0xFFFF);
856 Trampolines[10 * I + 7] = 0x0320f809;
857 Trampolines[10 * I + 8] = 0x00000000;
858 Trampolines[10 * I + 9] = 0x00000000;
859 }
860}
861
865 unsigned NumStubs) {
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
895 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
896 "PointersBlock is out of range");
897
898
899 uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlockWorkingMem);
901
902 for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 8) {
903 uint64_t HeighestAddr = ((PtrAddr + 0x800080008000) >> 48);
904 uint64_t HeigherAddr = ((PtrAddr + 0x80008000) >> 32);
905 uint64_t HiAddr = ((PtrAddr + 0x8000) >> 16);
906 Stub[8 * I + 0] = 0x3c190000 | (HeighestAddr & 0xFFFF);
907 Stub[8 * I + 1] = 0x67390000 | (HeigherAddr & 0xFFFF);
908 Stub[8 * I + 2] = 0x0019cc38;
909 Stub[8 * I + 3] = 0x67390000 | (HiAddr & 0xFFFF);
910 Stub[8 * I + 4] = 0x0019cc38;
911 Stub[8 * I + 5] = 0xdf390000 | (PtrAddr & 0xFFFF);
912 Stub[8 * I + 6] = 0x03200008;
913 Stub[8 * I + 7] = 0x00000000;
914 }
915}
916
921
922 const uint32_t ResolverCode[] = {
923 0xef810113,
924 0x00813023,
925 0x00913423,
926 0x01213823,
927 0x01313c23,
928 0x03413023,
929 0x03513423,
930 0x03613823,
931 0x03713c23,
932 0x05813023,
933 0x05913423,
934 0x05a13823,
935 0x05b13c23,
936 0x06113023,
937 0x06a13423,
938 0x06b13823,
939 0x06c13c23,
940 0x08d13023,
941 0x08e13423,
942 0x08f13823,
943 0x09013c23,
944 0x0b113023,
945 0x0a813427,
946 0x0a913827,
947 0x0b213c27,
948 0x0d313027,
949 0x0d413427,
950 0x0d513827,
951 0x0d613c27,
952 0x0f713027,
953 0x0f813427,
954 0x0f913827,
955 0x0fa13c27,
956 0x11b13027,
957 0x00000517,
958 0x0b053503,
959 0x00030593,
960 0xff458593,
961 0x00000617,
962 0x0a863603,
963 0x000600e7,
964 0x00050293,
965 0x00013403,
966 0x00813483,
967 0x01013903,
968 0x01813983,
969 0x02013a03,
970 0x02813a83,
971 0x03013b03,
972 0x03813b83,
973 0x04013c03,
974 0x04813c83,
975 0x05013d03,
976 0x05813d83,
977 0x06013083,
978 0x06813503,
979 0x07013583,
980 0x07813603,
981 0x08013683,
982 0x08813703,
983 0x09013783,
984 0x09813803,
985 0x0a013883,
986 0x0a813407,
987 0x0b013487,
988 0x0b813907,
989 0x0c013987,
990 0x0c813a07,
991 0x0d013a87,
992 0x0d813b07,
993 0x0e013b87,
994 0x0e813c07,
995 0x0f013c87,
996 0x0f813d07,
997 0x10013d87,
998 0x10810113,
999 0x00028067,
1000 0x12345678,
1001 0x12345678,
1002 0xdeadbeef,
1003 0x98765432,
1004 0xcafef00d
1005 };
1006
1007 const unsigned ReentryCtxAddrOffset = 0x138;
1008 const unsigned ReentryFnAddrOffset = 0x140;
1009
1010 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
1011 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
1013 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
1015}
1016
1020 unsigned NumTrampolines) {
1021
1023
1024 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
1026
1028 reinterpret_cast<uint32_t *>(TrampolineBlockWorkingMem);
1029 for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) {
1030 uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xFFFFF000;
1031 uint32_t Lo12 = OffsetToPtr - Hi20;
1032 Trampolines[4 * I + 0] = 0x00000297 | Hi20;
1033 Trampolines[4 * I + 1] =
1034 0x0002b283 | ((Lo12 & 0xFFF) << 20);
1035 Trampolines[4 * I + 2] = 0x00028367;
1036 Trampolines[4 * I + 3] = 0xdeadface;
1037 }
1038}
1039
1041 char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress,
1042 ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) {
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1068 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
1069 "PointersBlock is out of range");
1070
1071 uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlockWorkingMem);
1072
1073 for (unsigned I = 0; I < NumStubs; ++I) {
1075 PointersBlockTargetAddress - StubsBlockTargetAddress;
1076 uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xFFFFF000;
1077 uint32_t Lo12 = PtrDisplacement - Hi20;
1078 Stub[4 * I + 0] = 0x00000297 | Hi20;
1079 Stub[4 * I + 1] = 0x0002b283 | ((Lo12 & 0xFFF) << 20);
1080 Stub[4 * I + 2] = 0x00028067;
1081 Stub[4 * I + 3] = 0xfeedbeef;
1082 PointersBlockTargetAddress += PointerSize;
1083 StubsBlockTargetAddress += StubSize;
1084 }
1085}
1086
1091
1093 dbgs() << "Writing resolver code to "
1094 << formatv("{0:x16}", ResolverTargetAddress) << "\n";
1095 });
1096
1097 const uint32_t ResolverCode[] = {
1098 0x02fde063,
1099 0x29c00061,
1100 0x29c02064,
1101 0x29c04065,
1102 0x29c06066,
1103 0x29c08067,
1104 0x29c0a068,
1105 0x29c0c069,
1106 0x29c0e06a,
1107 0x29c1006b,
1108 0x2bc12060,
1109 0x2bc14061,
1110 0x2bc16062,
1111 0x2bc18063,
1112 0x2bc1a064,
1113 0x2bc1c065,
1114 0x2bc1e066,
1115 0x2bc20067,
1116 0x1c000004,
1117 0x28c1c084,
1118 0x001501a5,
1119 0x02ffd0a5,
1120 0x1c000006,
1121 0x28c1a0c6,
1122 0x4c0000c1,
1123 0x0015008c,
1124 0x2b820067,
1125 0x2b81e066,
1126 0x2b81c065,
1127 0x2b81a064,
1128 0x2b818063,
1129 0x2b816062,
1130 0x2b814061,
1131 0x2b812060,
1132 0x28c1006b,
1133 0x28c0e06a,
1134 0x28c0c069,
1135 0x28c0a068,
1136 0x28c08067,
1137 0x28c06066,
1138 0x28c04065,
1139 0x28c02064,
1140 0x28c00061,
1141 0x02c22063,
1142 0x4c000180,
1143 0x00000000,
1144 0x01234567,
1145 0xdeedbeef,
1146 0x98765432,
1147 0xcafef00d,
1148 };
1149
1150 const unsigned ReentryCtxAddrOffset = 0xb8;
1151 const unsigned ReentryFnAddrOffset = 0xc0;
1152
1153 memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
1154 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
1156 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
1158}
1159
1163 unsigned NumTrampolines) {
1164
1166 dbgs() << "Writing trampoline code to "
1167 << formatv("{0:x16}", TrampolineBlockTargetAddress) << "\n";
1168 });
1169
1171
1172 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
1174
1176 reinterpret_cast<uint32_t *>(TrampolineBlockWorkingMem);
1177 for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) {
1178 uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xfffff000;
1179 uint32_t Lo12 = OffsetToPtr - Hi20;
1180 Trampolines[4 * I + 0] =
1181 0x1c00000c |
1182 (((Hi20 >> 12) & 0xfffff) << 5);
1183 Trampolines[4 * I + 1] =
1184 0x28c0018c | ((Lo12 & 0xfff) << 10);
1185 Trampolines[4 * I + 2] = 0x4c00018d;
1186 Trampolines[4 * I + 3] = 0x0;
1187 }
1188}
1189
1191 char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress,
1192 ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) {
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1215 dbgs() << "Writing stubs code to "
1216 << formatv("{0:x16}", StubsBlockTargetAddress) << "\n";
1217 });
1219 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
1220 "PointersBlock is out of range");
1221
1222 uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlockWorkingMem);
1223
1224 for (unsigned I = 0; I < NumStubs; ++I) {
1226 PointersBlockTargetAddress - StubsBlockTargetAddress;
1227 uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xfffff000;
1228 uint32_t Lo12 = PtrDisplacement - Hi20;
1229 Stub[4 * I + 0] = 0x1c00000c | (((Hi20 >> 12) & 0xfffff)
1230 << 5);
1231 Stub[4 * I + 1] =
1232 0x28c0018c | ((Lo12 & 0xfff) << 10);
1233 Stub[4 * I + 2] = 0x4c000180;
1234 Stub[4 * I + 3] = 0x0;
1235 PointersBlockTargetAddress += PointerSize;
1236 StubsBlockTargetAddress += StubSize;
1237 }
1238}
1239
1240}
1241}
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)
Definition OrcABISupport.cpp:19
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.
Definition OrcABISupport.cpp:45
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...
Definition OrcABISupport.cpp:136
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.
Definition OrcABISupport.cpp:160
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
Definition OrcABISupport.cpp:405
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...
Definition OrcABISupport.cpp:459
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
Definition OrcABISupport.cpp:473
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.
Definition OrcABISupport.cpp:1087
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
Definition OrcABISupport.cpp:1190
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...
Definition OrcABISupport.cpp:1160
static LLVM_ABI void writeResolverCode(char *ResolverBlockWorkingMem, ExecutorAddr ResolverBlockTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr, bool isBigEndian)
Write the resolver code into the given memory.
Definition OrcABISupport.cpp:512
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
Definition OrcABISupport.cpp:643
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...
Definition OrcABISupport.cpp:618
static LLVM_ABI void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
Definition OrcABISupport.cpp:862
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...
Definition OrcABISupport.cpp:835
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
Definition OrcABISupport.cpp:689
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.
Definition OrcABISupport.cpp:1040
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...
Definition OrcABISupport.cpp:1017
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.
Definition OrcABISupport.cpp:917
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.
Definition OrcABISupport.cpp:217
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...
Definition OrcABISupport.cpp:199
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.
Definition OrcABISupport.cpp:253
static LLVM_ABI void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
Definition OrcABISupport.cpp:327
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.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.