LLVM  8.0.1
LazyReexports.cpp
Go to the documentation of this file.
1 //===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 
12 #include "llvm/ADT/Triple.h"
14 
15 #define DEBUG_TYPE "orc"
16 
17 namespace llvm {
18 namespace orc {
19 
20 void LazyCallThroughManager::NotifyResolvedFunction::anchor() {}
21 
23  ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr,
24  std::unique_ptr<TrampolinePool> TP)
25  : ES(ES), ErrorHandlerAddr(ErrorHandlerAddr), TP(std::move(TP)) {}
26 
29  std::shared_ptr<NotifyResolvedFunction> NotifyResolved) {
30  std::lock_guard<std::mutex> Lock(LCTMMutex);
31  auto Trampoline = TP->getTrampoline();
32 
33  if (!Trampoline)
34  return Trampoline.takeError();
35 
36  Reexports[*Trampoline] = std::make_pair(&SourceJD, std::move(SymbolName));
37  Notifiers[*Trampoline] = std::move(NotifyResolved);
38  return *Trampoline;
39 }
40 
43  JITDylib *SourceJD = nullptr;
45 
46  {
47  std::lock_guard<std::mutex> Lock(LCTMMutex);
48  auto I = Reexports.find(TrampolineAddr);
49  if (I == Reexports.end())
50  return ErrorHandlerAddr;
51  SourceJD = I->second.first;
52  SymbolName = I->second.second;
53  }
54 
55  auto LookupResult = ES.lookup(JITDylibSearchList({{SourceJD, true}}),
56  {SymbolName}, NoDependenciesToRegister, true);
57 
58  if (!LookupResult) {
59  ES.reportError(LookupResult.takeError());
60  return ErrorHandlerAddr;
61  }
62 
63  assert(LookupResult->size() == 1 && "Unexpected number of results");
64  assert(LookupResult->count(SymbolName) && "Unexpected result");
65 
66  auto ResolvedAddr = LookupResult->begin()->second.getAddress();
67 
68  std::shared_ptr<NotifyResolvedFunction> NotifyResolved = nullptr;
69  {
70  std::lock_guard<std::mutex> Lock(LCTMMutex);
71  auto I = Notifiers.find(TrampolineAddr);
72  if (I != Notifiers.end()) {
73  NotifyResolved = I->second;
74  Notifiers.erase(I);
75  }
76  }
77 
78  if (NotifyResolved) {
79  if (auto Err = (*NotifyResolved)(*SourceJD, SymbolName, ResolvedAddr)) {
80  ES.reportError(std::move(Err));
81  return ErrorHandlerAddr;
82  }
83  }
84 
85  return ResolvedAddr;
86 }
87 
90  JITTargetAddress ErrorHandlerAddr) {
91  switch (T.getArch()) {
92  default:
93  return make_error<StringError>(
94  std::string("No callback manager available for ") + T.str(),
96 
97  case Triple::aarch64:
98  return LocalLazyCallThroughManager::Create<OrcAArch64>(ES,
99  ErrorHandlerAddr);
100 
101  case Triple::x86:
102  return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr);
103 
104  case Triple::mips:
105  return LocalLazyCallThroughManager::Create<OrcMips32Be>(ES,
106  ErrorHandlerAddr);
107 
108  case Triple::mipsel:
109  return LocalLazyCallThroughManager::Create<OrcMips32Le>(ES,
110  ErrorHandlerAddr);
111 
112  case Triple::mips64:
113  case Triple::mips64el:
114  return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
115 
116  case Triple::x86_64:
117  if (T.getOS() == Triple::OSType::Win32)
118  return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>(
119  ES, ErrorHandlerAddr);
120  else
121  return LocalLazyCallThroughManager::Create<OrcX86_64_SysV>(
122  ES, ErrorHandlerAddr);
123  }
124 }
125 
127  LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager,
128  JITDylib &SourceJD, SymbolAliasMap CallableAliases, VModuleKey K)
129  : MaterializationUnit(extractFlags(CallableAliases), std::move(K)),
130  LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),
131  CallableAliases(std::move(CallableAliases)),
133  [&ISManager](JITDylib &JD, const SymbolStringPtr &SymbolName,
134  JITTargetAddress ResolvedAddr) {
135  return ISManager.updatePointer(*SymbolName, ResolvedAddr);
136  })) {}
137 
139  return "<Lazy Reexports>";
140 }
141 
142 void LazyReexportsMaterializationUnit::materialize(
144  auto RequestedSymbols = R.getRequestedSymbols();
145 
146  SymbolAliasMap RequestedAliases;
147  for (auto &RequestedSymbol : RequestedSymbols) {
148  auto I = CallableAliases.find(RequestedSymbol);
149  assert(I != CallableAliases.end() && "Symbol not found in alias map?");
150  RequestedAliases[I->first] = std::move(I->second);
151  CallableAliases.erase(I);
152  }
153 
154  if (!CallableAliases.empty())
155  R.replace(lazyReexports(LCTManager, ISManager, SourceJD,
156  std::move(CallableAliases)));
157 
159  for (auto &Alias : RequestedAliases) {
160 
161  auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
162  SourceJD, Alias.second.Aliasee, NotifyResolved);
163 
164  if (!CallThroughTrampoline) {
165  SourceJD.getExecutionSession().reportError(
166  CallThroughTrampoline.takeError());
168  return;
169  }
170 
171  StubInits[*Alias.first] =
172  std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags);
173  }
174 
175  if (auto Err = ISManager.createStubs(StubInits)) {
176  SourceJD.getExecutionSession().reportError(std::move(Err));
178  return;
179  }
180 
181  SymbolMap Stubs;
182  for (auto &Alias : RequestedAliases)
183  Stubs[Alias.first] = ISManager.findStub(*Alias.first, false);
184 
185  R.resolve(Stubs);
186  R.emit();
187 }
188 
189 void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,
190  const SymbolStringPtr &Name) {
191  assert(CallableAliases.count(Name) &&
192  "Symbol not covered by this MaterializationUnit");
193  CallableAliases.erase(Name);
194 }
195 
197 LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
199  for (auto &KV : Aliases) {
200  assert(KV.second.AliasFlags.isCallable() &&
201  "Lazy re-exports must be callable symbols");
202  SymbolFlags[KV.first] = KV.second.AliasFlags;
203  }
204  return SymbolFlags;
205 }
206 
207 } // End namespace orc.
208 } // End namespace llvm.
Base class for managing collections of named indirect stubs.
void emit()
Notifies the target JITDylib (and any pending queries on that JITDylib) that all symbols covered by t...
Definition: Core.cpp:415
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:299
void replace(std::unique_ptr< MaterializationUnit > MU)
Transfers responsibility to the given MaterializationUnit for all symbols defined by that Materializa...
Definition: Core.cpp:453
static sys::Mutex Lock
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:40
JITTargetAddress callThroughToSymbol(JITTargetAddress TrampolineAddr)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Definition: BitVector.h:938
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
std::vector< std::pair< JITDylib *, bool > > JITDylibSearchList
A list of (JITDylib*, bool) pairs.
Definition: Core.h:58
SymbolFlagsMap SymbolFlags
Definition: Core.h:282
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:155
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:290
StringRef getName() const override
Return the name of this materialization unit.
LazyReexportsMaterializationUnit(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, VModuleKey K)
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:41
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:516
const std::string & str() const
Definition: Triple.h:359
Pointer to a pooled string representing a symbol name.
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:176
LazyCallThroughManager(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr, std::unique_ptr< TrampolinePool > TP)
bool erase(const KeyT &Val)
Definition: DenseMap.h:298
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
Definition: Core.h:252
Expected< std::unique_ptr< LazyCallThroughManager > > createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LocalLazyCallThroughManager from the given triple and execution session. ...
void resolve(const SymbolMap &Symbols)
Notifies the target JITDylib that the given symbols have been resolved.
Definition: Core.cpp:393
std::unique_ptr< LazyReexportsMaterializationUnit > lazyReexports(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, VModuleKey K=VModuleKey())
Define lazy-reexports based on the given SymbolAliasMap.
SymbolNameSet getRequestedSymbols() const
Returns the names of any symbols covered by this MaterializationResponsibility object that have queri...
Definition: Core.cpp:389
An ExecutionSession represents a running JIT program.
Definition: Core.h:697
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:220
void reportError(Error Err)
Report a error for this execution session.
Definition: Core.h:754
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.
#define I(x, y, z)
Definition: MD5.cpp:58
iterator end()
Definition: DenseMap.h:109
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:171
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:123
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:443
aarch64 promote const
void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols, SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylib list for the given symbols.
Definition: Core.cpp:1742
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:49
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition: Core.cpp:143
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:496
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:78