LLVM 17.0.0git
MachOPlatform.h
Go to the documentation of this file.
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"
21
22#include <future>
23#include <thread>
24#include <vector>
25
26namespace llvm {
27namespace orc {
28
29/// Mediates between MachO initialization and ExecutionSession state.
30class MachOPlatform : public Platform {
31public:
32 // Used internally by MachOPlatform, but made public to enable serialization.
34 bool Sealed = false;
35 std::vector<ExecutorAddr> DepHeaders;
36 };
37
38 // Used internally by MachOPlatform, but made public to enable serialization.
40 std::vector<std::pair<ExecutorAddr, MachOJITDylibDepInfo>>;
41
42 /// Try to create a MachOPlatform instance, adding the ORC runtime to the
43 /// given JITDylib.
44 ///
45 /// The ORC runtime requires access to a number of symbols in libc++, and
46 /// requires access to symbols in libobjc, and libswiftCore to support
47 /// Objective-C and Swift code. It is up to the caller to ensure that the
48 /// requried symbols can be referenced by code added to PlatformJD. The
49 /// standard way to achieve this is to first attach dynamic library search
50 /// generators for either the given process, or for the specific required
51 /// libraries, to PlatformJD, then to create the platform instance:
52 ///
53 /// \code{.cpp}
54 /// auto &PlatformJD = ES.createBareJITDylib("stdlib");
55 /// PlatformJD.addGenerator(
56 /// ExitOnErr(EPCDynamicLibrarySearchGenerator
57 /// ::GetForTargetProcess(EPC)));
58 /// ES.setPlatform(
59 /// ExitOnErr(MachOPlatform::Create(ES, ObjLayer, EPC, PlatformJD,
60 /// "/path/to/orc/runtime")));
61 /// \endcode
62 ///
63 /// Alternatively, these symbols could be added to another JITDylib that
64 /// PlatformJD links against.
65 ///
66 /// Clients are also responsible for ensuring that any JIT'd code that
67 /// depends on runtime functions (including any code using TLV or static
68 /// destructors) can reference the runtime symbols. This is usually achieved
69 /// by linking any JITDylibs containing regular code against
70 /// PlatformJD.
71 ///
72 /// By default, MachOPlatform will add the set of aliases returned by the
73 /// standardPlatformAliases function. This includes both required aliases
74 /// (e.g. __cxa_atexit -> __orc_rt_macho_cxa_atexit for static destructor
75 /// support), and optional aliases that provide JIT versions of common
76 /// functions (e.g. dlopen -> __orc_rt_macho_jit_dlopen). Clients can
77 /// override these defaults by passing a non-None value for the
78 /// RuntimeAliases function, in which case the client is responsible for
79 /// setting up all aliases (including the required ones).
81 Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
82 JITDylib &PlatformJD, std::unique_ptr<DefinitionGenerator> OrcRuntime,
83 std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
84
85 /// Construct using a path to the ORC runtime.
87 Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
88 JITDylib &PlatformJD, const char *OrcRuntimePath,
89 std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
90
91 ExecutionSession &getExecutionSession() const { return ES; }
92 ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
93
94 Error setupJITDylib(JITDylib &JD) override;
95 Error teardownJITDylib(JITDylib &JD) override;
97 const MaterializationUnit &MU) override;
99
100 /// Returns an AliasMap containing the default aliases for the MachOPlatform.
101 /// This can be modified by clients when constructing the platform to add
102 /// or remove aliases.
104
105 /// Returns the array of required CXX aliases.
107
108 /// Returns the array of standard runtime utility aliases for MachO.
111
112private:
113 // Data needed for bootstrap only.
114 struct BootstrapInfo {
115 std::mutex Mutex;
116 std::condition_variable CV;
117 size_t ActiveGraphs = 0;
118 shared::AllocActions DeferredAAs;
119 ExecutorAddr MachOHeaderAddr;
120 };
121
122 // The MachOPlatformPlugin scans/modifies LinkGraphs to support MachO
123 // platform features including initializers, exceptions, TLV, and language
124 // runtime registration.
125 class MachOPlatformPlugin : public ObjectLinkingLayer::Plugin {
126 public:
127 MachOPlatformPlugin(MachOPlatform &MP) : MP(MP) {}
128
129 void modifyPassConfig(MaterializationResponsibility &MR,
130 jitlink::LinkGraph &G,
131 jitlink::PassConfiguration &Config) override;
132
134 getSyntheticSymbolDependencies(MaterializationResponsibility &MR) override;
135
136 // FIXME: We should be tentatively tracking scraped sections and discarding
137 // if the MR fails.
138 Error notifyFailed(MaterializationResponsibility &MR) override {
139 return Error::success();
140 }
141
142 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
143 return Error::success();
144 }
145
146 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
147 ResourceKey SrcKey) override {}
148
149 private:
150 using InitSymbolDepMap =
151 DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
152
153 struct UnwindSections {
154 SmallVector<ExecutorAddrRange> CodeRanges;
155 ExecutorAddrRange DwarfSection;
156 ExecutorAddrRange CompactUnwindSection;
157 };
158
159 struct ObjCImageInfo {
160 uint32_t Version = 0;
161 uint32_t Flags = 0;
162 };
163
164 Error bootstrapPipelineStart(jitlink::LinkGraph &G);
165 Error bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &G);
166 Error bootstrapPipelineEnd(jitlink::LinkGraph &G);
167
168 Error associateJITDylibHeaderSymbol(jitlink::LinkGraph &G,
169 MaterializationResponsibility &MR);
170
171 Error preserveImportantSections(jitlink::LinkGraph &G,
172 MaterializationResponsibility &MR);
173
174 Error processObjCImageInfo(jitlink::LinkGraph &G,
175 MaterializationResponsibility &MR);
176
177 Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
178
179 std::optional<UnwindSections> findUnwindSectionInfo(jitlink::LinkGraph &G);
180
181 Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD,
182 bool InBootstrapPhase);
183
184 Error createObjCRuntimeObject(jitlink::LinkGraph &G);
185 Error populateObjCRuntimeObject(jitlink::LinkGraph &G,
186 MaterializationResponsibility &MR);
187
188 std::mutex PluginMutex;
189 MachOPlatform &MP;
190
191 // FIXME: ObjCImageInfos and HeaderAddrs need to be cleared when
192 // JITDylibs are removed.
193 DenseMap<JITDylib *, ObjCImageInfo> ObjCImageInfos;
194 DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
195 InitSymbolDepMap InitSymbolDeps;
196 };
197
198 using GetJITDylibHeaderSendResultFn =
199 unique_function<void(Expected<ExecutorAddr>)>;
200 using GetJITDylibNameSendResultFn =
201 unique_function<void(Expected<StringRef>)>;
202 using PushInitializersSendResultFn =
203 unique_function<void(Expected<MachOJITDylibDepInfoMap>)>;
204 using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
205
206 static bool supportedTarget(const Triple &TT);
207
208 MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
209 JITDylib &PlatformJD,
210 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
211 Error &Err);
212
213 // Associate MachOPlatform JIT-side runtime support functions with handlers.
214 Error associateRuntimeSupportFunctions();
215
216 // Implements rt_pushInitializers by making repeat async lookups for
217 // initializer symbols (each lookup may spawn more initializer symbols if
218 // it pulls in new materializers, e.g. from objects in a static library).
219 void pushInitializersLoop(PushInitializersSendResultFn SendResult,
220 JITDylibSP JD);
221
222 // Handle requests from the ORC runtime to push MachO initializer info.
223 void rt_pushInitializers(PushInitializersSendResultFn SendResult,
224 ExecutorAddr JDHeaderAddr);
225
226 // Handle requests for symbol addresses from the ORC runtime.
227 void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
228 StringRef SymbolName);
229
230 // Call the ORC runtime to create a pthread key.
231 Expected<uint64_t> createPThreadKey();
232
233 ExecutionSession &ES;
234 JITDylib &PlatformJD;
235 ObjectLinkingLayer &ObjLinkingLayer;
236
237 SymbolStringPtr MachOHeaderStartSymbol = ES.intern("___dso_handle");
238
239 struct RuntimeFunction {
240 RuntimeFunction(SymbolStringPtr Name) : Name(std::move(Name)) {}
241 SymbolStringPtr Name;
242 ExecutorAddr Addr;
243 };
244
245 RuntimeFunction PlatformBootstrap{
246 ES.intern("___orc_rt_macho_platform_bootstrap")};
247 RuntimeFunction PlatformShutdown{
248 ES.intern("___orc_rt_macho_platform_shutdown")};
249 RuntimeFunction RegisterEHFrameSection{
250 ES.intern("___orc_rt_macho_register_ehframe_section")};
251 RuntimeFunction DeregisterEHFrameSection{
252 ES.intern("___orc_rt_macho_deregister_ehframe_section")};
253 RuntimeFunction RegisterJITDylib{
254 ES.intern("___orc_rt_macho_register_jitdylib")};
255 RuntimeFunction DeregisterJITDylib{
256 ES.intern("___orc_rt_macho_deregister_jitdylib")};
257 RuntimeFunction RegisterObjectPlatformSections{
258 ES.intern("___orc_rt_macho_register_object_platform_sections")};
259 RuntimeFunction DeregisterObjectPlatformSections{
260 ES.intern("___orc_rt_macho_deregister_object_platform_sections")};
261 RuntimeFunction CreatePThreadKey{
262 ES.intern("___orc_rt_macho_create_pthread_key")};
263 RuntimeFunction RegisterObjCRuntimeObject{
264 ES.intern("___orc_rt_macho_register_objc_runtime_object")};
265 RuntimeFunction DeregisterObjCRuntimeObject{
266 ES.intern("___orc_rt_macho_deregister_objc_runtime_object")};
267
268 DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
269
270 std::mutex PlatformMutex;
271 DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
272 DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
273 DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
274
275 std::atomic<BootstrapInfo *> Bootstrap;
276};
277
278namespace shared {
279
282
283} // end namespace shared
284} // end namespace orc
285} // end namespace llvm
286
287#endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
uint64_t Addr
RelaxConfig Config
Definition: ELF_riscv.cpp:490
#define G(x, y, z)
Definition: MD5.cpp:56
@ Flags
Definition: TextStubV5.cpp:93
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
An ExecutionSession represents a running JIT program.
Definition: Core.h:1364
Represents an address in the executor process.
Represents a JIT'd dynamic library.
Definition: Core.h:950
Mediates between MachO initialization and ExecutionSession state.
Definition: MachOPlatform.h:30
ObjectLinkingLayer & getObjectLinkingLayer() const
Definition: MachOPlatform.h:92
Error teardownJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...
Error setupJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is created (unless it is cre...
static ArrayRef< std::pair< const char *, const char * > > standardRuntimeUtilityAliases()
Returns the array of standard runtime utility aliases for MachO.
std::vector< std::pair< ExecutorAddr, MachOJITDylibDepInfo > > MachOJITDylibDepInfoMap
Definition: MachOPlatform.h:40
Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) override
This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...
static Expected< std::unique_ptr< MachOPlatform > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, std::unique_ptr< DefinitionGenerator > OrcRuntime, std::optional< SymbolAliasMap > RuntimeAliases=std::nullopt)
Try to create a MachOPlatform instance, adding the ORC runtime to the given JITDylib.
static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)
Returns an AliasMap containing the default aliases for the MachOPlatform.
ExecutionSession & getExecutionSession() const
Definition: MachOPlatform.h:91
Error notifyRemoving(ResourceTracker &RT) override
This method will be called under the ExecutionSession lock when a ResourceTracker is removed.
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:661
DenseMap< SymbolStringPtr, JITLinkSymbolSet > SyntheticSymbolDependenciesMap
An ObjectLayer implementation built on JITLink.
Platforms set up standard symbols and mediate interactions between dynamic initializers (e....
Definition: Core.h:1308
API to remove / transfer ownership of JIT resources.
Definition: Core.h:55
const uint64_t Version
Definition: InstrProf.h:1073
RuntimeFunction
IDs for all omp runtime library (RTL) functions.
Definition: OMPConstants.h:46
std::vector< AllocActionCallPair > AllocActions
A vector of allocation actions to be run for this allocation.
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition: Core.h:50
uintptr_t ResourceKey
Definition: Core.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1946
Definition: BitVector.h:858