LLVM  10.0.0svn
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 
19 void LazyCallThroughManager::NotifyResolvedFunction::anchor() {}
20 
22  ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr,
23  std::unique_ptr<TrampolinePool> TP)
24  : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(std::move(TP)) {}
25 
28  std::shared_ptr<NotifyResolvedFunction> NotifyResolved) {
29  std::lock_guard<std::mutex> Lock(LCTMMutex);
30  auto Trampoline = TP->getTrampoline();
31 
32  if (!Trampoline)
33  return Trampoline.takeError();
34 
35  Reexports[*Trampoline] = std::make_pair(&SourceJD, std::move(SymbolName));
36  Notifiers[*Trampoline] = std::move(NotifyResolved);
37  return *Trampoline;
38 }
39 
42  JITDylib *SourceJD = nullptr;
44 
45  {
46  std::lock_guard<std::mutex> Lock(LCTMMutex);
47  auto I = Reexports.find(TrampolineAddr);
48  if (I == Reexports.end())
49  return ErrorHandlerAddr;
50  SourceJD = I->second.first;
51  SymbolName = I->second.second;
52  }
53  auto LookupResult =
54  ES.lookup(JITDylibSearchList({{SourceJD, true}}), SymbolName);
55 
56  if (!LookupResult) {
57  ES.reportError(LookupResult.takeError());
58  return ErrorHandlerAddr;
59  }
60 
61  auto ResolvedAddr = LookupResult->getAddress();
62 
63  std::shared_ptr<NotifyResolvedFunction> NotifyResolved = nullptr;
64  {
65  std::lock_guard<std::mutex> Lock(LCTMMutex);
66  auto I = Notifiers.find(TrampolineAddr);
67  if (I != Notifiers.end()) {
68  NotifyResolved = I->second;
69  Notifiers.erase(I);
70  }
71  }
72 
73  if (NotifyResolved) {
74  if (auto Err = (*NotifyResolved)(*SourceJD, SymbolName, ResolvedAddr)) {
75  ES.reportError(std::move(Err));
76  return ErrorHandlerAddr;
77  }
78  }
79 
80  return ResolvedAddr;
81 }
82 
85  JITTargetAddress ErrorHandlerAddr) {
86  switch (T.getArch()) {
87  default:
88  return make_error<StringError>(
89  std::string("No callback manager available for ") + T.str(),
91 
92  case Triple::aarch64:
93  case Triple::aarch64_32:
94  return LocalLazyCallThroughManager::Create<OrcAArch64>(ES,
95  ErrorHandlerAddr);
96 
97  case Triple::x86:
98  return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr);
99 
100  case Triple::mips:
101  return LocalLazyCallThroughManager::Create<OrcMips32Be>(ES,
102  ErrorHandlerAddr);
103 
104  case Triple::mipsel:
105  return LocalLazyCallThroughManager::Create<OrcMips32Le>(ES,
106  ErrorHandlerAddr);
107 
108  case Triple::mips64:
109  case Triple::mips64el:
110  return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
111 
112  case Triple::x86_64:
113  if (T.getOS() == Triple::OSType::Win32)
114  return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>(
115  ES, ErrorHandlerAddr);
116  else
117  return LocalLazyCallThroughManager::Create<OrcX86_64_SysV>(
118  ES, ErrorHandlerAddr);
119  }
120 }
121 
123  LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager,
124  JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc,
125  VModuleKey K)
126  : MaterializationUnit(extractFlags(CallableAliases), std::move(K)),
127  LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),
128  CallableAliases(std::move(CallableAliases)),
130  [&ISManager](JITDylib &JD, const SymbolStringPtr &SymbolName,
131  JITTargetAddress ResolvedAddr) {
132  return ISManager.updatePointer(*SymbolName, ResolvedAddr);
133  })),
134  AliaseeTable(SrcJDLoc) {}
135 
137  return "<Lazy Reexports>";
138 }
139 
140 void LazyReexportsMaterializationUnit::materialize(
142  auto RequestedSymbols = R.getRequestedSymbols();
143 
144  SymbolAliasMap RequestedAliases;
145  for (auto &RequestedSymbol : RequestedSymbols) {
146  auto I = CallableAliases.find(RequestedSymbol);
147  assert(I != CallableAliases.end() && "Symbol not found in alias map?");
148  RequestedAliases[I->first] = std::move(I->second);
149  CallableAliases.erase(I);
150  }
151 
152  if (!CallableAliases.empty())
153  R.replace(lazyReexports(LCTManager, ISManager, SourceJD,
154  std::move(CallableAliases), AliaseeTable));
155 
157  for (auto &Alias : RequestedAliases) {
158 
159  auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
160  SourceJD, Alias.second.Aliasee, NotifyResolved);
161 
162  if (!CallThroughTrampoline) {
163  SourceJD.getExecutionSession().reportError(
164  CallThroughTrampoline.takeError());
166  return;
167  }
168 
169  StubInits[*Alias.first] =
170  std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags);
171  }
172 
173  if (AliaseeTable != nullptr && !RequestedAliases.empty())
174  AliaseeTable->trackImpls(RequestedAliases, &SourceJD);
175 
176  if (auto Err = ISManager.createStubs(StubInits)) {
177  SourceJD.getExecutionSession().reportError(std::move(Err));
179  return;
180  }
181 
182  SymbolMap Stubs;
183  for (auto &Alias : RequestedAliases)
184  Stubs[Alias.first] = ISManager.findStub(*Alias.first, false);
185 
186  // No registered dependencies, so these calls cannot fail.
187  cantFail(R.notifyResolved(Stubs));
188  cantFail(R.notifyEmitted());
189 }
190 
191 void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,
192  const SymbolStringPtr &Name) {
193  assert(CallableAliases.count(Name) &&
194  "Symbol not covered by this MaterializationUnit");
195  CallableAliases.erase(Name);
196 }
197 
199 LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
201  for (auto &KV : Aliases) {
202  assert(KV.second.AliasFlags.isCallable() &&
203  "Lazy re-exports must be callable symbols");
204  SymbolFlags[KV.first] = KV.second.AliasFlags;
205  }
206  return SymbolFlags;
207 }
208 
209 } // End namespace orc.
210 } // End namespace llvm.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:703
Base class for managing collections of named indirect stubs.
Error notifyEmitted()
Notifies the target JITDylib (and any pending queries on that JITDylib) that all symbols covered by t...
Definition: Core.cpp:396
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static std::unique_ptr< NotifyResolvedFunction > createNotifyResolvedFunction(NotifyResolvedImpl NotifyResolved)
Create a shared NotifyResolvedFunction from a given type that is callable with the correct signature...
Definition: LazyReexports.h:73
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:305
void replace(std::unique_ptr< MaterializationUnit > MU)
Transfers responsibility to the given MaterializationUnit for all symbols defined by that Materializa...
Definition: Core.cpp:437
static sys::Mutex Lock
LazyReexportsMaterializationUnit(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc, VModuleKey K)
JITTargetAddress callThroughToSymbol(JITTargetAddress TrampolineAddr)
Definition: BitVector.h:937
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
std::vector< std::pair< JITDylib *, bool > > JITDylibSearchList
A list of (JITDylib*, bool) pairs.
Definition: Core.h:59
SymbolFlagsMap SymbolFlags
Definition: Core.h:312
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:171
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:296
StringRef getName() const override
Return the name of this materialization unit.
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:41
void trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD)
Definition: Speculation.cpp:28
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:519
const std::string & str() const
Definition: Triple.h:365
Pointer to a pooled string representing a symbol name.
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
LazyCallThroughManager(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, std::unique_ptr< TrampolinePool > TP)
bool erase(const KeyT &Val)
Definition: DenseMap.h:272
std::unique_ptr< LazyReexportsMaterializationUnit > lazyReexports(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc=nullptr, VModuleKey K=VModuleKey())
Define lazy-reexports based on the given SymbolAliasMap.
Error notifyResolved(const SymbolMap &Symbols)
Notifies the target JITDylib that the given symbols have been resolved.
Definition: Core.cpp:375
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
Definition: Core.h:282
Expected< std::unique_ptr< LazyCallThroughManager > > createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LocalLazyCallThroughManager from the given triple and execution session. ...
SymbolNameSet getRequestedSymbols() const
Returns the names of any symbols covered by this MaterializationResponsibility object that have queri...
Definition: Core.cpp:371
An ExecutionSession represents a running JIT program.
Definition: Core.h:761
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:219
uint8_t uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:42
void reportError(Error Err)
Report a error for this execution session.
Definition: Core.h:826
Expected< JITTargetAddress > getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName, std::shared_ptr< NotifyResolvedFunction > NotifyResolved)
virtual Error updatePointer(StringRef Name, JITTargetAddress NewAddr)=0
Change the value of the implementation pointer for the stub.
void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylib list for the given symbols.
Definition: Core.cpp:1935
#define I(x, y, z)
Definition: MD5.cpp:58
iterator end()
Definition: DenseMap.h:82
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
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:96
virtual JITEvaluatedSymbol 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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void failMaterialization()
Notify all not-yet-emitted covered by this MaterializationResponsibility instance that an error has o...
Definition: Core.cpp:421
aarch64 promote const
Manages a set of &#39;lazy call-through&#39; trampolines.
Definition: LazyReexports.h:37
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:495
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77