21 : MR(MR), Deps(Deps) {}
23 void lookup(
const LookupSet &Symbols, OnResolvedFunction OnResolved)
override {
24 auto &ES = MR.getTargetJITDylib().getExecutionSession();
28 for (
auto &S : Symbols)
29 InternedSymbols.
add(ES.intern(S));
33 auto OnResolvedWithUnwrap =
34 [OnResolved = std::move(OnResolved)](
36 if (!InternedResult) {
37 OnResolved(InternedResult.takeError());
42 for (
auto &KV : *InternedResult)
43 Result[*KV.first] = {KV.second.getAddress().getValue(),
44 KV.second.getFlags()};
49 MR.getTargetJITDylib().withLinkOrderDo(
52 LookupKind::Static, LinkOrder, InternedSymbols, SymbolState::Resolved,
53 std::move(OnResolvedWithUnwrap),
60 for (
auto &KV : MR.getSymbols()) {
61 if (Symbols.count(*KV.first))
84 :
BaseT(ES), GetMemoryManager(
std::
move(GetMemoryManager)) {
89 assert(MemMgrs.
empty() &&
"Layer destroyed with resources still attached");
93 std::unique_ptr<MaterializationResponsibility> R,
94 std::unique_ptr<MemoryBuffer> O) {
95 assert(O &&
"Object must not be null");
97 auto &ES = getExecutionSession();
102 getExecutionSession().reportError(Obj.takeError());
103 R->failMaterialization();
109 auto InternalSymbols = std::make_shared<std::set<StringRef>>();
112 for (
auto &
Sym : (*Obj)->symbols()) {
115 if (
auto SymType =
Sym.getType()) {
119 ES.reportError(SymType.takeError());
120 R->failMaterialization();
125 if (!SymFlagsOrErr) {
127 ES.reportError(SymFlagsOrErr.
takeError());
128 R->failMaterialization();
134 if (AutoClaimObjectSymbols &&
136 auto SymName =
Sym.getName();
138 ES.reportError(SymName.takeError());
139 R->failMaterialization();
145 if (R->getSymbols().count(SymbolName))
150 ES.reportError(SymFlags.takeError());
151 R->failMaterialization();
155 ExtraSymbolsToClaim[SymbolName] = *SymFlags;
161 if (
auto SymName =
Sym.getName())
162 InternalSymbols->
insert(*SymName);
164 ES.reportError(SymName.takeError());
165 R->failMaterialization();
171 if (!ExtraSymbolsToClaim.
empty()) {
172 if (
auto Err = R->defineMaterializing(ExtraSymbolsToClaim)) {
173 ES.reportError(std::move(Err));
174 R->failMaterialization();
179 auto MemMgr = GetMemoryManager();
180 auto &MemMgrRef = *MemMgr;
184 std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
185 auto Deps = std::make_unique<SymbolDependenceMap>();
187 JITDylibSearchOrderResolver
Resolver(*SharedR, *Deps);
191 MemMgrRef,
Resolver, ProcessAllSections,
192 [
this, SharedR, &MemMgrRef, InternalSymbols](
195 std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
196 return onObjLoad(*SharedR, Obj, MemMgrRef, LoadedObjInfo,
197 ResolvedSymbols, *InternalSymbols);
199 [
this, SharedR, MemMgr = std::move(MemMgr), Deps = std::move(Deps)](
201 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
203 onObjEmit(*SharedR, std::move(Obj), std::move(MemMgr),
204 std::move(LoadedObjInfo), std::move(Deps), std::move(Err));
209 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
211 "Listener has already been registered");
212 EventListeners.push_back(&L);
216 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
218 assert(
I != EventListeners.end() &&
"Listener not registered");
219 EventListeners.erase(
I);
222Error RTDyldObjectLinkingLayer::onObjLoad(
226 std::map<StringRef, JITEvaluatedSymbol>
Resolved,
227 std::set<StringRef> &InternalSymbols) {
233 if (
auto *COFFObj = dyn_cast<object::COFFObjectFile>(&Obj)) {
234 auto &ES = getExecutionSession();
239 for (
auto &
Sym : COFFObj->symbols()) {
246 return Name.takeError();
252 R.getSymbols().count(ES.intern(*
Name)))
254 auto Sec =
Sym.getSection();
256 return Sec.takeError();
257 if (*Sec == COFFObj->section_end())
259 auto &COFFSec = *COFFObj->getCOFFSection(**Sec);
265 for (
auto &
Sym : COFFObj->symbols()) {
271 return Name.takeError();
276 if (
I !=
Resolved.end() || !R.getSymbols().count(ES.intern(*
Name)))
280 auto COFFSym = COFFObj->getCOFFSymbol(
Sym);
281 if (!COFFSym.isWeakExternal())
290 COFFObj->getSymbol(WeakExternal->TagIndex);
296 auto J =
Resolved.find(*TargetName);
298 return make_error<StringError>(
"Could alias target " + *TargetName +
309 if (InternalSymbols.count(KV.first))
312 auto InternedName = getExecutionSession().intern(KV.first);
313 auto Flags = KV.second.getFlags();
314 auto I =
R.getSymbols().find(InternedName);
315 if (
I !=
R.getSymbols().end()) {
318 if (OverrideObjectFlags)
324 if (
I->second.isWeak())
327 }
else if (AutoClaimObjectSymbols)
328 ExtraSymbolsToClaim[InternedName] =
Flags;
333 if (!ExtraSymbolsToClaim.
empty()) {
334 if (
auto Err =
R.defineMaterializing(ExtraSymbolsToClaim))
339 for (
auto &KV : ExtraSymbolsToClaim)
340 if (KV.second.isWeak() && !
R.getSymbols().count(KV.first))
341 Symbols.erase(KV.first);
344 if (
auto Err =
R.notifyResolved(Symbols)) {
345 R.failMaterialization();
350 NotifyLoaded(R, Obj, LoadedObjInfo);
355void RTDyldObjectLinkingLayer::onObjEmit(
358 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
359 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
360 std::unique_ptr<SymbolDependenceMap> Deps,
Error Err) {
362 getExecutionSession().reportError(std::move(Err));
363 R.failMaterialization();
368 for (
auto &[
Sym, Flags] :
R.getSymbols())
372 if (
auto Err =
R.notifyEmitted(SDG)) {
373 getExecutionSession().reportError(std::move(Err));
374 R.failMaterialization();
378 std::unique_ptr<object::ObjectFile> Obj;
379 std::unique_ptr<MemoryBuffer> ObjBuffer;
380 std::tie(Obj, ObjBuffer) =
O.takeBinary();
384 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
385 for (
auto *L : EventListeners)
391 NotifyEmitted(R, std::move(ObjBuffer));
393 if (
auto Err =
R.withResourceKeyDo(
394 [&](
ResourceKey K) { MemMgrs[K].push_back(std::move(MemMgr)); })) {
395 getExecutionSession().reportError(std::move(Err));
396 R.failMaterialization();
400Error RTDyldObjectLinkingLayer::handleRemoveResources(
JITDylib &JD,
403 std::vector<MemoryManagerUP> MemMgrsToRemove;
405 getExecutionSession().runSessionLocked([&] {
406 auto I = MemMgrs.
find(K);
407 if (
I != MemMgrs.
end()) {
408 std::swap(MemMgrsToRemove, I->second);
414 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
415 for (
auto &MemMgr : MemMgrsToRemove) {
416 for (
auto *L : EventListeners)
418 MemMgr->deregisterEHFrames();
425void RTDyldObjectLinkingLayer::handleTransferResources(
JITDylib &JD,
428 auto I = MemMgrs.
find(SrcKey);
429 if (
I != MemMgrs.
end()) {
430 auto &SrcMemMgrs =
I->second;
431 auto &DstMemMgrs = MemMgrs[DstKey];
432 DstMemMgrs.
reserve(DstMemMgrs.size() + SrcMemMgrs.size());
433 for (
auto &MemMgr : SrcMemMgrs)
434 DstMemMgrs.push_back(std::move(MemMgr));
438 MemMgrs.
erase(SrcKey);
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
JITEventListener - Abstract interface for use by the JIT to notify clients about significant events d...
static Expected< JITSymbolFlags > fromObjectSymbol(const object::SymbolRef &Symbol)
Construct a JITSymbolFlags value based on the flags of the given libobject symbol.
Symbol resolution interface.
virtual void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved)=0
Returns the fully resolved address and flags for each of the given symbols.
virtual Expected< LookupSet > getResponsibilitySet(const LookupSet &Symbols)=0
Returns the subset of the given symbols that should be materialized by the caller.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Information about the loaded object.
std::pair< iterator, bool > insert(const ValueT &V)
This class is the base class for all object file types.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
An ExecutionSession represents a running JIT program.
void registerResourceManager(ResourceManager &RM)
Register the given ResourceManager with this ExecutionSession.
Represents an address in the executor process.
Represents a JIT'd dynamic library.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
RTDyldObjectLinkingLayer(ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager)
Construct an ObjectLinkingLayer with the given NotifyLoaded, and NotifyEmitted functors.
void emit(std::unique_ptr< MaterializationResponsibility > R, std::unique_ptr< MemoryBuffer > O) override
Emit the object.
~RTDyldObjectLinkingLayer()
void unregisterJITEventListener(JITEventListener &L)
Unregister a JITEventListener.
void registerJITEventListener(JITEventListener &L)
Register a JITEventListener.
A set of symbols to look up, each associated with a SymbolLookupFlags value.
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
Pointer to a pooled string representing a symbol name.
@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS
std::vector< ExecutorSymbolDef > LookupResult
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
@ Resolved
Queried, materialization begun.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
void jitLinkForORC(object::OwningBinary< object::ObjectFile > O, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, bool ProcessAllSections, unique_function< Error(const object::ObjectFile &Obj, RuntimeDyld::LoadedObjectInfo &, std::map< StringRef, JITEvaluatedSymbol >)> OnLoaded, unique_function< void(object::OwningBinary< object::ObjectFile >, std::unique_ptr< RuntimeDyld::LoadedObjectInfo >, Error)> OnEmitted)
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
JITTargetAddress pointerToJITTargetAddress(T *Ptr)
Convert a pointer to a JITTargetAddress.
Implement std::hash so that hash_code can be used in STL containers.
A set of symbols and the their dependencies.
SymbolDependenceMap Dependencies