]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / ExecutionEngine / Orc / ObjectLinkingLayer.h
1 //===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- 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 // Contains the definition for an JITLink-based, in-process object linking
10 // layer.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
16
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
21 #include "llvm/ExecutionEngine/JITSymbol.h"
22 #include "llvm/ExecutionEngine/Orc/Core.h"
23 #include "llvm/ExecutionEngine/Orc/Layer.h"
24 #include "llvm/Support/Error.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <functional>
28 #include <list>
29 #include <memory>
30 #include <string>
31 #include <utility>
32 #include <vector>
33
34 namespace llvm {
35
36 namespace jitlink {
37 class EHFrameRegistrar;
38 } // namespace jitlink
39
40 namespace object {
41 class ObjectFile;
42 } // namespace object
43
44 namespace orc {
45
46 class ObjectLinkingLayerJITLinkContext;
47
48 /// An ObjectLayer implementation built on JITLink.
49 ///
50 /// Clients can use this class to add relocatable object files to an
51 /// ExecutionSession, and it typically serves as the base layer (underneath
52 /// a compiling layer like IRCompileLayer) for the rest of the JIT.
53 class ObjectLinkingLayer : public ObjectLayer {
54   friend class ObjectLinkingLayerJITLinkContext;
55
56 public:
57   /// Plugin instances can be added to the ObjectLinkingLayer to receive
58   /// callbacks when code is loaded or emitted, and when JITLink is being
59   /// configured.
60   class Plugin {
61   public:
62     virtual ~Plugin();
63     virtual void modifyPassConfig(MaterializationResponsibility &MR,
64                                   const Triple &TT,
65                                   jitlink::PassConfiguration &Config) {}
66     virtual void notifyLoaded(MaterializationResponsibility &MR) {}
67     virtual Error notifyEmitted(MaterializationResponsibility &MR) {
68       return Error::success();
69     }
70     virtual Error notifyRemovingModule(VModuleKey K) {
71       return Error::success();
72     }
73     virtual Error notifyRemovingAllModules() { return Error::success(); }
74   };
75
76   /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
77   /// and NotifyEmitted functors.
78   ObjectLinkingLayer(ExecutionSession &ES,
79                      jitlink::JITLinkMemoryManager &MemMgr);
80
81   /// Destruct an ObjectLinkingLayer.
82   ~ObjectLinkingLayer();
83
84   /// Add a pass-config modifier.
85   ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
86     std::lock_guard<std::mutex> Lock(LayerMutex);
87     Plugins.push_back(std::move(P));
88     return *this;
89   }
90
91   /// Emit the object.
92   void emit(MaterializationResponsibility R,
93             std::unique_ptr<MemoryBuffer> O) override;
94
95   /// Instructs this ObjectLinkingLayer instance to override the symbol flags
96   /// found in the AtomGraph with the flags supplied by the
97   /// MaterializationResponsibility instance. This is a workaround to support
98   /// symbol visibility in COFF, which does not use the libObject's
99   /// SF_Exported flag. Use only when generating / adding COFF object files.
100   ///
101   /// FIXME: We should be able to remove this if/when COFF properly tracks
102   /// exported symbols.
103   ObjectLinkingLayer &
104   setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
105     this->OverrideObjectFlags = OverrideObjectFlags;
106     return *this;
107   }
108
109   /// If set, this ObjectLinkingLayer instance will claim responsibility
110   /// for any symbols provided by a given object file that were not already in
111   /// the MaterializationResponsibility instance. Setting this flag allows
112   /// higher-level program representations (e.g. LLVM IR) to be added based on
113   /// only a subset of the symbols they provide, without having to write
114   /// intervening layers to scan and add the additional symbols. This trades
115   /// diagnostic quality for convenience however: If all symbols are enumerated
116   /// up-front then clashes can be detected and reported early (and usually
117   /// deterministically). If this option is set, clashes for the additional
118   /// symbols may not be detected until late, and detection may depend on
119   /// the flow of control through JIT'd code. Use with care.
120   ObjectLinkingLayer &
121   setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
122     this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
123     return *this;
124   }
125
126 private:
127   using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;
128
129   void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
130                         jitlink::PassConfiguration &PassConfig);
131   void notifyLoaded(MaterializationResponsibility &MR);
132   Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
133
134   Error removeModule(VModuleKey K);
135   Error removeAllModules();
136
137   mutable std::mutex LayerMutex;
138   jitlink::JITLinkMemoryManager &MemMgr;
139   bool OverrideObjectFlags = false;
140   bool AutoClaimObjectSymbols = false;
141   DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
142   std::vector<AllocPtr> UntrackedAllocs;
143   std::vector<std::unique_ptr<Plugin>> Plugins;
144 };
145
146 class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
147 public:
148   EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
149   Error notifyEmitted(MaterializationResponsibility &MR) override;
150   void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
151                         jitlink::PassConfiguration &PassConfig) override;
152   Error notifyRemovingModule(VModuleKey K) override;
153   Error notifyRemovingAllModules() override;
154
155 private:
156   jitlink::EHFrameRegistrar &Registrar;
157   DenseMap<MaterializationResponsibility *, JITTargetAddress> InProcessLinks;
158   DenseMap<VModuleKey, JITTargetAddress> TrackedEHFrameAddrs;
159   std::vector<JITTargetAddress> UntrackedEHFrameAddrs;
160 };
161
162 } // end namespace orc
163 } // end namespace llvm
164
165 #endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H