Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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"
17
#include "llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h"
18
#include "llvm/ExecutionEngine/Orc/Core.h"
19
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
20
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
21
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
22
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.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 =
38
      unique_function<Error(JITDylib &JD, StringRef DLLFileName)>;
39
 
40
  /// Try to create a COFFPlatform instance, adding the ORC runtime to the
41
  /// given JITDylib.
42
  static Expected<std::unique_ptr<COFFPlatform>>
43
  Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
44
         JITDylib &PlatformJD, const char *OrcRuntimePath,
45
         LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false,
46
         const char *VCRuntimePath = nullptr,
47
         std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
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;
54
  Error notifyAdding(ResourceTracker &RT,
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.
61
  static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES);
62
 
63
  /// Returns the array of required CXX aliases.
64
  static ArrayRef<std::pair<const char *, const char *>> requiredCXXAliases();
65
 
66
  /// Returns the array of standard runtime utility aliases for COFF.
67
  static ArrayRef<std::pair<const char *, const char *>>
68
  standardRuntimeUtilityAliases();
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 =
81
      SmallVector<std::pair<std::string, ExecutorAddrRange>>;
82
  using PushInitializersSendResultFn =
83
      unique_function<void(Expected<COFFJITDylibDepInfoMap>)>;
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,
95
                          jitlink::LinkGraph &G,
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(JITDylib &JD, ResourceKey K) override {
108
      return Error::success();
109
    }
110
 
111
    void notifyTransferringResources(JITDylib &JD, 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