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 ()
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];
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.