LLVM  15.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::riscv64:
135  return LocalLazyCallThroughManager::Create<OrcRiscv64>(ES,
136  ErrorHandlerAddr);
137 
138  case Triple::x86_64:
139  if (T.getOS() == Triple::OSType::Win32)
140  return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>(
141  ES, ErrorHandlerAddr);
142  else
143  return LocalLazyCallThroughManager::Create<OrcX86_64_SysV>(
144  ES, ErrorHandlerAddr);
145  }
146 }
147 
149  LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager,
150  JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
151  : MaterializationUnit(extractFlags(CallableAliases)),
152  LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),
153  CallableAliases(std::move(CallableAliases)), AliaseeTable(SrcJDLoc) {}
154 
156  return "<Lazy Reexports>";
157 }
158 
159 void LazyReexportsMaterializationUnit::materialize(
160  std::unique_ptr<MaterializationResponsibility> R) {
161  auto RequestedSymbols = R->getRequestedSymbols();
162 
163  SymbolAliasMap RequestedAliases;
164  for (auto &RequestedSymbol : RequestedSymbols) {
165  auto I = CallableAliases.find(RequestedSymbol);
166  assert(I != CallableAliases.end() && "Symbol not found in alias map?");
167  RequestedAliases[I->first] = std::move(I->second);
168  CallableAliases.erase(I);
169  }
170 
171  if (!CallableAliases.empty())
172  if (auto Err = R->replace(lazyReexports(LCTManager, ISManager, SourceJD,
173  std::move(CallableAliases),
174  AliaseeTable))) {
175  R->getExecutionSession().reportError(std::move(Err));
176  R->failMaterialization();
177  return;
178  }
179 
181  for (auto &Alias : RequestedAliases) {
182 
183  auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
184  SourceJD, Alias.second.Aliasee,
185  [&ISManager = this->ISManager,
186  StubSym = Alias.first](JITTargetAddress ResolvedAddr) -> Error {
187  return ISManager.updatePointer(*StubSym, ResolvedAddr);
188  });
189 
190  if (!CallThroughTrampoline) {
191  SourceJD.getExecutionSession().reportError(
192  CallThroughTrampoline.takeError());
193  R->failMaterialization();
194  return;
195  }
196 
197  StubInits[*Alias.first] =
198  std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags);
199  }
200 
201  if (AliaseeTable != nullptr && !RequestedAliases.empty())
202  AliaseeTable->trackImpls(RequestedAliases, &SourceJD);
203 
204  if (auto Err = ISManager.createStubs(StubInits)) {
205  SourceJD.getExecutionSession().reportError(std::move(Err));
206  R->failMaterialization();
207  return;
208  }
209 
210  SymbolMap Stubs;
211  for (auto &Alias : RequestedAliases)
212  Stubs[Alias.first] = ISManager.findStub(*Alias.first, false);
213 
214  // No registered dependencies, so these calls cannot fail.
215  cantFail(R->notifyResolved(Stubs));
216  cantFail(R->notifyEmitted());
217 }
218 
219 void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,
220  const SymbolStringPtr &Name) {
221  assert(CallableAliases.count(Name) &&
222  "Symbol not covered by this MaterializationUnit");
223  CallableAliases.erase(Name);
224 }
225 
226 MaterializationUnit::Interface
227 LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
229  for (auto &KV : Aliases) {
230  assert(KV.second.AliasFlags.isCallable() &&
231  "Lazy re-exports must be callable symbols");
232  SymbolFlags[KV.first] = KV.second.AliasFlags;
233  }
234  return MaterializationUnit::Interface(std::move(SymbolFlags), nullptr);
235 }
236 
237 } // End namespace orc.
238 } // 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::Triple::riscv64
@ riscv64
Definition: Triple.h:76
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::orc::JITDylib
Represents a JIT'd dynamic library.
Definition: Core.h:950
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:1482
llvm::unique_function
unique_function is a type-erasing functor similar to std::function.
Definition: FunctionExtras.h:56
llvm::Triple::x86
@ x86
Definition: Triple.h:85
llvm::orc::IndirectStubsManager
Base class for managing collections of named indirect stubs.
Definition: IndirectionUtils.h:282
llvm::orc::SymbolLookupSet
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:175
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:329
LazyReexports.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::DenseMapBase::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:304
llvm::orc::LazyCallThroughManager
Manages a set of 'lazy call-through' trampolines.
Definition: LazyReexports.h:38
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:86
llvm::orc::IndirectStubsManager::StubInitsMap
StringMap< std::pair< JITTargetAddress, JITSymbolFlags > > StubInitsMap
Map type for initializing the manager. See init.
Definition: IndirectionUtils.h:285
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:147
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:168
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::orc::LazyReexportsMaterializationUnit::LazyReexportsMaterializationUnit
LazyReexportsMaterializationUnit(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc)
Definition: LazyReexports.cpp:148
llvm::Triple::aarch64_32
@ aarch64_32
Definition: Triple.h:53
OrcABISupport.h
llvm::Triple::mips64
@ mips64
Definition: Triple.h:66
llvm::orc::MaterializationUnit
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:669
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:240
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
llvm::Triple::mips64el
@ mips64el
Definition: Triple.h:67
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:34
llvm::orc::SymbolMap
DenseMap< SymbolStringPtr, JITEvaluatedSymbol > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
Definition: Core.h:113
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:63
llvm::orc::SymbolAliasMap
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
Definition: Core.h:392
llvm::orc::LazyReexportsMaterializationUnit::getName
StringRef getName() const override
Return the name of this materialization unit.
Definition: LazyReexports.cpp:155
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:58
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:152
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:1665
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:745
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:116
llvm::DenseMapBase::empty
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:98
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:386
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
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:84
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::orc::LazyCallThroughManager::ReexportsEntry
Definition: LazyReexports.h:62
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1362
llvm::Triple::mipsel
@ mipsel
Definition: Triple.h:65
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:2077
llvm::orc::JITDylib::getExecutionSession
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:970
llvm::orc::LazyCallThroughManager::resolveTrampolineLandingAddress
void resolveTrampolineLandingAddress(JITTargetAddress TrampolineAddr, TrampolinePool::NotifyLandingResolvedFunction NotifyLandingResolved)
Definition: LazyReexports.cpp:70
llvm::orc::MaterializationUnit::SymbolFlags
SymbolFlagsMap SymbolFlags
Definition: Core.h:718
llvm::orc::JITDylibLookupFlags::MatchAllSymbols
@ MatchAllSymbols
llvm::Triple::mips
@ mips
Definition: Triple.h:64
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:158
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:51
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:76