blob: c1e7d27f446ebbb26f0c2d42a5529e97733c850c [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===-- 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
34namespace llvm {
35
36namespace jitlink {
37class EHFrameRegistrar;
38} // namespace jitlink
39
40namespace object {
41class ObjectFile;
42} // namespace object
43
44namespace orc {
45
46class 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.
53class ObjectLinkingLayer : public ObjectLayer {
54 friend class ObjectLinkingLayerJITLinkContext;
55
56public:
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
126private:
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
146class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
147public:
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
155private:
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