23#define DEBUG_TYPE "orc"
37class SPSMachOExecutorSymbolFlags;
49 return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, DDI.
Sealed,
55 return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, DDI.
Sealed,
64 using UT = std::underlying_type_t<MachOPlatform::MachOExecutorSymbolFlags>;
92using SPSRegisterSymbolsArgs =
95 SPSMachOExecutorSymbolFlags>>>;
97std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(
MachOPlatform &MOP,
100 return std::make_unique<jitlink::LinkGraph>(
101 std::move(Name), ES.getSymbolStringPool(), ES.getTargetTriple(),
106class MachOPlatformCompleteBootstrapMaterializationUnit
109 using SymbolTableVector =
113 MachOPlatformCompleteBootstrapMaterializationUnit(
114 MachOPlatform &MOP, StringRef PlatformJDName,
115 SymbolStringPtr CompleteBootstrapSymbol, SymbolTableVector SymTab,
117 ExecutorAddr PlatformBootstrap, ExecutorAddr PlatformShutdown,
118 ExecutorAddr RegisterJITDylib, ExecutorAddr DeregisterJITDylib,
119 ExecutorAddr RegisterObjectSymbolTable,
120 ExecutorAddr DeregisterObjectSymbolTable)
121 : MaterializationUnit(
123 MOP(MOP), PlatformJDName(PlatformJDName),
124 CompleteBootstrapSymbol(std::move(CompleteBootstrapSymbol)),
125 SymTab(std::move(SymTab)), DeferredAAs(std::move(DeferredAAs)),
126 MachOHeaderAddr(MachOHeaderAddr), PlatformBootstrap(PlatformBootstrap),
127 PlatformShutdown(PlatformShutdown), RegisterJITDylib(RegisterJITDylib),
128 DeregisterJITDylib(DeregisterJITDylib),
129 RegisterObjectSymbolTable(RegisterObjectSymbolTable),
130 DeregisterObjectSymbolTable(DeregisterObjectSymbolTable) {}
132 StringRef
getName()
const override {
133 return "MachOPlatformCompleteBootstrap";
136 void materialize(std::unique_ptr<MaterializationResponsibility> R)
override {
137 using namespace jitlink;
138 auto G = createPlatformGraph(MOP,
"<OrcRTCompleteBootstrap>");
139 auto &PlaceholderSection =
140 G->createSection(
"__orc_rt_cplt_bs", MemProt::Read);
141 auto &PlaceholderBlock =
142 G->createZeroFillBlock(PlaceholderSection, 1, ExecutorAddr(), 1, 0);
143 G->addDefinedSymbol(PlaceholderBlock, 0, *CompleteBootstrapSymbol, 1,
144 Linkage::Strong, Scope::Hidden,
false,
true);
147 G->allocActions().reserve(DeferredAAs.size() + 3);
150 G->allocActions().push_back(
156 G->allocActions().push_back(
158 SPSArgList<SPSString, SPSExecutorAddr>>(
159 RegisterJITDylib, PlatformJDName, MachOHeaderAddr)),
161 DeregisterJITDylib, MachOHeaderAddr))});
164 G->allocActions().push_back(
166 RegisterObjectSymbolTable, MachOHeaderAddr, SymTab)),
168 DeregisterObjectSymbolTable, MachOHeaderAddr, SymTab))});
171 std::move(DeferredAAs.begin(), DeferredAAs.end(),
172 std::back_inserter(
G->allocActions()));
174 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(
G));
177 void discard(
const JITDylib &JD,
const SymbolStringPtr &Sym)
override {}
181 StringRef PlatformJDName;
182 SymbolStringPtr CompleteBootstrapSymbol;
183 SymbolTableVector SymTab;
185 ExecutorAddr MachOHeaderAddr;
186 ExecutorAddr PlatformBootstrap;
187 ExecutorAddr PlatformShutdown;
188 ExecutorAddr RegisterJITDylib;
189 ExecutorAddr DeregisterJITDylib;
190 ExecutorAddr RegisterObjectSymbolTable;
191 ExecutorAddr DeregisterObjectSymbolTable;
194static StringRef ObjCRuntimeObjectSectionsData[] = {
202static StringRef ObjCRuntimeObjectSectionsText[] = {
209static StringRef ObjCRuntimeObjectSectionName =
210 "__llvm_jitlink_ObjCRuntimeRegistrationObject";
212static StringRef ObjCImageInfoSymbolName =
213 "__llvm_jitlink_macho_objc_imageinfo";
215struct ObjCImageInfoFlags {
216 uint16_t SwiftABIVersion;
217 uint16_t SwiftVersion;
218 bool HasCategoryClassProperties;
219 bool HasSignedObjCClassROs;
221 static constexpr uint32_t SIGNED_CLASS_RO = (1 << 4);
222 static constexpr uint32_t HAS_CATEGORY_CLASS_PROPERTIES = (1 << 6);
224 explicit ObjCImageInfoFlags(uint32_t RawFlags) {
225 HasSignedObjCClassROs = RawFlags & SIGNED_CLASS_RO;
226 HasCategoryClassProperties = RawFlags & HAS_CATEGORY_CLASS_PROPERTIES;
227 SwiftABIVersion = (RawFlags >> 8) & 0xFF;
228 SwiftVersion = (RawFlags >> 16) & 0xFFFF;
231 uint32_t rawFlags()
const {
233 if (HasCategoryClassProperties)
234 Result |= HAS_CATEGORY_CLASS_PROPERTIES;
235 if (HasSignedObjCClassROs)
236 Result |= SIGNED_CLASS_RO;
237 Result |= (SwiftABIVersion << 8);
238 Result |= (SwiftVersion << 16);
247std::optional<MachOPlatform::HeaderOptions::BuildVersionOpts>
253 switch (TT.getOS()) {
255 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
256 : MachO::PLATFORM_IOS;
262 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
263 : MachO::PLATFORM_TVOS;
266 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
267 : MachO::PLATFORM_WATCHOS;
270 Platform = TT.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR
271 : MachO::PLATFORM_XROS;
282 std::unique_ptr<DefinitionGenerator> OrcRuntime,
286 std::optional<SymbolAliasMap> RuntimeAliases) {
288 auto &ES = ObjLinkingLayer.getExecutionSession();
291 if (!supportedTarget(ES.getTargetTriple()))
293 ES.getTargetTriple().str(),
301 if (
auto Err = PlatformJD.define(
symbolAliases(std::move(*RuntimeAliases))))
302 return std::move(Err);
307 if (
auto Err = PlatformJD.define(
reexports(
308 ES.getBootstrapJITDylib(),
309 {{ES.intern(
"___orc_rt_jit_dispatch"),
310 {Mangle(rt::DispatchName),
311 JITSymbolFlags::Exported | JITSymbolFlags::Callable}},
312 {ES.intern(
"___orc_rt_jit_dispatch_ctx"),
313 {Mangle(rt::DispatchCtxName), JITSymbolFlags::Exported}}})))
319 auto P = std::unique_ptr<MachOPlatform>(
320 new MachOPlatform(ObjLinkingLayer, PlatformJD, std::move(OrcRuntime),
321 std::move(BuildHeaderOpts), std::move(PlatformJDOpts),
322 std::move(BuildMachOHeaderMU), Err));
324 return std::move(Err);
332 std::optional<SymbolAliasMap> RuntimeAliases) {
335 auto OrcRuntimeArchiveGenerator =
337 if (!OrcRuntimeArchiveGenerator)
338 return OrcRuntimeArchiveGenerator.takeError();
340 return Create(ObjLinkingLayer, PlatformJD,
341 std::move(*OrcRuntimeArchiveGenerator),
342 std::move(BuildHeaderOpts), std::move(PlatformJDOpts),
343 std::move(BuildMachOHeaderMU), std::move(RuntimeAliases));
351 if (
auto Err = JD.
define(BuildMachOHeaderMU(*
this, std::move(Opts))))
354 return ES.lookup({&JD}, MachOHeaderStartSymbol).takeError();
358 std::lock_guard<std::mutex> Lock(PlatformMutex);
359 auto I = JITDylibToHeaderAddr.find(&JD);
360 if (
I != JITDylibToHeaderAddr.end()) {
361 assert(HeaderAddrToJITDylib.count(
I->second) &&
362 "HeaderAddrToJITDylib missing entry");
363 HeaderAddrToJITDylib.erase(
I->second);
364 JITDylibToHeaderAddr.erase(
I);
366 JITDylibToPThreadKey.erase(&JD);
377 RegisteredInitSymbols[&JD].add(InitSym,
380 dbgs() <<
"MachOPlatform: Registered init symbol " << *InitSym <<
" for MU "
391 ArrayRef<std::pair<const char *, const char *>> AL) {
392 for (
auto &KV : AL) {
393 auto AliasName = ES.
intern(KV.first);
394 assert(!Aliases.
count(AliasName) &&
"Duplicate symbol name in alias map");
395 Aliases[std::move(AliasName)] = {ES.
intern(KV.second),
410 static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
411 {
"___cxa_atexit",
"___orc_rt_macho_cxa_atexit"}};
418 static const std::pair<const char *, const char *>
419 StandardRuntimeUtilityAliases[] = {
420 {
"___orc_rt_run_program",
"___orc_rt_macho_run_program"},
421 {
"___orc_rt_jit_dlerror",
"___orc_rt_macho_jit_dlerror"},
422 {
"___orc_rt_jit_dlopen",
"___orc_rt_macho_jit_dlopen"},
423 {
"___orc_rt_jit_dlupdate",
"___orc_rt_macho_jit_dlupdate"},
424 {
"___orc_rt_jit_dlclose",
"___orc_rt_macho_jit_dlclose"},
425 {
"___orc_rt_jit_dlsym",
"___orc_rt_macho_jit_dlsym"},
426 {
"___orc_rt_log_error",
"___orc_rt_log_error_to_stderr"}};
429 StandardRuntimeUtilityAliases);
434 static const std::pair<const char *, const char *>
435 StandardLazyCompilationAliases[] = {
436 {
"__orc_rt_reenter",
"__orc_rt_sysv_reenter"},
437 {
"__orc_rt_resolve_tag",
"___orc_rt_resolve_tag"}};
440 StandardLazyCompilationAliases);
447bool MachOPlatform::supportedTarget(
const Triple &TT) {
448 switch (TT.getArch()) {
458 switch (
G.getTargetTriple().getArch()) {
469MachOPlatform::flagsForSymbol(jitlink::Symbol &Sym) {
480MachOPlatform::MachOPlatform(
482 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
483 HeaderOptionsBuilder BuildHeaderOpts, HeaderOptions PlatformJDOpts,
484 MachOHeaderMUBuilder BuildMachOHeaderMU,
Error &Err)
485 : ES(ObjLinkingLayer.getExecutionSession()), PlatformJD(PlatformJD),
486 ObjLinkingLayer(ObjLinkingLayer),
487 BuildHeaderOpts(std::
move(BuildHeaderOpts)),
488 BuildMachOHeaderMU(std::
move(BuildMachOHeaderMU)) {
489 ErrorAsOutParameter
_(Err);
490 ObjLinkingLayer.addPlugin(std::make_unique<MachOPlatformPlugin>(*
this));
491 PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
495 std::optional<bool> ForceEHFrames;
496 if ((Err = ES.getBootstrapMapValue<
bool,
bool>(
"darwin-use-ehframes-only",
499 this->ForceEHFrames = ForceEHFrames.value_or(
false);
560 if ((Err = PlatformJD.define(
561 this->BuildMachOHeaderMU(*
this, std::move(PlatformJDOpts)))))
563 if ((Err = ES.lookup(&PlatformJD, MachOHeaderStartSymbol).takeError()))
570 {PlatformBootstrap.Name, PlatformShutdown.Name,
571 RegisterJITDylib.Name, DeregisterJITDylib.Name,
572 RegisterObjectSymbolTable.Name,
573 DeregisterObjectSymbolTable.Name,
574 RegisterObjectPlatformSections.Name,
575 DeregisterObjectPlatformSections.Name,
576 CreatePThreadKey.Name}))
582 std::unique_lock<std::mutex> Lock(PlatformMutex);
583 BI.CV.wait(Lock, [&]() {
return BI.ActiveGraphs == 0; });
588 auto BootstrapCompleteSymbol = ES.intern(
"__orc_rt_macho_complete_bootstrap");
589 if ((Err = PlatformJD.define(
590 std::make_unique<MachOPlatformCompleteBootstrapMaterializationUnit>(
591 *
this, PlatformJD.getName(), BootstrapCompleteSymbol,
592 std::move(BI.SymTab), std::move(BI.DeferredAAs),
593 BI.MachOHeaderAddr, PlatformBootstrap.Addr,
594 PlatformShutdown.Addr, RegisterJITDylib.Addr,
595 DeregisterJITDylib.Addr, RegisterObjectSymbolTable.Addr,
596 DeregisterObjectSymbolTable.Addr))))
600 std::move(BootstrapCompleteSymbol))
611 if ((Err = associateRuntimeSupportFunctions()))
615Error MachOPlatform::associateRuntimeSupportFunctions() {
618 using PushInitializersSPSSig =
619 SPSExpected<SPSMachOJITDylibDepInfoMap>(SPSExecutorAddr);
620 WFs[ES.intern(
"___orc_rt_macho_push_initializers_tag")] =
621 ES.wrapAsyncWithSPS<PushInitializersSPSSig>(
622 this, &MachOPlatform::rt_pushInitializers);
624 using PushSymbolsSPSSig =
625 SPSError(SPSExecutorAddr, SPSSequence<SPSTuple<SPSString, bool>>);
626 WFs[ES.intern(
"___orc_rt_macho_push_symbols_tag")] =
627 ES.wrapAsyncWithSPS<PushSymbolsSPSSig>(
this,
628 &MachOPlatform::rt_pushSymbols);
630 return ES.registerJITDispatchHandlers(PlatformJD, std::move(WFs));
633void MachOPlatform::pushInitializersLoop(
634 PushInitializersSendResultFn SendResult,
JITDylibSP JD) {
635 DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;
636 DenseMap<JITDylib *, SmallVector<JITDylib *>> JDDepMap;
639 ES.runSessionLocked([&]() {
640 while (!Worklist.empty()) {
643 auto DepJD = Worklist.back();
652 auto &
DM = It->second;
655 if (KV.first == DepJD)
657 DM.push_back(KV.first);
658 Worklist.push_back(KV.first);
663 auto RISItr = RegisteredInitSymbols.find(DepJD);
664 if (RISItr != RegisteredInitSymbols.end()) {
665 NewInitSymbols[DepJD] = std::move(RISItr->second);
666 RegisteredInitSymbols.erase(RISItr);
673 if (NewInitSymbols.
empty()) {
679 DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
682 std::lock_guard<std::mutex> Lock(PlatformMutex);
683 for (
auto &KV : JDDepMap) {
684 auto I = JITDylibToHeaderAddr.find(KV.first);
685 if (
I != JITDylibToHeaderAddr.end())
686 HeaderAddrs[KV.first] =
I->second;
692 DIM.reserve(JDDepMap.size());
693 for (
auto &KV : JDDepMap) {
694 auto HI = HeaderAddrs.
find(KV.first);
696 if (HI == HeaderAddrs.
end())
700 for (
auto &Dep : KV.second) {
701 auto HJ = HeaderAddrs.
find(Dep);
702 if (HJ != HeaderAddrs.
end())
703 DepInfo.DepHeaders.push_back(HJ->second);
705 DIM.push_back(std::make_pair(
H, std::move(DepInfo)));
713 [
this, SendResult = std::move(SendResult), JD](
Error Err)
mutable {
715 SendResult(std::move(Err));
717 pushInitializersLoop(std::move(SendResult), JD);
719 ES, std::move(NewInitSymbols));
722void MachOPlatform::rt_pushInitializers(PushInitializersSendResultFn SendResult,
726 std::lock_guard<std::mutex> Lock(PlatformMutex);
727 auto I = HeaderAddrToJITDylib.find(JDHeaderAddr);
728 if (
I != HeaderAddrToJITDylib.end())
733 dbgs() <<
"MachOPlatform::rt_pushInitializers(" << JDHeaderAddr <<
") ";
735 dbgs() <<
"pushing initializers for " << JD->
getName() <<
"\n";
737 dbgs() <<
"No JITDylib for header address.\n";
742 formatv(
"{0:x}", JDHeaderAddr),
747 pushInitializersLoop(std::move(SendResult), JD);
750void MachOPlatform::rt_pushSymbols(
751 PushSymbolsInSendResultFn SendResult,
ExecutorAddr Handle,
752 const std::vector<std::pair<StringRef, bool>> &SymbolNames) {
754 JITDylib *JD =
nullptr;
757 std::lock_guard<std::mutex> Lock(PlatformMutex);
758 auto I = HeaderAddrToJITDylib.find(Handle);
759 if (
I != HeaderAddrToJITDylib.end())
763 dbgs() <<
"MachOPlatform::rt_pushSymbols(";
767 dbgs() <<
"<invalid handle " << Handle <<
">, [ ";
768 for (
auto &Name : SymbolNames)
769 dbgs() <<
"\"" <<
Name.first <<
"\" ";
781 for (
auto &[Name,
Required] : SymbolNames)
789 [SendResult = std::move(SendResult)](Expected<SymbolMap>
Result)
mutable {
790 SendResult(
Result.takeError());
795Expected<uint64_t> MachOPlatform::createPThreadKey() {
796 if (!CreatePThreadKey.Addr)
798 "Attempting to create pthread key in target, but runtime support has "
799 "not been loaded yet",
802 Expected<uint64_t>
Result(0);
803 if (
auto Err = ES.callSPSWrapper<SPSExpected<uint64_t>(
void)>(
804 CreatePThreadKey.Addr,
Result))
805 return std::move(Err);
809void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
811 jitlink::PassConfiguration &Config) {
813 using namespace jitlink;
815 bool InBootstrapPhase =
false;
817 ExecutorAddr HeaderAddr;
819 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
822 InBootstrapPhase =
true;
823 ++MP.Bootstrap->ActiveGraphs;
829 if (
I != MP.JITDylibToHeaderAddr.end())
830 HeaderAddr =
I->second;
835 if (MP.ForceEHFrames)
844 Linkage::Strong, Scope::Local,
true);
849 return bootstrapPipelineRecordRuntimeFunctions(
G);
858 if (InitSymbol == MP.MachOHeaderStartSymbol && !InBootstrapPhase) {
860 return associateJITDylibHeaderSymbol(
G, MR);
869 if (
auto Err = preserveImportantSections(
G, MR))
871 return processObjCImageInfo(
G, MR);
874 [
this](LinkGraph &
G) {
return createObjCRuntimeObject(
G); });
876 [
this, &MR](LinkGraph &
G) {
return populateObjCRuntimeObject(
G, MR); });
884 return fixTLVSectionsAndEdges(G, JD);
890 auto JITSymTabInfo = std::make_shared<JITSymTabVector>();
892 return prepareSymbolTableRegistration(
G, *JITSymTabInfo);
895 InBootstrapPhase](LinkGraph &
G) {
896 return addSymbolTableRegistration(
G, MR, *JITSymTabInfo, InBootstrapPhase);
903 InBootstrapPhase](LinkGraph &
G) {
904 return registerObjectPlatformSections(G, JD, HeaderAddr, InBootstrapPhase);
909 if (InBootstrapPhase)
911 [
this](LinkGraph &
G) {
return bootstrapPipelineEnd(
G); });
914Error MachOPlatform::MachOPlatformPlugin::
915 bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &
G) {
917 std::pair<StringRef, ExecutorAddr *> RuntimeSymbols[] = {
918 {*MP.MachOHeaderStartSymbol, &MP.Bootstrap->MachOHeaderAddr},
919 {*MP.PlatformBootstrap.Name, &MP.PlatformBootstrap.Addr},
920 {*MP.PlatformShutdown.Name, &MP.PlatformShutdown.Addr},
921 {*MP.RegisterJITDylib.Name, &MP.RegisterJITDylib.Addr},
922 {*MP.DeregisterJITDylib.Name, &MP.DeregisterJITDylib.Addr},
923 {*MP.RegisterObjectSymbolTable.Name, &MP.RegisterObjectSymbolTable.Addr},
924 {*MP.DeregisterObjectSymbolTable.Name,
925 &MP.DeregisterObjectSymbolTable.Addr},
926 {*MP.RegisterObjectPlatformSections.Name,
927 &MP.RegisterObjectPlatformSections.Addr},
928 {*MP.DeregisterObjectPlatformSections.Name,
929 &MP.DeregisterObjectPlatformSections.Addr},
930 {*MP.CreatePThreadKey.Name, &MP.CreatePThreadKey.Addr},
931 {*MP.RegisterObjCRuntimeObject.Name, &MP.RegisterObjCRuntimeObject.Addr},
932 {*MP.DeregisterObjCRuntimeObject.Name,
933 &MP.DeregisterObjCRuntimeObject.Addr}};
935 bool RegisterMachOHeader =
false;
937 for (
auto *Sym :
G.defined_symbols()) {
938 for (
auto &RTSym : RuntimeSymbols) {
942 "Duplicate " + RTSym.first +
943 " detected during MachOPlatform bootstrap",
946 if (Sym->
getName() == MP.MachOHeaderStartSymbol)
947 RegisterMachOHeader =
true;
954 if (RegisterMachOHeader) {
957 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
958 MP.JITDylibToHeaderAddr[&MP.PlatformJD] = MP.Bootstrap->MachOHeaderAddr;
959 MP.HeaderAddrToJITDylib[MP.Bootstrap->MachOHeaderAddr] = &MP.PlatformJD;
965Error MachOPlatform::MachOPlatformPlugin::bootstrapPipelineEnd(
966 jitlink::LinkGraph &
G) {
967 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
969 --MP.Bootstrap->ActiveGraphs;
972 if (MP.Bootstrap->ActiveGraphs == 0)
973 MP.Bootstrap->CV.notify_all();
977Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
978 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
979 auto I =
llvm::find_if(
G.defined_symbols(), [
this](jitlink::Symbol *Sym) {
980 return Sym->getName() == MP.MachOHeaderStartSymbol;
982 assert(
I !=
G.defined_symbols().end() &&
"Missing MachO header start symbol");
985 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
986 auto HeaderAddr = (*I)->getAddress();
987 MP.JITDylibToHeaderAddr[&JD] = HeaderAddr;
988 MP.HeaderAddrToJITDylib[HeaderAddr] = &JD;
991 G.allocActions().push_back(
994 MP.RegisterJITDylib.Addr, JD.
getName(), HeaderAddr)),
996 MP.DeregisterJITDylib.Addr, HeaderAddr))});
1000Error MachOPlatform::MachOPlatformPlugin::preserveImportantSections(
1001 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1006 if (
auto *ObjCImageInfoSec =
1008 if (ObjCImageInfoSec->blocks_size() != 1)
1010 "In " +
G.getName() +
1011 "__DATA,__objc_imageinfo contains multiple blocks",
1013 G.addAnonymousSymbol(**ObjCImageInfoSec->blocks().begin(), 0, 0,
false,
1016 for (
auto *
B : ObjCImageInfoSec->blocks())
1017 if (!
B->edges_empty())
1020 " contains references to symbols",
1029 jitlink::Symbol *InitSym =
nullptr;
1037 auto *InitSection =
G.findSectionByName(InitSectionName);
1038 if (!InitSection || InitSection->empty())
1044 auto &
B = **InitSection->blocks().begin();
1045 InitSym = &
G.addDefinedSymbol(
1051 for (
auto *
B : InitSection->blocks()) {
1055 auto &S =
G.addAnonymousSymbol(*
B, 0,
B->getSize(),
false,
true);
1064Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
1065 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1077 auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();
1080 if (ObjCImageInfoBlocks.empty())
1082 " section in " +
G.getName(),
1086 if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())
1089 " section in " +
G.getName(),
1094 for (
auto &Sec :
G.sections()) {
1095 if (&Sec != ObjCImageInfo)
1096 for (
auto *
B : Sec.blocks())
1097 for (
auto &
E :
B->edges())
1098 if (
E.getTarget().isDefined() &&
1099 &
E.getTarget().getSection() == ObjCImageInfo)
1101 " is referenced within file " +
1106 auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();
1107 auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();
1113 std::lock_guard<std::mutex> Lock(PluginMutex);
1116 if (ObjCImageInfoItr != ObjCImageInfos.end()) {
1119 if (ObjCImageInfoItr->second.Version !=
Version)
1121 "ObjC version in " +
G.getName() +
1122 " does not match first registered version",
1124 if (ObjCImageInfoItr->second.Flags != Flags)
1125 if (
Error E = mergeImageInfoFlags(
G, MR, ObjCImageInfoItr->second, Flags))
1129 while (ObjCImageInfo->symbols_size() != 0)
1130 G.removeDefinedSymbol(**ObjCImageInfo->symbols().begin());
1131 G.removeBlock(ObjCImageInfoBlock);
1134 dbgs() <<
"MachOPlatform: Registered __objc_imageinfo for "
1136 <<
"; flags = " <<
formatv(
"{0:x4}", Flags) <<
"\n";
1140 G.addDefinedSymbol(ObjCImageInfoBlock, 0, ObjCImageInfoSymbolName,
1144 {{MR.getExecutionSession().intern(ObjCImageInfoSymbolName),
1145 JITSymbolFlags()}}))
1153Error MachOPlatform::MachOPlatformPlugin::mergeImageInfoFlags(
1154 jitlink::LinkGraph &
G, MaterializationResponsibility &MR,
1155 ObjCImageInfo &Info, uint32_t NewFlags) {
1156 if (
Info.Flags == NewFlags)
1159 ObjCImageInfoFlags Old(
Info.Flags);
1160 ObjCImageInfoFlags
New(NewFlags);
1163 if (Old.SwiftABIVersion &&
New.SwiftABIVersion &&
1164 Old.SwiftABIVersion !=
New.SwiftABIVersion)
1166 " does not match first registered flags",
1172 if (
Info.Finalized && Old.HasCategoryClassProperties &&
1173 !
New.HasCategoryClassProperties)
1176 " does not match first registered flags",
1178 if (
Info.Finalized && Old.HasSignedObjCClassROs && !
New.HasSignedObjCClassROs)
1181 " does not match first registered flags",
1190 if (Old.SwiftVersion &&
New.SwiftVersion)
1191 New.SwiftVersion = std::min(Old.SwiftVersion,
New.SwiftVersion);
1192 else if (Old.SwiftVersion)
1193 New.SwiftVersion = Old.SwiftVersion;
1195 if (!
New.SwiftABIVersion)
1196 New.SwiftABIVersion = Old.SwiftABIVersion;
1198 if (Old.HasCategoryClassProperties !=
New.HasCategoryClassProperties)
1199 New.HasCategoryClassProperties =
false;
1201 if (Old.HasSignedObjCClassROs !=
New.HasSignedObjCClassROs)
1202 New.HasSignedObjCClassROs =
false;
1205 dbgs() <<
"MachOPlatform: Merging __objc_imageinfo flags for "
1207 <<
formatv(
"{0:x4}", Old.rawFlags()) <<
")"
1208 <<
" with " <<
G.getName() <<
" (" <<
formatv(
"{0:x4}", NewFlags)
1210 <<
" -> " <<
formatv(
"{0:x4}",
New.rawFlags()) <<
"\n";
1217Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
1218 jitlink::LinkGraph &
G, JITDylib &JD) {
1219 auto TLVBootStrapSymbolName =
G.intern(
"__tlv_bootstrap");
1221 for (
auto *Sym :
G.external_symbols())
1222 if (Sym->
getName() == TLVBootStrapSymbolName) {
1224 MP.getExecutionSession().intern(
"___orc_rt_macho_tlv_get_addr");
1225 Sym->
setName(std::move(TLSGetADDR));
1231 std::optional<uint64_t>
Key;
1233 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1234 auto I = MP.JITDylibToPThreadKey.find(&JD);
1235 if (
I != MP.JITDylibToPThreadKey.end())
1240 if (
auto KeyOrErr = MP.createPThreadKey())
1243 return KeyOrErr.takeError();
1249 for (
auto *
B : ThreadDataSec->blocks()) {
1250 if (
B->getSize() != 3 *
G.getPointerSize())
1252 formatv(
"{0:x}",
B->getAddress()) +
1253 " has unexpected size",
1256 auto NewBlockContent =
G.allocateBuffer(
B->getSize());
1257 llvm::copy(
B->getContent(), NewBlockContent.data());
1258 memcpy(NewBlockContent.data() +
G.getPointerSize(), &PlatformKeyBits,
1259 G.getPointerSize());
1260 B->setContent(NewBlockContent);
1265 for (
auto *
B :
G.blocks())
1266 for (
auto &
E :
B->edges())
1269 E.setKind(jitlink::x86_64::
1270 RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable);
1275std::optional<MachOPlatform::MachOPlatformPlugin::UnwindSections>
1276MachOPlatform::MachOPlatformPlugin::findUnwindSectionInfo(
1277 jitlink::LinkGraph &
G) {
1278 using namespace jitlink;
1285 auto ScanUnwindInfoSection = [&](
Section &Sec, ExecutorAddrRange &SecRange,
1286 auto AddCodeBlocks) {
1287 if (Sec.blocks().empty())
1289 SecRange = (*Sec.blocks().
begin())->getRange();
1290 for (
auto *
B : Sec.blocks()) {
1291 auto R =
B->getRange();
1292 SecRange.Start = std::min(SecRange.Start,
R.Start);
1293 SecRange.End = std::max(SecRange.End,
R.End);
1299 ScanUnwindInfoSection(*EHFrameSec, US.DwarfSection, [&](
Block &
B) {
1300 if (auto *Fn = jitlink::EHFrameCFIBlockInspector::FromEdgeScan(B)
1302 if (Fn->getTarget().isDefined())
1303 CodeBlocks.push_back(&Fn->getTarget().getBlock());
1308 ScanUnwindInfoSection(
1309 *CUInfoSec, US.CompactUnwindSection, [&](
Block &
B) {
1310 for (auto &E : B.edges()) {
1311 assert(E.getTarget().isDefined() &&
1312 "unwind-info record edge has external target");
1313 assert(E.getKind() == Edge::KeepAlive &&
1314 "unwind-info record has unexpected edge kind");
1315 CodeBlocks.push_back(&E.getTarget().getBlock());
1322 if (CodeBlocks.
empty())
1323 return std::nullopt;
1328 return LHS->getAddress() <
RHS->getAddress();
1330 for (
auto *
B : CodeBlocks) {
1331 if (US.CodeRanges.empty() || US.CodeRanges.back().End !=
B->getAddress())
1332 US.CodeRanges.push_back(
B->getRange());
1334 US.CodeRanges.back().End =
B->getRange().End;
1338 dbgs() <<
"MachOPlatform identified unwind info in " <<
G.getName() <<
":\n"
1340 if (US.DwarfSection.Start)
1341 dbgs() << US.DwarfSection <<
"\n";
1344 dbgs() <<
" Compact-unwind: ";
1345 if (US.CompactUnwindSection.Start)
1346 dbgs() << US.CompactUnwindSection <<
"\n";
1349 <<
"for code ranges:\n";
1350 for (
auto &CR : US.CodeRanges)
1351 dbgs() <<
" " << CR <<
"\n";
1352 if (US.CodeRanges.size() >=
G.sections_size())
1353 dbgs() <<
"WARNING: High number of discontiguous code ranges! "
1354 "Padding may be interfering with coalescing.\n";
1360Error MachOPlatform::MachOPlatformPlugin::registerObjectPlatformSections(
1361 jitlink::LinkGraph &
G, JITDylib &JD, ExecutorAddr HeaderAddr,
1362 bool InBootstrapPhase) {
1366 jitlink::Section *ThreadDataSection =
1374 if (ThreadDataSection)
1375 G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
1377 ThreadDataSection = ThreadBSSSection;
1386 for (
auto &SecName : DataSections) {
1387 if (
auto *Sec =
G.findSectionByName(SecName)) {
1388 jitlink::SectionRange
R(*Sec);
1390 MachOPlatformSecs.
push_back({SecName,
R.getRange()});
1396 if (ThreadDataSection) {
1397 jitlink::SectionRange
R(*ThreadDataSection);
1405 ObjCRuntimeObjectSectionName};
1407 for (
auto &SecName : PlatformSections) {
1408 auto *Sec =
G.findSectionByName(SecName);
1411 jitlink::SectionRange
R(*Sec);
1415 MachOPlatformSecs.
push_back({SecName,
R.getRange()});
1418 std::optional<std::tuple<SmallVector<ExecutorAddrRange>, ExecutorAddrRange,
1421 if (
auto UI = findUnwindSectionInfo(
G))
1422 UnwindInfo = std::make_tuple(std::move(UI->CodeRanges), UI->DwarfSection,
1423 UI->CompactUnwindSection);
1425 if (!MachOPlatformSecs.
empty() || UnwindInfo) {
1428 dbgs() <<
"MachOPlatform: Scraped " <<
G.getName() <<
" init sections:\n";
1429 for (
auto &KV : MachOPlatformSecs)
1430 dbgs() <<
" " << KV.first <<
": " << KV.second <<
"\n";
1433 assert(HeaderAddr &&
"Null header registered for JD");
1434 using SPSRegisterObjectPlatformSectionsArgs = SPSArgList<
1436 SPSOptional<SPSTuple<SPSSequence<SPSExecutorAddrRange>,
1438 SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>>;
1443 MP.RegisterObjectPlatformSections.Addr, HeaderAddr, UnwindInfo,
1444 MachOPlatformSecs)),
1447 MP.DeregisterObjectPlatformSections.Addr, HeaderAddr,
1448 UnwindInfo, MachOPlatformSecs))};
1453 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1454 MP.Bootstrap->DeferredAAs.push_back(std::move(
AllocActions));
1461Error MachOPlatform::MachOPlatformPlugin::createObjCRuntimeObject(
1462 jitlink::LinkGraph &
G) {
1464 bool NeedTextSegment =
false;
1465 size_t NumRuntimeSections = 0;
1467 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData)
1468 if (
G.findSectionByName(ObjCRuntimeSectionName))
1469 ++NumRuntimeSections;
1471 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {
1472 if (
G.findSectionByName(ObjCRuntimeSectionName)) {
1473 ++NumRuntimeSections;
1474 NeedTextSegment =
true;
1479 if (NumRuntimeSections == 0)
1484 ++NumRuntimeSections;
1486 size_t MachOSize =
sizeof(MachO::mach_header_64) +
1487 (NeedTextSegment + 1) *
sizeof(MachO::segment_command_64) +
1488 NumRuntimeSections *
sizeof(MachO::section_64);
1490 auto &Sec =
G.createSection(ObjCRuntimeObjectSectionName,
1492 G.createMutableContentBlock(Sec, MachOSize, ExecutorAddr(), 16, 0,
true);
1497Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
1498 jitlink::LinkGraph &
G, MaterializationResponsibility &MR) {
1500 auto *ObjCRuntimeObjectSec =
1501 G.findSectionByName(ObjCRuntimeObjectSectionName);
1503 if (!ObjCRuntimeObjectSec)
1506 switch (
G.getTargetTriple().getArch()) {
1513 G.getTargetTriple().str(),
1517 auto &SecBlock = **ObjCRuntimeObjectSec->blocks().begin();
1520 MachO::section_64 Sec;
1521 unique_function<void(
size_t RecordOffset)> AddFixups;
1524 std::vector<SecDesc> TextSections, DataSections;
1525 auto AddSection = [&](SecDesc &SD, jitlink::Section &GraphSec) {
1526 jitlink::SectionRange SR(GraphSec);
1527 StringRef FQName = GraphSec.getName();
1528 memset(&SD.Sec, 0,
sizeof(MachO::section_64));
1530 memcpy(SD.Sec.segname, FQName.
data(), 6);
1531 SD.Sec.addr = SR.getStart() - SecBlock.getAddress();
1532 SD.Sec.size = SR.getSize();
1538 DataSections.push_back({});
1539 auto &SD = DataSections.back();
1540 memset(&SD.Sec, 0,
sizeof(SD.Sec));
1541 memcpy(SD.Sec.sectname,
"__objc_imageinfo", 16);
1542 strcpy(SD.Sec.segname,
"__DATA");
1544 jitlink::Symbol *ObjCImageInfoSym =
nullptr;
1545 SD.AddFixups = [&, ObjCImageInfoSym](
size_t RecordOffset)
mutable {
1546 auto PointerEdge = getPointerEdgeKind(
G);
1549 if (!ObjCImageInfoSym) {
1550 auto Name =
G.intern(ObjCImageInfoSymbolName);
1551 ObjCImageInfoSym =
G.findExternalSymbolByName(Name);
1552 if (!ObjCImageInfoSym)
1553 ObjCImageInfoSym =
G.findAbsoluteSymbolByName(Name);
1554 if (!ObjCImageInfoSym) {
1555 ObjCImageInfoSym =
G.findDefinedSymbolByName(Name);
1556 if (ObjCImageInfoSym) {
1557 std::optional<uint32_t>
Flags;
1559 std::lock_guard<std::mutex> Lock(PluginMutex);
1561 if (It != ObjCImageInfos.end()) {
1562 It->second.Finalized =
true;
1563 Flags = It->second.Flags;
1572 Content.size() == 8 &&
1573 "__objc_image_info size should have been verified already");
1578 if (!ObjCImageInfoSym)
1579 ObjCImageInfoSym = &
G.addExternalSymbol(std::move(Name), 8,
false);
1582 SecBlock.addEdge(PointerEdge,
1583 RecordOffset + ((
char *)&SD.Sec.addr - (
char *)&SD.Sec),
1584 *ObjCImageInfoSym, -SecBlock.getAddress().getValue());
1588 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsData) {
1589 if (
auto *GraphSec =
G.findSectionByName(ObjCRuntimeSectionName)) {
1590 DataSections.push_back({});
1591 AddSection(DataSections.back(), *GraphSec);
1595 for (
auto ObjCRuntimeSectionName : ObjCRuntimeObjectSectionsText) {
1596 if (
auto *GraphSec =
G.findSectionByName(ObjCRuntimeSectionName)) {
1597 TextSections.push_back({});
1598 AddSection(TextSections.back(), *GraphSec);
1602 assert(ObjCRuntimeObjectSec->blocks_size() == 1 &&
1603 "Unexpected number of blocks in runtime sections object");
1607 MachO::mach_header_64 Hdr;
1609 switch (
G.getTargetTriple().getArch()) {
1623 Hdr.
ncmds = 1 + !TextSections.empty();
1625 Hdr.
ncmds *
sizeof(MachO::segment_command_64) +
1626 (TextSections.size() + DataSections.size()) *
sizeof(MachO::section_64);
1630 auto SecContent = SecBlock.getAlreadyMutableContent();
1631 char *
P = SecContent.data();
1632 auto WriteMachOStruct = [&](
auto S) {
1635 memcpy(
P, &S,
sizeof(S));
1639 auto WriteSegment = [&](StringRef
Name, std::vector<SecDesc> &Secs) {
1640 MachO::segment_command_64 SegLC;
1641 memset(&SegLC, 0,
sizeof(SegLC));
1643 SegLC.
cmd = MachO::LC_SEGMENT_64;
1644 SegLC.
cmdsize =
sizeof(MachO::segment_command_64) +
1645 Secs.size() *
sizeof(MachO::section_64);
1646 SegLC.
nsects = Secs.size();
1647 WriteMachOStruct(SegLC);
1648 for (
auto &SD : Secs) {
1650 SD.AddFixups(
P - SecContent.data());
1651 WriteMachOStruct(SD.Sec);
1655 WriteMachOStruct(Hdr);
1656 if (!TextSections.empty())
1657 WriteSegment(
"__TEXT", TextSections);
1658 if (!DataSections.empty())
1659 WriteSegment(
"__DATA", DataSections);
1661 assert(
P == SecContent.end() &&
"Underflow writing ObjC runtime object");
1665Error MachOPlatform::MachOPlatformPlugin::prepareSymbolTableRegistration(
1666 jitlink::LinkGraph &
G, JITSymTabVector &JITSymTabInfo) {
1674 DenseMap<StringRef, jitlink::Symbol *> ExistingStrings;
1675 for (
auto *Sym : CStringSec->symbols()) {
1681 std::make_pair(StringRef(Content.data(), Content.size()), Sym));
1687 SmallVector<jitlink::Symbol *> SymsToProcess;
1691 for (
auto *Sym : SymsToProcess) {
1696 if (
I == ExistingStrings.
end()) {
1697 auto &NameBlock =
G.createMutableContentBlock(
1698 *CStringSec,
G.allocateCString(*Sym->
getName()),
1699 orc::ExecutorAddr(), 1, 0);
1700 auto &SymbolNameSym =
G.addAnonymousSymbol(
1701 NameBlock, 0, NameBlock.getSize(),
false,
true);
1702 JITSymTabInfo.push_back({Sym, &SymbolNameSym});
1704 JITSymTabInfo.push_back({Sym,
I->second});
1711Error MachOPlatform::MachOPlatformPlugin::addSymbolTableRegistration(
1712 jitlink::LinkGraph &
G, MaterializationResponsibility &MR,
1713 JITSymTabVector &JITSymTabInfo,
bool InBootstrapPhase) {
1715 ExecutorAddr HeaderAddr;
1717 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1719 assert(
I != MP.JITDylibToHeaderAddr.end() &&
"No header registered for JD");
1720 assert(
I->second &&
"Null header registered for JD");
1721 HeaderAddr =
I->second;
1728 std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
1729 auto &SymTab = MP.Bootstrap->SymTab;
1730 for (
auto &[OriginalSymbol, NameSym] : JITSymTabInfo)
1731 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),
1732 flagsForSymbol(*OriginalSymbol)});
1736 SymbolTableVector SymTab;
1737 for (
auto &[OriginalSymbol, NameSym] : JITSymTabInfo)
1738 SymTab.push_back({NameSym->getAddress(), OriginalSymbol->getAddress(),
1739 flagsForSymbol(*OriginalSymbol)});
1741 G.allocActions().push_back(
1743 MP.RegisterObjectSymbolTable.Addr, HeaderAddr, SymTab)),
1745 MP.DeregisterObjectSymbolTable.Addr, HeaderAddr, SymTab))});
1750template <
typename MachOTraits>
1760 B.Header.cputype = HdrInfo.CPUType;
1761 B.Header.cpusubtype = HdrInfo.CPUSubType;
1764 B.template addLoadCommand<MachO::LC_ID_DYLIB>(
1766 Opts.
IDDylib->CurrentVersion, Opts.
IDDylib->CompatibilityVersion);
1768 B.template addLoadCommand<MachO::LC_ID_DYLIB>(JD.
getName(), 0, 0, 0);
1771 B.template addLoadCommand<MachO::LC_UUID>(*Opts.
UUID);
1774 B.template addLoadCommand<MachO::LC_BUILD_VERSION>(
1775 BV.Platform, BV.MinOS, BV.SDK,
static_cast<uint32_t>(0));
1778 B.template addLoadCommand<MachO::LC_TARGET_TRIPLE>(*Opts.
TargetTriple);
1783 case LoadKind::Default:
1784 B.template addLoadCommand<MachO::LC_LOAD_DYLIB>(
1785 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,
1786 LD.D.CompatibilityVersion);
1788 case LoadKind::Weak:
1789 B.template addLoadCommand<MachO::LC_LOAD_WEAK_DYLIB>(
1790 LD.D.Name, LD.D.Timestamp, LD.D.CurrentVersion,
1791 LD.D.CompatibilityVersion);
1796 B.template addLoadCommand<MachO::LC_RPATH>(
P);
1798 auto HeaderContent =
G.allocateBuffer(
B.layout());
1799 B.write(HeaderContent);
1801 return G.createContentBlock(HeaderSection, HeaderContent,
ExecutorAddr(), 8,
1809 createHeaderInterface(
MOP,
std::
move(HeaderStartSymbol))),
1813 std::unique_ptr<MaterializationResponsibility> R) {
1814 auto G = createPlatformGraph(
MOP,
"<MachOHeaderMU>");
1815 addMachOHeader(R->getTargetJITDylib(), *
G, R->getInitializerSymbol());
1816 MOP.getObjectLinkingLayer().emit(std::move(R), std::move(
G));
1822void SimpleMachOHeaderMU::addMachOHeader(
1825 auto &HeaderSection =
G.createSection(
"__header",
MemProt::Read);
1829 G.addDefinedSymbol(HeaderBlock, 0, *InitializerSymbol, HeaderBlock.getSize(),
1832 for (
auto &HS : AdditionalHeaderSymbols)
1833 G.addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name, HeaderBlock.getSize(),
1841 switch (
MOP.getExecutionSession().getTargetTriple().getArch()) {
1844 return ::createHeaderBlock<MachO64LE>(
MOP,
Opts, JD,
G, HeaderSection);
1855 for (
auto &HS : AdditionalHeaderSymbols)
1864 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)
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)
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.
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.
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.
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.
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.