26#define DEBUG_TYPE "orc"
40class SPSMachOExecutorSymbolFlags;
52 return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.
Sealed,
58 return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.
Sealed,
67 using UT = std::underlying_type_t<MachOPlatform::MachOExecutorSymbolFlags>;
113 SPSSequence<SPSTuple<SPSString, bool>>)> {
121using SPSRegisterSymbolsArgs =
124 SPSMachOExecutorSymbolFlags>>>;
126std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(
MachOPlatform &MOP,
129 return std::make_unique<jitlink::LinkGraph>(
130 std::move(Name), ES.getSymbolStringPool(), ES.getTargetTriple(),
136class MachOPlatformCompleteBootstrapMaterializationUnit
139 using SymbolTableVector =
143 MachOPlatformCompleteBootstrapMaterializationUnit(
153 MOP(MOP), PlatformJDName(PlatformJDName),
154 CompleteBootstrapSymbol(std::move(CompleteBootstrapSymbol)),
155 SymTab(std::move(SymTab)), DeferredAAs(std::move(DeferredAAs)),
156 MachOHeaderAddr(MachOHeaderAddr), PlatformBootstrap(PlatformBootstrap),
157 PlatformShutdown(PlatformShutdown), RegisterJITDylib(RegisterJITDylib),
158 DeregisterJITDylib(DeregisterJITDylib),
159 RegisterObjectSymbolTable(RegisterObjectSymbolTable),
160 DeregisterObjectSymbolTable(DeregisterObjectSymbolTable) {}
162 StringRef
getName()
const override {
163 return "MachOPlatformCompleteBootstrap";
166 void materialize(std::unique_ptr<MaterializationResponsibility> R)
override {
167 using namespace jitlink;
168 auto G = createPlatformGraph(MOP,
"<OrcRTCompleteBootstrap>");
169 auto &PlaceholderSection =
170 G->createSection(
"__orc_rt_cplt_bs", MemProt::Read);
171 auto &PlaceholderBlock =
172 G->createZeroFillBlock(PlaceholderSection, 1, ExecutorAddr(), 1, 0);
173 G->addDefinedSymbol(PlaceholderBlock, 0, *CompleteBootstrapSymbol, 1,
174 Linkage::Strong, Scope::Hidden,
false,
true);
177 G->allocActions().reserve(DeferredAAs.size() + 3);
180 G->allocActions().push_back(
186 G->allocActions().push_back(
188 SPSArgList<SPSString, SPSExecutorAddr>>(
189 RegisterJITDylib, PlatformJDName, MachOHeaderAddr)),
191 DeregisterJITDylib, MachOHeaderAddr))});
194 G->allocActions().push_back(
196 RegisterObjectSymbolTable, MachOHeaderAddr, SymTab)),
198 DeregisterObjectSymbolTable, MachOHeaderAddr, SymTab))});
201 std::move(DeferredAAs.begin(), DeferredAAs.end(),
202 std::back_inserter(
G->allocActions()));
204 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(
G));
207 void discard(
const JITDylib &JD,
const SymbolStringPtr &Sym)
override {}
211 StringRef PlatformJDName;
212 SymbolStringPtr CompleteBootstrapSymbol;
213 SymbolTableVector SymTab;
215 ExecutorAddr MachOHeaderAddr;
216 ExecutorAddr PlatformBootstrap;
217 ExecutorAddr PlatformShutdown;
218 ExecutorAddr RegisterJITDylib;
219 ExecutorAddr DeregisterJITDylib;
220 ExecutorAddr RegisterObjectSymbolTable;
221 ExecutorAddr DeregisterObjectSymbolTable;
224static StringRef ObjCRuntimeObjectSectionsData[] = {
232static StringRef ObjCRuntimeObjectSectionsText[] = {
239static StringRef ObjCRuntimeObjectSectionName =
240 "__llvm_jitlink_ObjCRuntimeRegistrationObject";
242static StringRef ObjCImageInfoSymbolName =
243 "__llvm_jitlink_macho_objc_imageinfo";
245struct ObjCImageInfoFlags {
246 uint16_t SwiftABIVersion;
247 uint16_t SwiftVersion;
248 bool HasCategoryClassProperties;
249 bool HasSignedObjCClassROs;
251 static constexpr uint32_t SIGNED_CLASS_RO = (1 << 4);
252 static constexpr uint32_t HAS_CATEGORY_CLASS_PROPERTIES = (1 << 6);
254 explicit ObjCImageInfoFlags(uint32_t RawFlags) {
255 HasSignedObjCClassROs = RawFlags & SIGNED_CLASS_RO;
256 HasCategoryClassProperties = RawFlags & HAS_CATEGORY_CLASS_PROPERTIES;
257 SwiftABIVersion = (RawFlags >> 8) & 0xFF;
258 SwiftVersion = (RawFlags >> 16) & 0xFFFF;
261 uint32_t rawFlags()
const {
263 if (HasCategoryClassProperties)
264 Result |= HAS_CATEGORY_CLASS_PROPERTIES;
265 if (HasSignedObjCClassROs)
266 Result |= SIGNED_CLASS_RO;
267 Result |= (SwiftABIVersion << 8);
268 Result |= (SwiftVersion << 16);
277std::optional<MachOPlatform::HeaderOptions::BuildVersionOpts>
283 switch (TT.getOS()) {
285 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
286 : MachO::PLATFORM_IOS;
292 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
293 : MachO::PLATFORM_TVOS;
296 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
297 : MachO::PLATFORM_WATCHOS;
300 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR
301 : MachO::PLATFORM_XROS;
312 std::unique_ptr<DefinitionGenerator> OrcRuntime,
316 std::optional<SymbolAliasMap> RuntimeAliases) {
318 auto &ES = ObjLinkingLayer.getExecutionSession();
321 if (!supportedTarget(ES.getTargetTriple()))
323 ES.getTargetTriple().str(),
331 if (
auto Err = PlatformJD.define(
symbolAliases(std::move(*RuntimeAliases))))
332 return std::move(Err);
337 if (
auto Err = PlatformJD.define(
reexports(
338 ES.getBootstrapJITDylib(),
339 {{ES.intern(
"___orc_rt_jit_dispatch"),
340 {Mangle(rt::DispatchName),
341 JITSymbolFlags::Exported | JITSymbolFlags::Callable}},
342 {ES.intern(
"___orc_rt_jit_dispatch_ctx"),
343 {Mangle(rt::DispatchCtxName), JITSymbolFlags::Exported}}})))
349 auto P = std::unique_ptr<MachOPlatform>(
350 new MachOPlatform(ObjLinkingLayer, PlatformJD, std::move(OrcRuntime),
351 std::move(BuildHeaderOpts), std::move(PlatformJDOpts),
352 std::move(BuildMachOHeaderMU), Err));
354 return std::move(Err);
362 std::optional<SymbolAliasMap> RuntimeAliases) {
365 auto OrcRuntimeArchiveGenerator =
367 if (!OrcRuntimeArchiveGenerator)
368 return OrcRuntimeArchiveGenerator.takeError();
370 return Create(ObjLinkingLayer, PlatformJD,
371 std::move(*OrcRuntimeArchiveGenerator),
372 std::move(BuildHeaderOpts), std::move(PlatformJDOpts),
373 std::move(BuildMachOHeaderMU), std::move(RuntimeAliases));
381 if (
auto Err = JD.
define(BuildMachOHeaderMU(*
this, std::move(Opts))))
384 return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
388 std::lock_guard<std::mutex> Lock(PlatformMutex);
389 auto I = JITDylibToHeaderAddr.find(&JD);
390 if (
I != JITDylibToHeaderAddr.end()) {
391 assert(HeaderAddrToJITDylib.count(
I->second) &&
392 "HeaderAddrToJITDylib missing entry");
393 HeaderAddrToJITDylib.erase(
I->second);
394 JITDylibToHeaderAddr.erase(
I);
396 JITDylibToPThreadKey.erase(&JD);
407 RegisteredInitSymbols[&JD].add(InitSym,
410 dbgs() <<
"MachOPlatform: Registered init symbol " << *InitSym <<
" for MU "
421 ArrayRef<std::pair<const char *, const char *>> AL) {
422 for (
auto &KV : AL) {
423 auto AliasName = ES.
intern(KV.first);
424 assert(!Aliases.
count(AliasName) &&
"Duplicate symbol name in alias map");
425 Aliases[std::move(AliasName)] = {ES.
intern(KV.second),
440 static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
441 {
"___cxa_atexit",
"___orc_rt_macho_cxa_atexit"}};
448 static const std::pair<const char *, const char *>
449 StandardRuntimeUtilityAliases[] = {
450 {
"___orc_rt_run_program",
"___orc_rt_macho_run_program"},
451 {
"___orc_rt_jit_dlerror",
"___orc_rt_macho_jit_dlerror"},
452 {
"___orc_rt_jit_dlopen",
"___orc_rt_macho_jit_dlopen"},
453 {
"___orc_rt_jit_dlupdate",
"___orc_rt_macho_jit_dlupdate"},
454 {
"___orc_rt_jit_dlclose",
"___orc_rt_macho_jit_dlclose"},
455 {
"___orc_rt_jit_dlsym",
"___orc_rt_macho_jit_dlsym"},
456 {
"___orc_rt_log_error",
"___orc_rt_log_error_to_stderr"}};
459 StandardRuntimeUtilityAliases);
464 static const std::pair<const char *, const char *>
465 StandardLazyCompilationAliases[] = {
466 {
"__orc_rt_reenter",
"__orc_rt_sysv_reenter"}};
469 StandardLazyCompilationAliases);
476bool MachOPlatform::supportedTarget(
const Triple &TT) {
477 switch (TT.getArch()) {
487 switch (
G.getTargetTriple().getArch()) {
498MachOPlatform::flagsForSymbol(jitlink::Symbol &Sym) {
509MachOPlatform::MachOPlatform(
511 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
512 HeaderOptionsBuilder BuildHeaderOpts, HeaderOptions PlatformJDOpts,
513 MachOHeaderMUBuilder BuildMachOHeaderMU,
Error &Err)
514 : ES(ObjLinkingLayer.getExecutionSession()), PlatformJD(PlatformJD),
515 ObjLinkingLayer(ObjLinkingLayer),
516 BuildHeaderOpts(std::
move(BuildHeaderOpts)),
517 BuildMachOHeaderMU(std::
move(BuildMachOHeaderMU)) {
518 ErrorAsOutParameter
_(Err);
519 ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*
this));
520 PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
524 std::optional<bool> ForceEHFrames;
525 if ((Err = ES.getBootstrapMapValue<
bool,
bool>(
"darwin-use-ehframes-only",
528 this->ForceEHFrames = ForceEHFrames.value_or(
false);
589 if ((Err = PlatformJD.define(
590 this->BuildMachOHeaderMU(*
this, std::move(PlatformJDOpts)))))
592 if ((Err = ES.lookup(&PlatformJD, MachOHeaderStartSymbol).takeError()))
599 {PlatformBootstrap.Name, PlatformShutdown.Name,
600 RegisterJITDylib.Name, DeregisterJITDylib.Name,
601 RegisterObjectSymbolTable.Name,
602 DeregisterObjectSymbolTable.Name,
603 RegisterObjectPlatformSections.Name,
604 DeregisterObjectPlatformSections.Name,
605 CreatePThreadKey.Name}))
611 std::unique_lock<std::mutex> Lock(PlatformMutex);
612 BI.CV.wait(Lock, [&]() {
return BI.ActiveGraphs == 0; });
617 auto BootstrapCompleteSymbol = ES.intern(
"__orc_rt_macho_complete_bootstrap");
618 if ((Err = PlatformJD.define(
619 std::make_unique<MachOPlatformCompleteBootstrapMaterializationUnit>(
620 *
this, PlatformJD.getName(), BootstrapCompleteSymbol,
621 std::move(BI.SymTab), std::move(BI.DeferredAAs),
622 BI.MachOHeaderAddr, PlatformBootstrap.Addr,
623 PlatformShutdown.Addr, RegisterJITDylib.Addr,
624 DeregisterJITDylib.Addr, RegisterObjectSymbolTable.Addr,
625 DeregisterObjectSymbolTable.Addr))))
629 std::move(BootstrapCompleteSymbol))
640 if ((Err = associateRuntimeSupportFunctions()))
644Error MachOPlatform::associateRuntimeSupportFunctions() {
645 return ES.registerCallControllerHandlers(
648 this, &MachOPlatform::rt_pushInitializers),
650 this, &MachOPlatform::rt_pushSymbols));
653void MachOPlatform::pushInitializersLoop(
654 PushInitializersSendResultFn SendResult,
JITDylibSP JD) {
655 DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;
656 DenseMap<JITDylib *, SmallVector<JITDylib *>> JDDepMap;
659 ES.runSessionLocked([&]() {
660 while (!Worklist.empty()) {
663 auto DepJD = Worklist.back();
672 auto &
DM = It->second;
675 if (KV.first == DepJD)
677 DM.push_back(KV.first);
678 Worklist.push_back(KV.first);
683 auto RISItr = RegisteredInitSymbols.find(DepJD);
684 if (RISItr != RegisteredInitSymbols.end()) {
685 NewInitSymbols[DepJD] = std::move(RISItr->second);
686 RegisteredInitSymbols.erase(RISItr);
693 if (NewInitSymbols.
empty()) {
699 DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
702 std::lock_guard<std::mutex> Lock(PlatformMutex);
703 for (
auto &KV : JDDepMap) {
704 auto I = JITDylibToHeaderAddr.find(KV.first);
705 if (
I != JITDylibToHeaderAddr.end())
706 HeaderAddrs[KV.first] =
I->second;
712 DIM.reserve(JDDepMap.size());
713 for (
auto &KV : JDDepMap) {
714 auto HI = HeaderAddrs.
find(KV.first);
716 if (HI == HeaderAddrs.
end())
720 for (
auto &Dep : KV.second) {
721 auto HJ = HeaderAddrs.
find(Dep);
722 if (HJ != HeaderAddrs.
end())
723 DepInfo.DepHeaders.push_back(HJ->second);
725 DIM.push_back(std::make_pair(
H, std::move(DepInfo)));
733 [
this, SendResult = std::move(SendResult), JD](
Error Err)
mutable {
735 SendResult(std::move(Err));
737 pushInitializersLoop(std::move(SendResult), JD);
739 ES, std::move(NewInitSymbols));
742void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
746 std::lock_guard<std::mutex> Lock(PlatformMutex);
747 auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
748 if (
I != HeaderAddrToJITDylib.end())
753 dbgs() <<
"MachOPlatform::rt_pushInitializers(" << JDHeaderAddr <<
") ";
755 dbgs() <<
"pushing initializers for " << JD->
getName() <<
"\n";
757 dbgs() <<
"No JITDylib for header address.\n";
762 formatv(
"{0:x}", JDHeaderAddr),
767 pushInitializersLoop(std::move(SendResult), JD);
770void MachOPlatform::rt_pushSymbols(
771 PushSymbolsInSendResultFn SendResult,
ExecutorAddr Handle,
772 const std::vector<std::pair<StringRef, bool>> &SymbolNames) {
774 JITDylib *JD =
nullptr;
777 std::lock_guard<std::mutex> Lock(PlatformMutex);
778 auto I = HeaderAddrToJITDylib.find(Handle);
779 if (
I != HeaderAddrToJITDylib.end())
783 dbgs() <<
"MachOPlatform::rt_pushSymbols(";
787 dbgs() <<
"<invalid handle " << Handle <<
">, [ ";
788 for (
auto &Name : SymbolNames)
789 dbgs() <<
"\"" <<
Name.first <<
"\" ";
801 for (
auto &[Name,
Required] : SymbolNames)
809 [SendResult = std::move(SendResult)](Expected<SymbolMap>
Result)
mutable {
810 SendResult(
Result.takeError());
815Expected<uint64_t> MachOPlatform::createPThreadKey() {
816 if (!CreatePThreadKey.Addr)
818 "Attempting to create pthread key in target, but runtime support has "
819 "not been loaded yet",
822 using CreatePThreadKeyProxy = Proxy<Expected<uint64_t>()>;
823 CreatePThreadKeyProxy CreateKey(
824 sps::ProxySpec<macho_sps_ci::CreatePThreadKey>::dispatch,
825 CreatePThreadKey.Addr);
826 return CreateKey(ES);
829void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
831 jitlink::PassConfiguration &Config) {
833 using namespace jitlink;
835 bool InBootstrapPhase =
false;
837 ExecutorAddr HeaderAddr;
839 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
842 InBootstrapPhase =
true;
843 ++MP.Bootstrap->ActiveGraphs;
849 if (
I != MP.JITDylibToHeaderAddr.end())
850 HeaderAddr =
I->second;
855 if (MP.ForceEHFrames)
864 Linkage::Strong, Scope::Local,
true);
869 return bootstrapPipelineRecordRuntimeFunctions(
G);
878 if (InitSymbol == MP.MachOHeaderStartSymbol && !InBootstrapPhase) {
880 return associateJITDylibHeaderSymbol(
G, MR);
889 if (
auto Err = preserveImportantSections(
G, MR))
891 return processObjCImageInfo(
G, MR);
894 [
this](LinkGraph &
G) {
return createObjCRuntimeObject(
G); });
896 [
this, &MR](LinkGraph &
G) {
return populateObjCRuntimeObject(
G, MR); });
904 return fixTLVSectionsAndEdges(G, JD);
910 auto JITSymTabInfo = std::make_shared<JITSymTabVector>();
912 return prepareSymbolTableRegistration(
G, *JITSymTabInfo);
915 InBootstrapPhase](LinkGraph &
G) {
916 return addSymbolTableRegistration(
G, MR, *JITSymTabInfo, InBootstrapPhase);
923 InBootstrapPhase](LinkGraph &
G) {
924 return registerObjectPlatformSections(G, JD, HeaderAddr, InBootstrapPhase);
929 if (InBootstrapPhase)
931 [
this](LinkGraph &
G) {
return bootstrapPipelineEnd(
G); });
934Error MachOPlatform::MachOPlatformPlugin::
935 bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &
G) {
937 std::pair<StringRef, ExecutorAddr *> RuntimeSymbols[] = {
938 {*MP.MachOHeaderStartSymbol, &MP.Bootstrap->MachOHeaderAddr},
939 {*MP.PlatformBootstrap.Name, &MP.PlatformBootstrap.Addr},
940 {*MP.PlatformShutdown.Name, &MP.PlatformShutdown.Addr},
941 {*MP.RegisterJITDylib.Name, &MP.RegisterJITDylib.Addr},
942 {*MP.DeregisterJITDylib.Name, &MP.DeregisterJITDylib.Addr},
943 {*MP.RegisterObjectSymbolTable.Name, &MP.RegisterObjectSymbolTable.Addr},
944 {*MP.DeregisterObjectSymbolTable.Name,
945 &MP.DeregisterObjectSymbolTable.Addr},
946 {*MP.RegisterObjectPlatformSections.Name,
947 &MP.RegisterObjectPlatformSections.Addr},
948 {*MP.DeregisterObjectPlatformSections.Name,
949 &MP.DeregisterObjectPlatformSections.Addr},
950 {*MP.CreatePThreadKey.Name, &MP.CreatePThreadKey.Addr},
951 {*MP.RegisterObjCRuntimeObject.Name, &MP.RegisterObjCRuntimeObject.Addr},
952 {*MP.DeregisterObjCRuntimeObject.Name,
953 &MP.DeregisterObjCRuntimeObject.Addr}};
955 bool RegisterMachOHeader =
false;
957 for (
auto *Sym :
G.defined_symbols()) {
958 for (
auto &RTSym : RuntimeSymbols) {
962 "Duplicate " + RTSym.first +
963 " detected during MachOPlatform bootstrap",
966 if (Sym->
getName() == MP.MachOHeaderStartSymbol)
967 RegisterMachOHeader =
true;
974 if (RegisterMachOHeader) {
977 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
978 MP.JITDylibToHeaderAddr[&MP.PlatformJD] = MP.Bootstrap->MachOHeaderAddr;
979 MP.HeaderAddrToJITDylib[MP.Bootstrap->MachOHeaderAddr] = &MP.PlatformJD;
985Error MachOPlatform::MachOPlatformPlugin::bootstrapPipelineEnd(
986 jitlink::LinkGraph &
G) {
987 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
989 --MP.Bootstrap->ActiveGraphs;
992 if (MP.Bootstrap->ActiveGraphs == 0)
993 MP.Bootstrap->CV.notify_all();
997Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
998 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
999 auto I =
llvm::find_if(
G.defined_symbols(), [
this](jitlink::Symbol *Sym) {
1000 return Sym->getName() == MP.MachOHeaderStartSymbol;
1002 assert(
I !=
G.defined_symbols().end() &&
"Missing MachO header start symbol");
1005 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1006 auto HeaderAddr = (*I)->getAddress();
1007 MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
1008 MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
1011 G.allocActions().push_back(
1014 MP.RegisterJITDylib.Addr, JD.
getName(), HeaderAddr)),
1016 MP.DeregisterJITDylib.Addr, HeaderAddr))});
1020Error MachOPlatform::MachOPlatformPlugin::preserveImportantSections(
1021 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1026 if (
auto *ObjCImageInfoSec =
1028 if (ObjCImageInfoSec->blocks_size() != 1)
1030 "In " +
G.getName() +
1031 "__DATA,__objc_imageinfo contains multiple blocks",
1033 G.addAnonymousSymbol(**ObjCImageInfoSec->blocks().begin(), 0, 0,
false,
1036 for (
auto *
B : ObjCImageInfoSec->blocks())
1037 if (!
B->edges_empty())
1040 " contains references to symbols",
1049 jitlink::Symbol *InitSym =
nullptr;
1057 auto *InitSection =
G.findSectionByName(InitSectionName);
1058 if (!InitSection || InitSection->empty())
1064 auto &
B = **InitSection->blocks().begin();
1065 InitSym = &
G.addDefinedSymbol(
1071 for (
auto *
B : InitSection->blocks()) {
1075 auto &S =
G.addAnonymousSymbol(*
B, 0,
B->getSize(),
false,
true);
1084Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
1085 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1097 auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();
1100 if (ObjCImageInfoBlocks.empty())
1102 " section in " +
G.getName(),
1106 if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())
1109 " section in " +
G.getName(),
1114 for (
auto &Sec :
G.sections()) {
1115 if (&Sec != ObjCImageInfo)
1116 for (
auto *
B : Sec.blocks())
1117 for (
auto &
E :
B->edges())
1118 if (
E.getTarget().isDefined() &&
1119 &
E.getTarget().getSection() == ObjCImageInfo)
1121 " is referenced within file " +
1126 auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();
1127 auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();
1133 std::lock_guard<std::mutex> Lock(PluginMutex);
1136 if (ObjCImageInfoItr != ObjCImageInfos.end()) {
1139 if (ObjCImageInfoItr->second.Version !=
Version)
1141 "ObjC version in " +
G.getName() +
1142 " does not match first registered version",
1144 if (ObjCImageInfoItr->second.Flags != Flags)
1145 if (
Error E = mergeImageInfoFlags(
G, MR, ObjCImageInfoItr->second, Flags))
1149 while (ObjCImageInfo->symbols_size() != 0)
1150 G.removeDefinedSymbol(**ObjCImageInfo->symbols().begin());
1151 G.removeBlock(ObjCImageInfoBlock);
1154 dbgs() <<
"MachOPlatform: Registered __objc_imageinfo for "
1156 <<
"; flags = " <<
formatv(
"{0:x4}", Flags) <<
"\n";
1160 G.addDefinedSymbol(ObjCImageInfoBlock, 0, ObjCImageInfoSymbolName,
1164 {{MR.getExecutionSession().intern(ObjCImageInfoSymbolName),
1165 JITSymbolFlags()}}))
1173Error MachOPlatform::MachOPlatformPlugin::mergeImageInfoFlags(
1174 jitlink::LinkGraph &
G, MaterializationResponsibility &MR,
1175 ObjCImageInfo &Info, uint32_t NewFlags) {
1176 if (
Info.Flags == NewFlags)
1179 ObjCImageInfoFlags Old(
Info.Flags);
1180 ObjCImageInfoFlags
New(NewFlags);
1183 if (Old.SwiftABIVersion &&
New.SwiftABIVersion &&
1184 Old.SwiftABIVersion !=
New.SwiftABIVersion)
1186 " does not match first registered flags",
1192 if (
Info.Finalized && Old.HasCategoryClassProperties &&
1193 !
New.HasCategoryClassProperties)
1196 " does not match first registered flags",
1198 if (
Info.Finalized && Old.HasSignedObjCClassROs && !
New.HasSignedObjCClassROs)
1201 " does not match first registered flags",
1210 if (Old.SwiftVersion &&
New.SwiftVersion)
1211 New.SwiftVersion = std::min(Old.SwiftVersion,
New.SwiftVersion);
1212 else if (Old.SwiftVersion)
1213 New.SwiftVersion = Old.SwiftVersion;
1215 if (!
New.SwiftABIVersion)
1216 New.SwiftABIVersion = Old.SwiftABIVersion;
1218 if (Old.HasCategoryClassProperties !=
New.HasCategoryClassProperties)
1219 New.HasCategoryClassProperties =
false;
1221 if (Old.HasSignedObjCClassROs !=
New.HasSignedObjCClassROs)
1222 New.HasSignedObjCClassROs =
false;
1225 dbgs() <<
"MachOPlatform: Merging __objc_imageinfo flags for "
1227 <<
formatv(
"{0:x4}", Old.rawFlags()) <<
")"
1228 <<
" with " <<
G.getName() <<
" (" <<
formatv(
"{0:x4}", NewFlags)
1230 <<
" -> " <<
formatv(
"{0:x4}",
New.rawFlags()) <<
"\n";
1237Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
1238 jitlink::LinkGraph &
G, JITDylib &JD) {
1239 auto TLVBootStrapSymbolName =
G.intern(
"__tlv_bootstrap");
1241 for (
auto *Sym :
G.external_symbols())
1242 if (Sym->
getName() == TLVBootStrapSymbolName) {
1244 MP.getExecutionSession().intern(
"___orc_rt_macho_tlv_get_addr");
1245 Sym->
setName(std::move(TLSGetADDR));
1251 std::optional<uint64_t>
Key;
1253 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1254 auto I = MP.JITDylibToPThreadKey.find(&JD);
1255 if (
I != MP.JITDylibToPThreadKey.end())
1260 if (
auto KeyOrErr = MP.createPThreadKey())
1263 return KeyOrErr.takeError();
1269 for (
auto *
B : ThreadDataSec->blocks()) {
1270 if (
B->getSize() != 3 *
G.getPointerSize())
1272 formatv(
"{0:x}",
B->getAddress()) +
1273 " has unexpected size",
1276 auto NewBlockContent =
G.allocateBuffer(
B->getSize());
1277 llvm::copy(
B->getContent(), NewBlockContent.data());
1278 memcpy(NewBlockContent.data() +
G.getPointerSize(), &PlatformKeyBits,
1279 G.getPointerSize());
1280 B->setContent(NewBlockContent);
1285 for (
auto *
B :
G.blocks())
1286 for (
auto &
E :
B->edges())
1289 E.setKind(jitlink::x86_64::
1290 RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable);
1295std::optional<MachOPlatform::MachOPlatformPlugin::UnwindSections>
1296MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
1297 jitlink::LinkGraph &
G) {
1298 using namespace jitlink;
1305 auto ScanUnwindInfoSection = [&](
Section &Sec, ExecutorAddrRange &SecRange,
1306 auto AddCodeBlocks) {
1307 if (Sec.blocks().empty())
1309 SecRange = (*Sec.blocks().
begin())->getRange();
1310 for (
auto *
B : Sec.blocks()) {
1311 auto R =
B->getRange();
1312 SecRange.Start = std::min(SecRange.Start,
R.Start);
1313 SecRange.End = std::max(SecRange.End,
R.End);
1319 ScanUnwindInfoSection(*EHFrameSec, US.DwarfSection, [&](
Block &
B) {
1320 if (auto *Fn = jitlink::EHFrameCFIBlockInspector::FromEdgeScan(B)
1322 if (Fn->getTarget().isDefined())
1323 CodeBlocks.push_back(&Fn->getTarget().getBlock());
1328 ScanUnwindInfoSection(
1329 *CUInfoSec, US.CompactUnwindSection, [&](
Block &
B) {
1330 for (auto &E : B.edges()) {
1331 assert(E.getTarget().isDefined() &&
1332 "unwind-info record edge has external target");
1333 assert(E.getKind() == Edge::KeepAlive &&
1334 "unwind-info record has unexpected edge kind");
1335 CodeBlocks.push_back(&E.getTarget().getBlock());
1342 if (CodeBlocks.
empty())
1343 return std::nullopt;
1348 return LHS->getAddress() <
RHS->getAddress();
1350 for (
auto *
B : CodeBlocks) {
1351 if (US.CodeRanges.empty() || US.CodeRanges.back().End !=
B->getAddress())
1352 US.CodeRanges.push_back(
B->getRange());
1354 US.CodeRanges.back().End =
B->getRange().End;
1358 dbgs() <<
"MachOPlatform identified unwind info in " <<
G.getName() <<
":\n"
1360 if (US.DwarfSection.Start)
1361 dbgs() << US.DwarfSection <<
"\n";
1364 dbgs() <<
" Compact-unwind: ";
1365 if (US.CompactUnwindSection.Start)
1366 dbgs() << US.CompactUnwindSection <<
"\n";
1369 <<
"for code ranges:\n";
1370 for (
auto &CR : US.CodeRanges)
1371 dbgs() <<
" " << CR <<
"\n";
1372 if (US.CodeRanges.size() >=
G.sections_size())
1373 dbgs() <<
"WARNING: High number of discontiguous code ranges! "
1374 "Padding may be interfering with coalescing.\n";
1380Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
1381 jitlink::LinkGraph &
G, JITDylib &JD, ExecutorAddr HeaderAddr,
1382 bool InBootstrapPhase) {
1386 jitlink::Section *ThreadDataSection =
1394 if (ThreadDataSection)
1395 G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
1397 ThreadDataSection = ThreadBSSSection;
1406 for (
auto &SecName : DataSections) {
1407 if (
auto *Sec =
G.findSectionByName(SecName)) {
1408 jitlink::SectionRange
R(*Sec);
1410 MachOPlatformSecs.
push_back({SecName,
R.getRange()});
1416 if (ThreadDataSection) {
1417 jitlink::SectionRange
R(*ThreadDataSection);
1425 ObjCRuntimeObjectSectionName};
1427 for (
auto &SecName : PlatformSections) {
1428 auto *Sec =
G.findSectionByName(SecName);
1431 jitlink::SectionRange
R(*Sec);
1435 MachOPlatformSecs.
push_back({SecName,
R.getRange()});
1438 std::optional<std::tuple<SmallVector<ExecutorAddrRange>, ExecutorAddrRange,
1441 if (
auto UI = findUnwindSectionInfo(
G))
1442 UnwindInfo = std::make_tuple(std::move(UI->CodeRanges), UI->DwarfSection,
1443 UI->CompactUnwindSection);
1445 if (!MachOPlatformSecs.
empty() || UnwindInfo) {
1448 dbgs() <<
"MachOPlatform: Scraped " <<
G.getName() <<
" init sections:\n";
1449 for (
auto &KV : MachOPlatformSecs)
1450 dbgs() <<
" " << KV.first <<
": " << KV.second <<
"\n";
1453 assert(HeaderAddr &&
"Null header registered for JD");
1454 using SPSRegisterObjectPlatformSectionsArgs = SPSArgList<
1456 SPSOptional<SPSTuple<SPSSequence<SPSExecutorAddrRange>,
1458 SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>>;
1463 MP.RegisterObjectPlatformSections.Addr, HeaderAddr, UnwindInfo,
1464 MachOPlatformSecs)),
1467 MP.DeregisterObjectPlatformSections.Addr, HeaderAddr,
1468 UnwindInfo, MachOPlatformSecs))};
1473 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1474 MP.Bootstrap->DeferredAAs.push_back(std::move(
AllocActions));
1481Error MachOPlatform::MachOPlatformPlugin::createObjCRuntimeObject(
1482 jitlink::LinkGraph &
G) {
1484 bool NeedTextSegment =
false;
1485 size_t NumRuntimeSections = 0;
1487 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData)
1488 if (
G.findSectionByName(ObjCRuntimeSectionName))
1489 ++NumRuntimeSections;
1491 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {
1492 if (
G.findSectionByName(ObjCRuntimeSectionName)) {
1493 ++NumRuntimeSections;
1494 NeedTextSegment =
true;
1499 if (NumRuntimeSections == 0)
1504 ++NumRuntimeSections;
1506 size_t MachOSize =
sizeof(MachO::mach_header_64) +
1507 (NeedTextSegment + 1) *
sizeof(MachO::segment_command_64) +
1508 NumRuntimeSections *
sizeof(MachO::section_64);
1510 auto &Sec =
G.createSection(ObjCRuntimeObjectSectionName,
1512 G.createMutableContentBlock(Sec, MachOSize, ExecutorAddr(), 16, 0,
true);
1517Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
1518 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1520 auto *ObjCRuntimeObjectSec =
1521 G.findSectionByName(ObjCRuntimeObjectSectionName);
1523 if (!ObjCRuntimeObjectSec)
1526 switch (
G.getTargetTriple().getArch()) {
1533 G.getTargetTriple().str(),
1537 auto &SecBlock = **ObjCRuntimeObjectSec->blocks().begin();
1540 MachO::section_64 Sec;
1541 unique_function<void(
size_t RecordOffset)> AddFixups;
1544 std::vector<SecDesc> TextSections, DataSections;
1545 auto AddSection = [&](SecDesc &SD, jitlink::Section &GraphSec) {
1546 jitlink::SectionRange SR(GraphSec);
1547 StringRef FQName = GraphSec.getName();
1548 memset(&SD.Sec, 0,
sizeof(MachO::section_64));
1550 memcpy(SD.Sec.segname, FQName.
data(), 6);
1551 SD.Sec.addr = SR.getStart() - SecBlock.getAddress();
1552 SD.Sec.size = SR.getSize();
1558 DataSections.push_back({});
1559 auto &SD = DataSections.back();
1560 memset(&SD.Sec, 0,
sizeof(SD.Sec));
1561 memcpy(SD.Sec.sectname,
"__objc_imageinfo", 16);
1562 strcpy(SD.Sec.segname,
"__DATA");
1564 jitlink::Symbol *ObjCImageInfoSym =
nullptr;
1565 SD.AddFixups = [&, ObjCImageInfoSym](
size_t RecordOffset)
mutable {
1566 auto PointerEdge = getPointerEdgeKind(
G);
1569 if (!ObjCImageInfoSym) {
1570 auto Name =
G.intern(ObjCImageInfoSymbolName);
1571 ObjCImageInfoSym =
G.findExternalSymbolByName(Name);
1572 if (!ObjCImageInfoSym)
1573 ObjCImageInfoSym =
G.findAbsoluteSymbolByName(Name);
1574 if (!ObjCImageInfoSym) {
1575 ObjCImageInfoSym =
G.findDefinedSymbolByName(Name);
1576 if (ObjCImageInfoSym) {
1577 std::optional<uint32_t>
Flags;
1579 std::lock_guard<std::mutex> Lock(PluginMutex);
1581 if (It != ObjCImageInfos.end()) {
1582 It->second.Finalized =
true;
1583 Flags = It->second.Flags;
1592 Content.size() == 8 &&
1593 "__objc_image_info size should have been verified already");
1598 if (!ObjCImageInfoSym)
1599 ObjCImageInfoSym = &
G.addExternalSymbol(std::move(Name), 8,
false);
1602 SecBlock.addEdge(PointerEdge,
1603 RecordOffset +
offsetof(MachO::section_64, addr),
1604 *ObjCImageInfoSym, -SecBlock.getAddress().getValue());
1608 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData) {
1609 if (
auto *GraphSec =
G.findSectionByName(ObjCRuntimeSectionName)) {
1610 DataSections.push_back({});
1611 AddSection(DataSections.back(), *GraphSec);
1615 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {
1616 if (
auto *GraphSec =
G.findSectionByName(ObjCRuntimeSectionName)) {
1617 TextSections.push_back({});
1618 AddSection(TextSections.back(), *GraphSec);
1622 assert(ObjCRuntimeObjectSec->blocks_size() == 1 &&
1623 "Unexpected number of blocks in runtime sections object");
1627 MachO::mach_header_64 Hdr;
1629 switch (
G.getTargetTriple().getArch()) {
1643 Hdr.
ncmds = 1 + !TextSections.empty();
1645 Hdr.
ncmds *
sizeof(MachO::segment_command_64) +
1646 (TextSections.size() + DataSections.size()) *
sizeof(MachO::section_64);
1650 auto SecContent = SecBlock.getAlreadyMutableContent();
1651 char *
P = SecContent.data();
1652 auto WriteMachOStruct = [&](
auto S) {
1655 memcpy(
P, &S,
sizeof(S));
1659 auto WriteSegment = [&](StringRef
Name, std::vector<SecDesc> &Secs) {
1660 MachO::segment_command_64 SegLC;
1661 memset(&SegLC, 0,
sizeof(SegLC));
1663 SegLC.
cmd = MachO::LC_SEGMENT_64;
1664 SegLC.
cmdsize =
sizeof(MachO::segment_command_64) +
1665 Secs.size() *
sizeof(MachO::section_64);
1666 SegLC.
nsects = Secs.size();
1667 WriteMachOStruct(SegLC);
1668 for (
auto &SD : Secs) {
1670 SD.AddFixups(
P - SecContent.data());
1671 WriteMachOStruct(SD.Sec);
1675 WriteMachOStruct(Hdr);
1676 if (!TextSections.empty())
1677 WriteSegment(
"__TEXT", TextSections);
1678 if (!DataSections.empty())
1679 WriteSegment(
"__DATA", DataSections);
1681 assert(
P == SecContent.end() &&
"Underflow writing ObjC runtime object");
1685Error MachOPlatform::MachOPlatformPlugin::prepareSymbolTableRegistration(
1686 jitlink::LinkGraph &
G, JITSymTabVector &JITSymTabInfo) {
1694 DenseMap<StringRef, jitlink::Symbol *> ExistingStrings;
1695 for (
auto *Sym : CStringSec->symbols()) {
1701 std::make_pair(StringRef(Content.data(), Content.size()), Sym));
1707 SmallVector<jitlink::Symbol *> SymsToProcess;
1711 for (
auto *Sym : SymsToProcess) {
1716 if (
I == ExistingStrings.
end()) {
1717 auto &NameBlock =
G.createMutableContentBlock(
1718 *CStringSec,
G.allocateCString(*Sym->
getName()),
1719 orc::ExecutorAddr(), 1, 0);
1720 auto &SymbolNameSym =
G.addAnonymousSymbol(
1721 NameBlock, 0, NameBlock.getSize(),
false,
true);
1722 JITSymTabInfo.push_back({Sym, &SymbolNameSym});
1724 JITSymTabInfo.push_back({Sym,
I->second});
1731Error MachOPlatform::MachOPlatformPlugin::addSymbolTableRegistration(
1732 jitlink::LinkGraph &
G, MaterializationResponsibility &MR,
1733 JITSymTabVector &JITSymTabInfo,
bool InBootstrapPhase) {
1735 ExecutorAddr HeaderAddr;
1737 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1739 assert(
I != MP.JITDylibToHeaderAddr.end() &&
"No header registered for JD");
1740 assert(
I->second &&
"Null header registered for JD");
1741 HeaderAddr =
I->second;
1748 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1749 auto &SymTab = MP.Bootstrap->SymTab;
1750 for (
auto &[OriginalSymbol, NameSym] : JITSymTabInfo)
1751 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),
1752 flagsForSymbol(*OriginalSymbol)});
1756 SymbolTableVector SymTab;
1757 for (
auto &[OriginalSymbol, NameSym] : JITSymTabInfo)
1758 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),
1759 flagsForSymbol(*OriginalSymbol)});
1761 G.allocActions().push_back(
1763 MP.RegisterObjectSymbolTable.Addr, HeaderAddr, SymTab)),
1765 MP.DeregisterObjectSymbolTable.Addr, HeaderAddr, SymTab))});
1770template <
typename MachOTraits>
1780 B.Header.cputype = HdrInfo.CPUType;
1781 B.Header.cpusubtype = HdrInfo.CPUSubType;
1784 B.template addLoadCommand<MachO::LC_ID_DYLIB>(
1786 Opts.
IDDylib->CurrentVersion, Opts.
IDDylib->CompatibilityVersion);
1788 B.template addLoadCommand<MachO::LC_ID_DYLIB>(JD.
getName(), 0, 0, 0);
1791 B.template addLoadCommand<MachO::LC_UUID>(*Opts.
UUID);
1794 B.template addLoadCommand<MachO::LC_BUILD_VERSION>(
1795 BV.Platform, BV.MinOS, BV.SDK,
static_cast<uint32_t>(0));
1798 B.template addLoadCommand<MachO::LC_TARGET_TRIPLE>(*Opts.
TargetTriple);
1803 case LoadKind::Default:
1804 B.template addLoadCommand<MachO::LC_LOAD_DYLIB>(
1805 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,
1806 LD.D.CompatibilityVersion);
1808 case LoadKind::Weak:
1809 B.template addLoadCommand<MachO::LC_LOAD_WEAK_DYLIB>(
1810 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,
1811 LD.D.CompatibilityVersion);
1816 B.template addLoadCommand<MachO::LC_RPATH>(
P);
1818 auto HeaderContent =
G.allocateBuffer(
B.layout());
1819 B.write(HeaderContent);
1821 return G.createContentBlock(HeaderSection, HeaderContent,
ExecutorAddr(), 8,
1829 createHeaderInterface(
MOP,
std::
move(HeaderStartSymbol))),
1833 std::unique_ptr<MaterializationResponsibility> R) {
1834 auto G = createPlatformGraph(
MOP,
"<MachOHeaderMU>");
1835 addMachOHeader(R->getTargetJITDylib(), *
G, R->getInitializerSymbol());
1836 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(
G));
1842void SimpleMachOHeaderMU::addMachOHeader(
1845 auto &HeaderSection =
G.createSection(
"__header",
MemProt::Read);
1849 G.addDefinedSymbol(HeaderBlock, 0, *InitializerSymbol, HeaderBlock.getSize(),
1852 for (
auto &HS : AdditionalHeaderSymbols)
1853 G.addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name, HeaderBlock.getSize(),
1861 switch (
MOP.getExecutionSession().getTargetTriple().getArch()) {
1864 return ::createHeaderBlock<MachO64LE>(
MOP,
Opts, JD,
G, HeaderSection);
1875 for (
auto &HS : AdditionalHeaderSymbols)
1884 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")
#define offsetof(TYPE, MEMBER)
static StringRef getName(Value *V)
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.
iterator find(const_arg_type_t< KeyT > Val)
void reserve(size_type NumEntries)
Grow the DenseMap so that it can contain at least NumEntries items before resizing again.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
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.
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
Get the string size.
constexpr const char * data() const
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.
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.
Mangles symbol names then uniques them in the context of an ExecutionSession.
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.
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.
SPS tag type for expecteds, which are either a T or a string representing an error.
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.
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.
@ 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.
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 StringRef MachOObjCProtoListSectionName
LLVM_ABI StringRef MachOSwift5ProtosSectionName
LLVM_ABI StringRef MachOEHFrameSectionName
LLVM_ABI StringRef MachOModInitFuncSectionName
LLVM_ABI StringRef MachOObjCConstSectionName
LLVM_ABI StringRef MachODataDataSectionName
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...
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)
Swap the bytes of value to match the given endianness.
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)
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.
SPSExpected< uint64_t >() SPSSig
static constexpr SymbolNameSpec Name
static constexpr SymbolNameSpec Name
static constexpr SymbolNameSpec Name