1 //===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Utilities for executing JIT'd MachO in Orc.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
14 #define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ExecutionEngine/Orc/Core.h"
18 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
19 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
28 /// Enable registration of JIT'd ObjC classes and selectors.
29 Error enableObjCRegistration(const char *PathToLibObjC);
30 bool objCRegistrationEnabled();
32 class MachOJITDylibInitializers {
34 struct SectionExtent {
35 SectionExtent() = default;
36 SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
37 : Address(Address), NumPtrs(NumPtrs) {}
38 JITTargetAddress Address = 0;
42 using RawPointerSectionList = std::vector<SectionExtent>;
44 void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
45 this->ObjCImageInfoAddr = ObjCImageInfoAddr;
48 void addModInitsSection(SectionExtent ModInit) {
49 ModInitSections.push_back(std::move(ModInit));
52 const RawPointerSectionList &getModInitsSections() const {
53 return ModInitSections;
56 void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
57 ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
60 const RawPointerSectionList &getObjCSelRefsSections() const {
61 return ObjCSelRefsSections;
64 void addObjCClassListSection(SectionExtent ObjCClassList) {
65 ObjCClassListSections.push_back(std::move(ObjCClassList));
68 const RawPointerSectionList &getObjCClassListSections() const {
69 return ObjCClassListSections;
72 void runModInits() const;
73 void registerObjCSelectors() const;
74 Error registerObjCClasses() const;
78 JITTargetAddress ObjCImageInfoAddr;
79 RawPointerSectionList ModInitSections;
80 RawPointerSectionList ObjCSelRefsSections;
81 RawPointerSectionList ObjCClassListSections;
84 class MachOJITDylibDeinitializers {};
86 /// Mediates between MachO initialization and ExecutionSession state.
87 class MachOPlatform : public Platform {
89 using InitializerSequence =
90 std::vector<std::pair<JITDylib *, MachOJITDylibInitializers>>;
92 using DeinitializerSequence =
93 std::vector<std::pair<JITDylib *, MachOJITDylibDeinitializers>>;
95 MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
96 std::unique_ptr<MemoryBuffer> StandardSymbolsObject);
98 ExecutionSession &getExecutionSession() const { return ES; }
100 Error setupJITDylib(JITDylib &JD) override;
101 Error notifyAdding(ResourceTracker &RT,
102 const MaterializationUnit &MU) override;
103 Error notifyRemoving(ResourceTracker &RT) override;
105 Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
107 Expected<DeinitializerSequence> getDeinitializerSequence(JITDylib &JD);
110 // This ObjectLinkingLayer plugin scans JITLink graphs for __mod_init_func,
111 // __objc_classlist and __sel_ref sections and records their extents so that
112 // they can be run in the target process.
113 class InitScraperPlugin : public ObjectLinkingLayer::Plugin {
115 InitScraperPlugin(MachOPlatform &MP) : MP(MP) {}
117 void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
118 jitlink::PassConfiguration &Config) override;
120 LocalDependenciesMap getSyntheticSymbolLocalDependencies(
121 MaterializationResponsibility &MR) override;
123 // FIXME: We should be tentatively tracking scraped sections and discarding
125 Error notifyFailed(MaterializationResponsibility &MR) override {
126 return Error::success();
129 Error notifyRemovingResources(ResourceKey K) override {
130 return Error::success();
133 void notifyTransferringResources(ResourceKey DstKey,
134 ResourceKey SrcKey) override {}
137 using InitSymbolDepMap =
138 DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
140 void preserveInitSectionIfPresent(JITLinkSymbolVector &Syms,
141 jitlink::LinkGraph &G,
142 StringRef SectionName);
144 Error processObjCImageInfo(jitlink::LinkGraph &G,
145 MaterializationResponsibility &MR);
147 std::mutex InitScraperMutex;
149 DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
150 InitSymbolDepMap InitSymbolDeps;
153 void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
154 MachOJITDylibInitializers::SectionExtent ModInits,
155 MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
156 MachOJITDylibInitializers::SectionExtent ObjCClassList);
158 ExecutionSession &ES;
159 ObjectLinkingLayer &ObjLinkingLayer;
160 std::unique_ptr<MemoryBuffer> StandardSymbolsObject;
162 DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
164 // InitSeqs gets its own mutex to avoid locking the whole session when
165 // aggregating data from the jitlink.
166 std::mutex InitSeqsMutex;
167 DenseMap<JITDylib *, MachOJITDylibInitializers> InitSeqs;
170 } // end namespace orc
171 } // end namespace llvm
173 #endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H