21 void lookup(
const LookupSet &Symbols, OnResolvedFunction OnResolved)
override {
22 auto &ES = MR.getTargetJITDylib().getExecutionSession();
26 for (
auto &S : Symbols)
27 InternedSymbols.
add(ES.intern(S));
31 auto OnResolvedWithUnwrap =
32 [OnResolved = std::move(OnResolved)](
34 if (!InternedResult) {
35 OnResolved(InternedResult.takeError());
40 for (
auto &KV : *InternedResult)
41 Result[*KV.first] = {KV.second.getAddress().getValue(),
42 KV.second.getFlags()};
48 MR.addDependenciesForAll(Deps);
52 MR.getTargetJITDylib().withLinkOrderDo(
54 ES.lookup(LookupKind::Static, LinkOrder, InternedSymbols,
55 SymbolState::Resolved, std::move(OnResolvedWithUnwrap),
56 RegisterDependencies);
62 for (
auto &KV : MR.getSymbols()) {
63 if (Symbols.count(*KV.first))
85 :
BaseT(ES), GetMemoryManager(
std::
move(GetMemoryManager)) {
90 assert(MemMgrs.
empty() &&
"Layer destroyed with resources still attached");
94 std::unique_ptr<MaterializationResponsibility> R,
95 std::unique_ptr<MemoryBuffer> O) {
96 assert(O &&
"Object must not be null");
98 auto &ES = getExecutionSession();
103 getExecutionSession().reportError(Obj.takeError());
104 R->failMaterialization();
110 auto InternalSymbols = std::make_shared<std::set<StringRef>>();
113 for (
auto &
Sym : (*Obj)->symbols()) {
116 if (
auto SymType =
Sym.getType()) {
120 ES.reportError(SymType.takeError());
121 R->failMaterialization();
126 if (!SymFlagsOrErr) {
128 ES.reportError(SymFlagsOrErr.
takeError());
129 R->failMaterialization();
135 if (AutoClaimObjectSymbols &&
137 auto SymName =
Sym.getName();
139 ES.reportError(SymName.takeError());
140 R->failMaterialization();
146 if (R->getSymbols().count(SymbolName))
151 ES.reportError(SymFlags.takeError());
152 R->failMaterialization();
156 ExtraSymbolsToClaim[SymbolName] = *SymFlags;
162 if (
auto SymName =
Sym.getName())
163 InternalSymbols->
insert(*SymName);
165 ES.reportError(SymName.takeError());
166 R->failMaterialization();
172 if (!ExtraSymbolsToClaim.
empty()) {
173 if (
auto Err = R->defineMaterializing(ExtraSymbolsToClaim)) {
174 ES.reportError(std::move(Err));
175 R->failMaterialization();
180 auto MemMgr = GetMemoryManager();
181 auto &MemMgrRef = *MemMgr;
185 std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
187 JITDylibSearchOrderResolver
Resolver(*SharedR);
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)](
201 std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
203 onObjEmit(*SharedR, std::move(Obj), std::move(MemMgr),
204 std::move(LoadedObjInfo), 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,
Error Err) {
361 getExecutionSession().reportError(std::move(Err));
362 R.failMaterialization();
366 if (
auto Err =
R.notifyEmitted()) {
367 getExecutionSession().reportError(std::move(Err));
368 R.failMaterialization();
372 std::unique_ptr<object::ObjectFile> Obj;
373 std::unique_ptr<MemoryBuffer> ObjBuffer;
374 std::tie(Obj, ObjBuffer) =
O.takeBinary();
378 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
379 for (
auto *L : EventListeners)
385 NotifyEmitted(R, std::move(ObjBuffer));
387 if (
auto Err =
R.withResourceKeyDo(
388 [&](
ResourceKey K) { MemMgrs[K].push_back(std::move(MemMgr)); })) {
389 getExecutionSession().reportError(std::move(Err));
390 R.failMaterialization();
394Error RTDyldObjectLinkingLayer::handleRemoveResources(
JITDylib &JD,
397 std::vector<MemoryManagerUP> MemMgrsToRemove;
399 getExecutionSession().runSessionLocked([&] {
400 auto I = MemMgrs.
find(K);
401 if (
I != MemMgrs.
end()) {
402 std::swap(MemMgrsToRemove, I->second);
408 std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
409 for (
auto &MemMgr : MemMgrsToRemove) {
410 for (
auto *L : EventListeners)
412 MemMgr->deregisterEHFrames();
419void RTDyldObjectLinkingLayer::handleTransferResources(
JITDylib &JD,
422 auto I = MemMgrs.
find(SrcKey);
423 if (
I != MemMgrs.
end()) {
424 auto &SrcMemMgrs =
I->second;
425 auto &DstMemMgrs = MemMgrs[DstKey];
426 DstMemMgrs.
reserve(DstMemMgrs.size() + SrcMemMgrs.size());
427 for (
auto &MemMgr : SrcMemMgrs)
428 DstMemMgrs.push_back(std::move(MemMgr));
432 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.
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< ExecutorAddr > 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.