LLVM  16.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 
26 namespace llvm {
27 namespace orc {
28 
29 /// Mediates between MachO initialization and ExecutionSession state.
30 class MachOPlatform : public Platform {
31 public:
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, const char *OrcRuntimePath,
83  Optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
84 
85  ExecutionSession &getExecutionSession() const { return ES; }
86  ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
87 
88  Error setupJITDylib(JITDylib &JD) override;
89  Error teardownJITDylib(JITDylib &JD) override;
91  const MaterializationUnit &MU) override;
92  Error notifyRemoving(ResourceTracker &RT) override;
93 
94  /// Returns an AliasMap containing the default aliases for the MachOPlatform.
95  /// This can be modified by clients when constructing the platform to add
96  /// or remove aliases.
98 
99  /// Returns the array of required CXX aliases.
101 
102  /// Returns the array of standard runtime utility aliases for MachO.
105 
106  /// Returns true if the given section name is an initializer section.
107  static bool isInitializerSection(StringRef SegName, StringRef SectName);
108 
109 private:
110  // The MachOPlatformPlugin scans/modifies LinkGraphs to support MachO
111  // platform features including initializers, exceptions, TLV, and language
112  // runtime registration.
113  class MachOPlatformPlugin : public ObjectLinkingLayer::Plugin {
114  public:
115  MachOPlatformPlugin(MachOPlatform &MP) : MP(MP) {}
116 
117  void modifyPassConfig(MaterializationResponsibility &MR,
119  jitlink::PassConfiguration &Config) override;
120 
121  SyntheticSymbolDependenciesMap
122  getSyntheticSymbolDependencies(MaterializationResponsibility &MR) override;
123 
124  // FIXME: We should be tentatively tracking scraped sections and discarding
125  // if the MR fails.
126  Error notifyFailed(MaterializationResponsibility &MR) override {
127  return Error::success();
128  }
129 
130  Error notifyRemovingResources(ResourceKey K) override {
131  return Error::success();
132  }
133 
134  void notifyTransferringResources(ResourceKey DstKey,
135  ResourceKey SrcKey) override {}
136 
137  private:
138  using InitSymbolDepMap =
139  DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
140 
141  Error associateJITDylibHeaderSymbol(jitlink::LinkGraph &G,
142  MaterializationResponsibility &MR);
143 
144  Error preserveInitSections(jitlink::LinkGraph &G,
145  MaterializationResponsibility &MR);
146 
147  Error processObjCImageInfo(jitlink::LinkGraph &G,
148  MaterializationResponsibility &MR);
149 
150  Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
151 
152  Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD);
153 
154  Error registerEHSectionsPhase1(jitlink::LinkGraph &G);
155 
156  std::mutex PluginMutex;
157  MachOPlatform &MP;
158 
159  // FIXME: ObjCImageInfos and HeaderAddrs need to be cleared when
160  // JITDylibs are removed.
161  DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
162  DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
163  InitSymbolDepMap InitSymbolDeps;
164  };
165 
166  using GetJITDylibHeaderSendResultFn =
167  unique_function<void(Expected<ExecutorAddr>)>;
168  using GetJITDylibNameSendResultFn =
169  unique_function<void(Expected<StringRef>)>;
170  using PushInitializersSendResultFn =
171  unique_function<void(Expected<MachOJITDylibDepInfoMap>)>;
172  using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
173 
174  static bool supportedTarget(const Triple &TT);
175 
176  MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
177  JITDylib &PlatformJD,
178  std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
179  Error &Err);
180 
181  // Associate MachOPlatform JIT-side runtime support functions with handlers.
182  Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
183 
184  // Implements rt_pushInitializers by making repeat async lookups for
185  // initializer symbols (each lookup may spawn more initializer symbols if
186  // it pulls in new materializers, e.g. from objects in a static library).
187  void pushInitializersLoop(PushInitializersSendResultFn SendResult,
188  JITDylibSP JD);
189 
190  // Handle requests from the ORC runtime to push MachO initializer info.
191  void rt_pushInitializers(PushInitializersSendResultFn SendResult,
192  ExecutorAddr JDHeaderAddr);
193 
194  // Handle requests for symbol addresses from the ORC runtime.
195  void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
196  StringRef SymbolName);
197 
198  // Records the addresses of runtime symbols used by the platform.
199  Error bootstrapMachORuntime(JITDylib &PlatformJD);
200 
201  // Call the ORC runtime to create a pthread key.
202  Expected<uint64_t> createPThreadKey();
203 
204  enum PlatformState { BootstrapPhase1, BootstrapPhase2, Initialized };
205 
206  ExecutionSession &ES;
207  ObjectLinkingLayer &ObjLinkingLayer;
208 
209  SymbolStringPtr MachOHeaderStartSymbol;
210  std::atomic<PlatformState> State{BootstrapPhase1};
211 
212  ExecutorAddr orc_rt_macho_platform_bootstrap;
213  ExecutorAddr orc_rt_macho_platform_shutdown;
214  ExecutorAddr orc_rt_macho_register_ehframe_section;
215  ExecutorAddr orc_rt_macho_deregister_ehframe_section;
216  ExecutorAddr orc_rt_macho_register_jitdylib;
217  ExecutorAddr orc_rt_macho_deregister_jitdylib;
218  ExecutorAddr orc_rt_macho_register_object_platform_sections;
219  ExecutorAddr orc_rt_macho_deregister_object_platform_sections;
220  ExecutorAddr orc_rt_macho_create_pthread_key;
221 
222  DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
223 
224  std::mutex PlatformMutex;
225  DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
226  DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
227  DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
228 };
229 
230 namespace shared {
231 
234 
235 } // end namespace shared
236 } // end namespace orc
237 } // end namespace llvm
238 
239 #endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
llvm::orc::ResourceKey
uintptr_t ResourceKey
Definition: Core.h:50
llvm::orc::MachOPlatform::notifyRemoving
Error notifyRemoving(ResourceTracker &RT) override
This method will be called under the ExecutionSession lock when a ResourceTracker is removed.
Definition: MachOPlatform.cpp:274
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::orc::JITDylib
Represents a JIT'd dynamic library.
Definition: Core.h:953
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::orc::shared::SPSSequence
SPS tag type for sequences.
Definition: SimplePackedSerialization.h:205
StringRef.h
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::orc::MachOPlatform::teardownJITDylib
Error teardownJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...
Definition: MachOPlatform.cpp:245
llvm::orc::ResourceTracker
API to remove / transfer ownership of JIT resources.
Definition: Core.h:53
llvm::Optional
Definition: APInt.h:33
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::orc::MaterializationUnit
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:665
llvm::orc::MachOPlatform::requiredCXXAliases
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
Definition: MachOPlatform.cpp:296
llvm::orc::MachOPlatform
Mediates between MachO initialization and ExecutionSession state.
Definition: MachOPlatform.h:30
llvm::orc::MachOPlatform::isInitializerSection
static bool isInitializerSection(StringRef SegName, StringRef SectName)
Returns true if the given section name is an initializer section.
Definition: MachOPlatform.cpp:318
llvm::orc::MachOPlatform::MachOJITDylibDepInfoMap
std::vector< std::pair< ExecutorAddr, MachOJITDylibDepInfo > > MachOJITDylibDepInfoMap
Definition: MachOPlatform.h:40
llvm::orc::MachOPlatform::notifyAdding
Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) override
This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...
Definition: MachOPlatform.cpp:258
llvm::orc::MachOPlatform::MachOJITDylibDepInfo
Definition: MachOPlatform.h:33
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::DenseMap< SymbolStringPtr, SymbolAliasMapEntry >
llvm::orc::MachOPlatform::getObjectLinkingLayer
ObjectLinkingLayer & getObjectLinkingLayer() const
Definition: MachOPlatform.h:86
llvm::orc::JITDylibSP
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition: Core.h:48
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::orc::Platform
Platforms set up standard symbols and mediate interactions between dynamic initializers (e....
Definition: Core.h:1309
llvm::orc::ObjectLinkingLayer
An ObjectLayer implementation built on JITLink.
Definition: ObjectLinkingLayer.h:50
llvm::orc::MachOPlatform::setupJITDylib
Error setupJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is created (unless it is cre...
Definition: MachOPlatform.cpp:237
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
ExecutorAddress.h
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::orc::MachOPlatform::MachOJITDylibDepInfo::Sealed
bool Sealed
Definition: MachOPlatform.h:34
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1365
llvm::orc::MachOPlatform::standardRuntimeUtilityAliases
static ArrayRef< std::pair< const char *, const char * > > standardRuntimeUtilityAliases()
Returns the array of standard runtime utility aliases for MachO.
Definition: MachOPlatform.cpp:304
Core.h
llvm::orc::MachOPlatform::Create
static Expected< std::unique_ptr< MachOPlatform > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, Optional< SymbolAliasMap > RuntimeAliases=std::nullopt)
Try to create a MachOPlatform instance, adding the ORC runtime to the given JITDylib.
Definition: MachOPlatform.cpp:191
llvm::orc::MachOPlatform::MachOJITDylibDepInfo::DepHeaders
std::vector< ExecutorAddr > DepHeaders
Definition: MachOPlatform.h:35
llvm::orc::ObjectLinkingLayer::Plugin
Plugin instances can be added to the ObjectLinkingLayer to receive callbacks when code is loaded or e...
Definition: ObjectLinkingLayer.h:60
llvm::orc::MachOPlatform::standardPlatformAliases
static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)
Returns an AliasMap containing the default aliases for the MachOPlatform.
Definition: MachOPlatform.cpp:288
ExecutorProcessControl.h
ObjectLinkingLayer.h
llvm::orc::shared::SPSNamedExecutorAddrRangeSequence
SPSSequence< SPSTuple< SPSString, SPSExecutorAddrRange > > SPSNamedExecutorAddrRangeSequence
Definition: MachOPlatform.h:233
llvm::orc::MachOPlatform::getExecutionSession
ExecutionSession & getExecutionSession() const
Definition: MachOPlatform.h:85