22#define DEBUG_TYPE "orc"
36class SPSMachOExecutorSymbolFlags;
48 return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.
Sealed,
54 return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.
Sealed,
63 using UT = std::underlying_type_t<MachOPlatform::MachOExecutorSymbolFlags>;
91using SPSRegisterSymbolsArgs =
94 SPSMachOExecutorSymbolFlags>>>;
96std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(
MachOPlatform &MOP,
99 return std::make_unique<jitlink::LinkGraph>(
100 std::move(Name), ES.getSymbolStringPool(), ES.getTargetTriple(),
105class MachOPlatformCompleteBootstrapMaterializationUnit
108 using SymbolTableVector =
112 MachOPlatformCompleteBootstrapMaterializationUnit(
113 MachOPlatform &MOP, StringRef PlatformJDName,
114 SymbolStringPtr CompleteBootstrapSymbol, SymbolTableVector SymTab,
116 ExecutorAddr PlatformBootstrap, ExecutorAddr PlatformShutdown,
117 ExecutorAddr RegisterJITDylib, ExecutorAddr DeregisterJITDylib,
118 ExecutorAddr RegisterObjectSymbolTable,
119 ExecutorAddr DeregisterObjectSymbolTable)
120 : MaterializationUnit(
122 MOP(MOP), PlatformJDName(PlatformJDName),
123 CompleteBootstrapSymbol(std::move(CompleteBootstrapSymbol)),
124 SymTab(std::move(SymTab)), DeferredAAs(std::move(DeferredAAs)),
125 MachOHeaderAddr(MachOHeaderAddr), PlatformBootstrap(PlatformBootstrap),
126 PlatformShutdown(PlatformShutdown), RegisterJITDylib(RegisterJITDylib),
127 DeregisterJITDylib(DeregisterJITDylib),
128 RegisterObjectSymbolTable(RegisterObjectSymbolTable),
129 DeregisterObjectSymbolTable(DeregisterObjectSymbolTable) {}
131 StringRef
getName()
const override {
132 return "MachOPlatformCompleteBootstrap";
135 void materialize(std::unique_ptr<MaterializationResponsibility> R)
override {
136 using namespace jitlink;
137 auto G = createPlatformGraph(MOP,
"<OrcRTCompleteBootstrap>");
138 auto &PlaceholderSection =
139 G->createSection(
"__orc_rt_cplt_bs", MemProt::Read);
140 auto &PlaceholderBlock =
141 G->createZeroFillBlock(PlaceholderSection, 1, ExecutorAddr(), 1, 0);
142 G->addDefinedSymbol(PlaceholderBlock, 0, *CompleteBootstrapSymbol, 1,
143 Linkage::Strong, Scope::Hidden,
false,
true);
146 G->allocActions().reserve(DeferredAAs.size() + 3);
149 G->allocActions().push_back(
155 G->allocActions().push_back(
157 SPSArgList<SPSString, SPSExecutorAddr>>(
158 RegisterJITDylib, PlatformJDName, MachOHeaderAddr)),
160 DeregisterJITDylib, MachOHeaderAddr))});
163 G->allocActions().push_back(
165 RegisterObjectSymbolTable, MachOHeaderAddr, SymTab)),
167 DeregisterObjectSymbolTable, MachOHeaderAddr, SymTab))});
170 std::move(DeferredAAs.begin(), DeferredAAs.end(),
171 std::back_inserter(
G->allocActions()));
173 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(
G));
176 void discard(
const JITDylib &JD,
const SymbolStringPtr &Sym)
override {}
180 StringRef PlatformJDName;
181 SymbolStringPtr CompleteBootstrapSymbol;
182 SymbolTableVector SymTab;
184 ExecutorAddr MachOHeaderAddr;
185 ExecutorAddr PlatformBootstrap;
186 ExecutorAddr PlatformShutdown;
187 ExecutorAddr RegisterJITDylib;
188 ExecutorAddr DeregisterJITDylib;
189 ExecutorAddr RegisterObjectSymbolTable;
190 ExecutorAddr DeregisterObjectSymbolTable;
193static StringRef ObjCRuntimeObjectSectionsData[] = {
201static StringRef ObjCRuntimeObjectSectionsText[] = {
208static StringRef ObjCRuntimeObjectSectionName =
209 "__llvm_jitlink_ObjCRuntimeRegistrationObject";
211static StringRef ObjCImageInfoSymbolName =
212 "__llvm_jitlink_macho_objc_imageinfo";
214struct ObjCImageInfoFlags {
215 uint16_t SwiftABIVersion;
216 uint16_t SwiftVersion;
217 bool HasCategoryClassProperties;
218 bool HasSignedObjCClassROs;
220 static constexpr uint32_t SIGNED_CLASS_RO = (1 << 4);
221 static constexpr uint32_t HAS_CATEGORY_CLASS_PROPERTIES = (1 << 6);
223 explicit ObjCImageInfoFlags(uint32_t RawFlags) {
224 HasSignedObjCClassROs = RawFlags & SIGNED_CLASS_RO;
225 HasCategoryClassProperties = RawFlags & HAS_CATEGORY_CLASS_PROPERTIES;
226 SwiftABIVersion = (RawFlags >> 8) & 0xFF;
227 SwiftVersion = (RawFlags >> 16) & 0xFFFF;
230 uint32_t rawFlags()
const {
232 if (HasCategoryClassProperties)
233 Result |= HAS_CATEGORY_CLASS_PROPERTIES;
234 if (HasSignedObjCClassROs)
235 Result |= SIGNED_CLASS_RO;
236 Result |= (SwiftABIVersion << 8);
237 Result |= (SwiftVersion << 16);
246std::optional<MachOPlatform::HeaderOptions::BuildVersionOpts>
252 switch (TT.getOS()) {
254 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
255 : MachO::PLATFORM_IOS;
261 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
262 : MachO::PLATFORM_TVOS;
265 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
266 : MachO::PLATFORM_WATCHOS;
269 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR
270 : MachO::PLATFORM_XROS;
281 std::unique_ptr<DefinitionGenerator> OrcRuntime,
285 std::optional<SymbolAliasMap> RuntimeAliases) {
287 auto &ES = ObjLinkingLayer.getExecutionSession();
290 if (!supportedTarget(ES.getTargetTriple()))
292 ES.getTargetTriple().str(),
295 auto &EPC = ES.getExecutorProcessControl();
302 if (
auto Err = PlatformJD.define(
symbolAliases(std::move(*RuntimeAliases))))
303 return std::move(Err);
306 if (
auto Err = PlatformJD.define(
308 {EPC.getJITDispatchInfo().JITDispatchFunction,
310 {ES.intern(
"___orc_rt_jit_dispatch_ctx"),
311 {EPC.getJITDispatchInfo().JITDispatchContext,
313 return std::move(Err);
317 auto P = std::unique_ptr<MachOPlatform>(
318 new MachOPlatform(ObjLinkingLayer, PlatformJD, std::move(OrcRuntime),
319 std::move(BuildHeaderOpts), std::move(PlatformJDOpts),
320 std::move(BuildMachOHeaderMU), Err));
322 return std::move(Err);
330 std::optional<SymbolAliasMap> RuntimeAliases) {
333 auto OrcRuntimeArchiveGenerator =
335 if (!OrcRuntimeArchiveGenerator)
336 return OrcRuntimeArchiveGenerator.takeError();
338 return Create(ObjLinkingLayer, PlatformJD,
339 std::move(*OrcRuntimeArchiveGenerator),
340 std::move(BuildHeaderOpts), std::move(PlatformJDOpts),
341 std::move(BuildMachOHeaderMU), std::move(RuntimeAliases));
349 if (
auto Err = JD.
define(BuildMachOHeaderMU(*
this, std::move(Opts))))
352 return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
356 std::lock_guard<std::mutex> Lock(PlatformMutex);
357 auto I = JITDylibToHeaderAddr.find(&JD);
358 if (
I != JITDylibToHeaderAddr.end()) {
359 assert(HeaderAddrToJITDylib.count(
I->second) &&
360 "HeaderAddrToJITDylib missing entry");
361 HeaderAddrToJITDylib.erase(
I->second);
362 JITDylibToHeaderAddr.erase(
I);
364 JITDylibToPThreadKey.erase(&JD);
375 RegisteredInitSymbols[&JD].add(InitSym,
378 dbgs() <<
"MachOPlatform: Registered init symbol " << *InitSym <<
" for MU "
389 ArrayRef<std::pair<const char *, const char *>> AL) {
390 for (
auto &KV : AL) {
391 auto AliasName = ES.
intern(KV.first);
392 assert(!Aliases.
count(AliasName) &&
"Duplicate symbol name in alias map");
393 Aliases[std::move(AliasName)] = {ES.
intern(KV.second),
408 static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
409 {
"___cxa_atexit",
"___orc_rt_macho_cxa_atexit"}};
416 static const std::pair<const char *, const char *>
417 StandardRuntimeUtilityAliases[] = {
418 {
"___orc_rt_run_program",
"___orc_rt_macho_run_program"},
419 {
"___orc_rt_jit_dlerror",
"___orc_rt_macho_jit_dlerror"},
420 {
"___orc_rt_jit_dlopen",
"___orc_rt_macho_jit_dlopen"},
421 {
"___orc_rt_jit_dlupdate",
"___orc_rt_macho_jit_dlupdate"},
422 {
"___orc_rt_jit_dlclose",
"___orc_rt_macho_jit_dlclose"},
423 {
"___orc_rt_jit_dlsym",
"___orc_rt_macho_jit_dlsym"},
424 {
"___orc_rt_log_error",
"___orc_rt_log_error_to_stderr"}};
427 StandardRuntimeUtilityAliases);
432 static const std::pair<const char *, const char *>
433 StandardLazyCompilationAliases[] = {
434 {
"__orc_rt_reenter",
"__orc_rt_sysv_reenter"},
435 {
"__orc_rt_resolve_tag",
"___orc_rt_resolve_tag"}};
438 StandardLazyCompilationAliases);
445bool MachOPlatform::supportedTarget(
const Triple &TT) {
446 switch (TT.getArch()) {
456 switch (
G.getTargetTriple().getArch()) {
467MachOPlatform::flagsForSymbol(jitlink::Symbol &Sym) {
478MachOPlatform::MachOPlatform(
479 ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
480 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
484 ObjLinkingLayer(ObjLinkingLayer),
485 BuildHeaderOpts(std::
move(BuildHeaderOpts)),
486 BuildMachOHeaderMU(std::
move(BuildMachOHeaderMU)) {
487 ErrorAsOutParameter
_(Err);
488 ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*
this));
489 PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
493 std::optional<bool> ForceEHFrames;
494 if ((Err = ES.getBootstrapMapValue<
bool,
bool>(
"darwin-use-ehframes-only",
497 this->ForceEHFrames = ForceEHFrames.value_or(
false);
558 if ((Err = PlatformJD.define(
559 this->BuildMachOHeaderMU(*
this, std::move(PlatformJDOpts)))))
561 if ((Err = ES.lookup(&PlatformJD, MachOHeaderStartSymbol).takeError()))
568 {PlatformBootstrap.Name, PlatformShutdown.Name,
569 RegisterJITDylib.Name, DeregisterJITDylib.Name,
570 RegisterObjectSymbolTable.Name,
571 DeregisterObjectSymbolTable.Name,
572 RegisterObjectPlatformSections.Name,
573 DeregisterObjectPlatformSections.Name,
574 CreatePThreadKey.Name}))
580 std::unique_lock<std::mutex> Lock(PlatformMutex);
581 BI.CV.wait(Lock, [&]() {
return BI.ActiveGraphs == 0; });
586 auto BootstrapCompleteSymbol = ES.intern(
"__orc_rt_macho_complete_bootstrap");
587 if ((Err = PlatformJD.define(
588 std::make_unique<MachOPlatformCompleteBootstrapMaterializationUnit>(
589 *
this, PlatformJD.getName(), BootstrapCompleteSymbol,
590 std::move(BI.SymTab), std::move(BI.DeferredAAs),
591 BI.MachOHeaderAddr, PlatformBootstrap.Addr,
592 PlatformShutdown.Addr, RegisterJITDylib.Addr,
593 DeregisterJITDylib.Addr, RegisterObjectSymbolTable.Addr,
594 DeregisterObjectSymbolTable.Addr))))
598 std::move(BootstrapCompleteSymbol))
609 if ((Err = associateRuntimeSupportFunctions()))
613Error MachOPlatform::associateRuntimeSupportFunctions() {
616 using PushInitializersSPSSig =
617 SPSExpected<SPSMachOJITDylibDepInfoMap>(SPSExecutorAddr);
618 WFs[ES.intern(
"___orc_rt_macho_push_initializers_tag")] =
619 ES.wrapAsyncWithSPS<PushInitializersSPSSig>(
620 this, &MachOPlatform::rt_pushInitializers);
622 using PushSymbolsSPSSig =
623 SPSError(SPSExecutorAddr, SPSSequence<SPSTuple<SPSString, bool>>);
624 WFs[ES.intern(
"___orc_rt_macho_push_symbols_tag")] =
625 ES.wrapAsyncWithSPS<PushSymbolsSPSSig>(
this,
626 &MachOPlatform::rt_pushSymbols);
628 return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
631void MachOPlatform::pushInitializersLoop(
632 PushInitializersSendResultFn SendResult,
JITDylibSP JD) {
633 DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;
634 DenseMap<JITDylib *, SmallVector<JITDylib *>> JDDepMap;
637 ES.runSessionLocked([&]() {
638 while (!Worklist.empty()) {
641 auto DepJD = Worklist.back();
650 auto &
DM = It->second;
653 if (KV.first == DepJD)
655 DM.push_back(KV.first);
656 Worklist.push_back(KV.first);
661 auto RISItr = RegisteredInitSymbols.find(DepJD);
662 if (RISItr != RegisteredInitSymbols.end()) {
663 NewInitSymbols[DepJD] = std::move(RISItr->second);
664 RegisteredInitSymbols.erase(RISItr);
671 if (NewInitSymbols.
empty()) {
677 DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
680 std::lock_guard<std::mutex> Lock(PlatformMutex);
681 for (
auto &KV : JDDepMap) {
682 auto I = JITDylibToHeaderAddr.find(KV.first);
683 if (
I != JITDylibToHeaderAddr.end())
684 HeaderAddrs[KV.first] =
I->second;
690 DIM.reserve(JDDepMap.size());
691 for (
auto &KV : JDDepMap) {
692 auto HI = HeaderAddrs.
find(KV.first);
694 if (HI == HeaderAddrs.
end())
698 for (
auto &Dep : KV.second) {
699 auto HJ = HeaderAddrs.
find(Dep);
700 if (HJ != HeaderAddrs.
end())
701 DepInfo.DepHeaders.push_back(HJ->second);
703 DIM.push_back(std::make_pair(
H, std::move(DepInfo)));
711 [
this, SendResult = std::move(SendResult), JD](
Error Err)
mutable {
713 SendResult(std::move(Err));
715 pushInitializersLoop(std::move(SendResult), JD);
717 ES, std::move(NewInitSymbols));
720void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
724 std::lock_guard<std::mutex> Lock(PlatformMutex);
725 auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
726 if (
I != HeaderAddrToJITDylib.end())
731 dbgs() <<
"MachOPlatform::rt_pushInitializers(" << JDHeaderAddr <<
") ";
733 dbgs() <<
"pushing initializers for " << JD->
getName() <<
"\n";
735 dbgs() <<
"No JITDylib for header address.\n";
740 formatv(
"{0:x}", JDHeaderAddr),
745 pushInitializersLoop(std::move(SendResult), JD);
748void MachOPlatform::rt_pushSymbols(
749 PushSymbolsInSendResultFn SendResult,
ExecutorAddr Handle,
750 const std::vector<std::pair<StringRef, bool>> &SymbolNames) {
752 JITDylib *JD =
nullptr;
755 std::lock_guard<std::mutex> Lock(PlatformMutex);
756 auto I = HeaderAddrToJITDylib.find(Handle);
757 if (
I != HeaderAddrToJITDylib.end())
761 dbgs() <<
"MachOPlatform::rt_pushSymbols(";
765 dbgs() <<
"<invalid handle " << Handle <<
">, [ ";
766 for (
auto &Name : SymbolNames)
767 dbgs() <<
"\"" <<
Name.first <<
"\" ";
779 for (
auto &[Name,
Required] : SymbolNames)
787 [SendResult = std::move(SendResult)](Expected<SymbolMap>
Result)
mutable {
788 SendResult(
Result.takeError());
793Expected<uint64_t> MachOPlatform::createPThreadKey() {
794 if (!CreatePThreadKey.Addr)
796 "Attempting to create pthread key in target, but runtime support has "
797 "not been loaded yet",
800 Expected<uint64_t>
Result(0);
801 if (
auto Err = ES.callSPSWrapper<SPSExpected<uint64_t>(
void)>(
802 CreatePThreadKey.Addr,
Result))
803 return std::move(Err);
807void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
809 jitlink::PassConfiguration &Config) {
811 using namespace jitlink;
813 bool InBootstrapPhase =
false;
815 ExecutorAddr HeaderAddr;
817 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
820 InBootstrapPhase =
true;
821 ++MP.Bootstrap->ActiveGraphs;
827 if (
I != MP.JITDylibToHeaderAddr.end())
828 HeaderAddr =
I->second;
833 if (MP.ForceEHFrames)
842 Linkage::Strong, Scope::Local,
true);
847 return bootstrapPipelineRecordRuntimeFunctions(
G);
856 if (InitSymbol == MP.MachOHeaderStartSymbol && !InBootstrapPhase) {
858 return associateJITDylibHeaderSymbol(
G, MR);
867 if (
auto Err = preserveImportantSections(
G, MR))
869 return processObjCImageInfo(
G, MR);
872 [
this](LinkGraph &
G) {
return createObjCRuntimeObject(
G); });
874 [
this, &MR](LinkGraph &
G) {
return populateObjCRuntimeObject(
G, MR); });
882 return fixTLVSectionsAndEdges(G, JD);
888 auto JITSymTabInfo = std::make_shared<JITSymTabVector>();
890 return prepareSymbolTableRegistration(
G, *JITSymTabInfo);
893 InBootstrapPhase](LinkGraph &
G) {
894 return addSymbolTableRegistration(
G, MR, *JITSymTabInfo, InBootstrapPhase);
901 InBootstrapPhase](LinkGraph &
G) {
902 return registerObjectPlatformSections(G, JD, HeaderAddr, InBootstrapPhase);
907 if (InBootstrapPhase)
909 [
this](LinkGraph &
G) {
return bootstrapPipelineEnd(
G); });
912Error MachOPlatform::MachOPlatformPlugin::
913 bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &
G) {
915 std::pair<StringRef, ExecutorAddr *> RuntimeSymbols[] = {
916 {*MP.MachOHeaderStartSymbol, &MP.Bootstrap->MachOHeaderAddr},
917 {*MP.PlatformBootstrap.Name, &MP.PlatformBootstrap.Addr},
918 {*MP.PlatformShutdown.Name, &MP.PlatformShutdown.Addr},
919 {*MP.RegisterJITDylib.Name, &MP.RegisterJITDylib.Addr},
920 {*MP.DeregisterJITDylib.Name, &MP.DeregisterJITDylib.Addr},
921 {*MP.RegisterObjectSymbolTable.Name, &MP.RegisterObjectSymbolTable.Addr},
922 {*MP.DeregisterObjectSymbolTable.Name,
923 &MP.DeregisterObjectSymbolTable.Addr},
924 {*MP.RegisterObjectPlatformSections.Name,
925 &MP.RegisterObjectPlatformSections.Addr},
926 {*MP.DeregisterObjectPlatformSections.Name,
927 &MP.DeregisterObjectPlatformSections.Addr},
928 {*MP.CreatePThreadKey.Name, &MP.CreatePThreadKey.Addr},
929 {*MP.RegisterObjCRuntimeObject.Name, &MP.RegisterObjCRuntimeObject.Addr},
930 {*MP.DeregisterObjCRuntimeObject.Name,
931 &MP.DeregisterObjCRuntimeObject.Addr}};
933 bool RegisterMachOHeader =
false;
935 for (
auto *Sym :
G.defined_symbols()) {
936 for (
auto &RTSym : RuntimeSymbols) {
940 "Duplicate " + RTSym.first +
941 " detected during MachOPlatform bootstrap",
944 if (Sym->
getName() == MP.MachOHeaderStartSymbol)
945 RegisterMachOHeader =
true;
952 if (RegisterMachOHeader) {
955 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
956 MP.JITDylibToHeaderAddr[&MP.PlatformJD] = MP.Bootstrap->MachOHeaderAddr;
957 MP.HeaderAddrToJITDylib[MP.Bootstrap->MachOHeaderAddr] = &MP.PlatformJD;
963Error MachOPlatform::MachOPlatformPlugin::bootstrapPipelineEnd(
964 jitlink::LinkGraph &
G) {
965 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
967 --MP.Bootstrap->ActiveGraphs;
970 if (MP.Bootstrap->ActiveGraphs == 0)
971 MP.Bootstrap->CV.notify_all();
975Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
976 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
977 auto I =
llvm::find_if(
G.defined_symbols(), [
this](jitlink::Symbol *Sym) {
978 return Sym->getName() == MP.MachOHeaderStartSymbol;
980 assert(
I !=
G.defined_symbols().end() &&
"Missing MachO header start symbol");
983 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
984 auto HeaderAddr = (*I)->getAddress();
985 MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
986 MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
989 G.allocActions().push_back(
992 MP.RegisterJITDylib.Addr, JD.
getName(), HeaderAddr)),
994 MP.DeregisterJITDylib.Addr, HeaderAddr))});
998Error MachOPlatform::MachOPlatformPlugin::preserveImportantSections(
999 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1004 if (
auto *ObjCImageInfoSec =
1006 if (ObjCImageInfoSec->blocks_size() != 1)
1008 "In " +
G.getName() +
1009 "__DATA,__objc_imageinfo contains multiple blocks",
1011 G.addAnonymousSymbol(**ObjCImageInfoSec->blocks().begin(), 0, 0,
false,
1014 for (
auto *
B : ObjCImageInfoSec->blocks())
1015 if (!
B->edges_empty())
1018 " contains references to symbols",
1027 jitlink::Symbol *InitSym =
nullptr;
1035 auto *InitSection =
G.findSectionByName(InitSectionName);
1036 if (!InitSection || InitSection->empty())
1042 auto &
B = **InitSection->blocks().begin();
1043 InitSym = &
G.addDefinedSymbol(
1049 for (
auto *
B : InitSection->blocks()) {
1053 auto &S =
G.addAnonymousSymbol(*
B, 0,
B->getSize(),
false,
true);
1062Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
1063 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1075 auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();
1078 if (ObjCImageInfoBlocks.empty())
1080 " section in " +
G.getName(),
1084 if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())
1087 " section in " +
G.getName(),
1092 for (
auto &Sec :
G.sections()) {
1093 if (&Sec != ObjCImageInfo)
1094 for (
auto *
B : Sec.blocks())
1095 for (
auto &
E :
B->edges())
1096 if (
E.getTarget().isDefined() &&
1097 &
E.getTarget().getSection() == ObjCImageInfo)
1099 " is referenced within file " +
1104 auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();
1105 auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();
1111 std::lock_guard<std::mutex> Lock(PluginMutex);
1114 if (ObjCImageInfoItr != ObjCImageInfos.end()) {
1117 if (ObjCImageInfoItr->second.Version !=
Version)
1119 "ObjC version in " +
G.getName() +
1120 " does not match first registered version",
1122 if (ObjCImageInfoItr->second.Flags != Flags)
1123 if (
Error E = mergeImageInfoFlags(
G, MR, ObjCImageInfoItr->second, Flags))
1127 for (
auto *S : ObjCImageInfo->symbols())
1128 G.removeDefinedSymbol(*S);
1129 G.removeBlock(ObjCImageInfoBlock);
1132 dbgs() <<
"MachOPlatform: Registered __objc_imageinfo for "
1134 <<
"; flags = " <<
formatv(
"{0:x4}", Flags) <<
"\n";
1138 G.addDefinedSymbol(ObjCImageInfoBlock, 0, ObjCImageInfoSymbolName,
1142 {{MR.getExecutionSession().intern(ObjCImageInfoSymbolName),
1143 JITSymbolFlags()}}))
1151Error MachOPlatform::MachOPlatformPlugin::mergeImageInfoFlags(
1153 ObjCImageInfo &Info, uint32_t NewFlags) {
1154 if (
Info.Flags == NewFlags)
1157 ObjCImageInfoFlags Old(
Info.Flags);
1158 ObjCImageInfoFlags
New(NewFlags);
1161 if (Old.SwiftABIVersion &&
New.SwiftABIVersion &&
1162 Old.SwiftABIVersion !=
New.SwiftABIVersion)
1164 " does not match first registered flags",
1170 if (
Info.Finalized && Old.HasCategoryClassProperties &&
1171 !
New.HasCategoryClassProperties)
1174 " does not match first registered flags",
1176 if (
Info.Finalized && Old.HasSignedObjCClassROs && !
New.HasSignedObjCClassROs)
1179 " does not match first registered flags",
1188 if (Old.SwiftVersion &&
New.SwiftVersion)
1189 New.SwiftVersion = std::min(Old.SwiftVersion,
New.SwiftVersion);
1190 else if (Old.SwiftVersion)
1191 New.SwiftVersion = Old.SwiftVersion;
1193 if (!
New.SwiftABIVersion)
1194 New.SwiftABIVersion = Old.SwiftABIVersion;
1196 if (Old.HasCategoryClassProperties !=
New.HasCategoryClassProperties)
1197 New.HasCategoryClassProperties =
false;
1199 if (Old.HasSignedObjCClassROs !=
New.HasSignedObjCClassROs)
1200 New.HasSignedObjCClassROs =
false;
1203 dbgs() <<
"MachOPlatform: Merging __objc_imageinfo flags for "
1205 <<
formatv(
"{0:x4}", Old.rawFlags()) <<
")"
1206 <<
" with " <<
G.getName() <<
" (" <<
formatv(
"{0:x4}", NewFlags)
1208 <<
" -> " <<
formatv(
"{0:x4}",
New.rawFlags()) <<
"\n";
1215Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
1216 jitlink::LinkGraph &
G, JITDylib &JD) {
1217 auto TLVBootStrapSymbolName =
G.intern(
"__tlv_bootstrap");
1219 for (
auto *Sym :
G.external_symbols())
1220 if (Sym->
getName() == TLVBootStrapSymbolName) {
1222 MP.getExecutionSession().intern(
"___orc_rt_macho_tlv_get_addr");
1223 Sym->
setName(std::move(TLSGetADDR));
1229 std::optional<uint64_t>
Key;
1231 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1232 auto I = MP.JITDylibToPThreadKey.find(&JD);
1233 if (
I != MP.JITDylibToPThreadKey.end())
1238 if (
auto KeyOrErr = MP.createPThreadKey())
1241 return KeyOrErr.takeError();
1244 uint64_t PlatformKeyBits =
1247 for (
auto *
B : ThreadDataSec->blocks()) {
1248 if (
B->getSize() != 3 *
G.getPointerSize())
1250 formatv(
"{0:x}",
B->getAddress()) +
1251 " has unexpected size",
1254 auto NewBlockContent =
G.allocateBuffer(
B->getSize());
1255 llvm::copy(
B->getContent(), NewBlockContent.data());
1256 memcpy(NewBlockContent.data() +
G.getPointerSize(), &PlatformKeyBits,
1257 G.getPointerSize());
1258 B->setContent(NewBlockContent);
1263 for (
auto *
B :
G.blocks())
1264 for (
auto &
E :
B->edges())
1267 E.setKind(jitlink::x86_64::
1268 RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable);
1273std::optional<MachOPlatform::MachOPlatformPlugin::UnwindSections>
1274MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
1275 jitlink::LinkGraph &
G) {
1276 using namespace jitlink;
1283 auto ScanUnwindInfoSection = [&](
Section &Sec, ExecutorAddrRange &SecRange,
1284 auto AddCodeBlocks) {
1285 if (Sec.blocks().empty())
1287 SecRange = (*Sec.blocks().
begin())->getRange();
1288 for (
auto *
B : Sec.blocks()) {
1289 auto R =
B->getRange();
1290 SecRange.Start = std::min(SecRange.Start,
R.Start);
1291 SecRange.End = std::max(SecRange.End,
R.End);
1297 ScanUnwindInfoSection(*EHFrameSec, US.DwarfSection, [&](
Block &
B) {
1298 if (auto *Fn = jitlink::EHFrameCFIBlockInspector::FromEdgeScan(B)
1300 if (Fn->getTarget().isDefined())
1301 CodeBlocks.push_back(&Fn->getTarget().getBlock());
1306 ScanUnwindInfoSection(
1307 *CUInfoSec, US.CompactUnwindSection, [&](
Block &
B) {
1308 for (auto &E : B.edges()) {
1309 assert(E.getTarget().isDefined() &&
1310 "unwind-info record edge has external target");
1311 assert(E.getKind() == Edge::KeepAlive &&
1312 "unwind-info record has unexpected edge kind");
1313 CodeBlocks.push_back(&E.getTarget().getBlock());
1320 if (CodeBlocks.
empty())
1321 return std::nullopt;
1326 return LHS->getAddress() <
RHS->getAddress();
1328 for (
auto *
B : CodeBlocks) {
1329 if (US.CodeRanges.empty() || US.CodeRanges.back().End !=
B->getAddress())
1330 US.CodeRanges.push_back(
B->getRange());
1332 US.CodeRanges.back().End =
B->getRange().End;
1336 dbgs() <<
"MachOPlatform identified unwind info in " <<
G.getName() <<
":\n"
1338 if (US.DwarfSection.Start)
1339 dbgs() << US.DwarfSection <<
"\n";
1342 dbgs() <<
" Compact-unwind: ";
1343 if (US.CompactUnwindSection.Start)
1344 dbgs() << US.CompactUnwindSection <<
"\n";
1347 <<
"for code ranges:\n";
1348 for (
auto &CR : US.CodeRanges)
1349 dbgs() <<
" " << CR <<
"\n";
1350 if (US.CodeRanges.size() >=
G.sections_size())
1351 dbgs() <<
"WARNING: High number of discontiguous code ranges! "
1352 "Padding may be interfering with coalescing.\n";
1358Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
1360 bool InBootstrapPhase) {
1364 jitlink::Section *ThreadDataSection =
1372 if (ThreadDataSection)
1373 G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
1375 ThreadDataSection = ThreadBSSSection;
1384 for (
auto &SecName : DataSections) {
1385 if (
auto *Sec =
G.findSectionByName(SecName)) {
1386 jitlink::SectionRange
R(*Sec);
1388 MachOPlatformSecs.
push_back({SecName,
R.getRange()});
1394 if (ThreadDataSection) {
1395 jitlink::SectionRange
R(*ThreadDataSection);
1403 ObjCRuntimeObjectSectionName};
1405 for (
auto &SecName : PlatformSections) {
1406 auto *Sec =
G.findSectionByName(SecName);
1409 jitlink::SectionRange
R(*Sec);
1413 MachOPlatformSecs.
push_back({SecName,
R.getRange()});
1416 std::optional<std::tuple<SmallVector<ExecutorAddrRange>, ExecutorAddrRange,
1419 if (
auto UI = findUnwindSectionInfo(
G))
1420 UnwindInfo = std::make_tuple(std::move(UI->CodeRanges), UI->DwarfSection,
1421 UI->CompactUnwindSection);
1423 if (!MachOPlatformSecs.
empty() || UnwindInfo) {
1426 dbgs() <<
"MachOPlatform: Scraped " <<
G.getName() <<
" init sections:\n";
1427 for (
auto &KV : MachOPlatformSecs)
1428 dbgs() <<
" " << KV.first <<
": " << KV.second <<
"\n";
1431 assert(HeaderAddr &&
"Null header registered for JD");
1432 using SPSRegisterObjectPlatformSectionsArgs = SPSArgList<
1434 SPSOptional<SPSTuple<SPSSequence<SPSExecutorAddrRange>,
1436 SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>>;
1441 MP.RegisterObjectPlatformSections.Addr, HeaderAddr, UnwindInfo,
1442 MachOPlatformSecs)),
1445 MP.DeregisterObjectPlatformSections.Addr, HeaderAddr,
1446 UnwindInfo, MachOPlatformSecs))};
1451 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1452 MP.Bootstrap->DeferredAAs.push_back(std::move(
AllocActions));
1459Error MachOPlatform::MachOPlatformPlugin::createObjCRuntimeObject(
1460 jitlink::LinkGraph &
G) {
1462 bool NeedTextSegment =
false;
1463 size_t NumRuntimeSections = 0;
1465 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData)
1466 if (
G.findSectionByName(ObjCRuntimeSectionName))
1467 ++NumRuntimeSections;
1469 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {
1470 if (
G.findSectionByName(ObjCRuntimeSectionName)) {
1471 ++NumRuntimeSections;
1472 NeedTextSegment =
true;
1477 if (NumRuntimeSections == 0)
1482 ++NumRuntimeSections;
1484 size_t MachOSize =
sizeof(MachO::mach_header_64) +
1485 (NeedTextSegment + 1) *
sizeof(MachO::segment_command_64) +
1486 NumRuntimeSections *
sizeof(MachO::section_64);
1488 auto &Sec =
G.createSection(ObjCRuntimeObjectSectionName,
1490 G.createMutableContentBlock(Sec, MachOSize, ExecutorAddr(), 16, 0,
true);
1495Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
1496 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1498 auto *ObjCRuntimeObjectSec =
1499 G.findSectionByName(ObjCRuntimeObjectSectionName);
1501 if (!ObjCRuntimeObjectSec)
1504 switch (
G.getTargetTriple().getArch()) {
1511 G.getTargetTriple().str(),
1515 auto &SecBlock = **ObjCRuntimeObjectSec->blocks().begin();
1518 MachO::section_64 Sec;
1519 unique_function<void(
size_t RecordOffset)> AddFixups;
1522 std::vector<SecDesc> TextSections, DataSections;
1523 auto AddSection = [&](SecDesc &SD, jitlink::Section &GraphSec) {
1524 jitlink::SectionRange SR(GraphSec);
1525 StringRef FQName = GraphSec.getName();
1526 memset(&SD.Sec, 0,
sizeof(MachO::section_64));
1528 memcpy(SD.Sec.segname, FQName.
data(), 6);
1529 SD.Sec.addr = SR.getStart() - SecBlock.getAddress();
1530 SD.Sec.size = SR.getSize();
1536 DataSections.push_back({});
1537 auto &SD = DataSections.back();
1538 memset(&SD.Sec, 0,
sizeof(SD.Sec));
1539 memcpy(SD.Sec.sectname,
"__objc_imageinfo", 16);
1540 strcpy(SD.Sec.segname,
"__DATA");
1542 jitlink::Symbol *ObjCImageInfoSym =
nullptr;
1543 SD.AddFixups = [&, ObjCImageInfoSym](
size_t RecordOffset)
mutable {
1544 auto PointerEdge = getPointerEdgeKind(
G);
1547 if (!ObjCImageInfoSym) {
1548 auto Name =
G.intern(ObjCImageInfoSymbolName);
1549 ObjCImageInfoSym =
G.findExternalSymbolByName(Name);
1550 if (!ObjCImageInfoSym)
1551 ObjCImageInfoSym =
G.findAbsoluteSymbolByName(Name);
1552 if (!ObjCImageInfoSym) {
1553 ObjCImageInfoSym =
G.findDefinedSymbolByName(Name);
1554 if (ObjCImageInfoSym) {
1555 std::optional<uint32_t>
Flags;
1557 std::lock_guard<std::mutex> Lock(PluginMutex);
1559 if (It != ObjCImageInfos.end()) {
1560 It->second.Finalized =
true;
1561 Flags = It->second.Flags;
1570 Content.size() == 8 &&
1571 "__objc_image_info size should have been verified already");
1576 if (!ObjCImageInfoSym)
1577 ObjCImageInfoSym = &
G.addExternalSymbol(std::move(Name), 8,
false);
1580 SecBlock.addEdge(PointerEdge,
1581 RecordOffset + ((
char *)&SD.Sec.addr - (
char *)&SD.Sec),
1582 *ObjCImageInfoSym, -SecBlock.getAddress().getValue());
1586 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData) {
1587 if (
auto *GraphSec =
G.findSectionByName(ObjCRuntimeSectionName)) {
1588 DataSections.push_back({});
1589 AddSection(DataSections.back(), *GraphSec);
1593 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {
1594 if (
auto *GraphSec =
G.findSectionByName(ObjCRuntimeSectionName)) {
1595 TextSections.push_back({});
1596 AddSection(TextSections.back(), *GraphSec);
1600 assert(ObjCRuntimeObjectSec->blocks_size() == 1 &&
1601 "Unexpected number of blocks in runtime sections object");
1605 MachO::mach_header_64 Hdr;
1607 switch (
G.getTargetTriple().getArch()) {
1621 Hdr.
ncmds = 1 + !TextSections.empty();
1623 Hdr.
ncmds *
sizeof(MachO::segment_command_64) +
1624 (TextSections.size() + DataSections.size()) *
sizeof(MachO::section_64);
1628 auto SecContent = SecBlock.getAlreadyMutableContent();
1629 char *
P = SecContent.data();
1630 auto WriteMachOStruct = [&](
auto S) {
1633 memcpy(
P, &S,
sizeof(S));
1637 auto WriteSegment = [&](StringRef
Name, std::vector<SecDesc> &Secs) {
1638 MachO::segment_command_64 SegLC;
1639 memset(&SegLC, 0,
sizeof(SegLC));
1641 SegLC.
cmd = MachO::LC_SEGMENT_64;
1642 SegLC.
cmdsize =
sizeof(MachO::segment_command_64) +
1643 Secs.size() *
sizeof(MachO::section_64);
1644 SegLC.
nsects = Secs.size();
1645 WriteMachOStruct(SegLC);
1646 for (
auto &SD : Secs) {
1648 SD.AddFixups(
P - SecContent.data());
1649 WriteMachOStruct(SD.Sec);
1653 WriteMachOStruct(Hdr);
1654 if (!TextSections.empty())
1655 WriteSegment(
"__TEXT", TextSections);
1656 if (!DataSections.empty())
1657 WriteSegment(
"__DATA", DataSections);
1659 assert(
P == SecContent.end() &&
"Underflow writing ObjC runtime object");
1663Error MachOPlatform::MachOPlatformPlugin::prepareSymbolTableRegistration(
1664 jitlink::LinkGraph &
G, JITSymTabVector &JITSymTabInfo) {
1672 DenseMap<StringRef, jitlink::Symbol *> ExistingStrings;
1673 for (
auto *Sym : CStringSec->symbols()) {
1679 std::make_pair(StringRef(Content.data(), Content.size()), Sym));
1685 SmallVector<jitlink::Symbol *> SymsToProcess;
1689 for (
auto *Sym : SymsToProcess) {
1694 if (
I == ExistingStrings.
end()) {
1695 auto &NameBlock =
G.createMutableContentBlock(
1696 *CStringSec,
G.allocateCString(*Sym->
getName()),
1697 orc::ExecutorAddr(), 1, 0);
1698 auto &SymbolNameSym =
G.addAnonymousSymbol(
1699 NameBlock, 0, NameBlock.getSize(),
false,
true);
1700 JITSymTabInfo.push_back({Sym, &SymbolNameSym});
1702 JITSymTabInfo.push_back({Sym,
I->second});
1709Error MachOPlatform::MachOPlatformPlugin::addSymbolTableRegistration(
1710 jitlink::LinkGraph &
G, MaterializationResponsibility &MR,
1711 JITSymTabVector &JITSymTabInfo,
bool InBootstrapPhase) {
1713 ExecutorAddr HeaderAddr;
1715 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1717 assert(
I != MP.JITDylibToHeaderAddr.end() &&
"No header registered for JD");
1718 assert(
I->second &&
"Null header registered for JD");
1719 HeaderAddr =
I->second;
1726 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1727 auto &SymTab = MP.Bootstrap->SymTab;
1728 for (
auto &[OriginalSymbol, NameSym] : JITSymTabInfo)
1729 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),
1730 flagsForSymbol(*OriginalSymbol)});
1734 SymbolTableVector SymTab;
1735 for (
auto &[OriginalSymbol, NameSym] : JITSymTabInfo)
1736 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),
1737 flagsForSymbol(*OriginalSymbol)});
1739 G.allocActions().push_back(
1741 MP.RegisterObjectSymbolTable.Addr, HeaderAddr, SymTab)),
1743 MP.DeregisterObjectSymbolTable.Addr, HeaderAddr, SymTab))});
1748template <
typename MachOTraits>
1758 B.Header.cputype = HdrInfo.CPUType;
1759 B.Header.cpusubtype = HdrInfo.CPUSubType;
1762 B.template addLoadCommand<MachO::LC_ID_DYLIB>(
1764 Opts.
IDDylib->CurrentVersion, Opts.
IDDylib->CompatibilityVersion);
1766 B.template addLoadCommand<MachO::LC_ID_DYLIB>(JD.
getName(), 0, 0, 0);
1769 B.template addLoadCommand<MachO::LC_UUID>(*Opts.
UUID);
1772 B.template addLoadCommand<MachO::LC_BUILD_VERSION>(
1773 BV.Platform, BV.MinOS, BV.SDK,
static_cast<uint32_t>(0));
1778 case LoadKind::Default:
1779 B.template addLoadCommand<MachO::LC_LOAD_DYLIB>(
1780 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,
1781 LD.D.CompatibilityVersion);
1783 case LoadKind::Weak:
1784 B.template addLoadCommand<MachO::LC_LOAD_WEAK_DYLIB>(
1785 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,
1786 LD.D.CompatibilityVersion);
1791 B.template addLoadCommand<MachO::LC_RPATH>(
P);
1793 auto HeaderContent =
G.allocateBuffer(
B.layout());
1794 B.write(HeaderContent);
1796 return G.createContentBlock(HeaderSection, HeaderContent,
ExecutorAddr(), 8,
1804 createHeaderInterface(
MOP,
std::
move(HeaderStartSymbol))),
1808 std::unique_ptr<MaterializationResponsibility> R) {
1809 auto G = createPlatformGraph(
MOP,
"<MachOHeaderMU>");
1810 addMachOHeader(R->getTargetJITDylib(), *
G, R->getInitializerSymbol());
1811 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(
G));
1817void SimpleMachOHeaderMU::addMachOHeader(
1820 auto &HeaderSection =
G.createSection(
"__header",
MemProt::Read);
1824 G.addDefinedSymbol(HeaderBlock, 0, *InitializerSymbol, HeaderBlock.getSize(),
1827 for (
auto &HS : AdditionalHeaderSymbols)
1828 G.addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name, HeaderBlock.getSize(),
1836 switch (
MOP.getExecutionSession().getTargetTriple().getArch()) {
1839 return ::createHeaderBlock<MachO64LE>(
MOP,
Opts, JD,
G, HeaderSection);
1850 for (
auto &HS : AdditionalHeaderSymbols)
1859 switch (TT.getArch()) {
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")
#define LLVM_UNLIKELY(EXPR)
#define LLVM_LIKELY(EXPR)
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
static StringRef getName(Value *V)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
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)
StringRef - Represent a constant reference to a string, i.e.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Manages the enabling and disabling of subtarget specific features.
Triple - Helper class for working with autoconf configuration names.
An Addressable with content and edges.
ArrayRef< char > getContent() const
Get the content for this block. Block must not be a zero-fill block.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
MutableArrayRef< char > getMutableContent(LinkGraph &G)
Get mutable content for this block.
const std::string & getName() const
Get the name for this JITLinkDylib.
void removeSection(Section &Sec)
Remove a section.
Section * findSectionByName(StringRef Name)
Returns the section with the given name if it exists, otherwise returns null.
Symbol & addAbsoluteSymbol(orc::SymbolStringPtr Name, orc::ExecutorAddr Address, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive)
Add an absolute symbol.
Represents an object file section.
bool isCallable() const
Returns true is this symbol is callable.
const orc::SymbolStringPtr & getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
Linkage getLinkage() const
Get the linkage for this Symbol.
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
Block & getBlock()
Return the Block for this Symbol (Symbol must be defined).
void setName(orc::SymbolStringPtr Name)
Rename this symbol.
bool hasName() const
Returns true if this symbol has a name.
An ExecutionSession represents a running JIT program.
const Triple & getTargetTriple() const
Return the triple for the executor.
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.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Error defineMaterializing(SymbolFlagsMap SymbolFlags)
Attempt to claim responsibility for new definitions.
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,...
MaterializationUnit(Interface I)
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.
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, VisitMembersFunction VisitMembers=VisitMembersFunction(), GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())
Try to create a StaticLibraryDefinitionGenerator from the given path.
Pointer to a pooled string representing a symbol name.
A utility class for serializing to a blob from a variadic list.
Output char buffer with overflow check.
SPS tag type for sequences.
static size_t size(const MachOPlatform::MachOExecutorSymbolFlags &SF)
static bool deserialize(SPSInputBuffer &IB, MachOPlatform::MachOExecutorSymbolFlags &SF)
static bool serialize(SPSOutputBuffer &OB, const MachOPlatform::MachOExecutorSymbolFlags &SF)
static bool serialize(SPSOutputBuffer &OB, const MachOPlatform::MachOJITDylibDepInfo &DDI)
static size_t size(const MachOPlatform::MachOJITDylibDepInfo &DDI)
static bool deserialize(SPSInputBuffer &IB, MachOPlatform::MachOJITDylibDepInfo &DDI)
Specialize to describe how to serialize/deserialize to/from the given concrete type.
static Expected< WrapperFunctionCall > Create(ExecutorAddr FnAddr, const ArgTs &...Args)
Create a WrapperFunctionCall using the given SPS serializer to serialize the arguments.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ S_REGULAR
S_REGULAR - Regular section.
void swapStruct(fat_header &mh)
@ Pointer64
A plain 64-bit pointer value relocation.
@ RequestTLVPAndTransformToPCRel32TLVPLoadREXRelaxable
A TLVP entry getter/constructor, transformed to Delta32ToTLVPLoadREXRelaxable.
@ 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.
SPSTuple< bool, SPSSequence< SPSExecutorAddr > > SPSMachOJITDylibDepInfo
std::vector< AllocActionCallPair > AllocActions
A vector of allocation actions to be run for this allocation.
SPSSequence< SPSTuple< SPSExecutorAddr, SPSMachOJITDylibDepInfo > > SPSMachOJITDylibDepInfoMap
SPSTuple< SPSExecutorAddr, SPSExecutorAddr > SPSExecutorAddrRange
LLVM_ABI StringRef MachOSwift5EntrySectionName
LLVM_ABI StringRef MachOThreadBSSSectionName
LLVM_ABI StringRef MachOThreadVarsSectionName
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.
LLVM_ABI StringRef MachOObjCProtoListSectionName
LLVM_ABI StringRef MachOSwift5ProtosSectionName
LLVM_ABI StringRef MachOEHFrameSectionName
LLVM_ABI StringRef MachOModInitFuncSectionName
LLVM_ABI StringRef MachOObjCConstSectionName
LLVM_ABI StringRef MachODataDataSectionName
LLVM_ABI StringRef MachOCompactUnwindSectionName
LLVM_ABI StringRef MachOSwift5ProtoSectionName
@ MatchExportedSymbolsOnly
static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases, ArrayRef< std::pair< const char *, const char * > > AL)
LLVM_ABI StringRef MachOObjCCatListSectionName
LLVM_ABI StringRef MachOObjCClassRefsSectionName
LLVM_ABI StringRef MachOObjCDataSectionName
LLVM_ABI StringRef MachOObjCClassNameSectionName
LLVM_ABI StringRef MachOObjCMethNameSectionName
LLVM_ABI StringRef MachOInitSectionNames[22]
LLVM_ABI StringRef MachOObjCClassListSectionName
LLVM_ABI StringRef MachOObjCSelRefsSectionName
LLVM_ABI StringRef MachOSwift5FieldMetadataSectionName
LLVM_ABI StringRef MachOCStringSectionName
LLVM_ABI StringRef MachOObjCMethTypeSectionName
LLVM_ABI StringRef MachOSwift5TypesSectionName
LLVM_ABI StringRef MachOObjCNLCatListSectionName
jitlink::Block & createHeaderBlock(MachOPlatform &MOP, const MachOPlatform::HeaderOptions &Opts, JITDylib &JD, jitlink::LinkGraph &G, jitlink::Section &HeaderSection)
LLVM_ABI StringRef MachOObjCNLClassListSectionName
LLVM_ABI StringRef MachOObjCImageInfoSectionName
LLVM_ABI MachOHeaderInfo getMachOHeaderInfoFromTriple(const Triple &TT)
LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
LLVM_ABI StringRef MachOThreadDataSectionName
LLVM_ABI StringRef MachOUnwindInfoSectionName
LLVM_ABI StringRef MachODataCommonSectionName
LLVM_ABI StringRef MachOObjCProtoRefsSectionName
@ Ready
Emitted to memory, but waiting on transitive dependencies.
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
LLVM_ABI StringRef MachOSwift5TypeRefSectionName
LLVM_ABI StringRef MachOObjCCatList2SectionName
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
LLVM_ABI iterator begin() const
value_type byte_swap(value_type value, endianness endian)
uint32_t read32(const void *P, endianness E)
void write32(void *P, uint32_t V, endianness E)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
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...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
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 copy(R &&Range, OutputIt Out)
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.
Implement std::hash so that hash_code can be used in STL containers.
LinkGraphPassList PostAllocationPasses
Post-allocation passes.
LinkGraphPassList PostFixupPasses
Post-fixup passes.
LinkGraphPassList PostPrunePasses
Post-prune passes.
LinkGraphPassList PrePrunePasses
Pre-prune passes.