OSDN Git Service

[ORC] Add support for resource tracking/removal (removable code).
[android-x86/external-llvm-project.git] / llvm / include / llvm / ExecutionEngine / Orc / MachOPlatform.h
1 //===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Utilities for executing JIT'd MachO in Orc.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
14 #define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
15
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"
20
21 #include <future>
22 #include <thread>
23 #include <vector>
24
25 namespace llvm {
26 namespace orc {
27
28 /// Enable registration of JIT'd ObjC classes and selectors.
29 Error enableObjCRegistration(const char *PathToLibObjC);
30 bool objCRegistrationEnabled();
31
32 class MachOJITDylibInitializers {
33 public:
34   struct SectionExtent {
35     SectionExtent() = default;
36     SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
37         : Address(Address), NumPtrs(NumPtrs) {}
38     JITTargetAddress Address = 0;
39     uint64_t NumPtrs = 0;
40   };
41
42   using RawPointerSectionList = std::vector<SectionExtent>;
43
44   void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
45     this->ObjCImageInfoAddr = ObjCImageInfoAddr;
46   }
47
48   void addModInitsSection(SectionExtent ModInit) {
49     ModInitSections.push_back(std::move(ModInit));
50   }
51
52   const RawPointerSectionList &getModInitsSections() const {
53     return ModInitSections;
54   }
55
56   void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
57     ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
58   }
59
60   const RawPointerSectionList &getObjCSelRefsSections() const {
61     return ObjCSelRefsSections;
62   }
63
64   void addObjCClassListSection(SectionExtent ObjCClassList) {
65     ObjCClassListSections.push_back(std::move(ObjCClassList));
66   }
67
68   const RawPointerSectionList &getObjCClassListSections() const {
69     return ObjCClassListSections;
70   }
71
72   void runModInits() const;
73   void registerObjCSelectors() const;
74   Error registerObjCClasses() const;
75
76 private:
77
78   JITTargetAddress ObjCImageInfoAddr;
79   RawPointerSectionList ModInitSections;
80   RawPointerSectionList ObjCSelRefsSections;
81   RawPointerSectionList ObjCClassListSections;
82 };
83
84 class MachOJITDylibDeinitializers {};
85
86 /// Mediates between MachO initialization and ExecutionSession state.
87 class MachOPlatform : public Platform {
88 public:
89   using InitializerSequence =
90       std::vector<std::pair<JITDylib *, MachOJITDylibInitializers>>;
91
92   using DeinitializerSequence =
93       std::vector<std::pair<JITDylib *, MachOJITDylibDeinitializers>>;
94
95   MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
96                 std::unique_ptr<MemoryBuffer> StandardSymbolsObject);
97
98   ExecutionSession &getExecutionSession() const { return ES; }
99
100   Error setupJITDylib(JITDylib &JD) override;
101   Error notifyAdding(ResourceTracker &RT,
102                      const MaterializationUnit &MU) override;
103   Error notifyRemoving(ResourceTracker &RT) override;
104
105   Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
106
107   Expected<DeinitializerSequence> getDeinitializerSequence(JITDylib &JD);
108
109 private:
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 {
114   public:
115     InitScraperPlugin(MachOPlatform &MP) : MP(MP) {}
116
117     void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
118                           jitlink::PassConfiguration &Config) override;
119
120     LocalDependenciesMap getSyntheticSymbolLocalDependencies(
121         MaterializationResponsibility &MR) override;
122
123     // FIXME: We should be tentatively tracking scraped sections and discarding
124     // if the MR fails.
125     Error notifyFailed(MaterializationResponsibility &MR) override {
126       return Error::success();
127     }
128
129     Error notifyRemovingResources(ResourceKey K) override {
130       return Error::success();
131     }
132
133     void notifyTransferringResources(ResourceKey DstKey,
134                                      ResourceKey SrcKey) override {}
135
136   private:
137     using InitSymbolDepMap =
138         DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
139
140     void preserveInitSectionIfPresent(JITLinkSymbolVector &Syms,
141                                       jitlink::LinkGraph &G,
142                                       StringRef SectionName);
143
144     Error processObjCImageInfo(jitlink::LinkGraph &G,
145                                MaterializationResponsibility &MR);
146
147     std::mutex InitScraperMutex;
148     MachOPlatform &MP;
149     DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
150     InitSymbolDepMap InitSymbolDeps;
151   };
152
153   void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
154                         MachOJITDylibInitializers::SectionExtent ModInits,
155                         MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
156                         MachOJITDylibInitializers::SectionExtent ObjCClassList);
157
158   ExecutionSession &ES;
159   ObjectLinkingLayer &ObjLinkingLayer;
160   std::unique_ptr<MemoryBuffer> StandardSymbolsObject;
161
162   DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
163
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;
168 };
169
170 } // end namespace orc
171 } // end namespace llvm
172
173 #endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H