23 : MR(MR), Deps(Deps) {}
25 void lookup(
const LookupSet &Symbols, OnResolvedFunction OnResolved)
override {
26 auto &ES = MR.getTargetJITDylib().getExecutionSession();
30 for (
auto &S : Symbols)
31 InternedSymbols.
add(ES.intern(S));
35 auto OnResolvedWithUnwrap =
36 [OnResolved = std::move(OnResolved)](
38 if (!InternedResult) {
39 OnResolved(InternedResult.takeError());
44 for (
auto &KV : *InternedResult)
45 Result[*KV.first] = {KV.second.getAddress().getValue(),
46 KV.second.getFlags()};
51 MR.getTargetJITDylib().withLinkOrderDo(
54 LookupKind::Static, LinkOrder, InternedSymbols, SymbolState::Resolved,
55 std::move(OnResolvedWithUnwrap),
62 for (
auto &KV : MR.getSymbols()) {
63 if (Symbols.count(*KV.first))
86 :
BaseT(ES), GetMemoryManager(
std::
move(GetMemoryManager)) {
91 assert(MemMgrs.
empty() &&
"Layer destroyed with resources still attached");
95 std::unique_ptr<MaterializationResponsibility> R,
96 std::unique_ptr<MemoryBuffer> O) {
97 assert(O &&
"Object must not be null");
99 auto &ES = getExecutionSession();
104 getExecutionSession().reportError(Obj.takeError());
105 R->failMaterialization();
111 auto InternalSymbols = std::make_shared<std::set<StringRef>>();
114 for (
auto &
Sym : (*Obj)->symbols()) {
117 if (
auto SymType =
Sym.getType()) {
121 ES.reportError(SymType.takeError());
122 R->failMaterialization();
127 if (!SymFlagsOrErr) {
129 ES.reportError(SymFlagsOrErr.
takeError());
130 R->failMaterialization();
136 if (AutoClaimObjectSymbols &&
138 auto SymName =
Sym.getName();
140 ES.reportError(SymName.takeError());
141 R->failMaterialization();
147 if (R->getSymbols().count(SymbolName))
152 ES.reportError(SymFlags.takeError());
153 R->failMaterialization();
157 ExtraSymbolsToClaim[SymbolName] = *SymFlags;
163 if (
auto SymName =
Sym.getName())
164 InternalSymbols->
insert(*SymName);
166 ES.reportError(SymName.takeError());
167 R->failMaterialization();
173 if (!ExtraSymbolsToClaim.
empty()) {
174 if (
auto Err = R->defineMaterializing(ExtraSymbolsToClaim)) {
175 ES.reportError(std::move(Err));
176 R->failMaterialization();
181 auto MemMgr = GetMemoryManager();
182 auto &MemMgrRef = *MemMgr;
186 std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
187 auto Deps = std::make_unique<SymbolDependenceMap>();
190 std::make_unique<JITDylibSearchOrderResolver>(*SharedR, *Deps);
195 MemMgrRef, *ResolverPtr, ProcessAllSections,
196 [
this, SharedR, &MemMgrRef, InternalSymbols](
199 std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
200 return onObjLoad(*SharedR, Obj, MemMgrRef, LoadedObjInfo,
201 ResolvedSymbols, *InternalSymbols);
203 [
this, SharedR, MemMgr = std::move(MemMgr), Deps = std::move(Deps),
206 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
208 onObjEmit(*SharedR, std::move(Obj), std::move(MemMgr),
209 std::move(LoadedObjInfo), std::move(Deps), std::move(Err));
214 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
216 "Listener has already been registered");
217 EventListeners.push_back(&L);
221 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
223 assert(
I != EventListeners.end() &&
"Listener not registered");
224 EventListeners.erase(
I);
227Error RTDyldObjectLinkingLayer::onObjLoad(
231 std::map<StringRef, JITEvaluatedSymbol>
Resolved,
232 std::set<StringRef> &InternalSymbols) {
238 if (
auto *COFFObj = dyn_cast<object::COFFObjectFile>(&Obj)) {
239 auto &ES = getExecutionSession();
244 for (
auto &
Sym : COFFObj->symbols()) {
251 return Name.takeError();
257 R.getSymbols().count(ES.intern(*
Name)))
259 auto Sec =
Sym.getSection();
261 return Sec.takeError();
262 if (*Sec == COFFObj->section_end())
264 auto &COFFSec = *COFFObj->getCOFFSection(**Sec);
270 for (
auto &
Sym : COFFObj->symbols()) {
276 return Name.takeError();
281 if (
I !=
Resolved.end() || !R.getSymbols().count(ES.intern(*
Name)))
285 auto COFFSym = COFFObj->getCOFFSymbol(
Sym);
286 if (!COFFSym.isWeakExternal())
295 COFFObj->getSymbol(WeakExternal->TagIndex);
301 auto J =
Resolved.find(*TargetName);
303 return make_error<StringError>(
"Could alias target " + *TargetName +
314 if (InternalSymbols.count(KV.first))
317 auto InternedName = getExecutionSession().intern(KV.first);
318 auto Flags = KV.second.getFlags();
319 auto I =
R.getSymbols().find(InternedName);
320 if (
I !=
R.getSymbols().end()) {
323 if (OverrideObjectFlags)
329 if (
I->second.isWeak())
332 }
else if (AutoClaimObjectSymbols)
333 ExtraSymbolsToClaim[InternedName] =
Flags;
338 if (!ExtraSymbolsToClaim.
empty()) {
339 if (
auto Err =
R.defineMaterializing(ExtraSymbolsToClaim))
344 for (
auto &KV : ExtraSymbolsToClaim)
345 if (KV.second.isWeak() && !
R.getSymbols().count(KV.first))
346 Symbols.erase(KV.first);
349 if (
auto Err =
R.notifyResolved(Symbols)) {
350 R.failMaterialization();
355 NotifyLoaded(R, Obj, LoadedObjInfo);
360void RTDyldObjectLinkingLayer::onObjEmit(
363 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
364 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
365 std::unique_ptr<SymbolDependenceMap> Deps,
Error Err) {
367 getExecutionSession().reportError(std::move(Err));
368 R.failMaterialization();
373 for (
auto &[
Sym, Flags] :
R.getSymbols())
377 if (
auto Err =
R.notifyEmitted(SDG)) {
378 getExecutionSession().reportError(std::move(Err));
379 R.failMaterialization();
383 std::unique_ptr<object::ObjectFile> Obj;
384 std::unique_ptr<MemoryBuffer> ObjBuffer;
385 std::tie(Obj, ObjBuffer) =
O.takeBinary();
389 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
390 for (
auto *L : EventListeners)
396 NotifyEmitted(R, std::move(ObjBuffer));
398 if (
auto Err =
R.withResourceKeyDo(
399 [&](
ResourceKey K) { MemMgrs[K].push_back(std::move(MemMgr)); })) {
400 getExecutionSession().reportError(std::move(Err));
401 R.failMaterialization();
405Error RTDyldObjectLinkingLayer::handleRemoveResources(
JITDylib &JD,
408 std::vector<MemoryManagerUP> MemMgrsToRemove;
410 getExecutionSession().runSessionLocked([&] {
411 auto I = MemMgrs.
find(K);
412 if (
I != MemMgrs.
end()) {
413 std::swap(MemMgrsToRemove, I->second);
419 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
420 for (
auto &MemMgr : MemMgrsToRemove) {
421 for (
auto *L : EventListeners)
423 MemMgr->deregisterEHFrames();
430void RTDyldObjectLinkingLayer::handleTransferResources(
JITDylib &JD,
436 auto &DstMemMgrs = MemMgrs[DstKey];
437 auto &SrcMemMgrs = MemMgrs[SrcKey];
438 DstMemMgrs.
reserve(DstMemMgrs.size() + SrcMemMgrs.size());
439 for (
auto &MemMgr : SrcMemMgrs)
440 DstMemMgrs.push_back(std::move(MemMgr));
442 MemMgrs.
erase(SrcKey);
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
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