LLVM  9.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 
54  auto LookupResult = ES.lookup(JITDylibSearchList({{SourceJD, true}}),
55  {SymbolName}, NoDependenciesToRegister, true);
56 
57  if (!LookupResult) {
58  ES.reportError(LookupResult.takeError());
59  return ErrorHandlerAddr;
60  }
61 
62  assert(LookupResult->size() == 1 && "Unexpected number of results");
63  assert(LookupResult->count(SymbolName) && "Unexpected result");
64 
65  auto ResolvedAddr = LookupResult->begin()->second.getAddress();
66 
67  std::shared_ptr<NotifyResolvedFunction> NotifyResolved = nullptr;
68  {
69  std::lock_guard<std::mutex> Lock(LCTMMutex);
70  auto I = Notifiers.find(TrampolineAddr);
71  if (I != Notifiers.end()) {
72  NotifyResolved = I->second;
73  Notifiers.erase(I);
74  }
75  }
76 
77  if (NotifyResolved) {
78  if (auto Err = (*NotifyResolved)(*SourceJD, SymbolName, ResolvedAddr)) {
79  ES.reportError(std::move(Err));
80  return ErrorHandlerAddr;
81  }
82  }
83 
84  return ResolvedAddr;
85 }
86 
89  JITTargetAddress ErrorHandlerAddr) {
90  switch (T.getArch()) {
91  default:
92  return make_error<StringError>(
93  std::string("No callback manager available for ") + T.str(),
95 
96  case Triple::aarch64:
97  return LocalLazyCallThroughManager::Create<OrcAArch64>(ES,
98  ErrorHandlerAddr);
99 
100  case Triple::x86:
101  return LocalLazyCallThroughManager::Create<OrcI386>(ES, ErrorHandlerAddr);
102 
103  case Triple::mips:
104  return LocalLazyCallThroughManager::Create<OrcMips32Be>(ES,
105  ErrorHandlerAddr);
106 
107  case Triple::mipsel:
108  return LocalLazyCallThroughManager::Create<OrcMips32Le>(ES,
109  ErrorHandlerAddr);
110 
111  case Triple::mips64:
112  case Triple::mips64el:
113  return LocalLazyCallThroughManager::Create<OrcMips64>(ES, ErrorHandlerAddr);
114 
115  case Triple::x86_64:
116  if (T.getOS() == Triple::OSType::Win32)
117  return LocalLazyCallThroughManager::Create<OrcX86_64_Win32>(
118  ES, ErrorHandlerAddr);
119  else
120  return LocalLazyCallThroughManager::Create<OrcX86_64_SysV>(
121  ES, ErrorHandlerAddr);
122  }
123 }
124 
126  LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager,
127  JITDylib &SourceJD, SymbolAliasMap CallableAliases, VModuleKey K)
128  : MaterializationUnit(extractFlags(CallableAliases), std::move(K)),
129  LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),
130  CallableAliases(std::move(CallableAliases)),
132  [&ISManager](JITDylib &JD, const SymbolStringPtr &SymbolName,
133  JITTargetAddress ResolvedAddr) {
134  return ISManager.updatePointer(*SymbolName, ResolvedAddr);
135  })) {}
136 
138  return "<Lazy Reexports>";
139 }
140 
141 void LazyReexportsMaterializationUnit::materialize(
143  auto RequestedSymbols = R.getRequestedSymbols();
144 
145  SymbolAliasMap RequestedAliases;
146  for (auto &RequestedSymbol : RequestedSymbols) {
147  auto I = CallableAliases.find(RequestedSymbol);
148  assert(I != CallableAliases.end() && "Symbol not found in alias map?");
149  RequestedAliases[I->first] = std::move(I->second);
150  CallableAliases.erase(I);
151  }
152 
153  if (!CallableAliases.empty())
154  R.replace(lazyReexports(LCTManager, ISManager, SourceJD,
155  std::move(CallableAliases)));
156 
158  for (auto &Alias : RequestedAliases) {
159 
160  auto CallThroughTrampoline = LCTManager.getCallThroughTrampoline(
161  SourceJD, Alias.second.Aliasee, NotifyResolved);
162 
163  if (!CallThroughTrampoline) {
164  SourceJD.getExecutionSession().reportError(
165  CallThroughTrampoline.takeError());
167  return;
168  }
169 
170  StubInits[*Alias.first] =
171  std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags);
172  }
173 
174  if (auto Err = ISManager.createStubs(StubInits)) {
175  SourceJD.getExecutionSession().reportError(std::move(Err));
177  return;
178  }
179 
180  SymbolMap Stubs;
181  for (auto &Alias : RequestedAliases)
182  Stubs[Alias.first] = ISManager.findStub(*Alias.first, false);
183 
184  R.resolve(Stubs);
185  R.emit();
186 }
187 
188 void LazyReexportsMaterializationUnit::discard(const JITDylib &JD,
189  const SymbolStringPtr &Name) {
190  assert(CallableAliases.count(Name) &&
191  "Symbol not covered by this MaterializationUnit");
192  CallableAliases.erase(Name);
193 }
194 
196 LazyReexportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
198  for (auto &KV : Aliases) {
199  assert(KV.second.AliasFlags.isCallable() &&
200  "Lazy re-exports must be callable symbols");
201  SymbolFlags[KV.first] = KV.second.AliasFlags;
202  }
203  return SymbolFlags;
204 }
205 
206 } // End namespace orc.
207 } // 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:414
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:72
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:300
void replace(std::unique_ptr< MaterializationUnit > MU)
Transfers responsibility to the given MaterializationUnit for all symbols defined by that Materializa...
Definition: Core.cpp:452
static sys::Mutex Lock
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:39
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:57
SymbolFlagsMap SymbolFlags
Definition: Core.h:281
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:154
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:291
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:40
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:515
const std::string & str() const
Definition: Triple.h:360
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:43
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
Definition: Core.h:251
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:392
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:388
An ExecutionSession represents a running JIT program.
Definition: Core.h:696
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:219
void reportError(Error Err)
Report a error for this execution session.
Definition: Core.h:753
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:108
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:122
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:442
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:1721
Manages a set of &#39;lazy call-through&#39; trampolines.
Definition: LazyReexports.h:36
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition: Core.cpp:142
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