14#define DEBUG_TYPE "orc"
22 : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(TP) {}
27 assert(TP &&
"TrampolinePool not set");
29 std::lock_guard<std::mutex> Lock(LCTMMutex);
33 return Trampoline.takeError();
35 Reexports[*Trampoline] =
ReexportsEntry{&SourceJD, std::move(SymbolName)};
36 Notifiers[*Trampoline] = std::move(NotifyResolved);
42 return ErrorHandlerAddr;
47 std::lock_guard<std::mutex> Lock(LCTMMutex);
48 auto I = Reexports.find(TrampolineAddr);
49 if (
I == Reexports.end())
51 "Missing reexport for trampoline address %p" +
52 formatv(
"{0:x}", TrampolineAddr));
60 std::lock_guard<std::mutex> Lock(LCTMMutex);
61 auto I = Notifiers.find(TrampolineAddr);
62 if (
I != Notifiers.end()) {
63 NotifyResolved = std::move(
I->second);
68 return NotifyResolved ? NotifyResolved(ResolvedAddr) :
Error::success();
82 auto Callback = [
this, TrampolineAddr, SymbolName = Entry->SymbolName,
83 NotifyLandingResolved = std::move(NotifyLandingResolved)](
87 assert(
Result->count(SymbolName) &&
"Unexpected result value");
88 ExecutorAddr LandingAddr = (*Result)[SymbolName].getAddress();
93 NotifyLandingResolved(LandingAddr);
109 switch (
T.getArch()) {
111 return make_error<StringError>(
112 std::string(
"No callback manager available for ") +
T.str(),
117 return LocalLazyCallThroughManager::Create<OrcAArch64>(ES,
121 return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr);
124 return LocalLazyCallThroughManager::Create<OrcLoongArch64>(
125 ES, ErrorHandlerAddr);
128 return LocalLazyCallThroughManager::Create<OrcMips32Be>(ES,
132 return LocalLazyCallThroughManager::Create<OrcMips32Le>(ES,
137 return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
140 return LocalLazyCallThroughManager::Create<OrcRiscv64>(ES,
145 return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>(
146 ES, ErrorHandlerAddr);
148 return LocalLazyCallThroughManager::Create<OrcX86_64_SysV>(
149 ES, ErrorHandlerAddr);
157 LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),
158 CallableAliases(
std::
move(CallableAliases)), AliaseeTable(SrcJDLoc) {}
161 return "<Lazy Reexports>";
164void LazyReexportsMaterializationUnit::materialize(
165 std::unique_ptr<MaterializationResponsibility> R) {
166 auto RequestedSymbols = R->getRequestedSymbols();
169 for (
auto &RequestedSymbol : RequestedSymbols) {
170 auto I = CallableAliases.
find(RequestedSymbol);
171 assert(
I != CallableAliases.
end() &&
"Symbol not found in alias map?");
172 RequestedAliases[
I->first] = std::move(
I->second);
176 if (!CallableAliases.
empty())
177 if (
auto Err = R->replace(
lazyReexports(LCTManager, ISManager, SourceJD,
178 std::move(CallableAliases),
180 R->getExecutionSession().reportError(std::move(Err));
181 R->failMaterialization();
186 for (
auto &Alias : RequestedAliases) {
189 SourceJD, Alias.second.Aliasee,
190 [&ISManager = this->ISManager,
191 StubSym = Alias.first](ExecutorAddr ResolvedAddr) -> Error {
192 return ISManager.updatePointer(*StubSym, ResolvedAddr);
195 if (!CallThroughTrampoline) {
197 CallThroughTrampoline.takeError());
198 R->failMaterialization();
202 StubInits[*Alias.first] =
203 std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags);
206 if (AliaseeTable !=
nullptr && !RequestedAliases.empty())
207 AliaseeTable->
trackImpls(RequestedAliases, &SourceJD);
211 R->failMaterialization();
216 for (
auto &Alias : RequestedAliases)
217 Stubs[Alias.first] = ISManager.
findStub(*Alias.first,
false);
224void LazyReexportsMaterializationUnit::discard(
const JITDylib &JD,
225 const SymbolStringPtr &
Name) {
227 "Symbol not covered by this MaterializationUnit");
231MaterializationUnit::Interface
232LazyReexportsMaterializationUnit::extractFlags(
const SymbolAliasMap &Aliases) {
234 for (
auto &KV : Aliases) {
235 assert(KV.second.AliasFlags.isCallable() &&
236 "Lazy re-exports must be callable symbols");
239 return MaterializationUnit::Interface(std::move(
SymbolFlags),
nullptr);
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
An ExecutionSession represents a running JIT program.
void reportError(Error Err)
Report a error for this execution session.
void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Represents an address in the executor process.
void trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD)
Base class for managing collections of named indirect stubs.
virtual ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly)=0
Find the stub with the given name.
virtual Error createStubs(const StubInitsMap &StubInits)=0
Create StubInits.size() stubs with the given names, target addresses, and flags.
StringMap< std::pair< ExecutorAddr, JITSymbolFlags > > StubInitsMap
Map type for initializing the manager. See init.
Represents a JIT'd dynamic library.
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Manages a set of 'lazy call-through' trampolines.
ExecutorAddr reportCallThroughError(Error Err)
Expected< ReexportsEntry > findReexport(ExecutorAddr TrampolineAddr)
Error notifyResolved(ExecutorAddr TrampolineAddr, ExecutorAddr ResolvedAddr)
void resolveTrampolineLandingAddress(ExecutorAddr TrampolineAddr, TrampolinePool::NotifyLandingResolvedFunction NotifyLandingResolved)
LazyCallThroughManager(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr, TrampolinePool *TP)
Expected< ExecutorAddr > getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName, NotifyResolvedFunction NotifyResolved)
StringRef getName() const override
Return the name of this materialization unit.
LazyReexportsMaterializationUnit(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
SymbolFlagsMap SymbolFlags
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Pointer to a pooled string representing a symbol name.
Base class for pools of compiler re-entry trampolines.
Expected< ExecutorAddr > getTrampoline()
Get an available trampoline address.
unique_function is a type-erasing functor similar to std::function.
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
Expected< std::unique_ptr< LazyCallThroughManager > > createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr)
Create a LocalLazyCallThroughManager from the given triple and execution session.
std::unique_ptr< LazyReexportsMaterializationUnit > lazyReexports(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc=nullptr)
Define lazy-reexports based on the given SymbolAliasMap.
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
@ Ready
Emitted to memory, but waiting on transitive dependencies.
This is an optimization pass for GlobalISel generic memory operations.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
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.
Implement std::hash so that hash_code can be used in STL containers.