LLVM 17.0.0git
ELFNixPlatform.h
Go to the documentation of this file.
1//===-- ELFNixPlatform.h -- Utilities for executing ELF 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// Linux/BSD support for executing JIT'd ELF in Orc.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_ELFNIXPLATFORM_H
14#define LLVM_EXECUTIONENGINE_ORC_ELFNIXPLATFORM_H
15
16#include "llvm/ADT/StringRef.h"
21
22#include <future>
23#include <thread>
24#include <vector>
25
26namespace llvm {
27namespace orc {
28
32};
33
35 using SectionList = std::vector<ExecutorAddrRange>;
36
39
40 std::string Name;
42
44};
45
47
49 std::vector<ELFNixJITDylibInitializers>;
50
52 std::vector<ELFNixJITDylibDeinitializers>;
53
54/// Mediates between ELFNix initialization and ExecutionSession state.
55class ELFNixPlatform : public Platform {
56public:
57 /// Try to create a ELFNixPlatform instance, adding the ORC runtime to the
58 /// given JITDylib.
59 ///
60 /// The ORC runtime requires access to a number of symbols in
61 /// libc++. It is up to the caller to ensure that the requried
62 /// symbols can be referenced by code added to PlatformJD. The
63 /// standard way to achieve this is to first attach dynamic library
64 /// search generators for either the given process, or for the
65 /// specific required libraries, to PlatformJD, then to create the
66 /// platform instance:
67 ///
68 /// \code{.cpp}
69 /// auto &PlatformJD = ES.createBareJITDylib("stdlib");
70 /// PlatformJD.addGenerator(
71 /// ExitOnErr(EPCDynamicLibrarySearchGenerator
72 /// ::GetForTargetProcess(EPC)));
73 /// ES.setPlatform(
74 /// ExitOnErr(ELFNixPlatform::Create(ES, ObjLayer, EPC, PlatformJD,
75 /// "/path/to/orc/runtime")));
76 /// \endcode
77 ///
78 /// Alternatively, these symbols could be added to another JITDylib that
79 /// PlatformJD links against.
80 ///
81 /// Clients are also responsible for ensuring that any JIT'd code that
82 /// depends on runtime functions (including any code using TLV or static
83 /// destructors) can reference the runtime symbols. This is usually achieved
84 /// by linking any JITDylibs containing regular code against
85 /// PlatformJD.
86 ///
87 /// By default, ELFNixPlatform will add the set of aliases returned by the
88 /// standardPlatformAliases function. This includes both required aliases
89 /// (e.g. __cxa_atexit -> __orc_rt_elf_cxa_atexit for static destructor
90 /// support), and optional aliases that provide JIT versions of common
91 /// functions (e.g. dlopen -> __orc_rt_elf_jit_dlopen). Clients can
92 /// override these defaults by passing a non-None value for the
93 /// RuntimeAliases function, in which case the client is responsible for
94 /// setting up all aliases (including the required ones).
96 Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
97 JITDylib &PlatformJD, const char *OrcRuntimePath,
98 std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
99
100 ExecutionSession &getExecutionSession() const { return ES; }
101 ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
102
103 Error setupJITDylib(JITDylib &JD) override;
104 Error teardownJITDylib(JITDylib &JD) override;
106 const MaterializationUnit &MU) override;
108
109 /// Returns an AliasMap containing the default aliases for the ELFNixPlatform.
110 /// This can be modified by clients when constructing the platform to add
111 /// or remove aliases.
113 JITDylib &PlatformJD);
114
115 /// Returns the array of required CXX aliases.
117
118 /// Returns the array of standard runtime utility aliases for ELF.
121
122 /// Returns true if the given section name is an initializer section.
123 static bool isInitializerSection(StringRef SecName);
124
125private:
126 // The ELFNixPlatformPlugin scans/modifies LinkGraphs to support ELF
127 // platform features including initializers, exceptions, TLV, and language
128 // runtime registration.
129 class ELFNixPlatformPlugin : public ObjectLinkingLayer::Plugin {
130 public:
131 ELFNixPlatformPlugin(ELFNixPlatform &MP) : MP(MP) {}
132
133 void modifyPassConfig(MaterializationResponsibility &MR,
135 jitlink::PassConfiguration &Config) override;
136
138 getSyntheticSymbolDependencies(MaterializationResponsibility &MR) override;
139
140 // FIXME: We should be tentatively tracking scraped sections and discarding
141 // if the MR fails.
142 Error notifyFailed(MaterializationResponsibility &MR) override {
143 return Error::success();
144 }
145
146 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
147 return Error::success();
148 }
149
150 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
151 ResourceKey SrcKey) override {}
152
153 private:
154 using InitSymbolDepMap =
155 DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
156
157 void addInitializerSupportPasses(MaterializationResponsibility &MR,
158 jitlink::PassConfiguration &Config);
159
160 void addDSOHandleSupportPasses(MaterializationResponsibility &MR,
161 jitlink::PassConfiguration &Config);
162
163 void addEHAndTLVSupportPasses(MaterializationResponsibility &MR,
164 jitlink::PassConfiguration &Config);
165
166 Error preserveInitSections(jitlink::LinkGraph &G,
167 MaterializationResponsibility &MR);
168
169 Error registerInitSections(jitlink::LinkGraph &G, JITDylib &JD);
170
171 Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
172
173 std::mutex PluginMutex;
174 ELFNixPlatform &MP;
175 InitSymbolDepMap InitSymbolDeps;
176 };
177
178 using SendInitializerSequenceFn =
179 unique_function<void(Expected<ELFNixJITDylibInitializerSequence>)>;
180
181 using SendDeinitializerSequenceFn =
182 unique_function<void(Expected<ELFNixJITDylibDeinitializerSequence>)>;
183
184 using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
185
186 static bool supportedTarget(const Triple &TT);
187
188 ELFNixPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
189 JITDylib &PlatformJD,
190 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
191 Error &Err);
192
193 // Associate ELFNixPlatform JIT-side runtime support functions with handlers.
194 Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
195
196 void getInitializersBuildSequencePhase(SendInitializerSequenceFn SendResult,
197 JITDylib &JD,
198 std::vector<JITDylibSP> DFSLinkOrder);
199
200 void getInitializersLookupPhase(SendInitializerSequenceFn SendResult,
201 JITDylib &JD);
202
203 void rt_getInitializers(SendInitializerSequenceFn SendResult,
204 StringRef JDName);
205
206 void rt_getDeinitializers(SendDeinitializerSequenceFn SendResult,
207 ExecutorAddr Handle);
208
209 void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
210 StringRef SymbolName);
211
212 // Records the addresses of runtime symbols used by the platform.
213 Error bootstrapELFNixRuntime(JITDylib &PlatformJD);
214
215 Error registerInitInfo(JITDylib &JD,
216 ArrayRef<jitlink::Section *> InitSections);
217
218 Error registerPerObjectSections(const ELFPerObjectSectionsToRegister &POSR);
219
220 Expected<uint64_t> createPThreadKey();
221
222 ExecutionSession &ES;
223 ObjectLinkingLayer &ObjLinkingLayer;
224
225 SymbolStringPtr DSOHandleSymbol;
226 std::atomic<bool> RuntimeBootstrapped{false};
227
228 ExecutorAddr orc_rt_elfnix_platform_bootstrap;
229 ExecutorAddr orc_rt_elfnix_platform_shutdown;
230 ExecutorAddr orc_rt_elfnix_register_object_sections;
231 ExecutorAddr orc_rt_elfnix_create_pthread_key;
232
233 DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
234
235 // InitSeqs gets its own mutex to avoid locking the whole session when
236 // aggregating data from the jitlink.
237 std::mutex PlatformMutex;
238 DenseMap<JITDylib *, ELFNixJITDylibInitializers> InitSeqs;
239 std::vector<ELFPerObjectSectionsToRegister> BootstrapPOSRs;
240
241 DenseMap<ExecutorAddr, JITDylib *> HandleAddrToJITDylib;
242 DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
243};
244
245namespace shared {
246
249
250template <>
253
254public:
255 static size_t size(const ELFPerObjectSectionsToRegister &MOPOSR) {
256 return SPSELFPerObjectSectionsToRegister::AsArgList::size(
257 MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
258 }
259
260 static bool serialize(SPSOutputBuffer &OB,
261 const ELFPerObjectSectionsToRegister &MOPOSR) {
262 return SPSELFPerObjectSectionsToRegister::AsArgList::serialize(
263 OB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
264 }
265
268 return SPSELFPerObjectSectionsToRegister::AsArgList::deserialize(
269 IB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
270 }
271};
272
275
278
281
282/// Serialization traits for ELFNixJITDylibInitializers.
283template <>
286public:
287 static size_t size(const ELFNixJITDylibInitializers &MOJDIs) {
288 return SPSELFNixJITDylibInitializers::AsArgList::size(
289 MOJDIs.Name, MOJDIs.DSOHandleAddress, MOJDIs.InitSections);
290 }
291
292 static bool serialize(SPSOutputBuffer &OB,
293 const ELFNixJITDylibInitializers &MOJDIs) {
294 return SPSELFNixJITDylibInitializers::AsArgList::serialize(
295 OB, MOJDIs.Name, MOJDIs.DSOHandleAddress, MOJDIs.InitSections);
296 }
297
300 return SPSELFNixJITDylibInitializers::AsArgList::deserialize(
301 IB, MOJDIs.Name, MOJDIs.DSOHandleAddress, MOJDIs.InitSections);
302 }
303};
304
306
309
310template <>
313public:
314 static size_t size(const ELFNixJITDylibDeinitializers &MOJDDs) { return 0; }
315
316 static bool serialize(SPSOutputBuffer &OB,
317 const ELFNixJITDylibDeinitializers &MOJDDs) {
318 return true;
319 }
320
324 return true;
325 }
326};
327
328} // end namespace shared
329} // end namespace orc
330} // end namespace llvm
331
332#endif // LLVM_EXECUTIONENGINE_ORC_ELFNIXPLATFORM_H
#define G(x, y, z)
Definition: MD5.cpp:56
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
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:111
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Mediates between ELFNix initialization and ExecutionSession state.
ObjectLinkingLayer & getObjectLinkingLayer() const
static Expected< SymbolAliasMap > standardPlatformAliases(ExecutionSession &ES, JITDylib &PlatformJD)
Returns an AliasMap containing the default aliases for the ELFNixPlatform.
Error notifyAdding(ResourceTracker &RT, const MaterializationUnit &MU) override
This method will be called under the ExecutionSession lock each time a MaterializationUnit is added t...
Error notifyRemoving(ResourceTracker &RT) override
This method will be called under the ExecutionSession lock when a ResourceTracker is removed.
Error setupJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is created (unless it is cre...
ExecutionSession & getExecutionSession() const
static bool isInitializerSection(StringRef SecName)
Returns true if the given section name is an initializer section.
static ArrayRef< std::pair< const char *, const char * > > standardRuntimeUtilityAliases()
Returns the array of standard runtime utility aliases for ELF.
static Expected< std::unique_ptr< ELFNixPlatform > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, std::optional< SymbolAliasMap > RuntimeAliases=std::nullopt)
Try to create a ELFNixPlatform instance, adding the ORC runtime to the given JITDylib.
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
Error teardownJITDylib(JITDylib &JD) override
This method will be called outside the session lock each time a JITDylib is removed to allow the Plat...
An ExecutionSession represents a running JIT program.
Definition: Core.h:1373
Represents an address in the executor process.
Represents a JIT'd dynamic library.
Definition: Core.h:962
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:673
Plugin instances can be added to the ObjectLinkingLayer to receive callbacks when code is loaded or e...
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:1317
API to remove / transfer ownership of JIT resources.
Definition: Core.h:53
Input char buffer with underflow check.
Output char buffer with overflow check.
static bool serialize(SPSOutputBuffer &OB, const ELFNixJITDylibDeinitializers &MOJDDs)
static bool deserialize(SPSInputBuffer &IB, ELFNixJITDylibDeinitializers &MOJDDs)
static bool deserialize(SPSInputBuffer &IB, ELFNixJITDylibInitializers &MOJDIs)
static bool serialize(SPSOutputBuffer &OB, const ELFNixJITDylibInitializers &MOJDIs)
static bool serialize(SPSOutputBuffer &OB, const ELFPerObjectSectionsToRegister &MOPOSR)
Specialize to describe how to serialize/deserialize to/from the given concrete type.
std::vector< ELFNixJITDylibDeinitializers > ELFNixJITDylibDeinitializerSequence
uintptr_t ResourceKey
Definition: Core.h:50
std::vector< ELFNixJITDylibInitializers > ELFNixJITDylibInitializerSequence
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:1862
Definition: BitVector.h:851
StringMap< SectionList > InitSections
ELFNixJITDylibInitializers(std::string Name, ExecutorAddr DSOHandleAddress)
std::vector< ExecutorAddrRange > SectionList
Represents an address range in the exceutor process.