LLVM 24.0.0git
COFFPlatform.cpp
Go to the documentation of this file.
1//===------- COFFPlatform.cpp - Utilities for executing COFF in Orc -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11
22#include "llvm/Object/COFF.h"
23
25
26#define DEBUG_TYPE "orc"
27
28using namespace llvm;
29using namespace llvm::orc;
30using namespace llvm::orc::shared;
31
32namespace llvm {
33namespace orc {
34namespace shared {
35
45
46} // namespace shared
47} // namespace orc
48} // namespace llvm
49// Controller-interface descriptors for the COFF platform runtime's
50// bootstrap-time SPS wrapper calls. Kept in the .cpp (the COFF platform's
51// private contract with its runtime; the SPS arg types live here too), and in
52// a named namespace so the constexpr Name members -- read only as constants by
53// ProxySpec -- don't trip -Wunused-const-variable.
56 static constexpr SymbolNameSpec Name =
57 SymbolNameSpec::c("__orc_rt_coff_platform_bootstrap");
58 using SPSSig = void();
59};
61 static constexpr SymbolNameSpec Name =
62 SymbolNameSpec::c("__orc_rt_coff_register_jitdylib");
64};
66 static constexpr SymbolNameSpec Name =
67 SymbolNameSpec::c("__orc_rt_coff_register_object_sections");
69};
70} // namespace llvm::orc::coff_sps_ci
71
72// Specs for the call-controller handlers that the COFF platform runtime calls.
74struct LookupSymbol : sps::HandlerSpec<SPSExpected<SPSExecutorAddr>(
75 SPSExecutorAddr, SPSString)> {
76 static constexpr SymbolNameSpec Name =
77 SymbolNameSpec::c("__orc_rt_coff_symbol_lookup_tag");
78};
80 : sps::HandlerSpec<SPSExpected<SPSCOFFJITDylibDepInfoMap>(
81 SPSExecutorAddr)> {
82 static constexpr SymbolNameSpec Name =
83 SymbolNameSpec::c("__orc_rt_coff_push_initializers_tag");
84};
85} // namespace llvm::orc::coff_sps_handlers
86
87namespace {
88
89class COFFHeaderMaterializationUnit : public MaterializationUnit {
90public:
91 COFFHeaderMaterializationUnit(COFFPlatform &CP,
92 const SymbolStringPtr &HeaderStartSymbol)
93 : MaterializationUnit(createHeaderInterface(CP, HeaderStartSymbol)),
94 CP(CP) {}
95
96 StringRef getName() const override { return "COFFHeaderMU"; }
97
98 void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
99 auto G = std::make_unique<jitlink::LinkGraph>(
100 "<COFFHeaderMU>", CP.getExecutionSession().getSymbolStringPool(),
101 CP.getExecutionSession().getTargetTriple(),
102 CP.getExecutionSession().getTargetTriple().getArchPointerBitWidth() / 8,
104 auto &HeaderSection = G->createSection("__header", MemProt::Read);
105 auto &HeaderBlock = createHeaderBlock(*G, HeaderSection);
106
107 // Init symbol is __ImageBase symbol.
108 auto &ImageBaseSymbol = G->addDefinedSymbol(
109 HeaderBlock, 0, *R->getInitializerSymbol(), HeaderBlock.getSize(),
111
112 addImageBaseRelocationEdge(HeaderBlock, ImageBaseSymbol);
113
114 CP.getObjectLinkingLayer().emit(std::move(R), std::move(G));
115 }
116
117 void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {}
118
119private:
120 struct HeaderSymbol {
121 const char *Name;
122 uint64_t Offset;
123 };
124
125 struct NTHeader {
126 support::ulittle32_t PEMagic;
127 object::coff_file_header FileHeader;
128 struct PEHeader {
129 object::pe32plus_header Header;
130 object::data_directory DataDirectory[COFF::NUM_DATA_DIRECTORIES + 1];
131 } OptionalHeader;
132 };
133
134 struct HeaderBlockContent {
135 object::dos_header DOSHeader;
136 COFFHeaderMaterializationUnit::NTHeader NTHeader;
137 };
138
139 static jitlink::Block &createHeaderBlock(jitlink::LinkGraph &G,
140 jitlink::Section &HeaderSection) {
141 HeaderBlockContent Hdr = {};
142
143 // Set up magic
144 Hdr.DOSHeader.Magic[0] = 'M';
145 Hdr.DOSHeader.Magic[1] = 'Z';
146 Hdr.DOSHeader.AddressOfNewExeHeader =
147 offsetof(HeaderBlockContent, NTHeader);
148 uint32_t PEMagic = *reinterpret_cast<const uint32_t *>(COFF::PEMagic);
149 Hdr.NTHeader.PEMagic = PEMagic;
150 Hdr.NTHeader.OptionalHeader.Header.Magic = COFF::PE32Header::PE32_PLUS;
151
152 switch (G.getTargetTriple().getArch()) {
153 case Triple::x86_64:
154 Hdr.NTHeader.FileHeader.Machine = COFF::IMAGE_FILE_MACHINE_AMD64;
155 break;
156 default:
157 llvm_unreachable("Unrecognized architecture");
158 }
159
160 auto HeaderContent = G.allocateContent(
161 ArrayRef<char>(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));
162
163 return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,
164 0);
165 }
166
167 static void addImageBaseRelocationEdge(jitlink::Block &B,
168 jitlink::Symbol &ImageBase) {
169 auto ImageBaseOffset = offsetof(HeaderBlockContent, NTHeader) +
170 offsetof(NTHeader, OptionalHeader) +
171 offsetof(object::pe32plus_header, ImageBase);
172 B.addEdge(jitlink::x86_64::Pointer64, ImageBaseOffset, ImageBase, 0);
173 }
174
175 static MaterializationUnit::Interface
176 createHeaderInterface(COFFPlatform &MOP,
177 const SymbolStringPtr &HeaderStartSymbol) {
178 SymbolFlagsMap HeaderSymbolFlags;
179
180 HeaderSymbolFlags[HeaderStartSymbol] = JITSymbolFlags::Exported;
181
182 return MaterializationUnit::Interface(std::move(HeaderSymbolFlags),
183 HeaderStartSymbol);
184 }
185
186 COFFPlatform &CP;
187};
188
189} // end anonymous namespace
190
191namespace llvm {
192namespace orc {
193
194Expected<std::unique_ptr<COFFPlatform>>
196 std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
197 LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
198 const char *VCRuntimePath,
199 std::optional<SymbolAliasMap> RuntimeAliases) {
200
201 auto &ES = ObjLinkingLayer.getExecutionSession();
202
203 // If the target is not supported then bail out immediately.
204 if (!supportedTarget(ES.getTargetTriple()))
205 return make_error<StringError>("Unsupported COFFPlatform triple: " +
206 ES.getTargetTriple().str(),
208
209 auto GeneratorArchive =
210 object::Archive::create(OrcRuntimeArchiveBuffer->getMemBufferRef());
211 if (!GeneratorArchive)
212 return GeneratorArchive.takeError();
213
214 std::set<std::string> DylibsToPreload;
215 auto OrcRuntimeArchiveGenerator = StaticLibraryDefinitionGenerator::Create(
216 ObjLinkingLayer, nullptr, std::move(*GeneratorArchive),
217 COFFImportFileScanner(DylibsToPreload));
218 if (!OrcRuntimeArchiveGenerator)
219 return OrcRuntimeArchiveGenerator.takeError();
220
221 // We need a second instance of the archive (for now) for the Platform. We
222 // can `cantFail` this call, since if it were going to fail it would have
223 // failed above.
224 auto RuntimeArchive = cantFail(
225 object::Archive::create(OrcRuntimeArchiveBuffer->getMemBufferRef()));
226
227 // Create default aliases if the caller didn't supply any.
228 if (!RuntimeAliases)
229 RuntimeAliases = standardPlatformAliases(ES);
230
231 // Define the aliases.
232 if (auto Err = PlatformJD.define(symbolAliases(std::move(*RuntimeAliases))))
233 return std::move(Err);
234
235 {
236 // Add JIT dispatch reexports from bootstrap JITDylib.
237 MangleAndInterner Mangle(ES);
238 auto Exports = buildSimpleReexportsAliasMap(
239 ES.getBootstrapJITDylib(),
240 {{Mangle(rt::DispatchName), Mangle(rt::DispatchCtxName)}});
241 if (!Exports)
242 return Exports.takeError();
243 if (auto Err =
244 PlatformJD.define(reexports(ES.getBootstrapJITDylib(), *Exports)))
245 return Err;
246 }
247
248 // Create the instance.
249 Error Err = Error::success();
250 auto P = std::unique_ptr<COFFPlatform>(new COFFPlatform(
251 ObjLinkingLayer, PlatformJD, std::move(*OrcRuntimeArchiveGenerator),
252 std::move(DylibsToPreload), std::move(OrcRuntimeArchiveBuffer),
253 std::move(RuntimeArchive), std::move(LoadDynLibrary), StaticVCRuntime,
254 VCRuntimePath, Err));
255 if (Err)
256 return std::move(Err);
257 return std::move(P);
258}
259
262 const char *OrcRuntimePath,
263 LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
264 const char *VCRuntimePath,
265 std::optional<SymbolAliasMap> RuntimeAliases) {
266
267 auto ArchiveBuffer = MemoryBuffer::getFile(OrcRuntimePath);
268 if (!ArchiveBuffer)
269 return createFileError(OrcRuntimePath, ArchiveBuffer.getError());
270
271 return Create(ObjLinkingLayer, PlatformJD, std::move(*ArchiveBuffer),
272 std::move(LoadDynLibrary), StaticVCRuntime, VCRuntimePath,
273 std::move(RuntimeAliases));
274}
275
276Expected<MemoryBufferRef> COFFPlatform::getPerJDObjectFile() {
277 auto PerJDObj = OrcRuntimeArchive->findSym("__orc_rt_coff_per_jd_marker");
278 if (!PerJDObj)
279 return PerJDObj.takeError();
280
281 if (!*PerJDObj)
282 return make_error<StringError>("Could not find per jd object file",
284
285 auto Buffer = (*PerJDObj)->getAsBinary();
286 if (!Buffer)
287 return Buffer.takeError();
288
289 return (*Buffer)->getMemoryBufferRef();
290}
291
293 ArrayRef<std::pair<const char *, const char *>> AL) {
294 for (auto &KV : AL) {
295 auto AliasName = ES.intern(KV.first);
296 assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");
297 Aliases[std::move(AliasName)] = {ES.intern(KV.second),
299 }
300}
301
303 if (auto Err = JD.define(std::make_unique<COFFHeaderMaterializationUnit>(
304 *this, COFFHeaderStartSymbol)))
305 return Err;
306
307 if (auto Err = ES.lookup({&JD}, COFFHeaderStartSymbol).takeError())
308 return Err;
309
310 // Define the CXX aliases.
311 SymbolAliasMap CXXAliases;
312 addAliases(ES, CXXAliases, requiredCXXAliases());
313 if (auto Err = JD.define(symbolAliases(std::move(CXXAliases))))
314 return Err;
315
316 auto PerJDObj = getPerJDObjectFile();
317 if (!PerJDObj)
318 return PerJDObj.takeError();
319
320 auto I = getObjectFileInterface(ES, *PerJDObj);
321 if (!I)
322 return I.takeError();
323
324 if (auto Err = ObjLinkingLayer.add(
325 JD, MemoryBuffer::getMemBuffer(*PerJDObj, false), std::move(*I)))
326 return Err;
327
328 if (!Bootstrapping) {
329 auto ImportedLibs = StaticVCRuntime
330 ? VCRuntimeBootstrap->loadStaticVCRuntime(JD)
331 : VCRuntimeBootstrap->loadDynamicVCRuntime(JD);
332 if (!ImportedLibs)
333 return ImportedLibs.takeError();
334 for (auto &Lib : *ImportedLibs)
335 if (auto Err = LoadDynLibrary(JD, Lib))
336 return Err;
337 if (StaticVCRuntime)
338 if (auto Err = VCRuntimeBootstrap->initializeStaticVCRuntime(JD))
339 return Err;
340 }
341
342 JD.addGenerator(DLLImportDefinitionGenerator::Create(ES, ObjLinkingLayer));
343 return Error::success();
344}
345
347 std::lock_guard<std::mutex> Lock(PlatformMutex);
348 auto I = JITDylibToHeaderAddr.find(&JD);
349 if (I != JITDylibToHeaderAddr.end()) {
350 assert(HeaderAddrToJITDylib.count(I->second) &&
351 "HeaderAddrToJITDylib missing entry");
352 HeaderAddrToJITDylib.erase(I->second);
353 JITDylibToHeaderAddr.erase(I);
354 }
355 return Error::success();
356}
357
359 const MaterializationUnit &MU) {
360 auto &JD = RT.getJITDylib();
361 const auto &InitSym = MU.getInitializerSymbol();
362 if (!InitSym)
363 return Error::success();
364
365 RegisteredInitSymbols[&JD].add(InitSym,
367
368 LLVM_DEBUG({
369 dbgs() << "COFFPlatform: Registered init symbol " << *InitSym << " for MU "
370 << MU.getName() << "\n";
371 });
372 return Error::success();
373}
374
378
384
387 static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
388 {"_CxxThrowException", "__orc_rt_coff_cxx_throw_exception"},
389 {"_onexit", "__orc_rt_coff_onexit_per_jd"},
390 {"atexit", "__orc_rt_coff_atexit_per_jd"}};
391
392 return ArrayRef<std::pair<const char *, const char *>>(RequiredCXXAliases);
393}
394
397 static const std::pair<const char *, const char *>
398 StandardRuntimeUtilityAliases[] = {
399 {"__orc_rt_run_program", "__orc_rt_coff_run_program"},
400 {"__orc_rt_jit_dlerror", "__orc_rt_coff_jit_dlerror"},
401 {"__orc_rt_jit_dlopen", "__orc_rt_coff_jit_dlopen"},
402 {"__orc_rt_jit_dlupdate", "__orc_rt_coff_jit_dlupdate"},
403 {"__orc_rt_jit_dlclose", "__orc_rt_coff_jit_dlclose"},
404 {"__orc_rt_jit_dlsym", "__orc_rt_coff_jit_dlsym"},
405 {"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}};
406
408 StandardRuntimeUtilityAliases);
409}
410
411bool COFFPlatform::supportedTarget(const Triple &TT) {
412 switch (TT.getArch()) {
413 case Triple::x86_64:
414 return true;
415 default:
416 return false;
417 }
418}
419
420COFFPlatform::COFFPlatform(
421 ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
422 std::unique_ptr<StaticLibraryDefinitionGenerator> OrcRuntimeGenerator,
423 std::set<std::string> DylibsToPreload,
424 std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
425 std::unique_ptr<object::Archive> OrcRuntimeArchive,
426 LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
427 const char *VCRuntimePath, Error &Err)
428 : ES(ObjLinkingLayer.getExecutionSession()),
429 ObjLinkingLayer(ObjLinkingLayer),
430 LoadDynLibrary(std::move(LoadDynLibrary)),
431 OrcRuntimeArchiveBuffer(std::move(OrcRuntimeArchiveBuffer)),
432 OrcRuntimeArchive(std::move(OrcRuntimeArchive)),
433 StaticVCRuntime(StaticVCRuntime),
434 COFFHeaderStartSymbol(ES.intern("__ImageBase")) {
436
437 Bootstrapping.store(true);
438 ObjLinkingLayer.addPlugin(std::make_unique<COFFPlatformPlugin>(*this));
439
440 // Load vc runtime
441 auto VCRT =
442 COFFVCRuntimeBootstrapper::Create(ES, ObjLinkingLayer, VCRuntimePath);
443 if (!VCRT) {
444 Err = VCRT.takeError();
445 return;
446 }
447 VCRuntimeBootstrap = std::move(*VCRT);
448
449 auto ImportedLibs =
450 StaticVCRuntime ? VCRuntimeBootstrap->loadStaticVCRuntime(PlatformJD)
451 : VCRuntimeBootstrap->loadDynamicVCRuntime(PlatformJD);
452 if (!ImportedLibs) {
453 Err = ImportedLibs.takeError();
454 return;
455 }
456
457 for (auto &Lib : *ImportedLibs)
458 DylibsToPreload.insert(Lib);
459
460 PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
461
462 // PlatformJD hasn't been set up by the platform yet (since we're creating
463 // the platform now), so set it up.
464 if (auto E2 = setupJITDylib(PlatformJD)) {
465 Err = std::move(E2);
466 return;
467 }
468
469 for (auto& Lib : DylibsToPreload)
470 if (auto E2 = this->LoadDynLibrary(PlatformJD, Lib)) {
471 Err = std::move(E2);
472 return;
473 }
474
475 if (StaticVCRuntime)
476 if (auto E2 = VCRuntimeBootstrap->initializeStaticVCRuntime(PlatformJD)) {
477 Err = std::move(E2);
478 return;
479 }
480
481 // Associate wrapper function tags with JIT-side function implementations.
482 if (auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {
483 Err = std::move(E2);
484 return;
485 }
486
487 // Lookup addresses of runtime functions callable by the platform,
488 // call the platform bootstrap function to initialize the platform-state
489 // object in the executor.
490 if (auto E2 = bootstrapCOFFRuntime(PlatformJD)) {
491 Err = std::move(E2);
492 return;
493 }
494
495 Bootstrapping.store(false);
496 JDBootstrapStates.clear();
497}
498
499Expected<COFFPlatform::JITDylibDepMap>
500COFFPlatform::buildJDDepMap(JITDylib &JD) {
501 return ES.runSessionLocked([&]() -> Expected<JITDylibDepMap> {
502 JITDylibDepMap JDDepMap;
503
504 SmallVector<JITDylib *, 16> Worklist({&JD});
505 while (!Worklist.empty()) {
506 auto CurJD = Worklist.back();
507 Worklist.pop_back();
508
509 auto &DM = JDDepMap[CurJD];
510 CurJD->withLinkOrderDo([&](const JITDylibSearchOrder &O) {
511 DM.reserve(O.size());
512 for (auto &KV : O) {
513 if (KV.first == CurJD)
514 continue;
515 {
516 // Bare jitdylibs not known to the platform
517 std::lock_guard<std::mutex> Lock(PlatformMutex);
518 if (!JITDylibToHeaderAddr.count(KV.first)) {
519 LLVM_DEBUG({
520 dbgs() << "JITDylib unregistered to COFFPlatform detected in "
521 "LinkOrder: "
522 << CurJD->getName() << "\n";
523 });
524 continue;
525 }
526 }
527 DM.push_back(KV.first);
528 // Push unvisited entry.
529 if (JDDepMap.try_emplace(KV.first).second)
530 Worklist.push_back(KV.first);
531 }
532 });
533 }
534 return std::move(JDDepMap);
535 });
536}
537
538void COFFPlatform::pushInitializersLoop(PushInitializersSendResultFn SendResult,
539 JITDylibSP JD,
540 JITDylibDepMap &JDDepMap) {
541 SmallVector<JITDylib *, 16> Worklist({JD.get()});
542 DenseSet<JITDylib *> Visited({JD.get()});
543 DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;
544 ES.runSessionLocked([&]() {
545 while (!Worklist.empty()) {
546 auto CurJD = Worklist.back();
547 Worklist.pop_back();
548
549 auto RISItr = RegisteredInitSymbols.find(CurJD);
550 if (RISItr != RegisteredInitSymbols.end()) {
551 NewInitSymbols[CurJD] = std::move(RISItr->second);
552 RegisteredInitSymbols.erase(RISItr);
553 }
554
555 for (auto *DepJD : JDDepMap[CurJD])
556 if (Visited.insert(DepJD).second)
557 Worklist.push_back(DepJD);
558 }
559 });
560
561 // If there are no further init symbols to look up then send the link order
562 // (as a list of header addresses) to the caller.
563 if (NewInitSymbols.empty()) {
564 // Build the dep info map to return.
565 COFFJITDylibDepInfoMap DIM;
566 DIM.reserve(JDDepMap.size());
567 for (auto &KV : JDDepMap) {
568 std::lock_guard<std::mutex> Lock(PlatformMutex);
569 COFFJITDylibDepInfo DepInfo;
570 DepInfo.reserve(KV.second.size());
571 for (auto &Dep : KV.second) {
572 DepInfo.push_back(JITDylibToHeaderAddr[Dep]);
573 }
574 auto H = JITDylibToHeaderAddr[KV.first];
575 DIM.push_back(std::make_pair(H, std::move(DepInfo)));
576 }
577 SendResult(DIM);
578 return;
579 }
580
581 // Otherwise issue a lookup and re-run this phase when it completes.
583 [this, SendResult = std::move(SendResult), &JD,
584 JDDepMap = std::move(JDDepMap)](Error Err) mutable {
585 if (Err)
586 SendResult(std::move(Err));
587 else
588 pushInitializersLoop(std::move(SendResult), JD, JDDepMap);
589 },
590 ES, std::move(NewInitSymbols));
591}
592
593void COFFPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
594 ExecutorAddr JDHeaderAddr) {
595 JITDylibSP JD;
596 {
597 std::lock_guard<std::mutex> Lock(PlatformMutex);
598 auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
599 if (I != HeaderAddrToJITDylib.end())
600 JD = I->second;
601 }
602
603 LLVM_DEBUG({
604 dbgs() << "COFFPlatform::rt_pushInitializers(" << JDHeaderAddr << ") ";
605 if (JD)
606 dbgs() << "pushing initializers for " << JD->getName() << "\n";
607 else
608 dbgs() << "No JITDylib for header address.\n";
609 });
610
611 if (!JD) {
612 SendResult(make_error<StringError>("No JITDylib with header addr " +
613 formatv("{0:x}", JDHeaderAddr),
615 return;
616 }
617
618 auto JDDepMap = buildJDDepMap(*JD);
619 if (!JDDepMap) {
620 SendResult(JDDepMap.takeError());
621 return;
622 }
623
624 pushInitializersLoop(std::move(SendResult), JD, *JDDepMap);
625}
626
627void COFFPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult,
628 ExecutorAddr Handle, StringRef SymbolName) {
629 LLVM_DEBUG(dbgs() << "COFFPlatform::rt_lookupSymbol(\"" << Handle << "\")\n");
630
631 JITDylib *JD = nullptr;
632
633 {
634 std::lock_guard<std::mutex> Lock(PlatformMutex);
635 auto I = HeaderAddrToJITDylib.find(Handle);
636 if (I != HeaderAddrToJITDylib.end())
637 JD = I->second;
638 }
639
640 if (!JD) {
641 LLVM_DEBUG(dbgs() << " No JITDylib for handle " << Handle << "\n");
642 SendResult(make_error<StringError>("No JITDylib associated with handle " +
643 formatv("{0:x}", Handle),
645 return;
646 }
647
648 // Use functor class to work around XL build compiler issue on AIX.
649 class RtLookupNotifyComplete {
650 public:
651 RtLookupNotifyComplete(SendSymbolAddressFn &&SendResult)
652 : SendResult(std::move(SendResult)) {}
653 void operator()(Expected<SymbolMap> Result) {
654 if (Result) {
655 assert(Result->size() == 1 && "Unexpected result map count");
656 SendResult(Result->begin()->second.getAddress());
657 } else {
658 SendResult(Result.takeError());
659 }
660 }
661
662 private:
663 SendSymbolAddressFn SendResult;
664 };
665
666 ES.lookup(
668 SymbolLookupSet(ES.intern(SymbolName)), SymbolState::Ready,
669 RtLookupNotifyComplete(std::move(SendResult)), NoDependenciesToRegister);
670}
671
672Error COFFPlatform::associateRuntimeSupportFunctions(JITDylib &PlatformJD) {
673 return ES.registerCallControllerHandlers(
674 PlatformJD,
676 this, &COFFPlatform::rt_lookupSymbol),
678 this, &COFFPlatform::rt_pushInitializers));
679}
680
681Error COFFPlatform::runBootstrapInitializers(JDBootstrapState &BState) {
682 llvm::sort(BState.Initializers);
683 if (auto Err =
684 runBootstrapSubsectionInitializers(BState, ".CRT$XIA", ".CRT$XIZ"))
685 return Err;
686
687 if (auto Err = runSymbolIfExists(*BState.JD, "__run_after_c_init"))
688 return Err;
689
690 if (auto Err =
691 runBootstrapSubsectionInitializers(BState, ".CRT$XCA", ".CRT$XCZ"))
692 return Err;
693 return Error::success();
694}
695
696Error COFFPlatform::runBootstrapSubsectionInitializers(JDBootstrapState &BState,
697 StringRef Start,
698 StringRef End) {
699 CallInt32VoidProxy CallInitializer;
700 if (auto Err = lookupAndApply(
701 ES.getBootstrapJITDylib(),
702 {recordProxy<sps::CallInt32VoidProxySpec>(&CallInitializer)}))
703 return Err;
704 for (auto &Initializer : BState.Initializers)
705 if (Initializer.first >= Start && Initializer.first <= End &&
706 Initializer.second) {
707 auto Res = CallInitializer(ES, Initializer.second);
708 if (!Res)
709 return Res.takeError();
710 }
711 return Error::success();
712}
713
714Error COFFPlatform::bootstrapCOFFRuntime(JITDylib &PlatformJD) {
715 // Lookup of runtime symbols causes the collection of initializers if
716 // it's static linking setting.
717 if (auto Err = lookupAndApply(
718 PlatformJD,
719 {recordAddr(SymbolNameSpec::c("__orc_rt_coff_platform_bootstrap"),
720 &orc_rt_coff_platform_bootstrap),
721 recordAddr(SymbolNameSpec::c("__orc_rt_coff_platform_shutdown"),
722 &orc_rt_coff_platform_shutdown),
723 recordAddr(SymbolNameSpec::c("__orc_rt_coff_register_jitdylib"),
724 &orc_rt_coff_register_jitdylib),
725 recordAddr(SymbolNameSpec::c("__orc_rt_coff_deregister_jitdylib"),
726 &orc_rt_coff_deregister_jitdylib),
728 SymbolNameSpec::c("__orc_rt_coff_register_object_sections"),
729 &orc_rt_coff_register_object_sections),
731 SymbolNameSpec::c("__orc_rt_coff_deregister_object_sections"),
732 &orc_rt_coff_deregister_object_sections)}))
733 return Err;
734
735 // These runtime entry points are held as addresses because their primary use
736 // is as alloc-action tags (see the register/deregister sites below). The
737 // direct dispatches here are a bootstrap-time artifact, so rather than
738 // holding proxies as members we build them over the resolved addresses.
739 // TODO: drop these dispatches once bootstrap no longer needs them.
740 using PlatformBootstrapProxy = Proxy<void()>;
741 using RegisterJITDylibProxy = Proxy<void(std::string, ExecutorAddr)>;
742 using RegisterObjectSectionsProxy =
743 Proxy<void(ExecutorAddr, COFFObjectSectionsMap, bool)>;
744 using sps::ProxySpec;
745
746 PlatformBootstrapProxy PlatformBootstrap(
747 ProxySpec<coff_sps_ci::PlatformBootstrap>::dispatch,
748 orc_rt_coff_platform_bootstrap);
749 RegisterJITDylibProxy RegisterJITDylib(
750 ProxySpec<coff_sps_ci::RegisterJITDylib>::dispatch,
751 orc_rt_coff_register_jitdylib);
752 RegisterObjectSectionsProxy RegisterObjectSections(
753 ProxySpec<coff_sps_ci::RegisterObjectSections>::dispatch,
754 orc_rt_coff_register_object_sections);
755
756 // Call bootstrap functions
757 if (auto Err = PlatformBootstrap(ES))
758 return Err;
759
760 // Do the pending jitdylib registration actions that we couldn't do
761 // because orc runtime was not linked fully.
762 for (auto KV : JDBootstrapStates) {
763 auto &JDBState = KV.second;
764 if (auto Err = RegisterJITDylib(ES, JDBState.JDName, JDBState.HeaderAddr))
765 return Err;
766
767 for (auto &ObjSectionMap : JDBState.ObjectSectionsMaps)
768 if (auto Err = RegisterObjectSections(ES, JDBState.HeaderAddr,
769 ObjSectionMap, false))
770 return Err;
771 }
772
773 // Run static initializers collected in bootstrap stage.
774 for (auto KV : JDBootstrapStates) {
775 auto &JDBState = KV.second;
776 if (auto Err = runBootstrapInitializers(JDBState))
777 return Err;
778 }
779
780 return Error::success();
781}
782
783Error COFFPlatform::runSymbolIfExists(JITDylib &PlatformJD,
784 StringRef SymbolName) {
785 ExecutorAddr TargetFn;
786 if (auto Err = lookupAndApply(
787 PlatformJD, {recordAddr(SymbolNameSpec::c(SymbolName), &TargetFn,
789 return Err;
790 if (!TargetFn)
791 return Error::success(); // No target function.
792
793 CallInt32VoidProxy CallFn;
794 if (auto Err =
795 lookupAndApply(ES.getBootstrapJITDylib(),
796 {recordProxy<sps::CallInt32VoidProxySpec>(&CallFn)}))
797 return Err;
798
799 return CallFn(ES, TargetFn).takeError();
800}
801
802void COFFPlatform::COFFPlatformPlugin::modifyPassConfig(
803 MaterializationResponsibility &MR, jitlink::LinkGraph &LG,
804 jitlink::PassConfiguration &Config) {
805
806 bool IsBootstrapping = CP.Bootstrapping.load();
807
808 if (auto InitSymbol = MR.getInitializerSymbol()) {
809 if (InitSymbol == CP.COFFHeaderStartSymbol) {
810 Config.PostAllocationPasses.push_back(
811 [this, &MR, IsBootstrapping](jitlink::LinkGraph &G) {
812 return associateJITDylibHeaderSymbol(G, MR, IsBootstrapping);
813 });
814 return;
815 }
816 Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) {
817 return preserveInitializerSections(G, MR);
818 });
819 }
820
821 if (!IsBootstrapping)
822 Config.PostFixupPasses.push_back(
823 [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
824 return registerObjectPlatformSections(G, JD);
825 });
826 else
827 Config.PostFixupPasses.push_back(
828 [this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
829 return registerObjectPlatformSectionsInBootstrap(G, JD);
830 });
831}
832
833Error COFFPlatform::COFFPlatformPlugin::associateJITDylibHeaderSymbol(
834 jitlink::LinkGraph &G, MaterializationResponsibility &MR,
835 bool IsBootstraping) {
836 auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
837 return *Sym->getName() == *CP.COFFHeaderStartSymbol;
838 });
839 assert(I != G.defined_symbols().end() && "Missing COFF header start symbol");
840
841 auto &JD = MR.getTargetJITDylib();
842 std::lock_guard<std::mutex> Lock(CP.PlatformMutex);
843 auto HeaderAddr = (*I)->getAddress();
844 CP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
845 CP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
846 if (!IsBootstraping) {
847 G.allocActions().push_back(
849 SPSArgList<SPSString, SPSExecutorAddr>>(
850 CP.orc_rt_coff_register_jitdylib, JD.getName(), HeaderAddr)),
851 cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
852 CP.orc_rt_coff_deregister_jitdylib, HeaderAddr))});
853 } else {
854 G.allocActions().push_back(
855 {{},
856 cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
857 CP.orc_rt_coff_deregister_jitdylib, HeaderAddr))});
858 JDBootstrapState BState;
859 BState.JD = &JD;
860 BState.JDName = JD.getName();
861 BState.HeaderAddr = HeaderAddr;
862 CP.JDBootstrapStates.emplace(&JD, BState);
863 }
864
865 return Error::success();
866}
867
868Error COFFPlatform::COFFPlatformPlugin::registerObjectPlatformSections(
869 jitlink::LinkGraph &G, JITDylib &JD) {
870 COFFObjectSectionsMap ObjSecs;
871 auto HeaderAddr = CP.JITDylibToHeaderAddr[&JD];
872 assert(HeaderAddr && "Must be registered jitdylib");
873 for (auto &S : G.sections()) {
874 jitlink::SectionRange Range(S);
875 if (Range.getSize())
876 ObjSecs.push_back(std::make_pair(S.getName().str(), Range.getRange()));
877 }
878
879 G.allocActions().push_back(
881 CP.orc_rt_coff_register_object_sections, HeaderAddr, ObjSecs, true)),
882 cantFail(
884 CP.orc_rt_coff_deregister_object_sections, HeaderAddr,
885 ObjSecs))});
886
887 return Error::success();
888}
889
890Error COFFPlatform::COFFPlatformPlugin::preserveInitializerSections(
891 jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
892
893 if (const auto &InitSymName = MR.getInitializerSymbol()) {
894
895 jitlink::Symbol *InitSym = nullptr;
896
897 for (auto &InitSection : G.sections()) {
898 // Skip non-init sections.
899 if (!isCOFFInitializerSection(InitSection.getName()) ||
900 InitSection.empty())
901 continue;
902
903 // Create the init symbol if it has not been created already and attach it
904 // to the first block.
905 if (!InitSym) {
906 auto &B = **InitSection.blocks().begin();
907 InitSym = &G.addDefinedSymbol(
908 B, 0, *InitSymName, B.getSize(), jitlink::Linkage::Strong,
910 }
911
912 // Add keep-alive edges to anonymous symbols in all other init blocks.
913 for (auto *B : InitSection.blocks()) {
914 if (B == &InitSym->getBlock())
915 continue;
916
917 auto &S = G.addAnonymousSymbol(*B, 0, B->getSize(), false, true);
918 InitSym->getBlock().addEdge(jitlink::Edge::KeepAlive, 0, S, 0);
919 }
920 }
921 }
922
923 return Error::success();
924}
925
926Error COFFPlatform::COFFPlatformPlugin::
927 registerObjectPlatformSectionsInBootstrap(jitlink::LinkGraph &G,
928 JITDylib &JD) {
929 std::lock_guard<std::mutex> Lock(CP.PlatformMutex);
930 auto HeaderAddr = CP.JITDylibToHeaderAddr[&JD];
931 COFFObjectSectionsMap ObjSecs;
932 for (auto &S : G.sections()) {
933 jitlink::SectionRange Range(S);
934 if (Range.getSize())
935 ObjSecs.push_back(std::make_pair(S.getName().str(), Range.getRange()));
936 }
937
938 G.allocActions().push_back(
939 {{},
940 cantFail(
942 CP.orc_rt_coff_deregister_object_sections, HeaderAddr,
943 ObjSecs))});
944
945 auto &BState = CP.JDBootstrapStates[&JD];
946 BState.ObjectSectionsMaps.push_back(std::move(ObjSecs));
947
948 // Collect static initializers
949 for (auto &S : G.sections())
950 if (isCOFFInitializerSection(S.getName()))
951 for (auto *B : S.blocks()) {
952 if (B->edges_empty())
953 continue;
954 for (auto &E : B->edges())
955 BState.Initializers.push_back(std::make_pair(
956 S.getName().str(), E.getTarget().getAddress() + E.getAddend()));
957 }
958
959 return Error::success();
960}
961
962} // End namespace orc.
963} // End namespace llvm.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
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 _
#define offsetof(TYPE, MEMBER)
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
#define H(x, y, z)
Definition MD5.cpp:56
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
static StringRef getName(Value *V)
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:762
Helper for Errors used as out-parameters.
Definition Error.h:1160
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
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,...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Manages the enabling and disabling of subtarget specific features.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)
Definition Archive.cpp:811
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...
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.
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.
Error teardownJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...
static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)
Returns an AliasMap containing the default aliases for the COFFPlatform.
Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) override
This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
Error notifyRemoving(ResourceTracker &RT) override
This method will be called under the ExecutionSession lock when a ResourceTracker is removed.
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.
Definition Core.h:1097
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition Core.h:1178
Represents an address in the executor process.
Represents a JIT'd dynamic library.
Definition Core.h:668
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Definition Core.h:1614
GeneratorT & addGenerator(std::unique_ptr< GeneratorT > DefGenerator)
Adds a definition generator to this JITDylib and returns a referenece to it.
Definition Core.h:1597
LinkGraphLinkingLayer & addPlugin(std::shared_ptr< Plugin > P)
Add a plugin.
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition Mangling.h:28
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition Core.h:343
const SymbolStringPtr & getInitializerSymbol() const
Returns the initialization pseudo-symbol, if any.
Definition Core.h:382
JITDylib & getTargetJITDylib() const
Returns the target JITDylib that these symbols are being materialized into.
Definition Core.h:368
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...
Definition Core.cpp:1489
API to remove / transfer ownership of JIT resources.
Definition Core.h:65
JITDylib & getJITDylib() const
Return the JITDylib targeted by this tracker.
Definition Core.h:80
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.
A symbol name together with the naming level (SymbolNameKind) it is expressed in, so that a Mangler /...
static constexpr SymbolNameSpec c(StringRef Name)
Pointer to a pooled string representing a symbol name.
A utility class for serializing to a blob from a variadic list.
static Expected< WrapperFunctionCall > Create(ExecutorAddr FnAddr, const ArgTs &...Args)
Create a WrapperFunctionCall using the given SPS serializer to serialize the arguments.
Base class for specs that bind handlers for calls with the SPS signature SPSSigT.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_FILE_MACHINE_AMD64
Definition COFF.h:98
@ NUM_DATA_DIRECTORIES
Definition COFF.h:647
static const char PEMagic[]
Definition COFF.h:36
SPSSequence< SPSExecutorAddr > SPSCOFFJITDylibDepInfo
SPSSequence< char > SPSString
SPS tag type for strings, which are equivalent to sequences of chars.
SPSArgList< SPSExecutorAddr, SPSCOFFObjectSectionsMap, bool > SPSCOFFRegisterObjectSectionsArgs
SPSSequence< SPSTuple< SPSString, SPSExecutorAddrRange > > SPSCOFFObjectSectionsMap
SPSSequence< SPSTuple< SPSExecutorAddr, SPSCOFFJITDylibDepInfo > > SPSCOFFJITDylibDepInfoMap
SPSArgList< SPSExecutorAddr, SPSCOFFObjectSectionsMap > SPSCOFFDeregisterObjectSectionsArgs
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
Definition Core.h:142
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition Core.h:60
Proxy< int32_t(ExecutorAddr)> CallInt32VoidProxy
Protocol-agnostic interface for running an int32_t() function in the executor.
Definition CallProxies.h:45
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)
Create a ReExportsMaterializationUnit with the given aliases.
Definition Core.h:517
ExecutionSession::CallControllerHandlerBinding bindCallControllerHandler(HandlerT &&H, SymbolLookupFlags LF=SymbolLookupFlags::RequiredSymbol)
Bind H, using the given spec, to the tag with the spec's default name.
LLVM_ABI void lookupAndApply(unique_function< void(Error)> OnApplied, LookupKind K, const JITDylibSearchOrder &SearchOrder, ArrayRef< LookupPrepareFn > PrepareFns)
Resolve the symbols contributed by every prepare function with a single lookup, then let each of thei...
std::unique_ptr< ReExportsMaterializationUnit > reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, JITDylibLookupFlags SourceJDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Create a materialization unit for re-exporting symbols from another JITDylib with alternative names/f...
Definition Core.h:526
LookupPrepareFn recordAddr(SymbolNameSpec Name, ExecutorAddr *A, SymbolLookupFlags LF=SymbolLookupFlags::RequiredSymbol)
Records the address of the symbol with the given name.
static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases, ArrayRef< std::pair< const char *, const char * > > AL)
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...
Definition Core.cpp:42
LLVM_ABI bool isCOFFInitializerSection(StringRef Name)
@ Ready
Emitted to memory, but waiting on transitive dependencies.
Definition Core.h:545
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
Definition Core.h:167
LLVM_ABI Expected< SymbolAliasMap > buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols)
Build a SymbolAliasMap for the common case where you want to re-export symbols from another JITDylib ...
Definition Core.cpp:484
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
Definition Endian.h:270
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.
Definition Error.h:1415
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
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.
Definition Error.h:340
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:879
static constexpr SymbolNameSpec Name
void(SPSString, SPSExecutorAddr) SPSSig
static constexpr SymbolNameSpec Name
void(SPSExecutorAddr, SPSCOFFObjectSectionsMap, bool) SPSSig
static constexpr SymbolNameSpec Name