21 JITDylibSearchOrderResolver(MaterializationResponsibility &MR,
23 : MR(MR), Deps(Deps) {}
25 void lookup(
const LookupSet &Symbols,
26 OnResolvedFunction OnResolved)
override {
27 auto &ES = MR.getTargetJITDylib().getExecutionSession();
28 SymbolLookupSet InternedSymbols;
31 for (
auto &S : Symbols)
32 InternedSymbols.
add(ES.intern(S));
36 auto OnResolvedWithUnwrap =
37 [OnResolved = std::move(OnResolved)](
38 Expected<SymbolMap> InternedResult)
mutable {
39 if (!InternedResult) {
40 OnResolved(InternedResult.takeError());
45 for (
auto &KV : *InternedResult)
46 Result[*KV.first] = {KV.second.getAddress().getValue(),
47 KV.second.getFlags()};
52 MR.getTargetJITDylib().withLinkOrderDo(
55 LookupKind::Static, LinkOrder, InternedSymbols, SymbolState::Resolved,
56 std::move(OnResolvedWithUnwrap),
60 Expected<LookupSet> getResponsibilitySet(
const LookupSet &Symbols)
override {
63 for (
auto &KV : MR.getSymbols()) {
72 MaterializationResponsibility &MR;
83using BaseT = RTTIExtends<RTDyldObjectLinkingLayer, ObjectLayer>;
87 :
BaseT(ES), GetMemoryManager(
std::
move(GetMemoryManager)) {
93 "Layer destroyed with resources still attached"
94 "(ExecutionSession::endSession() must be called prior to "
99 std::unique_ptr<MaterializationResponsibility> R,
100 std::unique_ptr<MemoryBuffer> O) {
101 assert(O &&
"Object must not be null");
103 auto &ES = getExecutionSession();
108 getExecutionSession().reportError(Obj.takeError());
109 R->failMaterialization();
115 auto InternalSymbols = std::make_shared<std::set<StringRef>>();
118 for (
auto &Sym : (*Obj)->symbols()) {
121 if (
auto SymType = Sym.getType()) {
125 ES.reportError(SymType.takeError());
126 R->failMaterialization();
131 if (!SymFlagsOrErr) {
133 ES.reportError(SymFlagsOrErr.
takeError());
134 R->failMaterialization();
140 if (AutoClaimObjectSymbols &&
142 auto SymName = Sym.getName();
144 ES.reportError(SymName.takeError());
145 R->failMaterialization();
151 if (R->getSymbols().count(SymbolName))
156 ES.reportError(SymFlags.takeError());
157 R->failMaterialization();
161 ExtraSymbolsToClaim[SymbolName] = *SymFlags;
167 if (
auto SymName = Sym.getName())
168 InternalSymbols->insert(*SymName);
170 ES.reportError(SymName.takeError());
171 R->failMaterialization();
177 if (!ExtraSymbolsToClaim.
empty()) {
178 if (
auto Err = R->defineMaterializing(ExtraSymbolsToClaim)) {
179 ES.reportError(std::move(Err));
180 R->failMaterialization();
185 auto MemMgr = GetMemoryManager(*O);
186 auto &MemMgrRef = *MemMgr;
190 std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
191 auto Deps = std::make_unique<SymbolDependenceMap>();
194 std::make_unique<JITDylibSearchOrderResolver>(*SharedR, *Deps);
199 MemMgrRef, *ResolverPtr, ProcessAllSections,
200 [
this, SharedR, &MemMgrRef, InternalSymbols](
203 std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
204 return onObjLoad(*SharedR, Obj, MemMgrRef, LoadedObjInfo,
205 ResolvedSymbols, *InternalSymbols);
207 [
this, SharedR, MemMgr = std::move(MemMgr), Deps = std::move(Deps),
210 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
212 onObjEmit(*SharedR, std::move(Obj), std::move(MemMgr),
213 std::move(LoadedObjInfo), std::move(Deps), std::move(Err));
218 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
220 "Listener has already been registered");
221 EventListeners.push_back(&L);
225 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
227 assert(
I != EventListeners.end() &&
"Listener not registered");
228 EventListeners.erase(
I);
231Error RTDyldObjectLinkingLayer::onObjLoad(
235 std::map<StringRef, JITEvaluatedSymbol>
Resolved,
236 std::set<StringRef> &InternalSymbols) {
243 auto &ES = getExecutionSession();
248 for (
auto &Sym : COFFObj->symbols()) {
253 auto Name = Sym.getName();
255 return Name.takeError();
260 if (
I ==
Resolved.end() || InternalSymbols.count(*Name) ||
261 R.getSymbols().count(ES.intern(*Name)))
263 auto Sec = Sym.getSection();
265 return Sec.takeError();
266 if (*Sec == COFFObj->section_end())
268 auto &COFFSec = *COFFObj->getCOFFSection(**Sec);
274 for (
auto &Sym : COFFObj->symbols()) {
278 auto Name = Sym.getName();
280 return Name.takeError();
285 if (
I !=
Resolved.end() || !R.getSymbols().count(ES.intern(*Name)))
289 auto COFFSym = COFFObj->getCOFFSymbol(Sym);
290 if (!COFFSym.isWeakExternal())
299 COFFObj->getSymbol(WeakExternal->TagIndex);
305 auto J =
Resolved.find(*TargetName);
318 if (InternalSymbols.count(KV.first))
321 auto InternedName = getExecutionSession().intern(KV.first);
322 auto Flags = KV.second.getFlags();
323 auto I =
R.getSymbols().find(InternedName);
324 if (
I !=
R.getSymbols().end()) {
327 if (OverrideObjectFlags)
333 if (
I->second.isWeak())
336 }
else if (AutoClaimObjectSymbols)
337 ExtraSymbolsToClaim[InternedName] =
Flags;
339 Symbols[InternedName] = {ExecutorAddr(KV.second.getAddress()),
Flags};
342 if (!ExtraSymbolsToClaim.
empty()) {
343 if (
auto Err =
R.defineMaterializing(ExtraSymbolsToClaim))
348 for (
auto &KV : ExtraSymbolsToClaim)
349 if (KV.second.isWeak() && !
R.getSymbols().count(KV.first))
353 if (
auto Err =
R.notifyResolved(Symbols)) {
354 R.failMaterialization();
359 NotifyLoaded(R, Obj, LoadedObjInfo);
364void RTDyldObjectLinkingLayer::onObjEmit(
366 object::OwningBinary<object::ObjectFile> O,
367 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
368 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
369 std::unique_ptr<SymbolDependenceMap> Deps,
Error Err) {
371 getExecutionSession().reportError(std::move(Err));
372 R.failMaterialization();
376 SymbolDependenceGroup SDG;
377 for (
auto &[Sym, Flags] :
R.getSymbols())
381 if (
auto Err =
R.notifyEmitted(SDG)) {
382 getExecutionSession().reportError(std::move(Err));
383 R.failMaterialization();
387 std::unique_ptr<object::ObjectFile> Obj;
388 std::unique_ptr<MemoryBuffer> ObjBuffer;
389 std::tie(Obj, ObjBuffer) =
O.takeBinary();
393 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
394 for (
auto *L : EventListeners)
400 NotifyEmitted(R, std::move(ObjBuffer));
402 if (
auto Err =
R.withResourceKeyDo(
403 [&](
ResourceKey K) { MemMgrs[K].push_back(std::move(MemMgr)); })) {
404 getExecutionSession().reportError(std::move(Err));
405 R.failMaterialization();
409Error RTDyldObjectLinkingLayer::handleRemoveResources(
JITDylib &JD,
412 std::vector<MemoryManagerUP> MemMgrsToRemove;
414 getExecutionSession().runSessionLocked([&] {
415 auto I = MemMgrs.find(K);
416 if (
I != MemMgrs.end()) {
423 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
424 for (
auto &MemMgr : MemMgrsToRemove) {
425 for (
auto *L : EventListeners)
427 MemMgr->deregisterEHFrames();
434void RTDyldObjectLinkingLayer::handleTransferResources(
JITDylib &JD,
437 if (MemMgrs.contains(SrcKey)) {
440 auto &DstMemMgrs = MemMgrs[DstKey];
441 auto &SrcMemMgrs = MemMgrs[SrcKey];
442 DstMemMgrs.reserve(DstMemMgrs.size() + SrcMemMgrs.size());
443 for (
auto &MemMgr : SrcMemMgrs)
444 DstMemMgrs.push_back(std::move(MemMgr));
446 MemMgrs.erase(SrcKey);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
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 LLVM_ABI Expected< JITSymbolFlags > fromObjectSymbol(const object::SymbolRef &Symbol)
Construct a JITSymbolFlags value based on the flags of the given libobject symbol.
Symbol resolution interface.
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.
LLVM_ABI void registerResourceManager(ResourceManager &RM)
Register the given ResourceManager with this ExecutionSession.
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.
unique_function< std::unique_ptr< RuntimeDyld::MemoryManager >( const MemoryBuffer &)> GetMemoryManagerFunction
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.
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
DenseMap< JITDylib *, SymbolNameSet > SymbolDependenceMap
A map from JITDylibs to sets of symbols.
@ Resolved
Queried, materialization begun.
RTTIExtends< ObjectTransformLayer, ObjectLayer > BaseT
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI 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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SymbolDependenceMap Dependencies