LLVM: lib/ExecutionEngine/Orc/COFFPlatform.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

17

19

21

23

24#define DEBUG_TYPE "orc"

25

26using namespace llvm;

29

30namespace llvm {

31namespace orc {

33

43

44}

45}

46}

47namespace {

48

50public:

51 COFFHeaderMaterializationUnit(COFFPlatform &CP,

54 CP(CP) {}

55

56 StringRef getName() const override { return "COFFHeaderMU"; }

57

58 void materialize(std::unique_ptr R) override {

59 auto G = std::make_uniquejitlink::LinkGraph(

60 "", CP.getExecutionSession().getSymbolStringPool(),

61 CP.getExecutionSession().getTargetTriple(), SubtargetFeatures(),

63 auto &HeaderSection = G->createSection("__header", MemProt::Read);

65

66

67 auto &ImageBaseSymbol = G->addDefinedSymbol(

68 HeaderBlock, 0, *R->getInitializerSymbol(), HeaderBlock.getSize(),

69 jitlink::Linkage::Strong, jitlink::Scope::Default, false, true);

70

71 addImageBaseRelocationEdge(HeaderBlock, ImageBaseSymbol);

72

73 CP.getObjectLinkingLayer().emit(std::move(R), std::move(G));

74 }

75

76 void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {}

77

78private:

79 struct HeaderSymbol {

80 const char *Name;

81 uint64_t Offset;

82 };

83

84 struct NTHeader {

86 object::coff_file_header FileHeader;

87 struct PEHeader {

88 object::pe32plus_header Header;

90 } OptionalHeader;

91 };

92

93 struct HeaderBlockContent {

94 object::dos_header DOSHeader;

95 COFFHeaderMaterializationUnit::NTHeader NTHeader;

96 };

97

99 jitlink::Section &HeaderSection) {

100 HeaderBlockContent Hdr = {};

101

102

103 Hdr.DOSHeader.Magic[0] = 'M';

104 Hdr.DOSHeader.Magic[1] = 'Z';

105 Hdr.DOSHeader.AddressOfNewExeHeader =

106 offsetof(HeaderBlockContent, NTHeader);

107 uint32_t PEMagic = *reinterpret_cast<const uint32_t *>(COFF::PEMagic);

108 Hdr.NTHeader.PEMagic = PEMagic;

110

111 switch (G.getTargetTriple().getArch()) {

114 break;

115 default:

117 }

118

119 auto HeaderContent = G.allocateContent(

120 ArrayRef(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));

121

122 return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,

123 0);

124 }

125

126 static void addImageBaseRelocationEdge(jitlink::Block &B,

127 jitlink::Symbol &ImageBase) {

128 auto ImageBaseOffset = offsetof(HeaderBlockContent, NTHeader) +

129 offsetof(NTHeader, OptionalHeader) +

130 offsetof(object::pe32plus_header, ImageBase);

132 }

133

134 static MaterializationUnit::Interface

135 createHeaderInterface(COFFPlatform &MOP,

136 const SymbolStringPtr &HeaderStartSymbol) {

138

140

141 return MaterializationUnit::Interface(std::move(HeaderSymbolFlags),

142 HeaderStartSymbol);

143 }

144

145 COFFPlatform &CP;

146};

147

148}

149

