LLVM  16.0.0git
COFFPlatform.h
Go to the documentation of this file.
1 //===--- COFFPlatform.h -- Utilities for executing COFF 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 COFF in Orc.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
14 #define LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
15 
16 #include "llvm/ADT/StringRef.h"
23 
24 #include <future>
25 #include <memory>
26 #include <thread>
27 #include <vector>
28 
29 namespace llvm {
30 namespace orc {
31 
32 /// Mediates between COFF initialization and ExecutionSession state.
33 class COFFPlatform : public Platform {
34 public:
35  /// A function that will be called with the name of dll file that must be
36  /// loaded.
37  using LoadDynamicLibrary =
39 
40  /// Try to create a COFFPlatform instance, adding the ORC runtime to the
41  /// given JITDylib.
43  Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
44  JITDylib &PlatformJD, const char *OrcRuntimePath,
45  LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false,
46  const char *VCRuntimePath = nullptr,
47  Optional<SymbolAliasMap> RuntimeAliases = None);
48 
49  ExecutionSession &getExecutionSession() const { return ES; }
50  ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
51 
52  Error setupJITDylib(JITDylib &JD) override;
53  Error teardownJITDylib(JITDylib &JD) override;
55  const MaterializationUnit &MU) override;
56  Error notifyRemoving(ResourceTracker &RT) override;
57 
58  /// Returns an AliasMap containing the default aliases for the COFFPlatform.
59  /// This can be modified by clients when constructing the platform to add
60  /// or remove aliases.
62 
63  /// Returns the array of required CXX aliases.
65 
66  /// Returns the array of standard runtime utility aliases for COFF.
69 
70  static bool isInitializerSection(StringRef Name) {
71  return Name.startswith(".CRT");
72  }
73 
74  static StringRef getSEHFrameSectionName() { return ".pdata"; }
75 
76 private:
77  using COFFJITDylibDepInfo = std::vector<ExecutorAddr>;
78  using COFFJITDylibDepInfoMap =
79  std::vector<std::pair<ExecutorAddr, COFFJITDylibDepInfo>>;
80  using COFFObjectSectionsMap =
82  using PushInitializersSendResultFn =
84  using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
85  using JITDylibDepMap = DenseMap<JITDylib *, SmallVector<JITDylib *>>;
86 
87  // The COFFPlatformPlugin scans/modifies LinkGraphs to support COFF
88  // platform features including initializers, exceptions, and language
89  // runtime registration.
90  class COFFPlatformPlugin : public ObjectLinkingLayer::Plugin {
91  public:
92  COFFPlatformPlugin(COFFPlatform &CP) : CP(CP) {}
93 
94  void modifyPassConfig(MaterializationResponsibility &MR,
96  jitlink::PassConfiguration &Config) override;
97 
98  SyntheticSymbolDependenciesMap
99  getSyntheticSymbolDependencies(MaterializationResponsibility &MR) override;
100 
101  // FIXME: We should be tentatively tracking scraped sections and discarding
102  // if the MR fails.
103  Error notifyFailed(MaterializationResponsibility &MR) override {
104  return Error::success();
105  }
106 
107  Error notifyRemovingResources(ResourceKey K) override {
108  return Error::success();
109  }
110 
111  void notifyTransferringResources(ResourceKey DstKey,
112  ResourceKey SrcKey) override {}
113 
114  private:
115  using InitSymbolDepMap =
116  DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
117 
118  Error associateJITDylibHeaderSymbol(jitlink::LinkGraph &G,
119  MaterializationResponsibility &MR,
120  bool Bootstrap);
121 
122  Error preserveInitializerSections(jitlink::LinkGraph &G,
123  MaterializationResponsibility &MR);
124  Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD);
125  Error registerObjectPlatformSectionsInBootstrap(jitlink::LinkGraph &G,
126  JITDylib &JD);
127 
128  std::mutex PluginMutex;
129  COFFPlatform &CP;
130  InitSymbolDepMap InitSymbolDeps;
131  };
132 
133  struct JDBootstrapState {
134  JITDylib *JD = nullptr;
135  std::string JDName;
136  ExecutorAddr HeaderAddr;
137  std::list<COFFObjectSectionsMap> ObjectSectionsMaps;
138  SmallVector<std::pair<std::string, ExecutorAddr>> Initializers;
139  };
140 
141  static bool supportedTarget(const Triple &TT);
142 
143  COFFPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
144  JITDylib &PlatformJD, const char *OrcRuntimePath,
145  LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
146  const char *VCRuntimePath, Error &Err);
147 
148  // Associate COFFPlatform JIT-side runtime support functions with handlers.
149  Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
150 
151  // Records the addresses of runtime symbols used by the platform.
152  Error bootstrapCOFFRuntime(JITDylib &PlatformJD);
153 
154  // Run a specific void function if it exists.
155  Error runSymbolIfExists(JITDylib &PlatformJD, StringRef SymbolName);
156 
157  // Run collected initializers in boostrap stage.
158  Error runBootstrapInitializers(JDBootstrapState &BState);
159  Error runBootstrapSubsectionInitializers(JDBootstrapState &BState,
160  StringRef Start, StringRef End);
161 
162  // Build dependency graph of a JITDylib
163  Expected<JITDylibDepMap> buildJDDepMap(JITDylib &JD);
164 
165  Expected<MemoryBufferRef> getPerJDObjectFile();
166 
167  // Implements rt_pushInitializers by making repeat async lookups for
168  // initializer symbols (each lookup may spawn more initializer symbols if
169  // it pulls in new materializers, e.g. from objects in a static library).
170  void pushInitializersLoop(PushInitializersSendResultFn SendResult,
171  JITDylibSP JD, JITDylibDepMap &JDDepMap);
172 
173  void rt_pushInitializers(PushInitializersSendResultFn SendResult,
174  ExecutorAddr JDHeaderAddr);
175 
176  void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
177  StringRef SymbolName);
178 
179  ExecutionSession &ES;
180  ObjectLinkingLayer &ObjLinkingLayer;
181 
182  LoadDynamicLibrary LoadDynLibrary;
183  std::unique_ptr<COFFVCRuntimeBootstrapper> VCRuntimeBootstrap;
184  std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer;
185  std::unique_ptr<object::Archive> OrcRuntimeArchive;
186  bool StaticVCRuntime;
187 
188  SymbolStringPtr COFFHeaderStartSymbol;
189 
190  // State of bootstrap in progress
191  std::map<JITDylib *, JDBootstrapState> JDBootstrapStates;
192  std::atomic<bool> Bootstrapping;
193 
194  ExecutorAddr orc_rt_coff_platform_bootstrap;
195  ExecutorAddr orc_rt_coff_platform_shutdown;
196  ExecutorAddr orc_rt_coff_register_object_sections;
197  ExecutorAddr orc_rt_coff_deregister_object_sections;
198  ExecutorAddr orc_rt_coff_register_jitdylib;
199  ExecutorAddr orc_rt_coff_deregister_jitdylib;
200 
201  DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
202  DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
203 
204  DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
205 
206  std::set<std::string> DylibsToPreload;
207 
208  std::mutex PlatformMutex;
209 };
210 
211 } // end namespace orc
212 } // end namespace llvm
213 
214 #endif // LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
llvm::orc::ResourceKey
uintptr_t ResourceKey
Definition: Core.h:50
llvm::orc::COFFPlatform::isInitializerSection
static bool isInitializerSection(StringRef Name)
Definition: COFFPlatform.h:70
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::orc::COFFPlatform::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: COFFPlatform.cpp:234
llvm::orc::JITDylib
Represents a JIT'd dynamic library.
Definition: Core.h:953
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::unique_function< Error(JITDylib &JD, StringRef DLLFileName)>
StringRef.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
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
ExecutionUtils.h
llvm::orc::COFFPlatform::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: COFFPlatform.cpp:278
llvm::orc::COFFPlatform::LoadDynamicLibrary
unique_function< Error(JITDylib &JD, StringRef DLLFileName)> LoadDynamicLibrary
A function that will be called with the name of dll file that must be loaded.
Definition: COFFPlatform.h:38
llvm::orc::COFFPlatform::standardRuntimeUtilityAliases
static ArrayRef< std::pair< const char *, const char * > > standardRuntimeUtilityAliases()
Returns the array of standard runtime utility aliases for COFF.
Definition: COFFPlatform.cpp:328
llvm::orc::COFFPlatform
Mediates between COFF initialization and ExecutionSession state.
Definition: COFFPlatform.h:33
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::DenseMap< SymbolStringPtr, SymbolAliasMapEntry >
llvm::orc::JITDylibSP
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition: Core.h:48
llvm::orc::COFFPlatform::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: COFFPlatform.cpp:290
llvm::orc::COFFPlatform::Create
static Expected< std::unique_ptr< COFFPlatform > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD, const char *OrcRuntimePath, LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime=false, const char *VCRuntimePath=nullptr, Optional< SymbolAliasMap > RuntimeAliases=None)
Try to create a COFFPlatform instance, adding the ORC runtime to the given JITDylib.
Definition: COFFPlatform.cpp:163
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::orc::COFFPlatform::notifyRemoving
Error notifyRemoving(ResourceTracker &RT) override
This method will be called under the ExecutionSession lock when a ResourceTracker is removed.
Definition: COFFPlatform.cpp:307
COFFVCRuntimeSupport.h
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::COFFPlatform::getSEHFrameSectionName
static StringRef getSEHFrameSectionName()
Definition: COFFPlatform.h:74
llvm::orc::COFFPlatform::getExecutionSession
ExecutionSession & getExecutionSession() const
Definition: COFFPlatform.h:49
llvm::orc::ObjectLinkingLayer
An ObjectLayer implementation built on JITLink.
Definition: ObjectLinkingLayer.h:50
llvm::HexagonISD::CP
@ CP
Definition: HexagonISelLowering.h:53
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
llvm::orc::COFFPlatform::getObjectLinkingLayer
ObjectLinkingLayer & getObjectLinkingLayer() const
Definition: COFFPlatform.h:50
ExecutorAddress.h
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1365
Core.h
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
ExecutorProcessControl.h
ObjectLinkingLayer.h
llvm::orc::COFFPlatform::requiredCXXAliases
static ArrayRef< std::pair< const char *, const char * > > requiredCXXAliases()
Returns the array of required CXX aliases.
Definition: COFFPlatform.cpp:318
llvm::orc::COFFPlatform::standardPlatformAliases
static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES)
Returns an AliasMap containing the default aliases for the COFFPlatform.
Definition: COFFPlatform.cpp:311