LLVM  14.0.0git
LazyReexports.cpp
Go to the documentation of this file.
1 //===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "llvm/ADT/Triple.h"
13 
14 #define DEBUG_TYPE "orc"
15 
16 namespace llvm {
17 namespace orc {
18 
20  ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP)
21  : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(TP) {}
22 
25  NotifyResolvedFunction NotifyResolved) {
26  assert(TP && "TrampolinePool not set");
27 
28  std::lock_guard<std::mutex> Lock(LCTMMutex);
29  auto Trampoline = TP->getTrampoline();
30 
31  if (!Trampoline)
32  return Trampoline.takeError();
33 
34  Reexports[*Trampoline] = ReexportsEntry{&SourceJD, std::move(SymbolName)};
35  Notifiers[*Trampoline] = std::move(NotifyResolved);
36  return *Trampoline;
37 }
38 
40  ES.reportError(std::move(Err));
41  return ErrorHandlerAddr;
42 }
43 
46  std::lock_guard<std::mutex> Lock(LCTMMutex);
47  auto I = Reexports.find(TrampolineAddr);
48  if (I == Reexports.end())
50  "Missing reexport for trampoline address %p",
51  TrampolineAddr);
52  return I->second;
53 }
54 
56  JITTargetAddress ResolvedAddr) {
57  NotifyResolvedFunction NotifyResolved;
58  {
59  std::lock_guard<std::mutex> Lock(LCTMMutex);
60  auto I = Notifiers.find(TrampolineAddr);
61  if (I != Notifiers.end()) {
62  NotifyResolved = std::move(I->second);
63  Notifiers.erase(I);
64  }
65  }
66 
67  return NotifyResolved ? NotifyResolved(ResolvedAddr) : Error::success();
68 }
69 
71  JITTargetAddress TrampolineAddr,
72  NotifyLandingResolvedFunction NotifyLandingResolved) {
73 
74  auto Entry = findReexport(TrampolineAddr);
75  if (!Entry)
76  return NotifyLandingResolved(reportCallThroughError(Entry.takeError()));
77 
78  // Declaring SLS and the callback outside of the call to ES.lookup is a
79  // workaround to fix build failures on AIX and on z/OS platforms.
80  SymbolLookupSet SLS({Entry->SymbolName});
81  auto Callback = [this, TrampolineAddr, SymbolName = Entry->SymbolName,
82  NotifyLandingResolved = std::move(NotifyLandingResolved)](
83  Expected<SymbolMap> Result) mutable {
84  if (Result) {
85  assert(Result->size() == 1 && "Unexpected result size");
86  assert(Result->count(SymbolName) && "Unexpected result value");
87  JITTargetAddress LandingAddr = (*Result)[SymbolName].getAddress();
88 
89  if (auto Err = notifyResolved(TrampolineAddr, LandingAddr))
90  NotifyLandingResolved(reportCallThroughError(std::move(Err)));
91  else
92  NotifyLandingResolved(LandingAddr);
93  } else {
94  NotifyLandingResolved(reportCallThroughError(Result.takeError()));
95  }
96  };
97 
99  makeJITDylibSearchOrder(Entry->SourceJD,
101  std::move(SLS), SymbolState::Ready, std::move(Callback),
103 }
104 
107  JITTargetAddress ErrorHandlerAddr) {
108  switch (T.getArch()) {
109  default:
110  return make_error<StringError>(
111  std::string("No callback manager available for ") + T.str(),
113 
114  case Triple::aarch64:
115  case Triple::aarch64_32:
116  return LocalLazyCallThroughManager::Create<OrcAArch64>(ES,
117  ErrorHandlerAddr);
118 
119  case Triple::x86:
120  return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr);
121 
122  case Triple::mips:
123  return LocalLazyCallThroughManager::Create<OrcMips32Be>(ES,
124  ErrorHandlerAddr);
125 
126  case Triple::mipsel:
127  return LocalLazyCallThroughManager::Create<OrcMips32Le>(ES,
128  ErrorHandlerAddr);
129 
130  case Triple::mips64:
131  case Triple::mips64el:
132  return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
133 
134  case Triple::x86_64:
135  if (T.getOS() == Triple::OSType::Win32)
136  return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>(
137  ES, ErrorHandlerAddr);
138  else
139  return LocalLazyCallThroughManager::Create<OrcX86_64_SysV>(
140  ES, ErrorHandlerAddr);
141  }
142 }
143 
145  LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager,
146  JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
147  : MaterializationUnit(extractFlags(CallableAliases), nullptr),
148  LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),
149  CallableAliases(std::move(CallableAliases)), AliaseeTable(SrcJDLoc) {}
150 
152  return "<Lazy Reexports>";
153 }
154 
155 void LazyReexportsMaterializationUnit::materialize(
156  std::unique_ptr<MaterializationResponsibility> R) {
157  auto RequestedSymbols = R->getRequestedSymbols();
158 
159  SymbolAliasMap RequestedAliases;
160  for (auto &RequestedSymbol : RequestedSymbols) {
161  auto I = CallableAliases.find(RequestedSymbol);
162  assert(I != CallableAliases.end() && "Symbol not found in alias map?");
163  RequestedAliases[I->first] = std::move(I->second);
164  CallableAliases.erase(I);
165  }
166 
167  if (!CallableAliases.empty())
168  if (auto Err = R->replace(lazyReexports(LCTManager, ISManager, SourceJD,
169  std::move(CallableAliases),
170  AliaseeTable))) {
171  R->getExecutionSession().reportError(std::move(Err));
172  R->failMaterialization();
173  return;
174  }
175 
177  for (auto &Alias : RequestedAliases) {
178 
179  auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
180  SourceJD, Alias.second.Aliasee,
181  [&ISManager = this->ISManager,
182  StubSym = Alias.first](JITTargetAddress ResolvedAddr) -> Error {
183  return ISManager.updatePointer(*StubSym, ResolvedAddr);
184  });
185 
186  if (!CallThroughTrampoline) {
187  SourceJD.getExecutionSession().reportError(
188  CallThroughTrampoline.takeError());
189  R->failMaterialization();
190  return;
191  }
192 
193  StubInits[*Alias.first] =
194  std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags);
195  }
196 
197  if (AliaseeTable != nullptr && !RequestedAliases.empty())
198  AliaseeTable->trackImpls(RequestedAliases, &SourceJD);
199 
200  if (auto Err = ISManager.createStubs(StubInits)) {
201  SourceJD.getExecutionSession().reportError(std::move(Err));
202  R->failMaterialization();
203  return;
204  }
205 
206  SymbolMap Stubs;
207  for (auto &Alias : RequestedAliases)
208  Stubs[Alias.first] = ISManager.findStub(*Alias.first, false);
209 
210  // No registered dependencies, so these calls cannot fail.
211  cantFail(R->notifyResolved(Stubs));
212  cantFail(R->notifyEmitted());
213 }
214 
215 void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,
216  const SymbolStringPtr &Name) {
217  assert(CallableAliases.count(Name) &&
218  "Symbol not covered by this MaterializationUnit");
219  CallableAliases.erase(Name);
220 }
221 
223 LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
225  for (auto &KV : Aliases) {
226  assert(KV.second.AliasFlags.isCallable() &&
227  "Lazy re-exports must be callable symbols");
228  SymbolFlags[KV.first] = KV.second.AliasFlags;
229  }
230  return SymbolFlags;
231 }
232 
233 } // End namespace orc.
234 } // End namespace llvm.
llvm::orc::IndirectStubsManager::createStubs
virtual Error createStubs(const StubInitsMap &StubInits)=0
Create StubInits.size() stubs with the given names, target addresses, and flags.
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::orc::JITDylib
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:921
llvm::orc::ImplSymbolMap
Definition: Speculation.h:35
llvm::orc::ExecutionSession::reportError
void reportError(Error Err)
Report a error for this execution session.
Definition: Core.h:1390
llvm::unique_function
unique_function is a type-erasing functor similar to std::function.
Definition: FunctionExtras.h:55
llvm::Triple::x86
@ x86
Definition: Triple.h:83
llvm::orc::IndirectStubsManager
Base class for managing collections of named indirect stubs.
Definition: IndirectionUtils.h:275
llvm::orc::SymbolLookupSet
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:174
llvm::orc::LookupKind::Static
@ Static
llvm::orc::SymbolStringPtr
Pointer to a pooled string representing a symbol name.
Definition: SymbolStringPool.h:50
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
LazyReexports.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::DenseMapBase::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:302
llvm::orc::LazyCallThroughManager
Manages a set of 'lazy call-through' trampolines.
Definition: LazyReexports.h:38
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:84
llvm::orc::IndirectStubsManager::StubInitsMap
StringMap< std::pair< JITTargetAddress, JITSymbolFlags > > StubInitsMap
Map type for initializing the manager. See init.
Definition: IndirectionUtils.h:278
llvm::DenseMapBase::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::orc::lazyReexports
std::unique_ptr< LazyReexportsMaterializationUnit > lazyReexports(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc=nullptr)
Define lazy-reexports based on the given SymbolAliasMap.
Definition: LazyReexports.h:167
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::orc::LazyReexportsMaterializationUnit::LazyReexportsMaterializationUnit
LazyReexportsMaterializationUnit(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
Definition: LazyReexports.cpp:144
llvm::Triple::aarch64_32
@ aarch64_32
Definition: Triple.h:54
OrcABISupport.h
llvm::Triple::mips64
@ mips64
Definition: Triple.h:64
llvm::orc::MaterializationUnit
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:663
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:198
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
llvm::Triple::mips64el
@ mips64el
Definition: Triple.h:65
llvm::orc::NoDependenciesToRegister
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition: Core.cpp:35
llvm::orc::SymbolMap
DenseMap< SymbolStringPtr, JITEvaluatedSymbol > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
Definition: Core.h:112
llvm::orc::LazyCallThroughManager::findReexport
Expected< ReexportsEntry > findReexport(JITTargetAddress TrampolineAddr)
Definition: LazyReexports.cpp:45
llvm::orc::TrampolinePool
Base class for pools of compiler re-entry trampolines.
Definition: IndirectionUtils.h:56
llvm::orc::SymbolAliasMap
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
Definition: Core.h:391
llvm::orc::LazyReexportsMaterializationUnit::getName
StringRef getName() const override
Return the name of this materialization unit.
Definition: LazyReexports.cpp:151
llvm::orc::LazyCallThroughManager::getCallThroughTrampoline
Expected< JITTargetAddress > getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName, NotifyResolvedFunction NotifyResolved)
Definition: LazyReexports.cpp:23
uint64_t
llvm::orc::LazyCallThroughManager::reportCallThroughError
JITTargetAddress reportCallThroughError(Error Err)
Definition: LazyReexports.cpp:39
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap< SymbolStringPtr, SymbolAliasMapEntry >
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1609
Triple.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
llvm::orc::SymbolState::Ready
@ Ready
Emitted to memory, but waiting on transitive dependencies.
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:737
llvm::orc::createLocalLazyCallThroughManager
Expected< std::unique_ptr< LazyCallThroughManager > > createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LocalLazyCallThroughManager from the given triple and execution session.
Definition: LazyReexports.cpp:106
llvm::orc::SymbolFlagsMap
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
Definition: Core.h:115
llvm::DenseMapBase::empty
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:97
llvm::orc::ImplSymbolMap::trackImpls
void trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD)
Definition: Speculation.cpp:25
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:381
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1231
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::orc::LazyCallThroughManager::notifyResolved
Error notifyResolved(JITTargetAddress TrampolineAddr, JITTargetAddress ResolvedAddr)
Definition: LazyReexports.cpp:55
llvm::DenseMapBase::end
iterator end()
Definition: DenseMap.h:83
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::LazyCallThroughManager::ReexportsEntry
Definition: LazyReexports.h:62
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1289
llvm::Triple::mipsel
@ mipsel
Definition: Triple.h:63
llvm::JITTargetAddress
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:42
llvm::orc::LazyCallThroughManager::LazyCallThroughManager
LazyCallThroughManager(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP)
Definition: LazyReexports.cpp:19
llvm::orc::ExecutionSession::lookup
void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Definition: Core.cpp:1954
llvm::orc::JITDylib::getExecutionSession
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:941
llvm::orc::LazyCallThroughManager::resolveTrampolineLandingAddress
void resolveTrampolineLandingAddress(JITTargetAddress TrampolineAddr, TrampolinePool::NotifyLandingResolvedFunction NotifyLandingResolved)
Definition: LazyReexports.cpp:70
llvm::orc::MaterializationUnit::SymbolFlags
SymbolFlagsMap SymbolFlags
Definition: Core.h:704
llvm::orc::JITDylibLookupFlags::MatchAllSymbols
@ MatchAllSymbols
llvm::Triple::mips
@ mips
Definition: Triple.h:62
llvm::orc::makeJITDylibSearchOrder
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...
Definition: Core.h:157
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:52
llvm::orc::IndirectStubsManager::findStub
virtual JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly)=0
Find the stub with the given name.
llvm::orc::TrampolinePool::getTrampoline
Expected< JITTargetAddress > getTrampoline()
Get an available trampoline address.
Definition: IndirectionUtils.h:69