150namespace llvm {

151namespace orc {

152

153Expected<std::unique_ptr>

155 std::unique_ptr OrcRuntimeArchiveBuffer,

157 const char *VCRuntimePath,

158 std::optional RuntimeAliases) {

159

160 auto &ES = ObjLinkingLayer.getExecutionSession();

161

162

163 if (!supportedTarget(ES.getTargetTriple()))

165 ES.getTargetTriple().str(),

167

168 auto &EPC = ES.getExecutorProcessControl();

169

170 auto GeneratorArchive =

172 if (!GeneratorArchive)

173 return GeneratorArchive.takeError();

174

175 std::setstd::string DylibsToPreload;

177 ObjLinkingLayer, nullptr, std::move(*GeneratorArchive),

179 if (!OrcRuntimeArchiveGenerator)

180 return OrcRuntimeArchiveGenerator.takeError();

181

182

183

184

185 auto RuntimeArchive = cantFail(

187

188

189 if (!RuntimeAliases)

191

192

193 if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))

194 return std::move(Err);

195

196 auto &HostFuncJD = ES.createBareJITDylib("$");

197

198

199 if (auto Err = HostFuncJD.define(

201 {EPC.getJITDispatchInfo().JITDispatchFunction,

203 {ES.intern("__orc_rt_jit_dispatch_ctx"),

204 {EPC.getJITDispatchInfo().JITDispatchContext,

206 return std::move(Err);

207

209

210

212 auto P = std::unique_ptr(new COFFPlatform(

213 ObjLinkingLayer, PlatformJD, std::move(*OrcRuntimeArchiveGenerator),

214 std::move(DylibsToPreload), std::move(OrcRuntimeArchiveBuffer),

215 std::move(RuntimeArchive), std::move(LoadDynLibrary), StaticVCRuntime,

216 VCRuntimePath, Err));

217 if (Err)

218 return std::move(Err);

219 return std::move(P);

220}

221

224 const char *OrcRuntimePath,

226 const char *VCRuntimePath,

227 std::optional RuntimeAliases) {

228

230 if (!ArchiveBuffer)

231 return createFileError(OrcRuntimePath, ArchiveBuffer.getError());

232

233 return Create(ObjLinkingLayer, PlatformJD, std::move(*ArchiveBuffer),

234 std::move(LoadDynLibrary), StaticVCRuntime, VCRuntimePath,

235 std::move(RuntimeAliases));

236}

237

239 auto PerJDObj = OrcRuntimeArchive->findSym("__orc_rt_coff_per_jd_marker");

240 if (!PerJDObj)

241 return PerJDObj.takeError();

242

243 if (!*PerJDObj)

246

247 auto Buffer = (*PerJDObj)->getAsBinary();

248 if (!Buffer)

249 return Buffer.takeError();

250

251 return (*Buffer)->getMemoryBufferRef();

252}

253

255 ArrayRef<std::pair<const char *, const char *>> AL) {

256 for (auto &KV : AL) {

257 auto AliasName = ES.intern(KV.first);

258 assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");

259 Aliases[std::move(AliasName)] = {ES.intern(KV.second),

261 }

262}

263

265 if (auto Err = JD.define(std::make_unique(

266 *this, COFFHeaderStartSymbol)))

267 return Err;

268

269 if (auto Err = ES.lookup({&JD}, COFFHeaderStartSymbol).takeError())

270 return Err;

271

272

276 return Err;

277

278 auto PerJDObj = getPerJDObjectFile();

279 if (!PerJDObj)

280 return PerJDObj.takeError();

281

283 if (I)

284 return I.takeError();

285

286 if (auto Err = ObjLinkingLayer.add(

288 return Err;

289

290 if (!Bootstrapping) {

291 auto ImportedLibs = StaticVCRuntime

292 ? VCRuntimeBootstrap->loadStaticVCRuntime(JD)

293 : VCRuntimeBootstrap->loadDynamicVCRuntime(JD);

294 if (!ImportedLibs)

295 return ImportedLibs.takeError();

296 for (auto &Lib : *ImportedLibs)

297 if (auto Err = LoadDynLibrary(JD, Lib))

298 return Err;

299 if (StaticVCRuntime)

300 if (auto Err = VCRuntimeBootstrap->initializeStaticVCRuntime(JD))

301 return Err;

302 }

303

306}

307

309 std::lock_guardstd::mutex Lock(PlatformMutex);

310 auto I = JITDylibToHeaderAddr.find(&JD);

311 if (I != JITDylibToHeaderAddr.end()) {

312 assert(HeaderAddrToJITDylib.count(I->second) &&

313 "HeaderAddrToJITDylib missing entry");

314 HeaderAddrToJITDylib.erase(I->second);

315 JITDylibToHeaderAddr.erase(I);

316 }

318}

319

324 if (!InitSym)

326

327 RegisteredInitSymbols[&JD].add(InitSym,

329

331 dbgs() << "COFFPlatform: Registered init symbol " << *InitSym << " for MU "

333 });

335}

336

340

346

349 static const std::pair<const char *, const char *> RequiredCXXAliases[] = {

350 {"_CxxThrowException", "__orc_rt_coff_cxx_throw_exception"},

351 {"_onexit", "__orc_rt_coff_onexit_per_jd"},

352 {"atexit", "__orc_rt_coff_atexit_per_jd"}};

353

355}

