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.