23#define DEBUG_TYPE "orc"
36 createDSOHandleSectionInterface(ENP, DSOHandleSymbol)),
41 void materialize(std::unique_ptr<MaterializationResponsibility> R)
override {
47 switch (TT.getArch()) {
73 auto G = std::make_unique<jitlink::LinkGraph>(
74 "<DSOHandleMU>", TT, PointerSize, Endianness,
76 auto &DSOHandleSection =
77 G->createSection(
".data.__dso_handle", MemProt::Read);
78 auto &DSOHandleBlock =
G->createContentBlock(
81 auto &DSOHandleSymbol =
G->addDefinedSymbol(
82 DSOHandleBlock, 0, *R->getInitializerSymbol(), DSOHandleBlock.getSize(),
83 jitlink::Linkage::Strong, jitlink::Scope::Default,
false,
true);
84 DSOHandleBlock.addEdge(EdgeKind, 0, DSOHandleSymbol, 0);
102 static const char Content[8] = {0};
117 JITDylib &PlatformJD, std::unique_ptr<DefinitionGenerator> OrcRuntime,
118 std::optional<SymbolAliasMap> RuntimeAliases) {
122 return make_error<StringError>(
"Unsupported ELFNixPlatform triple: " +
129 if (!RuntimeAliases) {
131 if (!StandardRuntimeAliases)
132 return StandardRuntimeAliases.takeError();
133 RuntimeAliases = std::move(*StandardRuntimeAliases);
138 return std::move(Err);
141 if (
auto Err = PlatformJD.
define(
143 {EPC.getJITDispatchInfo().JITDispatchFunction,
145 {ES.
intern(
"__orc_rt_jit_dispatch_ctx"),
146 {EPC.getJITDispatchInfo().JITDispatchContext,
148 return std::move(Err);
153 ES, ObjLinkingLayer, PlatformJD, std::move(OrcRuntime), Err));
155 return std::move(Err);
162 JITDylib &PlatformJD,
const char *OrcRuntimePath,
163 std::optional<SymbolAliasMap> RuntimeAliases) {
166 auto OrcRuntimeArchiveGenerator =
168 if (!OrcRuntimeArchiveGenerator)
169 return OrcRuntimeArchiveGenerator.takeError();
171 return Create(ES, ObjLinkingLayer, PlatformJD,
172 std::move(*OrcRuntimeArchiveGenerator),
173 std::move(RuntimeAliases));
178 std::make_unique<DSOHandleMaterializationUnit>(*
this, DSOHandleSymbol));
192 RegisteredInitSymbols[&JD].add(InitSym,
195 dbgs() <<
"ELFNixPlatform: Registered init symbol " << *InitSym
196 <<
" for MU " << MU.
getName() <<
"\n";
206 ArrayRef<std::pair<const char *, const char *>> AL) {
207 for (
auto &KV : AL) {
208 auto AliasName = ES.
intern(KV.first);
209 assert(!Aliases.
count(AliasName) &&
"Duplicate symbol name in alias map");
210 Aliases[std::move(AliasName)] = {ES.
intern(KV.second),
226 static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
227 {
"__cxa_atexit",
"__orc_rt_elfnix_cxa_atexit"},
228 {
"atexit",
"__orc_rt_elfnix_atexit"}};
235 static const std::pair<const char *, const char *>
236 StandardRuntimeUtilityAliases[] = {
237 {
"__orc_rt_run_program",
"__orc_rt_elfnix_run_program"},
238 {
"__orc_rt_jit_dlerror",
"__orc_rt_elfnix_jit_dlerror"},
239 {
"__orc_rt_jit_dlopen",
"__orc_rt_elfnix_jit_dlopen"},
240 {
"__orc_rt_jit_dlclose",
"__orc_rt_elfnix_jit_dlclose"},
241 {
"__orc_rt_jit_dlsym",
"__orc_rt_elfnix_jit_dlsym"},
242 {
"__orc_rt_log_error",
"__orc_rt_log_error_to_stderr"}};
245 StandardRuntimeUtilityAliases);
248bool ELFNixPlatform::supportedTarget(
const Triple &TT) {
249 switch (TT.getArch()) {
261ELFNixPlatform::ELFNixPlatform(
264 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
Error &Err)
265 : ES(ES), ObjLinkingLayer(ObjLinkingLayer),
266 DSOHandleSymbol(ES.intern(
"__dso_handle")) {
269 ObjLinkingLayer.
addPlugin(std::make_unique<ELFNixPlatformPlugin>(*
this));
271 PlatformJD.
addGenerator(std::move(OrcRuntimeGenerator));
280 RegisteredInitSymbols[&PlatformJD].add(
284 if (
auto E2 = associateRuntimeSupportFunctions(PlatformJD)) {
292 if (
auto E2 = bootstrapELFNixRuntime(PlatformJD)) {
298Error ELFNixPlatform::associateRuntimeSupportFunctions(
JITDylib &PlatformJD) {
301 using GetInitializersSPSSig =
303 WFs[ES.
intern(
"__orc_rt_elfnix_get_initializers_tag")] =
305 this, &ELFNixPlatform::rt_getInitializers);
307 using GetDeinitializersSPSSig =
309 WFs[ES.
intern(
"__orc_rt_elfnix_get_deinitializers_tag")] =
311 this, &ELFNixPlatform::rt_getDeinitializers);
313 using LookupSymbolSPSSig =
315 WFs[ES.
intern(
"__orc_rt_elfnix_symbol_lookup_tag")] =
317 &ELFNixPlatform::rt_lookupSymbol);
322void ELFNixPlatform::getInitializersBuildSequencePhase(
323 SendInitializerSequenceFn SendResult,
JITDylib &JD,
324 std::vector<JITDylibSP> DFSLinkOrder) {
327 std::lock_guard<std::mutex> Lock(PlatformMutex);
328 for (
auto &InitJD :
reverse(DFSLinkOrder)) {
330 dbgs() <<
"ELFNixPlatform: Appending inits for \"" << InitJD->getName()
331 <<
"\" to sequence\n";
333 auto ISItr = InitSeqs.find(InitJD.get());
334 if (ISItr != InitSeqs.end()) {
335 FullInitSeq.emplace_back(std::move(ISItr->second));
336 InitSeqs.erase(ISItr);
341 SendResult(std::move(FullInitSeq));
344void ELFNixPlatform::getInitializersLookupPhase(
345 SendInitializerSequenceFn SendResult,
JITDylib &JD) {
349 SendResult(DFSLinkOrder.takeError());
355 for (
auto &InitJD : *DFSLinkOrder) {
356 auto RISItr = RegisteredInitSymbols.find(InitJD.get());
357 if (RISItr != RegisteredInitSymbols.end()) {
358 NewInitSymbols[InitJD.get()] = std::move(RISItr->second);
359 RegisteredInitSymbols.erase(RISItr);
366 if (NewInitSymbols.
empty()) {
367 getInitializersBuildSequencePhase(std::move(SendResult), JD,
368 std::move(*DFSLinkOrder));
374 [
this, SendResult = std::move(SendResult), &JD](
Error Err)
mutable {
376 SendResult(std::move(Err));
378 getInitializersLookupPhase(std::move(SendResult), JD);
380 ES, std::move(NewInitSymbols));
383void ELFNixPlatform::rt_getInitializers(SendInitializerSequenceFn SendResult,
386 dbgs() <<
"ELFNixPlatform::rt_getInitializers(\"" << JDName <<
"\")\n";
392 dbgs() <<
" No such JITDylib \"" << JDName <<
"\". Sending error.\n";
394 SendResult(make_error<StringError>(
"No JITDylib named " + JDName,
399 getInitializersLookupPhase(std::move(SendResult), *JD);
402void ELFNixPlatform::rt_getDeinitializers(
403 SendDeinitializerSequenceFn SendResult,
ExecutorAddr Handle) {
405 dbgs() <<
"ELFNixPlatform::rt_getDeinitializers(\"" << Handle <<
"\")\n";
411 std::lock_guard<std::mutex> Lock(PlatformMutex);
412 auto I = HandleAddrToJITDylib.find(Handle);
413 if (
I != HandleAddrToJITDylib.end())
418 LLVM_DEBUG(
dbgs() <<
" No JITDylib for handle " << Handle <<
"\n");
419 SendResult(make_error<StringError>(
"No JITDylib associated with handle " +
428void ELFNixPlatform::rt_lookupSymbol(SendSymbolAddressFn SendResult,
432 dbgs() <<
"ELFNixPlatform::rt_lookupSymbol(\"" << Handle <<
"\")\n";
438 std::lock_guard<std::mutex> Lock(PlatformMutex);
439 auto I = HandleAddrToJITDylib.find(Handle);
440 if (
I != HandleAddrToJITDylib.end())
445 LLVM_DEBUG(
dbgs() <<
" No JITDylib for handle " << Handle <<
"\n");
446 SendResult(make_error<StringError>(
"No JITDylib associated with handle " +
453 class RtLookupNotifyComplete {
455 RtLookupNotifyComplete(SendSymbolAddressFn &&SendResult)
456 : SendResult(
std::
move(SendResult)) {}
459 assert(
Result->size() == 1 &&
"Unexpected result map count");
460 SendResult(
Result->begin()->second.getAddress());
462 SendResult(
Result.takeError());
467 SendSymbolAddressFn SendResult;
476Error ELFNixPlatform::bootstrapELFNixRuntime(
JITDylib &PlatformJD) {
478 std::pair<const char *, ExecutorAddr *> Symbols[] = {
479 {
"__orc_rt_elfnix_platform_bootstrap", &orc_rt_elfnix_platform_bootstrap},
480 {
"__orc_rt_elfnix_platform_shutdown", &orc_rt_elfnix_platform_shutdown},
481 {
"__orc_rt_elfnix_register_object_sections",
482 &orc_rt_elfnix_register_object_sections},
483 {
"__orc_rt_elfnix_create_pthread_key",
484 &orc_rt_elfnix_create_pthread_key}};
487 std::vector<std::pair<SymbolStringPtr, ExecutorAddr *>> AddrsToRecord;
488 for (
const auto &KV : Symbols) {
491 AddrsToRecord.push_back({std::move(
Name), KV.second});
494 auto RuntimeSymbolAddrs = ES.
lookup(
496 if (!RuntimeSymbolAddrs)
497 return RuntimeSymbolAddrs.takeError();
499 for (
const auto &KV : AddrsToRecord) {
500 auto &
Name = KV.first;
501 assert(RuntimeSymbolAddrs->count(
Name) &&
"Missing runtime symbol?");
502 *KV.second = (*RuntimeSymbolAddrs)[
Name].getAddress();
505 auto PJDDSOHandle = ES.
lookup(
508 return PJDDSOHandle.takeError();
511 orc_rt_elfnix_platform_bootstrap,
512 PJDDSOHandle->getAddress().getValue()))
518 RuntimeBootstrapped =
true;
519 std::vector<ELFPerObjectSectionsToRegister> DeferredPOSRs;
521 std::lock_guard<std::mutex> Lock(PlatformMutex);
522 DeferredPOSRs = std::move(BootstrapPOSRs);
525 for (
auto &
D : DeferredPOSRs)
526 if (
auto Err = registerPerObjectSections(
D))
532Error ELFNixPlatform::registerInitInfo(
535 std::unique_lock<std::mutex> Lock(PlatformMutex);
539 auto I = InitSeqs.find(&JD);
540 if (
I == InitSeqs.end()) {
547 if (
auto Err = ES.
lookup(SearchOrder, DSOHandleSymbol).takeError())
551 I = InitSeqs.find(&JD);
553 "Entry missing after header symbol lookup?");
555 InitSeq = &
I->second;
558 for (
auto *Sec : InitSections) {
561 InitSeq->
InitSections[Sec->getName()].push_back(
R.getRange());
567Error ELFNixPlatform::registerPerObjectSections(
570 if (!orc_rt_elfnix_register_object_sections)
571 return make_error<StringError>(
"Attempting to register per-object "
572 "sections, but runtime support has not "
579 orc_rt_elfnix_register_object_sections, ErrResult, POSR))
585 if (!orc_rt_elfnix_create_pthread_key)
586 return make_error<StringError>(
587 "Attempting to create pthread key in target, but runtime support has "
588 "not been loaded yet",
593 orc_rt_elfnix_create_pthread_key,
Result))
594 return std::move(Err);
598void ELFNixPlatform::ELFNixPlatformPlugin::modifyPassConfig(
605 addDSOHandleSupportPasses(MR,
Config);
613 addInitializerSupportPasses(MR,
Config);
616 addEHAndTLVSupportPasses(MR,
Config);
620ELFNixPlatform::ELFNixPlatformPlugin::getSyntheticSymbolDependencies(
622 std::lock_guard<std::mutex> Lock(PluginMutex);
623 auto I = InitSymbolDeps.find(&MR);
624 if (
I != InitSymbolDeps.end()) {
625 SyntheticSymbolDependenciesMap
Result;
627 InitSymbolDeps.erase(&MR);
630 return SyntheticSymbolDependenciesMap();
633void ELFNixPlatform::ELFNixPlatformPlugin::addInitializerSupportPasses(
638 if (
auto Err = preserveInitSections(
G, MR))
643 Config.PostFixupPasses.push_back(
645 return registerInitSections(
G, JD);
649void ELFNixPlatform::ELFNixPlatformPlugin::addDSOHandleSupportPasses(
654 auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
655 return Sym->getName() == *MP.DSOHandleSymbol;
657 assert(
I !=
G.defined_symbols().end() &&
"Missing DSO handle symbol");
659 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
660 auto HandleAddr = (*I)->getAddress();
661 MP.HandleAddrToJITDylib[HandleAddr] = &JD;
662 assert(!MP.InitSeqs.count(&JD) &&
"InitSeq entry for JD already exists");
663 MP.InitSeqs.insert(std::make_pair(
670void ELFNixPlatform::ELFNixPlatformPlugin::addEHAndTLVSupportPasses(
678 Config.PostPrunePasses.push_back(
680 return fixTLVSectionsAndEdges(G, JD);
689 jitlink::SectionRange R(*EHFrameSection);
691 POSR.EHFrameSection = R.getRange();
704 if (ThreadDataSection)
705 G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
707 ThreadDataSection = ThreadBSSSection;
712 if (ThreadDataSection) {
722 if (!MP.RuntimeBootstrapped) {
723 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
724 MP.BootstrapPOSRs.push_back(POSR);
729 if (
auto Err = MP.registerPerObjectSections(POSR))
737Error ELFNixPlatform::ELFNixPlatformPlugin::preserveInitSections(
740 JITLinkSymbolSet InitSectionSymbols;
741 for (
auto &InitSection :
G.sections()) {
749 for (
auto &
Sym : InitSection.symbols()) {
750 auto &
B =
Sym->getBlock();
751 if (
Sym->isLive() &&
Sym->getOffset() == 0 &&
752 Sym->getSize() ==
B.getSize() && !AlreadyLiveBlocks.
count(&
B)) {
753 InitSectionSymbols.insert(
Sym);
759 for (
auto *
B : InitSection.blocks())
760 if (!AlreadyLiveBlocks.
count(
B))
761 InitSectionSymbols.insert(
762 &
G.addAnonymousSymbol(*
B, 0,
B->getSize(),
false,
true));
765 if (!InitSectionSymbols.empty()) {
766 std::lock_guard<std::mutex> Lock(PluginMutex);
767 InitSymbolDeps[&MR] = std::move(InitSectionSymbols);
773Error ELFNixPlatform::ELFNixPlatformPlugin::registerInitSections(
780 for (
auto &Sec :
G.sections()) {
788 dbgs() <<
"ELFNixPlatform: Scraped " <<
G.getName() <<
" init sections:\n";
789 for (
auto *Sec : InitSections) {
791 dbgs() <<
" " << Sec->getName() <<
": " <<
R.getRange() <<
"\n";
795 return MP.registerInitInfo(JD, InitSections);
798Error ELFNixPlatform::ELFNixPlatformPlugin::fixTLVSectionsAndEdges(
801 for (
auto *
Sym :
G.external_symbols()) {
802 if (
Sym->getName() ==
"__tls_get_addr") {
803 Sym->setName(
"___orc_rt_elfnix_tls_get_addr");
804 }
else if (
Sym->getName() ==
"__tlsdesc_resolver") {
805 Sym->setName(
"___orc_rt_elfnix_tlsdesc_resolver");
809 auto *TLSInfoEntrySection =
G.findSectionByName(
"$__TLSINFO");
811 if (TLSInfoEntrySection) {
812 std::optional<uint64_t>
Key;
814 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
815 auto I = MP.JITDylibToPThreadKey.find(&JD);
816 if (
I != MP.JITDylibToPThreadKey.end())
820 if (
auto KeyOrErr = MP.createPThreadKey())
823 return KeyOrErr.takeError();
829 for (
auto *
B : TLSInfoEntrySection->blocks()) {
832 assert(
B->getSize() == (
G.getPointerSize() * 2) &&
833 "TLS descriptor must be 2 words length");
834 auto TLSInfoEntryContent =
B->getMutableContent(
G);
835 memcpy(TLSInfoEntryContent.data(), &PlatformKeyBits,
G.getPointerSize());
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
Implements a dense probed hash-table based set.
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.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
const std::string & str() const
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const std::string & getName() const
Get the name for this JITLinkDylib.
Represents a section address range via a pair of Block pointers to the first and last Blocks in the s...
Represents an object file section.
An ExecutionSession represents a running JIT program.
ExecutorProcessControl & getExecutorProcessControl()
Get the ExecutorProcessControl object associated with this ExecutionSession.
const Triple & getTargetTriple() const
Return the triple for the executor.
Error callSPSWrapper(ExecutorAddr WrapperFnAddr, WrapperCallArgTs &&...WrapperCallArgs)
Run a wrapper function using SPS to serialize the arguments and deserialize the results.
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
JITDylib * getJITDylibByName(StringRef Name)
Return a pointer to the "name" JITDylib.
static JITDispatchHandlerFunction wrapAsyncWithSPS(HandlerT &&H)
Wrap a handler that takes concrete argument types (and a sender for a concrete return type) to produc...
void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Error registerJITDispatchHandlers(JITDylib &JD, JITDispatchHandlerAssociationMap WFs)
For each tag symbol name, associate the corresponding AsyncHandlerWrapperFunction with the address of...
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
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.
static Expected< std::vector< JITDylibSP > > getDFSLinkOrder(ArrayRef< JITDylibSP > JDs)
Returns the given JITDylibs and all of their transitive dependencies in DFS order (based on linkage r...
auto withLinkOrderDo(Func &&F) -> decltype(F(std::declval< const JITDylibSearchOrder & >()))
Do something with the link order (run under the session lock).
GeneratorT & addGenerator(std::unique_ptr< GeneratorT > DefGenerator)
Adds a definition generator to this JITDylib and returns a referenece to it.
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.
SymbolFlagsMap SymbolFlags
virtual void materialize(std::unique_ptr< MaterializationResponsibility > R)=0
Implementations of this method should materialize all symbols in the materialzation unit,...
const SymbolStringPtr & getInitializerSymbol() const
Returns the initialization symbol for this MaterializationUnit (if any).
An ObjectLayer implementation built on JITLink.
ObjectLinkingLayer & addPlugin(std::shared_ptr< Plugin > P)
Add a plugin.
void emit(std::unique_ptr< MaterializationResponsibility > R, std::unique_ptr< MemoryBuffer > O) override
Emit an object file.
API to remove / transfer ownership of JIT resources.
JITDylib & getJITDylib() const
Return the JITDylib targeted by this tracker.
static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Load(ObjectLayer &L, const char *FileName, GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())
Try to create a StaticLibraryDefinitionGenerator from the given path.
A set of symbols to look up, each associated with a SymbolLookupFlags value.
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
Pointer to a pooled string representing a symbol name.
SPS tag type for expecteds, which are either a T or a string representing an error.
SPS tag type for sequences.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Pointer64
A plain 64-bit pointer value relocation.
@ Pointer64
A plain 64-bit pointer value relocation.
const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
StringRef ELFThreadBSSSectionName
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
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.
StringRef ELFEHFrameSectionName
std::vector< ELFNixJITDylibDeinitializers > ELFNixJITDylibDeinitializerSequence
@ MatchExportedSymbolsOnly
static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases, ArrayRef< std::pair< const char *, const char * > > AL)
StringRef ELFThreadDataSectionName
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
@ Ready
Emitted to memory, but waiting on transitive dependencies.
std::vector< ELFNixJITDylibInitializers > ELFNixJITDylibInitializerSequence
bool isELFInitializerSection(StringRef SecName)
value_type byte_swap(value_type value, endianness endian)
This is an optimization pass for GlobalISel generic memory operations.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
StringMap< SectionList > InitSections
ExecutorAddrRange EHFrameSection
ExecutorAddrRange ThreadDataSection