356

359 static const std::pair<const char *, const char *>

360 StandardRuntimeUtilityAliases[] = {

361 {"__orc_rt_run_program", "__orc_rt_coff_run_program"},

362 {"__orc_rt_jit_dlerror", "__orc_rt_coff_jit_dlerror"},

363 {"__orc_rt_jit_dlopen", "__orc_rt_coff_jit_dlopen"},

364 {"__orc_rt_jit_dlupdate", "__orc_rt_coff_jit_dlupdate"},

365 {"__orc_rt_jit_dlclose", "__orc_rt_coff_jit_dlclose"},

366 {"__orc_rt_jit_dlsym", "__orc_rt_coff_jit_dlsym"},

367 {"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}};

368

370 StandardRuntimeUtilityAliases);

371}

372

373bool COFFPlatform::supportedTarget(const Triple &TT) {

374 switch (TT.getArch()) {

376 return true;

377 default:

378 return false;

379 }

380}

381

382COFFPlatform::COFFPlatform(

384 std::unique_ptr OrcRuntimeGenerator,

385 std::setstd::string DylibsToPreload,

386 std::unique_ptr OrcRuntimeArchiveBuffer,

387 std::unique_ptrobject::Archive OrcRuntimeArchive,

388 LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,

389 const char *VCRuntimePath, Error &Err)

390 : ES(ObjLinkingLayer.getExecutionSession()),

391 ObjLinkingLayer(ObjLinkingLayer),

392 LoadDynLibrary(std::move(LoadDynLibrary)),

393 OrcRuntimeArchiveBuffer(std::move(OrcRuntimeArchiveBuffer)),

394 OrcRuntimeArchive(std::move(OrcRuntimeArchive)),

395 StaticVCRuntime(StaticVCRuntime),

396 COFFHeaderStartSymbol(ES.intern("__ImageBase")) {

398

399 Bootstrapping.store(true);

400 ObjLinkingLayer.addPlugin(std::make_unique(*this));

401

402

403 auto VCRT =

405 if (!VCRT) {

406 Err = VCRT.takeError();

407 return;

408 }

409 VCRuntimeBootstrap = std::move(*VCRT);

410

411 auto ImportedLibs =

412 StaticVCRuntime ? VCRuntimeBootstrap->loadStaticVCRuntime(PlatformJD)

413 : VCRuntimeBootstrap->loadDynamicVCRuntime(PlatformJD);

414 if (!ImportedLibs) {

415 Err = ImportedLibs.takeError();

416 return;

417 }

418

419 for (auto &Lib : *ImportedLibs)

420 DylibsToPreload.insert(Lib);

421

422 PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));

423

424

425

427 Err = std::move(E2);

428 return;

429 }

430

431 for (auto& Lib : DylibsToPreload)

432 if (auto E2 = this->LoadDynLibrary(PlatformJD, Lib)) {

433 Err = std::move(E2);

434 return;

435 }

436

437 if (StaticVCRuntime)

438 if (auto E2 = VCRuntimeBootstrap->initializeStaticVCRuntime(PlatformJD)) {

439 Err = std::move(E2);

440 return;

441 }

442

443

444 if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {

445 Err = std::move(E2);

446 return;

447 }

448

449

450

451

452 if (auto E2 = bootstrapCOFFRuntime(PlatformJD)) {

453 Err = std::move(E2);

454 return;

455 }

456

457 Bootstrapping.store(false);

458 JDBootstrapStates.clear();

459}

460

461ExpectedCOFFPlatform::JITDylibDepMap

