LLVM  14.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 
32 };
33 
35  using SectionList = std::vector<ExecutorAddrRange>;
36 
38  : Name(std::move(Name)),
40 
41  std::string Name;
44 
46 };
47 
49 
50 using MachOJITDylibInitializerSequence = std::vector<MachOJITDylibInitializers>;
51 
53  std::vector<MachOJITDylibDeinitializers>;
54 
55 /// Mediates between MachO initialization and ExecutionSession state.
56 class MachOPlatform : public Platform {
57 public:
58  /// Try to create a MachOPlatform instance, adding the ORC runtime to the
59  /// given JITDylib.
60  ///
61  /// The ORC runtime requires access to a number of symbols in libc++, and
62  /// requires access to symbols in libobjc, and libswiftCore to support
63  /// Objective-C and Swift code. It is up to the caller to ensure that the
64  /// requried symbols can be referenced by code added to PlatformJD. The
65  /// standard way to achieve this is to first attach dynamic library search
66  /// generators for either the given process, or for the specific required
67  /// libraries, to PlatformJD, then to create the platform instance:
68  ///
69  /// \code{.cpp}
70  /// auto &PlatformJD = ES.createBareJITDylib("stdlib");
71  /// PlatformJD.addGenerator(
72  /// ExitOnErr(EPCDynamicLibrarySearchGenerator
73  /// ::GetForTargetProcess(EPC)));
74  /// ES.setPlatform(
75  /// ExitOnErr(MachOPlatform::Create(ES, ObjLayer, EPC, PlatformJD,
76  /// "/path/to/orc/runtime")));
77  /// \endcode
78  ///
79  /// Alternatively, these symbols could be added to another JITDylib that
80  /// PlatformJD links against.
81  ///
82  /// Clients are also responsible for ensuring that any JIT'd code that
83  /// depends on runtime functions (including any code using TLV or static
84  /// destructors) can reference the runtime symbols. This is usually achieved
85  /// by linking any JITDylibs containing regular code against
86  /// PlatformJD.
87  ///
88  /// By default, MachOPlatform will add the set of aliases returned by the
89  /// standardPlatformAliases function. This includes both required aliases
90  /// (e.g. __cxa_atexit -> __orc_rt_macho_cxa_atexit for static destructor
91  /// support), and optional aliases that provide JIT versions of common
92  /// functions (e.g. dlopen -> __orc_rt_macho_jit_dlopen). Clients can
93  /// override these defaults by passing a non-None value for the
94  /// RuntimeAliases function, in which case the client is responsible for
95  /// setting up all aliases (including the required ones).
97  Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
98  JITDylib &PlatformJD, const char *OrcRuntimePath,
99  Optional<SymbolAliasMap> RuntimeAliases = None);
100 
101  ExecutionSession &getExecutionSession() const { return ES; }
102  ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
103 
104  Error setupJITDylib(JITDylib &JD) override;
106  const MaterializationUnit &MU) override;
107  Error notifyRemoving(ResourceTracker &RT) override;
108 
109  /// Returns an AliasMap containing the default aliases for the MachOPlatform.
110  /// This can be modified by clients when constructing the platform to add
111  /// or remove aliases.
113 
114  /// Returns the array of required CXX aliases.
116 
117  /// Returns the array of standard runtime utility aliases for MachO.
120 
121  /// Returns true if the given section name is an initializer section.
122  static bool isInitializerSection(StringRef SegName, StringRef SectName);
123 
124 private:
125  // The MachOPlatformPlugin scans/modifies LinkGraphs to support MachO
126  // platform features including initializers, exceptions, TLV, and language
127  // runtime registration.
128  class MachOPlatformPlugin : public ObjectLinkingLayer::Plugin {
129  public:
130  MachOPlatformPlugin(MachOPlatform &MP) : MP(MP) {}
131 
132  void modifyPassConfig(MaterializationResponsibility &MR,
134  jitlink::PassConfiguration &Config) override;
135 
136  SyntheticSymbolDependenciesMap
137  getSyntheticSymbolDependencies(MaterializationResponsibility &MR) override;
138 
139  // FIXME: We should be tentatively tracking scraped sections and discarding
140  // if the MR fails.
141  Error notifyFailed(MaterializationResponsibility &MR) override {
142  return Error::success();
143  }
144 
145  Error notifyRemovingResources(ResourceKey K) override {
146  return Error::success();
147  }
148 
149  void notifyTransferringResources(ResourceKey DstKey,
150  ResourceKey SrcKey) override {}
151 
152  private:
153  using InitSymbolDepMap =
154  DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
155 
156  void addInitializerSupportPasses(MaterializationResponsibility &MR,
157  jitlink::PassConfiguration &Config);
158 
159  void addMachOHeaderSupportPasses(MaterializationResponsibility &MR,
160  jitlink::PassConfiguration &Config);
161 
162  void addEHAndTLVSupportPasses(MaterializationResponsibility &MR,
163  jitlink::PassConfiguration &Config);
164 
165  Error preserveInitSections(jitlink::LinkGraph &G,
166  MaterializationResponsibility &MR);
167 
168  Error processObjCImageInfo(jitlink::LinkGraph &G,
169  MaterializationResponsibility &MR);
170 
171  Error registerInitSections(jitlink::LinkGraph &G, JITDylib &JD);
172 
173  Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
174 
175  std::mutex PluginMutex;
176  MachOPlatform &MP;
177  DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
178  InitSymbolDepMap InitSymbolDeps;
179  };
180 
181  using SendInitializerSequenceFn =
182  unique_function<void(Expected<MachOJITDylibInitializerSequence>)>;
183 
184  using SendDeinitializerSequenceFn =
185  unique_function<void(Expected<MachOJITDylibDeinitializerSequence>)>;
186 
187  using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
188 
189  static bool supportedTarget(const Triple &TT);
190 
191  MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
192  JITDylib &PlatformJD,
193  std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
194  Error &Err);
195 
196  // Associate MachOPlatform JIT-side runtime support functions with handlers.
197  Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
198 
199  void getInitializersBuildSequencePhase(SendInitializerSequenceFn SendResult,
200  JITDylib &JD,
201  std::vector<JITDylibSP> DFSLinkOrder);
202 
203  void getInitializersLookupPhase(SendInitializerSequenceFn SendResult,
204  JITDylib &JD);
205 
206  void rt_getInitializers(SendInitializerSequenceFn SendResult,
207  StringRef JDName);
208 
209  void rt_getDeinitializers(SendDeinitializerSequenceFn SendResult,
210  ExecutorAddr Handle);
211 
212  void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
213  StringRef SymbolName);
214 
215  // Records the addresses of runtime symbols used by the platform.
216  Error bootstrapMachORuntime(JITDylib &PlatformJD);
217 
218  Error registerInitInfo(JITDylib &JD, ExecutorAddr ObjCImageInfoAddr,
219  ArrayRef<jitlink::Section *> InitSections);
220 
221  Error registerPerObjectSections(const MachOPerObjectSectionsToRegister &POSR);
222 
223  Expected<uint64_t> createPThreadKey();
224 
225  ExecutionSession &ES;
226  ObjectLinkingLayer &ObjLinkingLayer;
227 
228  SymbolStringPtr MachOHeaderStartSymbol;
229  std::atomic<bool> RuntimeBootstrapped{false};
230 
231  ExecutorAddr orc_rt_macho_platform_bootstrap;
232  ExecutorAddr orc_rt_macho_platform_shutdown;
233  ExecutorAddr orc_rt_macho_register_object_sections;
234  ExecutorAddr orc_rt_macho_create_pthread_key;
235 
236  DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
237 
238  // InitSeqs gets its own mutex to avoid locking the whole session when
239  // aggregating data from the jitlink.
240  std::mutex PlatformMutex;
241  DenseMap<JITDylib *, MachOJITDylibInitializers> InitSeqs;
242  std::vector<MachOPerObjectSectionsToRegister> BootstrapPOSRs;
243 
244  DenseMap<JITTargetAddress, JITDylib *> HeaderAddrToJITDylib;
245  DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
246 };
247 
248 namespace shared {
249 
252 
253 template <>
256 
257 public:
258  static size_t size(const MachOPerObjectSectionsToRegister &MOPOSR) {
260  MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
261  }
262 
264  const MachOPerObjectSectionsToRegister &MOPOSR) {
265  return SPSMachOPerObjectSectionsToRegister::AsArgList::serialize(
266  OB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
267  }
268 
269  static bool deserialize(SPSInputBuffer &IB,
271  return SPSMachOPerObjectSectionsToRegister::AsArgList::deserialize(
272  IB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
273  }
274 };
275 
277  SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRangeSequence>>;
278 
280  SPSTuple<SPSString, SPSExecutorAddr, SPSExecutorAddr,
282 
285 
286 /// Serialization traits for MachOJITDylibInitializers.
287 template <>
290 public:
291  static size_t size(const MachOJITDylibInitializers &MOJDIs) {
293  MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress,
294  MOJDIs.InitSections);
295  }
296 
298  const MachOJITDylibInitializers &MOJDIs) {
299  return SPSMachOJITDylibInitializers::AsArgList::serialize(
300  OB, MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress,
301  MOJDIs.InitSections);
302  }
303 
304  static bool deserialize(SPSInputBuffer &IB,
305  MachOJITDylibInitializers &MOJDIs) {
306  return SPSMachOJITDylibInitializers::AsArgList::deserialize(
307  IB, MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress,
308  MOJDIs.InitSections);
309  }
310 };
311 
313 
316 
317 template <>
320 public:
321  static size_t size(const MachOJITDylibDeinitializers &MOJDDs) { return 0; }
322 
324  const MachOJITDylibDeinitializers &MOJDDs) {
325  return true;
326  }
327 
328  static bool deserialize(SPSInputBuffer &IB,
329  MachOJITDylibDeinitializers &MOJDDs) {
330  MOJDDs = MachOJITDylibDeinitializers();
331  return true;
332  }
333 };
334 
335 } // end namespace shared
336 } // end namespace orc
337 } // end namespace llvm
338 
339 #endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:37
llvm::orc::ResourceKey
uintptr_t ResourceKey
Definition: Core.h:50
llvm::orc::shared::SPSMachOPerObjectSectionsToRegister
SPSTuple< SPSExecutorAddrRange, SPSExecutorAddrRange > SPSMachOPerObjectSectionsToRegister
Definition: MachOPlatform.h:251
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:220
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::orc::JITDylib
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:922
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::orc::shared::SPSSequence
SPS tag type for sequences.
Definition: SimplePackedSerialization.h:193
llvm::orc::shared::SPSSerializationTraits
Specialize to describe how to serialize/deserialize to/from the given concrete type.
Definition: SimplePackedSerialization.h:103
StringRef.h
llvm::orc::MachOJITDylibInitializers
Definition: MachOPlatform.h:34
llvm::orc::shared::SPSOutputBuffer
Output char buffer with overflow check.
Definition: SimplePackedSerialization.h:53
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibInitializers, MachOJITDylibInitializers >::serialize
static bool serialize(SPSOutputBuffer &OB, const MachOJITDylibInitializers &MOJDIs)
Definition: MachOPlatform.h:297
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::orc::MachOJITDylibInitializers::SectionList
std::vector< ExecutorAddrRange > SectionList
Definition: MachOPlatform.h:35
llvm::orc::ResourceTracker
API to remove / transfer ownership of JIT resources.
Definition: Core.h:53
llvm::orc::MachOJITDylibDeinitializerSequence
std::vector< MachOJITDylibDeinitializers > MachOJITDylibDeinitializerSequence
Definition: MachOPlatform.h:53
llvm::Optional
Definition: APInt.h:33
llvm::orc::shared::SPSInputBuffer
Input char buffer with underflow check.
Definition: SimplePackedSerialization.h:72
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::orc::MachOJITDylibInitializerSequence
std::vector< MachOJITDylibInitializers > MachOJITDylibInitializerSequence
Definition: MachOPlatform.h:50
llvm::orc::MachOJITDylibDeinitializers
Definition: MachOPlatform.h:48
llvm::orc::shared::SPSTuple
SPS tag type for tuples.
Definition: SimplePackedSerialization.h:183
llvm::orc::MachOJITDylibInitializers::Name
std::string Name
Definition: MachOPlatform.h:41
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDeinitializers, MachOJITDylibDeinitializers >::serialize
static bool serialize(SPSOutputBuffer &OB, const MachOJITDylibDeinitializers &MOJDDs)
Definition: MachOPlatform.h:323
llvm::orc::MachOJITDylibInitializers::MachOJITDylibInitializers
MachOJITDylibInitializers(std::string Name, ExecutorAddr MachOHeaderAddress)
Definition: MachOPlatform.h:37
llvm::orc::MaterializationUnit
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:664
llvm::orc::MachOPlatform::Create
static Expected< std::unique_ptr< MachOPlatform > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, Optional< SymbolAliasMap > RuntimeAliases=None)
Try to create a MachOPlatform instance, adding the ORC runtime to the given JITDylib.
Definition: MachOPlatform.cpp:153
llvm::orc::shared::SPSNamedExecutorAddrRangeSequenceMap
SPSSequence< SPSTuple< SPSString, SPSExecutorAddrRangeSequence > > SPSNamedExecutorAddrRangeSequenceMap
Definition: ELFNixPlatform.h:272
llvm::orc::MachOPlatform::requiredCXXAliases
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
Definition: MachOPlatform.cpp:242
llvm::orc::shared::SPSEmpty
Definition: SimplePackedSerialization.h:177
llvm::orc::MachOJITDylibInitializers::MachOHeaderAddress
ExecutorAddr MachOHeaderAddress
Definition: MachOPlatform.h:42
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDeinitializers, MachOJITDylibDeinitializers >::deserialize
static bool deserialize(SPSInputBuffer &IB, MachOJITDylibDeinitializers &MOJDDs)
Definition: MachOPlatform.h:328
llvm::orc::MachOPlatform
Mediates between MachO initialization and ExecutionSession state.
Definition: MachOPlatform.h:56
llvm::orc::ExecutorAddrRange
Represents an address range in the exceutor process.
Definition: ExecutorAddress.h:134
llvm::None
const NoneType None
Definition: None.h:23
llvm::StringMap< SectionList >
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibInitializers, MachOJITDylibInitializers >::deserialize
static bool deserialize(SPSInputBuffer &IB, MachOJITDylibInitializers &MOJDIs)
Definition: MachOPlatform.h:304
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:260
llvm::orc::MachOPerObjectSectionsToRegister::EHFrameSection
ExecutorAddrRange EHFrameSection
Definition: MachOPlatform.h:30
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:204
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::orc::shared::SPSSerializationTraits< SPSMachOPerObjectSectionsToRegister, MachOPerObjectSectionsToRegister >::size
static size_t size(const MachOPerObjectSectionsToRegister &MOPOSR)
Definition: MachOPlatform.h:258
llvm::DenseMap
Definition: DenseMap.h:714
llvm::orc::MachOPlatform::getObjectLinkingLayer
ObjectLinkingLayer & getObjectLinkingLayer() const
Definition: MachOPlatform.h:102
size
i< reg-> size
Definition: README.txt:166
llvm::move
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:1609
llvm::orc::MachOPerObjectSectionsToRegister::ThreadDataSection
ExecutorAddrRange ThreadDataSection
Definition: MachOPlatform.h:31
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:58
llvm::orc::Platform
Platforms set up standard symbols and mediate interactions between dynamic initializers (e....
Definition: Core.h:1222
llvm::X86II::OB
@ OB
Definition: X86BaseInfo.h:796
llvm::orc::MachOPerObjectSectionsToRegister
Definition: MachOPlatform.h:29
llvm::orc::ObjectLinkingLayer
An ObjectLayer implementation built on JITLink.
Definition: ObjectLinkingLayer.h:54
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:199
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:381
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibDeinitializers, MachOJITDylibDeinitializers >::size
static size_t size(const MachOJITDylibDeinitializers &MOJDDs)
Definition: MachOPlatform.h:321
std
Definition: BitVector.h:838
ExecutorAddress.h
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1275
llvm::orc::shared::SPSSerializationTraits< SPSMachOPerObjectSectionsToRegister, MachOPerObjectSectionsToRegister >::serialize
static bool serialize(SPSOutputBuffer &OB, const MachOPerObjectSectionsToRegister &MOPOSR)
Definition: MachOPlatform.h:263
llvm::orc::MachOJITDylibInitializers::ObjCImageInfoAddress
ExecutorAddr ObjCImageInfoAddress
Definition: MachOPlatform.h:43
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:250
llvm::orc::shared::SPSMachOJITDylibInitializers
SPSTuple< SPSString, SPSExecutorAddr, SPSExecutorAddr, SPSNamedExecutorAddrRangeSequenceMap > SPSMachOJITDylibInitializers
Definition: MachOPlatform.h:281
Core.h
llvm::orc::MachOJITDylibInitializers::InitSections
StringMap< SectionList > InitSections
Definition: MachOPlatform.h:45
llvm::orc::shared::SPSSerializationTraits< SPSMachOJITDylibInitializers, MachOJITDylibInitializers >::size
static size_t size(const MachOJITDylibInitializers &MOJDIs)
Definition: MachOPlatform.h:291
llvm::orc::ObjectLinkingLayer::Plugin
Plugin instances can be added to the ObjectLinkingLayer to receive callbacks when code is loaded or e...
Definition: ObjectLinkingLayer.h:64
llvm::orc::MachOPlatform::standardPlatformAliases
static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)
Returns an AliasMap containing the default aliases for the MachOPlatform.
Definition: MachOPlatform.cpp:234
ExecutorProcessControl.h
llvm::orc::shared::SPSSerializationTraits< SPSMachOPerObjectSectionsToRegister, MachOPerObjectSectionsToRegister >::deserialize
static bool deserialize(SPSInputBuffer &IB, MachOPerObjectSectionsToRegister &MOPOSR)
Definition: MachOPlatform.h:269
ObjectLinkingLayer.h
llvm::orc::shared::SPSString
SPSSequence< char > SPSString
SPS tag type for strings, which are equivalent to sequences of chars.
Definition: SimplePackedSerialization.h:196
llvm::orc::MachOPlatform::getExecutionSession
ExecutionSession & getExecutionSession() const
Definition: MachOPlatform.h:101