462COFFPlatform::buildJDDepMap(JITDylib &JD) {

463 return ES.runSessionLocked([&]() -> Expected {

464 JITDylibDepMap JDDepMap;

465

467 while (!Worklist.empty()) {

468 auto CurJD = Worklist.back();

469 Worklist.pop_back();

470

471 auto &DM = JDDepMap[CurJD];

473 DM.reserve(O.size());

474 for (auto &KV : O) {

475 if (KV.first == CurJD)

476 continue;

477 {

478

479 std::lock_guardstd::mutex Lock(PlatformMutex);

480 if (!JITDylibToHeaderAddr.count(KV.first)) {

482 dbgs() << "JITDylib unregistered to COFFPlatform detected in "

483 "LinkOrder: "

484 << CurJD->getName() << "\n";

485 });

486 continue;

487 }

488 }

489 DM.push_back(KV.first);

490

491 if (JDDepMap.try_emplace(KV.first).second)

492 Worklist.push_back(KV.first);

493 }

494 });

495 }

496 return std::move(JDDepMap);

497 });

498}

499

500void COFFPlatform::pushInitializersLoop(PushInitializersSendResultFn SendResult,

502 JITDylibDepMap &JDDepMap) {

504 DenseSet<JITDylib *> Visited({JD.get()});

505 DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;

506 ES.runSessionLocked([&]() {

507 while (!Worklist.empty()) {

508 auto CurJD = Worklist.back();

509 Worklist.pop_back();

510

511 auto RISItr = RegisteredInitSymbols.find(CurJD);

512 if (RISItr != RegisteredInitSymbols.end()) {

513 NewInitSymbols[CurJD] = std::move(RISItr->second);

514 RegisteredInitSymbols.erase(RISItr);

515 }

516

517 for (auto *DepJD : JDDepMap[CurJD])

518 if (Visited.insert(DepJD).second)

519 Worklist.push_back(DepJD);

520 }

521 });

522

523

524

525 if (NewInitSymbols.empty()) {

526

527 COFFJITDylibDepInfoMap DIM;

528 DIM.reserve(JDDepMap.size());

529 for (auto &KV : JDDepMap) {

530 std::lock_guardstd::mutex Lock(PlatformMutex);

531 COFFJITDylibDepInfo DepInfo;

532 DepInfo.reserve(KV.second.size());

533 for (auto &Dep : KV.second) {

534 DepInfo.push_back(JITDylibToHeaderAddr[Dep]);

535 }

536 auto H = JITDylibToHeaderAddr[KV.first];

537 DIM.push_back(std::make_pair(H, std::move(DepInfo)));

538 }

539 SendResult(DIM);

540 return;

541 }

542

543

545 [this, SendResult = std::move(SendResult), &JD,

546 JDDepMap = std::move(JDDepMap)](Error Err) mutable {

547 if (Err)

548 SendResult(std::move(Err));

549 else

550 pushInitializersLoop(std::move(SendResult), JD, JDDepMap);

551 },

552 ES, std::move(NewInitSymbols));

553}

554

555void COFFPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,

558 {

559 std::lock_guardstd::mutex Lock(PlatformMutex);

560 auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);

561 if (I != HeaderAddrToJITDylib.end())

562 JD = I->second;

563 }

564

566 dbgs() << "COFFPlatform::rt_pushInitializers(" << JDHeaderAddr << ") ";

567 if (JD)

568 dbgs() << "pushing initializers for " << JD->getName() << "\n";

569 else

570 dbgs() << "No JITDylib for header address.\n";

571 });

572

573 if (!JD) {

575 formatv("{0:x}", JDHeaderAddr),

577 return;

578 }

579

580 auto JDDepMap = buildJDDepMap(*JD);

581 if (!JDDepMap) {

582 SendResult(JDDepMap.takeError());

583 return;

584 }

585

586 pushInitializersLoop(std::move(SendResult), JD, *JDDepMap);

587}

588

589void COFFPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult,

591 LLVM_DEBUG(dbgs() << "COFFPlatform::rt_lookupSymbol(\"" << Handle << "\")\n");

592

593 JITDylib *JD = nullptr;

594

595 {

596 std::lock_guardstd::mutex Lock(PlatformMutex);

597 auto I = HeaderAddrToJITDylib.find(Handle);

598 if (I != HeaderAddrToJITDylib.end())

599 JD = I->second;

600 }

601

602 if (!JD) {

603 LLVM_DEBUG(dbgs() << " No JITDylib for handle " << Handle << "\n");

605 formatv("{0:x}", Handle),

607 return;

608 }

609

610

611 class RtLookupNotifyComplete {

612 public:

613 RtLookupNotifyComplete(SendSymbolAddressFn &&SendResult)

614 : SendResult(std::move(SendResult)) {}

615 void operator()(Expected Result) {

617 assert(Result->size() == 1 && "Unexpected result map count");

618 SendResult(Result->begin()->second.getAddress());

619 } else {

620 SendResult(Result.takeError());

621 }

622 }

623

624 private:

625 SendSymbolAddressFn SendResult;

626 };

627

628 ES.lookup(

632}

633

634Error COFFPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {

636

637 using LookupSymbolSPSSig =

638 SPSExpected(SPSExecutorAddr, SPSString);

639 WFs[ES.intern("__orc_rt_coff_symbol_lookup_tag")] =

640 ES.wrapAsyncWithSPS(this,

641 &COFFPlatform::rt_lookupSymbol);

642 using PushInitializersSPSSig =

643 SPSExpected(SPSExecutorAddr);

644 WFs[ES.intern("__orc_rt_coff_push_initializers_tag")] =

645 ES.wrapAsyncWithSPS(

646 this, &COFFPlatform::rt_pushInitializers);

647

648 return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));

649}

650

651Error COFFPlatform::runBootstrapInitializers(JDBootstrapState &BState) {

653 if (auto Err =

654 runBootstrapSubsectionInitializers(BState, ".CRT$XIA", ".CRT$XIZ"))

655 return Err;

656

657 if (auto Err = runSymbolIfExists(*BState.JD, "__run_after_c_init"))

658 return Err;

659

660 if (auto Err =

661 runBootstrapSubsectionInitializers(BState, ".CRT$XCA", ".CRT$XCZ"))

662 return Err;

664}

665

666Error COFFPlatform::runBootstrapSubsectionInitializers(JDBootstrapState &BState,

667 StringRef Start,

668 StringRef End) {

669 for (auto &Initializer : BState.Initializers)

670 if (Initializer.first >= Start && Initializer.first <= End &&

671 Initializer.second) {

672 auto Res =

673 ES.getExecutorProcessControl().runAsVoidFunction(Initializer.second);

674 if (!Res)

675 return Res.takeError();

676 }

678}

679

680Error COFFPlatform::bootstrapCOFFRuntime(JITDylib &PlatformJD) {

681

682

685 {

686 {ES.intern("__orc_rt_coff_platform_bootstrap"),

687 &orc_rt_coff_platform_bootstrap},

688 {ES.intern("__orc_rt_coff_platform_shutdown"),

689 &orc_rt_coff_platform_shutdown},

690 {ES.intern("__orc_rt_coff_register_jitdylib"),

691 &orc_rt_coff_register_jitdylib},

692 {ES.intern("__orc_rt_coff_deregister_jitdylib"),

693 &orc_rt_coff_deregister_jitdylib},

694 {ES.intern("__orc_rt_coff_register_object_sections"),

695 &orc_rt_coff_register_object_sections},

696 {ES.intern("__orc_rt_coff_deregister_object_sections"),

697 &orc_rt_coff_deregister_object_sections},

698 }))

699 return Err;

700

701

702 if (auto Err = ES.callSPSWrapper<void()>(orc_rt_coff_platform_bootstrap))

703 return Err;

704

705

706

707 for (auto KV : JDBootstrapStates) {

708 auto &JDBState = KV.second;

709 if (auto Err = ES.callSPSWrapper<void(SPSString, SPSExecutorAddr)>(

710 orc_rt_coff_register_jitdylib, JDBState.JDName,

711 JDBState.HeaderAddr))

712 return Err;

713

714 for (auto &ObjSectionMap : JDBState.ObjectSectionsMaps)

715 if (auto Err = ES.callSPSWrapper<void(SPSExecutorAddr,

717 orc_rt_coff_register_object_sections, JDBState.HeaderAddr,

718 ObjSectionMap, false))

719 return Err;

720 }

721

722

723 for (auto KV : JDBootstrapStates) {

724 auto &JDBState = KV.second;

725 if (auto Err = runBootstrapInitializers(JDBState))

726 return Err;

727 }

728

730}

731

732Error COFFPlatform::runSymbolIfExists(JITDylib &PlatformJD,

733 StringRef SymbolName) {

734 ExecutorAddr jit_function;

737 {{ES.intern(SymbolName), &jit_function}});

738 if (!AfterCLookupErr) {

739 auto Res = ES.getExecutorProcessControl().runAsVoidFunction(jit_function);

740 if (!Res)

741 return Res.takeError();

743 }

744 if (!AfterCLookupErr.isA())

745 return AfterCLookupErr;

748}

749

750void COFFPlatform::COFFPlatformPlugin::modifyPassConfig(

752 jitlink::PassConfiguration &Config) {

753

754 bool IsBootstrapping = CP.Bootstrapping.load();

755

757 if (InitSymbol == CP.COFFHeaderStartSymbol) {

759 [this, &MR, IsBootstrapping](jitlink::LinkGraph &G) {

760 return associateJITDylibHeaderSymbol(G, MR, IsBootstrapping);

761 });

762 return;

763 }

764 Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) {

765 return preserveInitializerSections(G, MR);

766 });

767 }

768

769 if (!IsBootstrapping)

772 return registerObjectPlatformSections(G, JD);

773 });

774 else

777 return registerObjectPlatformSectionsInBootstrap(G, JD);

778 });

779}

780

781Error COFFPlatform::COFFPlatformPlugin::associateJITDylibHeaderSymbol(

782 jitlink::LinkGraph &G, MaterializationResponsibility &MR,

783 bool IsBootstraping) {

784 auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {

785 return *Sym->getName() == *CP.COFFHeaderStartSymbol;

786 });

787 assert(I != G.defined_symbols().end() && "Missing COFF header start symbol");

788

790 std::lock_guardstd::mutex Lock(CP.PlatformMutex);

791 auto HeaderAddr = (*I)->getAddress();

792 CP.JITDylibToHeaderAddr[&JD] = HeaderAddr;

793 CP.HeaderAddrToJITDylib[HeaderAddr] = &JD;

794 if (!IsBootstraping) {

795 G.allocActions().push_back(

797 SPSArgList<SPSString, SPSExecutorAddr>>(

798 CP.orc_rt_coff_register_jitdylib, JD.getName(), HeaderAddr)),

800 CP.orc_rt_coff_deregister_jitdylib, HeaderAddr))});

801 } else {

802 G.allocActions().push_back(

803 {{},

805 CP.orc_rt_coff_deregister_jitdylib, HeaderAddr))});

806 JDBootstrapState BState;

807 BState.JD = &JD;

808 BState.JDName = JD.getName();

809 BState.HeaderAddr = HeaderAddr;

810 CP.JDBootstrapStates.emplace(&JD, BState);

811 }

812

814}

815

816Error COFFPlatform::COFFPlatformPlugin::registerObjectPlatformSections(

817 jitlink::LinkGraph &G, JITDylib &JD) {

818 COFFObjectSectionsMap ObjSecs;

819 auto HeaderAddr = CP.JITDylibToHeaderAddr[&JD];

820 assert(HeaderAddr && "Must be registered jitdylib");

821 for (auto &S : G.sections()) {

822 jitlink::SectionRange Range(S);

823 if (Range.getSize())

824 ObjSecs.push_back(std::make_pair(S.getName().str(), Range.getRange()));

825 }

826

827 G.allocActions().push_back(

829 CP.orc_rt_coff_register_object_sections, HeaderAddr, ObjSecs, true)),

832 CP.orc_rt_coff_deregister_object_sections, HeaderAddr,

833 ObjSecs))});

834

836}

837

838Error COFFPlatform::COFFPlatformPlugin::preserveInitializerSections(

839 jitlink::LinkGraph &G, MaterializationResponsibility &MR) {

840

842

843 jitlink::Symbol *InitSym = nullptr;

844

845 for (auto &InitSection : G.sections()) {

846

848 InitSection.empty())

849 continue;

850

851

852

853 if (!InitSym) {

854 auto &B = **InitSection.blocks().begin();

855 InitSym = &G.addDefinedSymbol(

858 }

859

860

861 for (auto *B : InitSection.blocks()) {

863 continue;

864

865 auto &S = G.addAnonymousSymbol(*B, 0, B->getSize(), false, true);

866 InitSym->getBlock().addEdge(jitlink::Edge::KeepAlive, 0, S, 0);

867 }

868 }

869 }

870

872}

873

874Error COFFPlatform::COFFPlatformPlugin::

875 registerObjectPlatformSectionsInBootstrap(jitlink::LinkGraph &G,

876 JITDylib &JD) {

877 std::lock_guardstd::mutex Lock(CP.PlatformMutex);

878 auto HeaderAddr = CP.JITDylibToHeaderAddr[&JD];

879 COFFObjectSectionsMap ObjSecs;

880 for (auto &S : G.sections()) {

881 jitlink::SectionRange Range(S);

882 if (Range.getSize())

883 ObjSecs.push_back(std::make_pair(S.getName().str(), Range.getRange()));

884 }

885

886 G.allocActions().push_back(

887 {{},

890 CP.orc_rt_coff_deregister_object_sections, HeaderAddr,

891 ObjSecs))});

892

893 auto &BState = CP.JDBootstrapStates[&JD];

894 BState.ObjectSectionsMaps.push_back(std::move(ObjSecs));

895

896

897 for (auto &S : G.sections())

899 for (auto *B : S.blocks()) {

900 if (B->edges_empty())

901 continue;

902 for (auto &E : B->edges())

903 BState.Initializers.push_back(std::make_pair(

904 S.getName().str(), E.getTarget().getAddress() + E.getAddend()));

905 }

906

908}

909

910}

911}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")

#define offsetof(TYPE, MEMBER)

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

static StringRef getName(Value *V)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

Helper for Errors used as out-parameters.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)

Open the specified memory range as a MemoryBuffer.

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

Triple - Helper class for working with autoconf configuration names.

void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)

Add an edge to this block.

const std::string & getName() const

Get the name for this JITLinkDylib.

Block & getBlock()

Return the Block for this Symbol (Symbol must be defined).

static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)

Mediates between COFF initialization and ExecutionSession state.

Error setupJITDylib(JITDylib &JD) override

This method will be called outside the session lock each time a JITDylib is created (unless it is cre...

Definition COFFPlatform.cpp:264

static Expected< std::unique_ptr< COFFPlatform > > Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, std::unique_ptr< MemoryBuffer > OrcRuntimeArchiveBuffer, LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime=false, const char *VCRuntimePath=nullptr, std::optional< SymbolAliasMap > RuntimeAliases=std::nullopt)

Try to create a COFFPlatform instance, adding the ORC runtime to the given JITDylib.

Definition COFFPlatform.cpp:154

unique_function< Error(JITDylib &JD, StringRef DLLFileName)> LoadDynamicLibrary

A function that will be called with the name of dll file that must be loaded.

static ArrayRef< std::pair< const char *, const char * > > standardRuntimeUtilityAliases()

Returns the array of standard runtime utility aliases for COFF.

Definition COFFPlatform.cpp:358

Error teardownJITDylib(JITDylib &JD) override

This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...

Definition COFFPlatform.cpp:308

static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)

Returns an AliasMap containing the default aliases for the COFFPlatform.

Definition COFFPlatform.cpp:341

Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) override

This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...

Definition COFFPlatform.cpp:320

static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()

Returns the array of required CXX aliases.

Definition COFFPlatform.cpp:348

Error notifyRemoving(ResourceTracker &RT) override

This method will be called under the ExecutionSession lock when a ResourceTracker is removed.

Definition COFFPlatform.cpp:337

static LLVM_ABI Expected< std::unique_ptr< COFFVCRuntimeBootstrapper > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, const char *RuntimePath=nullptr)

Try to create a COFFVCRuntimeBootstrapper instance.

static std::unique_ptr< DLLImportDefinitionGenerator > Create(ExecutionSession &ES, ObjectLinkingLayer &L)

Creates a DLLImportDefinitionGenerator instance.

An ExecutionSession represents a running JIT program.

SymbolStringPtr intern(StringRef SymName)

Add a symbol name to the SymbolStringPool and return a pointer to it.

DenseMap< SymbolStringPtr, JITDispatchHandlerFunction > JITDispatchHandlerAssociationMap

A map associating tag names with asynchronous wrapper function implementations in the JIT.

Represents an address in the executor process.

Represents a JIT'd dynamic library.

Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)

Define all symbols provided by the materialization unit to be part of this JITDylib.

LLVM_ABI void addToLinkOrder(const JITDylibSearchOrder &NewLinks)

Append the given JITDylibSearchOrder to the link order for this JITDylib (discarding any elements alr...

GeneratorT & addGenerator(std::unique_ptr< GeneratorT > DefGenerator)

Adds a definition generator to this JITDylib and returns a referenece to it.

LinkGraphLinkingLayer & addPlugin(std::shared_ptr< Plugin > P)

Add a plugin.

Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...

const SymbolStringPtr & getInitializerSymbol() const

Returns the initialization pseudo-symbol, if any.

JITDylib & getTargetJITDylib() const

Returns the target JITDylib that these symbols are being materialized into.

A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...

virtual StringRef getName() const =0

Return the name of this materialization unit.

const SymbolStringPtr & getInitializerSymbol() const

Returns the initialization symbol for this MaterializationUnit (if any).

An ObjectLayer implementation built on JITLink.

static void lookupInitSymbolsAsync(unique_function< void(Error)> OnComplete, ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)

Performs an async lookup for the given symbols in each of the given JITDylibs, calling the given hand...

API to remove / transfer ownership of JIT resources.

JITDylib & getJITDylib() const

Return the JITDylib targeted by this tracker.

static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Create(ObjectLayer &L, std::unique_ptr< MemoryBuffer > ArchiveBuffer, std::unique_ptr< object::Archive > Archive, VisitMembersFunction VisitMembers=VisitMembersFunction(), GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())

Try to create a StaticLibrarySearchGenerator from the given memory buffer and Archive object.

Pointer to a pooled string representing a symbol name.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ IMAGE_FILE_MACHINE_AMD64

static const char PEMagic[]

@ Pointer64

A plain 64-bit pointer value relocation.

LLVM_ABI const char * getGenericEdgeKindName(Edge::Kind K)

Returns the string name of the given generic edge kind, or "unknown" otherwise.

JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)

Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...

std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder

A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.

IntrusiveRefCntPtr< JITDylib > JITDylibSP

std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)

Create a ReExportsMaterializationUnit with the given aliases.

std::unique_ptr< AbsoluteSymbolsMaterializationUnit > absoluteSymbols(SymbolMap Symbols)

Create an AbsoluteSymbolsMaterializationUnit with the given symbols.

@ MatchExportedSymbolsOnly

LLVM_ABI void lookupAndRecordAddrs(unique_function< void(Error)> OnRecorded, ExecutionSession &ES, LookupKind K, const JITDylibSearchOrder &SearchOrder, std::vector< std::pair< SymbolStringPtr, ExecutorAddr * > > Pairs, SymbolLookupFlags LookupFlags=SymbolLookupFlags::RequiredSymbol)

Record addresses of the given symbols in the given ExecutorAddrs.

static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases, ArrayRef< std::pair< const char *, const char * > > AL)

Definition COFFPlatform.cpp:254

LLVM_ABI Expected< MaterializationUnit::Interface > getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer)

Returns a MaterializationUnit::Interface for the object file contained in the given buffer,...

jitlink::Block & createHeaderBlock(MachOPlatform &MOP, const MachOPlatform::HeaderOptions &Opts, JITDylib &JD, jitlink::LinkGraph &G, jitlink::Section &HeaderSection)

LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister

This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...

LLVM_ABI bool isCOFFInitializerSection(StringRef Name)

@ Ready

Emitted to memory, but waiting on transitive dependencies.

DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap

A map of Symbols to (Symbol, Flags) pairs.

DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap

A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

This is an optimization pass for GlobalISel generic memory operations.

Error createFileError(const Twine &F, Error E)

Concatenate a source file path and/or name with an Error.

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

void consumeError(Error Err)

Consume a Error without doing anything.

Implement std::hash so that hash_code can be used in STL containers.

LinkGraphPassList PostAllocationPasses

Post-allocation passes.

LinkGraphPassList PostFixupPasses

Post-fixup passes.

LinkGraphPassList PrePrunePasses

Pre-prune passes.