1 //===--- Core.cpp - Core ORC APIs (MaterializationUnit, JITDylib, etc.) ---===//
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 
9 #include "llvm/ExecutionEngine/Orc/Core.h"
10 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/Config/llvm-config.h"
13 #include "llvm/ExecutionEngine/Orc/OrcError.h"
14 #include "llvm/Support/CommandLine.h"
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/Format.h"
17 
18 #if LLVM_ENABLE_THREADS
19 #include <future>
20 #endif
21 
22 #define DEBUG_TYPE "orc"
23 
24 using namespace llvm;
25 
26 namespace {
27 
28 #ifndef NDEBUG
29 
30 cl::opt<bool> PrintHidden("debug-orc-print-hidden", cl::init(true),
31                           cl::desc("debug print hidden symbols defined by "
32                                    "materialization units"),
33                           cl::Hidden);
34 
35 cl::opt<bool> PrintCallable("debug-orc-print-callable", cl::init(true),
36                             cl::desc("debug print callable symbols defined by "
37                                      "materialization units"),
38                             cl::Hidden);
39 
40 cl::opt<bool> PrintData("debug-orc-print-data", cl::init(true),
41                         cl::desc("debug print data symbols defined by "
42                                  "materialization units"),
43                         cl::Hidden);
44 
45 #endif // NDEBUG
46 
47 // SetPrinter predicate that prints every element.
48 template <typename T> struct PrintAll {
49   bool operator()(const T &E) { return true; }
50 };
51 
52 bool anyPrintSymbolOptionSet() {
53 #ifndef NDEBUG
54   return PrintHidden || PrintCallable || PrintData;
55 #else
56   return false;
57 #endif // NDEBUG
58 }
59 
60 bool flagsMatchCLOpts(const JITSymbolFlags &Flags) {
61 #ifndef NDEBUG
62   // Bail out early if this is a hidden symbol and we're not printing hiddens.
63   if (!PrintHidden && !Flags.isExported())
64     return false;
65 
66   // Return true if this is callable and we're printing callables.
67   if (PrintCallable && Flags.isCallable())
68     return true;
69 
70   // Return true if this is data and we're printing data.
71   if (PrintData && !Flags.isCallable())
72     return true;
73 
74   // otherwise return false.
75   return false;
76 #else
77   return false;
78 #endif // NDEBUG
79 }
80 
81 // Prints a sequence of items, filtered by an user-supplied predicate.
82 template <typename Sequence,
83           typename Pred = PrintAll<typename Sequence::value_type>>
84 class SequencePrinter {
85 public:
86   SequencePrinter(const Sequence &S, char OpenSeq, char CloseSeq,
87                   Pred ShouldPrint = Pred())
88       : S(S), OpenSeq(OpenSeq), CloseSeq(CloseSeq),
89         ShouldPrint(std::move(ShouldPrint)) {}
90 
91   void printTo(llvm::raw_ostream &OS) const {
92     bool PrintComma = false;
93     OS << OpenSeq;
94     for (auto &E : S) {
95       if (ShouldPrint(E)) {
96         if (PrintComma)
97           OS << ',';
98         OS << ' ' << E;
99         PrintComma = true;
100       }
101     }
102     OS << ' ' << CloseSeq;
103   }
104 
105 private:
106   const Sequence &S;
107   char OpenSeq;
108   char CloseSeq;
109   mutable Pred ShouldPrint;
110 };
111 
112 template <typename Sequence, typename Pred>
113 SequencePrinter<Sequence, Pred> printSequence(const Sequence &S, char OpenSeq,
114                                               char CloseSeq, Pred P = Pred()) {
115   return SequencePrinter<Sequence, Pred>(S, OpenSeq, CloseSeq, std::move(P));
116 }
117 
118 // Render a SequencePrinter by delegating to its printTo method.
119 template <typename Sequence, typename Pred>
120 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
121                               const SequencePrinter<Sequence, Pred> &Printer) {
122   Printer.printTo(OS);
123   return OS;
124 }
125 
126 struct PrintSymbolFlagsMapElemsMatchingCLOpts {
127   bool operator()(const orc::SymbolFlagsMap::value_type &KV) {
128     return flagsMatchCLOpts(KV.second);
129   }
130 };
131 
132 struct PrintSymbolMapElemsMatchingCLOpts {
133   bool operator()(const orc::SymbolMap::value_type &KV) {
134     return flagsMatchCLOpts(KV.second.getFlags());
135   }
136 };
137 
138 } // end anonymous namespace
139 
140 namespace llvm {
141 namespace orc {
142 
143 char FailedToMaterialize::ID = 0;
144 char SymbolsNotFound::ID = 0;
145 char SymbolsCouldNotBeRemoved::ID = 0;
146 
147 RegisterDependenciesFunction NoDependenciesToRegister =
148     RegisterDependenciesFunction();
149 
150 void MaterializationUnit::anchor() {}
151 
152 raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym) {
153   return OS << *Sym;
154 }
155 
156 raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) {
157   return OS << printSequence(Symbols, '{', '}', PrintAll<SymbolStringPtr>());
158 }
159 
160 raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols) {
161   return OS << printSequence(Symbols, '[', ']', PrintAll<SymbolStringPtr>());
162 }
163 
164 raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
165   if (Flags.hasError())
166     OS << "[*ERROR*]";
167   if (Flags.isCallable())
168     OS << "[Callable]";
169   else
170     OS << "[Data]";
171   if (Flags.isWeak())
172     OS << "[Weak]";
173   else if (Flags.isCommon())
174     OS << "[Common]";
175 
176   if (!Flags.isExported())
177     OS << "[Hidden]";
178 
179   return OS;
180 }
181 
182 raw_ostream &operator<<(raw_ostream &OS, const JITEvaluatedSymbol &Sym) {
183   return OS << format("0x%016" PRIx64, Sym.getAddress()) << " "
184             << Sym.getFlags();
185 }
186 
187 raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV) {
188   return OS << "(\"" << KV.first << "\", " << KV.second << ")";
189 }
190 
191 raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) {
192   return OS << "(\"" << KV.first << "\": " << KV.second << ")";
193 }
194 
195 raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) {
196   return OS << printSequence(SymbolFlags, '{', '}',
197                              PrintSymbolFlagsMapElemsMatchingCLOpts());
198 }
199 
200 raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) {
201   return OS << printSequence(Symbols, '{', '}',
202                              PrintSymbolMapElemsMatchingCLOpts());
203 }
204 
205 raw_ostream &operator<<(raw_ostream &OS,
206                         const SymbolDependenceMap::value_type &KV) {
207   return OS << "(" << KV.first->getName() << ", " << KV.second << ")";
208 }
209 
210 raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) {
211   return OS << printSequence(Deps, '{', '}',
212                              PrintAll<SymbolDependenceMap::value_type>());
213 }
214 
215 raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) {
216   OS << "MU@" << &MU << " (\"" << MU.getName() << "\"";
217   if (anyPrintSymbolOptionSet())
218     OS << ", " << MU.getSymbols();
219   return OS << ")";
220 }
221 
222 raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K) {
223   switch (K) {
224   case LookupKind::Static:
225     return OS << "Static";
226   case LookupKind::DLSym:
227     return OS << "DLSym";
228   }
229   llvm_unreachable("Invalid lookup kind");
230 }
231 
232 raw_ostream &operator<<(raw_ostream &OS,
233                         const JITDylibLookupFlags &JDLookupFlags) {
234   switch (JDLookupFlags) {
235   case JITDylibLookupFlags::MatchExportedSymbolsOnly:
236     return OS << "MatchExportedSymbolsOnly";
237   case JITDylibLookupFlags::MatchAllSymbols:
238     return OS << "MatchAllSymbols";
239   }
240   llvm_unreachable("Invalid JITDylib lookup flags");
241 }
242 
243 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags) {
244   switch (LookupFlags) {
245   case SymbolLookupFlags::RequiredSymbol:
246     return OS << "RequiredSymbol";
247   case SymbolLookupFlags::WeaklyReferencedSymbol:
248     return OS << "WeaklyReferencedSymbol";
249   }
250   llvm_unreachable("Invalid symbol lookup flags");
251 }
252 
253 raw_ostream &operator<<(raw_ostream &OS,
254                         const SymbolLookupSet::value_type &KV) {
255   return OS << "(" << KV.first << ", " << KV.second << ")";
256 }
257 
258 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet) {
259   return OS << printSequence(LookupSet, '{', '}',
260                              PrintAll<SymbolLookupSet::value_type>());
261 }
262 
263 raw_ostream &operator<<(raw_ostream &OS,
264                         const JITDylibSearchOrder &SearchOrder) {
265   OS << "[";
266   if (!SearchOrder.empty()) {
267     assert(SearchOrder.front().first &&
268            "JITDylibList entries must not be null");
269     OS << " (\"" << SearchOrder.front().first->getName() << "\", "
270        << SearchOrder.begin()->second << ")";
271     for (auto &KV :
272          make_range(std::next(SearchOrder.begin(), 1), SearchOrder.end())) {
273       assert(KV.first && "JITDylibList entries must not be null");
274       OS << ", (\"" << KV.first->getName() << "\", " << KV.second << ")";
275     }
276   }
277   OS << " ]";
278   return OS;
279 }
280 
281 raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases) {
282   OS << "{";
283   for (auto &KV : Aliases)
284     OS << " " << *KV.first << ": " << KV.second.Aliasee << " "
285        << KV.second.AliasFlags;
286   OS << " }";
287   return OS;
288 }
289 
290 raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S) {
291   switch (S) {
292   case SymbolState::Invalid:
293     return OS << "Invalid";
294   case SymbolState::NeverSearched:
295     return OS << "Never-Searched";
296   case SymbolState::Materializing:
297     return OS << "Materializing";
298   case SymbolState::Resolved:
299     return OS << "Resolved";
300   case SymbolState::Emitted:
301     return OS << "Emitted";
302   case SymbolState::Ready:
303     return OS << "Ready";
304   }
305   llvm_unreachable("Invalid state");
306 }
307 
308 FailedToMaterialize::FailedToMaterialize(
309     std::shared_ptr<SymbolDependenceMap> Symbols)
310     : Symbols(std::move(Symbols)) {
311   assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");
312 }
313 
314 std::error_code FailedToMaterialize::convertToErrorCode() const {
315   return orcError(OrcErrorCode::UnknownORCError);
316 }
317 
318 void FailedToMaterialize::log(raw_ostream &OS) const {
319   OS << "Failed to materialize symbols: " << *Symbols;
320 }
321 
322 SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) {
323   for (auto &Sym : Symbols)
324     this->Symbols.push_back(Sym);
325   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
326 }
327 
328 SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols)
329     : Symbols(std::move(Symbols)) {
330   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
331 }
332 
333 std::error_code SymbolsNotFound::convertToErrorCode() const {
334   return orcError(OrcErrorCode::UnknownORCError);
335 }
336 
337 void SymbolsNotFound::log(raw_ostream &OS) const {
338   OS << "Symbols not found: " << Symbols;
339 }
340 
341 SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(SymbolNameSet Symbols)
342     : Symbols(std::move(Symbols)) {
343   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
344 }
345 
346 std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const {
347   return orcError(OrcErrorCode::UnknownORCError);
348 }
349 
350 void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const {
351   OS << "Symbols could not be removed: " << Symbols;
352 }
353 
354 AsynchronousSymbolQuery::AsynchronousSymbolQuery(
355     const SymbolLookupSet &Symbols, SymbolState RequiredState,
356     SymbolsResolvedCallback NotifyComplete)
357     : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
358   assert(RequiredState >= SymbolState::Resolved &&
359          "Cannot query for a symbols that have not reached the resolve state "
360          "yet");
361 
362   OutstandingSymbolsCount = Symbols.size();
363 
364   for (auto &KV : Symbols)
365     ResolvedSymbols[KV.first] = nullptr;
366 }
367 
368 void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
369     const SymbolStringPtr &Name, JITEvaluatedSymbol Sym) {
370   auto I = ResolvedSymbols.find(Name);
371   assert(I != ResolvedSymbols.end() &&
372          "Resolving symbol outside the requested set");
373   assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name");
374   I->second = std::move(Sym);
375   --OutstandingSymbolsCount;
376 }
377 
378 void AsynchronousSymbolQuery::handleComplete() {
379   assert(OutstandingSymbolsCount == 0 &&
380          "Symbols remain, handleComplete called prematurely");
381 
382   auto TmpNotifyComplete = std::move(NotifyComplete);
383   NotifyComplete = SymbolsResolvedCallback();
384   TmpNotifyComplete(std::move(ResolvedSymbols));
385 }
386 
387 bool AsynchronousSymbolQuery::canStillFail() { return !!NotifyComplete; }
388 
389 void AsynchronousSymbolQuery::handleFailed(Error Err) {
390   assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&
391          OutstandingSymbolsCount == 0 &&
392          "Query should already have been abandoned");
393   NotifyComplete(std::move(Err));
394   NotifyComplete = SymbolsResolvedCallback();
395 }
396 
397 void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
398                                                  SymbolStringPtr Name) {
399   bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
400   (void)Added;
401   assert(Added && "Duplicate dependence notification?");
402 }
403 
404 void AsynchronousSymbolQuery::removeQueryDependence(
405     JITDylib &JD, const SymbolStringPtr &Name) {
406   auto QRI = QueryRegistrations.find(&JD);
407   assert(QRI != QueryRegistrations.end() &&
408          "No dependencies registered for JD");
409   assert(QRI->second.count(Name) && "No dependency on Name in JD");
410   QRI->second.erase(Name);
411   if (QRI->second.empty())
412     QueryRegistrations.erase(QRI);
413 }
414 
415 void AsynchronousSymbolQuery::detach() {
416   ResolvedSymbols.clear();
417   OutstandingSymbolsCount = 0;
418   for (auto &KV : QueryRegistrations)
419     KV.first->detachQueryHelper(*this, KV.second);
420   QueryRegistrations.clear();
421 }
422 
423 MaterializationResponsibility::~MaterializationResponsibility() {
424   assert(SymbolFlags.empty() &&
425          "All symbols should have been explicitly materialized or failed");
426 }
427 
428 SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
429   return JD.getRequestedSymbols(SymbolFlags);
430 }
431 
432 Error MaterializationResponsibility::notifyResolved(const SymbolMap &Symbols) {
433   LLVM_DEBUG({
434     dbgs() << "In " << JD.getName() << " resolving " << Symbols << "\n";
435   });
436 #ifndef NDEBUG
437   for (auto &KV : Symbols) {
438     auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common;
439     auto I = SymbolFlags.find(KV.first);
440     assert(I != SymbolFlags.end() &&
441            "Resolving symbol outside this responsibility set");
442     assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&
443            "Resolving symbol with incorrect flags");
444   }
445 #endif
446 
447   return JD.resolve(Symbols);
448 }
449 
450 Error MaterializationResponsibility::notifyEmitted() {
451 
452   LLVM_DEBUG({
453     dbgs() << "In " << JD.getName() << " emitting " << SymbolFlags << "\n";
454   });
455 
456   if (auto Err = JD.emit(SymbolFlags))
457     return Err;
458 
459   SymbolFlags.clear();
460   return Error::success();
461 }
462 
463 Error MaterializationResponsibility::defineMaterializing(
464     SymbolFlagsMap NewSymbolFlags) {
465 
466   LLVM_DEBUG({
467       dbgs() << "In " << JD.getName() << " defining materializing symbols "
468              << NewSymbolFlags << "\n";
469     });
470   if (auto AcceptedDefs = JD.defineMaterializing(std::move(NewSymbolFlags))) {
471     // Add all newly accepted symbols to this responsibility object.
472     for (auto &KV : *AcceptedDefs)
473       SymbolFlags.insert(KV);
474     return Error::success();
475   } else
476     return AcceptedDefs.takeError();
477 }
478 
479 void MaterializationResponsibility::failMaterialization() {
480 
481   LLVM_DEBUG({
482     dbgs() << "In " << JD.getName() << " failing materialization for "
483            << SymbolFlags << "\n";
484   });
485 
486   JITDylib::FailedSymbolsWorklist Worklist;
487 
488   for (auto &KV : SymbolFlags)
489     Worklist.push_back(std::make_pair(&JD, KV.first));
490   SymbolFlags.clear();
491 
492   JD.notifyFailed(std::move(Worklist));
493 }
494 
495 void MaterializationResponsibility::replace(
496     std::unique_ptr<MaterializationUnit> MU) {
497 
498   for (auto &KV : MU->getSymbols())
499     SymbolFlags.erase(KV.first);
500 
501   if (MU->getInitializerSymbol() == InitSymbol)
502     InitSymbol = nullptr;
503 
504   LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {
505     dbgs() << "In " << JD.getName() << " replacing symbols with " << *MU
506            << "\n";
507   }););
508 
509   JD.replace(std::move(MU));
510 }
511 
512 MaterializationResponsibility
513 MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
514                                         VModuleKey NewKey) {
515 
516   if (NewKey == VModuleKey())
517     NewKey = K;
518 
519   SymbolStringPtr DelegatedInitSymbol;
520   SymbolFlagsMap DelegatedFlags;
521 
522   for (auto &Name : Symbols) {
523     auto I = SymbolFlags.find(Name);
524     assert(I != SymbolFlags.end() &&
525            "Symbol is not tracked by this MaterializationResponsibility "
526            "instance");
527 
528     DelegatedFlags[Name] = std::move(I->second);
529     if (Name == InitSymbol)
530       std::swap(InitSymbol, DelegatedInitSymbol);
531 
532     SymbolFlags.erase(I);
533   }
534 
535   return MaterializationResponsibility(JD, std::move(DelegatedFlags),
536                                        std::move(DelegatedInitSymbol),
537                                        std::move(NewKey));
538 }
539 
540 void MaterializationResponsibility::addDependencies(
541     const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
542   assert(SymbolFlags.count(Name) &&
543          "Symbol not covered by this MaterializationResponsibility instance");
544   JD.addDependencies(Name, Dependencies);
545 }
546 
547 void MaterializationResponsibility::addDependenciesForAll(
548     const SymbolDependenceMap &Dependencies) {
549   for (auto &KV : SymbolFlags)
550     JD.addDependencies(KV.first, Dependencies);
551 }
552 
553 AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
554     SymbolMap Symbols, VModuleKey K)
555     : MaterializationUnit(extractFlags(Symbols), nullptr, std::move(K)),
556       Symbols(std::move(Symbols)) {}
557 
558 StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
559   return "<Absolute Symbols>";
560 }
561 
562 void AbsoluteSymbolsMaterializationUnit::materialize(
563     MaterializationResponsibility R) {
564   // No dependencies, so these calls can't fail.
565   cantFail(R.notifyResolved(Symbols));
566   cantFail(R.notifyEmitted());
567 }
568 
569 void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
570                                                  const SymbolStringPtr &Name) {
571   assert(Symbols.count(Name) && "Symbol is not part of this MU");
572   Symbols.erase(Name);
573 }
574 
575 SymbolFlagsMap
576 AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
577   SymbolFlagsMap Flags;
578   for (const auto &KV : Symbols)
579     Flags[KV.first] = KV.second.getFlags();
580   return Flags;
581 }
582 
583 ReExportsMaterializationUnit::ReExportsMaterializationUnit(
584     JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
585     SymbolAliasMap Aliases, VModuleKey K)
586     : MaterializationUnit(extractFlags(Aliases), nullptr, std::move(K)),
587       SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
588       Aliases(std::move(Aliases)) {}
589 
590 StringRef ReExportsMaterializationUnit::getName() const {
591   return "<Reexports>";
592 }
593 
594 void ReExportsMaterializationUnit::materialize(
595     MaterializationResponsibility R) {
596 
597   auto &ES = R.getTargetJITDylib().getExecutionSession();
598   JITDylib &TgtJD = R.getTargetJITDylib();
599   JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
600 
601   // Find the set of requested aliases and aliasees. Return any unrequested
602   // aliases back to the JITDylib so as to not prematurely materialize any
603   // aliasees.
604   auto RequestedSymbols = R.getRequestedSymbols();
605   SymbolAliasMap RequestedAliases;
606 
607   for (auto &Name : RequestedSymbols) {
608     auto I = Aliases.find(Name);
609     assert(I != Aliases.end() && "Symbol not found in aliases map?");
610     RequestedAliases[Name] = std::move(I->second);
611     Aliases.erase(I);
612   }
613 
614   LLVM_DEBUG({
615     ES.runSessionLocked([&]() {
616       dbgs() << "materializing reexports: target = " << TgtJD.getName()
617              << ", source = " << SrcJD.getName() << " " << RequestedAliases
618              << "\n";
619     });
620   });
621 
622   if (!Aliases.empty()) {
623     if (SourceJD)
624       R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
625     else
626       R.replace(symbolAliases(std::move(Aliases)));
627   }
628 
629   // The OnResolveInfo struct will hold the aliases and responsibilty for each
630   // query in the list.
631   struct OnResolveInfo {
632     OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases)
633         : R(std::move(R)), Aliases(std::move(Aliases)) {}
634 
635     MaterializationResponsibility R;
636     SymbolAliasMap Aliases;
637   };
638 
639   // Build a list of queries to issue. In each round we build the largest set of
640   // aliases that we can resolve without encountering a chain definition of the
641   // form Foo -> Bar, Bar -> Baz. Such a form would deadlock as the query would
642   // be waitin on a symbol that it itself had to resolve. Usually this will just
643   // involve one round and a single query.
644 
645   std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
646       QueryInfos;
647   while (!RequestedAliases.empty()) {
648     SymbolNameSet ResponsibilitySymbols;
649     SymbolLookupSet QuerySymbols;
650     SymbolAliasMap QueryAliases;
651 
652     // Collect as many aliases as we can without including a chain.
653     for (auto &KV : RequestedAliases) {
654       // Chain detected. Skip this symbol for this round.
655       if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
656                                RequestedAliases.count(KV.second.Aliasee)))
657         continue;
658 
659       ResponsibilitySymbols.insert(KV.first);
660       QuerySymbols.add(KV.second.Aliasee);
661       QueryAliases[KV.first] = std::move(KV.second);
662     }
663 
664     // Remove the aliases collected this round from the RequestedAliases map.
665     for (auto &KV : QueryAliases)
666       RequestedAliases.erase(KV.first);
667 
668     assert(!QuerySymbols.empty() && "Alias cycle detected!");
669 
670     auto QueryInfo = std::make_shared<OnResolveInfo>(
671         R.delegate(ResponsibilitySymbols), std::move(QueryAliases));
672     QueryInfos.push_back(
673         make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
674   }
675 
676   // Issue the queries.
677   while (!QueryInfos.empty()) {
678     auto QuerySymbols = std::move(QueryInfos.back().first);
679     auto QueryInfo = std::move(QueryInfos.back().second);
680 
681     QueryInfos.pop_back();
682 
683     auto RegisterDependencies = [QueryInfo,
684                                  &SrcJD](const SymbolDependenceMap &Deps) {
685       // If there were no materializing symbols, just bail out.
686       if (Deps.empty())
687         return;
688 
689       // Otherwise the only deps should be on SrcJD.
690       assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
691              "Unexpected dependencies for reexports");
692 
693       auto &SrcJDDeps = Deps.find(&SrcJD)->second;
694       SymbolDependenceMap PerAliasDepsMap;
695       auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
696 
697       for (auto &KV : QueryInfo->Aliases)
698         if (SrcJDDeps.count(KV.second.Aliasee)) {
699           PerAliasDeps = {KV.second.Aliasee};
700           QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
701         }
702     };
703 
704     auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
705       auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
706       if (Result) {
707         SymbolMap ResolutionMap;
708         for (auto &KV : QueryInfo->Aliases) {
709           assert(Result->count(KV.second.Aliasee) &&
710                  "Result map missing entry?");
711           ResolutionMap[KV.first] = JITEvaluatedSymbol(
712               (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
713         }
714         if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) {
715           ES.reportError(std::move(Err));
716           QueryInfo->R.failMaterialization();
717           return;
718         }
719         if (auto Err = QueryInfo->R.notifyEmitted()) {
720           ES.reportError(std::move(Err));
721           QueryInfo->R.failMaterialization();
722           return;
723         }
724       } else {
725         ES.reportError(Result.takeError());
726         QueryInfo->R.failMaterialization();
727       }
728     };
729 
730     ES.lookup(LookupKind::Static,
731               JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
732               QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
733               std::move(RegisterDependencies));
734   }
735 }
736 
737 void ReExportsMaterializationUnit::discard(const JITDylib &JD,
738                                            const SymbolStringPtr &Name) {
739   assert(Aliases.count(Name) &&
740          "Symbol not covered by this MaterializationUnit");
741   Aliases.erase(Name);
742 }
743 
744 SymbolFlagsMap
745 ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
746   SymbolFlagsMap SymbolFlags;
747   for (auto &KV : Aliases)
748     SymbolFlags[KV.first] = KV.second.AliasFlags;
749 
750   return SymbolFlags;
751 }
752 
753 Expected<SymbolAliasMap>
754 buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
755   SymbolLookupSet LookupSet(Symbols);
756   auto Flags = SourceJD.lookupFlags(
757       LookupKind::Static, JITDylibLookupFlags::MatchAllSymbols, LookupSet);
758 
759   if (!Flags)
760     return Flags.takeError();
761 
762   if (!LookupSet.empty()) {
763     LookupSet.sortByName();
764     return make_error<SymbolsNotFound>(LookupSet.getSymbolNames());
765   }
766 
767   SymbolAliasMap Result;
768   for (auto &Name : Symbols) {
769     assert(Flags->count(Name) && "Missing entry in flags map");
770     Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]);
771   }
772 
773   return Result;
774 }
775 
776 ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
777                                        JITDylibLookupFlags SourceJDLookupFlags,
778                                        SymbolPredicate Allow)
779     : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
780       Allow(std::move(Allow)) {}
781 
782 Error ReexportsGenerator::tryToGenerate(LookupKind K, JITDylib &JD,
783                                         JITDylibLookupFlags JDLookupFlags,
784                                         const SymbolLookupSet &LookupSet) {
785   assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
786 
787   // Use lookupFlags to find the subset of symbols that match our lookup.
788   auto Flags = SourceJD.lookupFlags(K, JDLookupFlags, LookupSet);
789   if (!Flags)
790     return Flags.takeError();
791 
792   // Create an alias map.
793   orc::SymbolAliasMap AliasMap;
794   for (auto &KV : *Flags)
795     if (!Allow || Allow(KV.first))
796       AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
797 
798   if (AliasMap.empty())
799     return Error::success();
800 
801   // Define the re-exports.
802   return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
803 }
804 
805 JITDylib::DefinitionGenerator::~DefinitionGenerator() {}
806 
807 void JITDylib::removeGenerator(DefinitionGenerator &G) {
808   ES.runSessionLocked([&]() {
809     auto I = std::find_if(DefGenerators.begin(), DefGenerators.end(),
810                           [&](const std::unique_ptr<DefinitionGenerator> &H) {
811                             return H.get() == &G;
812                           });
813     assert(I != DefGenerators.end() && "Generator not found");
814     DefGenerators.erase(I);
815   });
816 }
817 
818 Expected<SymbolFlagsMap>
819 JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) {
820 
821   return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
822     std::vector<SymbolTable::iterator> AddedSyms;
823     std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs;
824 
825     for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end();
826          SFItr != SFEnd; ++SFItr) {
827 
828       auto &Name = SFItr->first;
829       auto &Flags = SFItr->second;
830 
831       auto EntryItr = Symbols.find(Name);
832 
833       // If the entry already exists...
834       if (EntryItr != Symbols.end()) {
835 
836         // If this is a strong definition then error out.
837         if (!Flags.isWeak()) {
838           // Remove any symbols already added.
839           for (auto &SI : AddedSyms)
840             Symbols.erase(SI);
841 
842           // FIXME: Return all duplicates.
843           return make_error<DuplicateDefinition>(std::string(*Name));
844         }
845 
846         // Otherwise just make a note to discard this symbol after the loop.
847         RejectedWeakDefs.push_back(SFItr);
848         continue;
849       } else
850         EntryItr =
851           Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
852 
853       AddedSyms.push_back(EntryItr);
854       EntryItr->second.setState(SymbolState::Materializing);
855     }
856 
857     // Remove any rejected weak definitions from the SymbolFlags map.
858     while (!RejectedWeakDefs.empty()) {
859       SymbolFlags.erase(RejectedWeakDefs.back());
860       RejectedWeakDefs.pop_back();
861     }
862 
863     return SymbolFlags;
864   });
865 }
866 
867 void JITDylib::replace(std::unique_ptr<MaterializationUnit> MU) {
868   assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
869 
870   auto MustRunMU =
871       ES.runSessionLocked([&, this]() -> std::unique_ptr<MaterializationUnit> {
872 
873 #ifndef NDEBUG
874         for (auto &KV : MU->getSymbols()) {
875           auto SymI = Symbols.find(KV.first);
876           assert(SymI != Symbols.end() && "Replacing unknown symbol");
877           assert(SymI->second.isInMaterializationPhase() &&
878                  "Can not call replace on a symbol that is not materializing");
879           assert(!SymI->second.hasMaterializerAttached() &&
880                  "Symbol should not have materializer attached already");
881           assert(UnmaterializedInfos.count(KV.first) == 0 &&
882                  "Symbol being replaced should have no UnmaterializedInfo");
883         }
884 #endif // NDEBUG
885 
886         // If any symbol has pending queries against it then we need to
887         // materialize MU immediately.
888         for (auto &KV : MU->getSymbols()) {
889           auto MII = MaterializingInfos.find(KV.first);
890           if (MII != MaterializingInfos.end()) {
891             if (MII->second.hasQueriesPending())
892               return std::move(MU);
893           }
894         }
895 
896         // Otherwise, make MU responsible for all the symbols.
897         auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
898         for (auto &KV : UMI->MU->getSymbols()) {
899           auto SymI = Symbols.find(KV.first);
900           assert(SymI->second.getState() == SymbolState::Materializing &&
901                  "Can not replace a symbol that is not materializing");
902           assert(!SymI->second.hasMaterializerAttached() &&
903                  "Can not replace a symbol that has a materializer attached");
904           assert(UnmaterializedInfos.count(KV.first) == 0 &&
905                  "Unexpected materializer entry in map");
906           SymI->second.setAddress(SymI->second.getAddress());
907           SymI->second.setMaterializerAttached(true);
908           UnmaterializedInfos[KV.first] = UMI;
909         }
910 
911         return nullptr;
912       });
913 
914   if (MustRunMU)
915     ES.dispatchMaterialization(*this, std::move(MustRunMU));
916 }
917 
918 SymbolNameSet
919 JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
920   return ES.runSessionLocked([&]() {
921     SymbolNameSet RequestedSymbols;
922 
923     for (auto &KV : SymbolFlags) {
924       assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
925       assert(Symbols.find(KV.first)->second.isInMaterializationPhase() &&
926              "getRequestedSymbols can only be called for symbols that have "
927              "started materializing");
928       auto I = MaterializingInfos.find(KV.first);
929       if (I == MaterializingInfos.end())
930         continue;
931 
932       if (I->second.hasQueriesPending())
933         RequestedSymbols.insert(KV.first);
934     }
935 
936     return RequestedSymbols;
937   });
938 }
939 
940 void JITDylib::addDependencies(const SymbolStringPtr &Name,
941                                const SymbolDependenceMap &Dependencies) {
942   assert(Symbols.count(Name) && "Name not in symbol table");
943   assert(Symbols[Name].isInMaterializationPhase() &&
944          "Can not add dependencies for a symbol that is not materializing");
945 
946   LLVM_DEBUG({
947       dbgs() << "In " << getName() << " adding dependencies for "
948              << *Name << ": " << Dependencies << "\n";
949     });
950 
951   // If Name is already in an error state then just bail out.
952   if (Symbols[Name].getFlags().hasError())
953     return;
954 
955   auto &MI = MaterializingInfos[Name];
956   assert(Symbols[Name].getState() != SymbolState::Emitted &&
957          "Can not add dependencies to an emitted symbol");
958 
959   bool DependsOnSymbolInErrorState = false;
960 
961   // Register dependencies, record whether any depenendency is in the error
962   // state.
963   for (auto &KV : Dependencies) {
964     assert(KV.first && "Null JITDylib in dependency?");
965     auto &OtherJITDylib = *KV.first;
966     auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib];
967 
968     for (auto &OtherSymbol : KV.second) {
969 
970       // Check the sym entry for the dependency.
971       auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol);
972 
973 #ifndef NDEBUG
974       // Assert that this symbol exists and has not reached the ready state
975       // already.
976       assert(OtherSymI != OtherJITDylib.Symbols.end() &&
977              (OtherSymI->second.getState() < SymbolState::Ready &&
978               "Dependency on emitted/ready symbol"));
979 #endif
980 
981       auto &OtherSymEntry = OtherSymI->second;
982 
983       // If the dependency is in an error state then note this and continue,
984       // we will move this symbol to the error state below.
985       if (OtherSymEntry.getFlags().hasError()) {
986         DependsOnSymbolInErrorState = true;
987         continue;
988       }
989 
990       // If the dependency was not in the error state then add it to
991       // our list of dependencies.
992       assert(OtherJITDylib.MaterializingInfos.count(OtherSymbol) &&
993              "No MaterializingInfo for dependency");
994       auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
995 
996       if (OtherSymEntry.getState() == SymbolState::Emitted)
997         transferEmittedNodeDependencies(MI, Name, OtherMI);
998       else if (&OtherJITDylib != this || OtherSymbol != Name) {
999         OtherMI.Dependants[this].insert(Name);
1000         DepsOnOtherJITDylib.insert(OtherSymbol);
1001       }
1002     }
1003 
1004     if (DepsOnOtherJITDylib.empty())
1005       MI.UnemittedDependencies.erase(&OtherJITDylib);
1006   }
1007 
1008   // If this symbol dependended on any symbols in the error state then move
1009   // this symbol to the error state too.
1010   if (DependsOnSymbolInErrorState)
1011     Symbols[Name].setFlags(Symbols[Name].getFlags() | JITSymbolFlags::HasError);
1012 }
1013 
1014 Error JITDylib::resolve(const SymbolMap &Resolved) {
1015   SymbolNameSet SymbolsInErrorState;
1016   AsynchronousSymbolQuerySet CompletedQueries;
1017 
1018   ES.runSessionLocked([&, this]() {
1019     struct WorklistEntry {
1020       SymbolTable::iterator SymI;
1021       JITEvaluatedSymbol ResolvedSym;
1022     };
1023 
1024     std::vector<WorklistEntry> Worklist;
1025     Worklist.reserve(Resolved.size());
1026 
1027     // Build worklist and check for any symbols in the error state.
1028     for (const auto &KV : Resolved) {
1029 
1030       assert(!KV.second.getFlags().hasError() &&
1031              "Resolution result can not have error flag set");
1032 
1033       auto SymI = Symbols.find(KV.first);
1034 
1035       assert(SymI != Symbols.end() && "Symbol not found");
1036       assert(!SymI->second.hasMaterializerAttached() &&
1037              "Resolving symbol with materializer attached?");
1038       assert(SymI->second.getState() == SymbolState::Materializing &&
1039              "Symbol should be materializing");
1040       assert(SymI->second.getAddress() == 0 &&
1041              "Symbol has already been resolved");
1042 
1043       if (SymI->second.getFlags().hasError())
1044         SymbolsInErrorState.insert(KV.first);
1045       else {
1046         auto Flags = KV.second.getFlags();
1047         Flags &= ~(JITSymbolFlags::Weak | JITSymbolFlags::Common);
1048         assert(Flags == (SymI->second.getFlags() &
1049                          ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&
1050                "Resolved flags should match the declared flags");
1051 
1052         Worklist.push_back(
1053             {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
1054       }
1055     }
1056 
1057     // If any symbols were in the error state then bail out.
1058     if (!SymbolsInErrorState.empty())
1059       return;
1060 
1061     while (!Worklist.empty()) {
1062       auto SymI = Worklist.back().SymI;
1063       auto ResolvedSym = Worklist.back().ResolvedSym;
1064       Worklist.pop_back();
1065 
1066       auto &Name = SymI->first;
1067 
1068       // Resolved symbols can not be weak: discard the weak flag.
1069       JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
1070       SymI->second.setAddress(ResolvedSym.getAddress());
1071       SymI->second.setFlags(ResolvedFlags);
1072       SymI->second.setState(SymbolState::Resolved);
1073 
1074       auto &MI = MaterializingInfos[Name];
1075       for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
1076         Q->notifySymbolMetRequiredState(Name, ResolvedSym);
1077         Q->removeQueryDependence(*this, Name);
1078         if (Q->isComplete())
1079           CompletedQueries.insert(std::move(Q));
1080       }
1081     }
1082   });
1083 
1084   assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
1085          "Can't fail symbols and completed queries at the same time");
1086 
1087   // If we failed any symbols then return an error.
1088   if (!SymbolsInErrorState.empty()) {
1089     auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1090     (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1091     return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1092   }
1093 
1094   // Otherwise notify all the completed queries.
1095   for (auto &Q : CompletedQueries) {
1096     assert(Q->isComplete() && "Q not completed");
1097     Q->handleComplete();
1098   }
1099 
1100   return Error::success();
1101 }
1102 
1103 Error JITDylib::emit(const SymbolFlagsMap &Emitted) {
1104   AsynchronousSymbolQuerySet CompletedQueries;
1105   SymbolNameSet SymbolsInErrorState;
1106   DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
1107 
1108   ES.runSessionLocked([&, this]() {
1109     std::vector<SymbolTable::iterator> Worklist;
1110 
1111     // Scan to build worklist, record any symbols in the erorr state.
1112     for (const auto &KV : Emitted) {
1113       auto &Name = KV.first;
1114 
1115       auto SymI = Symbols.find(Name);
1116       assert(SymI != Symbols.end() && "No symbol table entry for Name");
1117 
1118       if (SymI->second.getFlags().hasError())
1119         SymbolsInErrorState.insert(Name);
1120       else
1121         Worklist.push_back(SymI);
1122     }
1123 
1124     // If any symbols were in the error state then bail out.
1125     if (!SymbolsInErrorState.empty())
1126       return;
1127 
1128     // Otherwise update dependencies and move to the emitted state.
1129     while (!Worklist.empty()) {
1130       auto SymI = Worklist.back();
1131       Worklist.pop_back();
1132 
1133       auto &Name = SymI->first;
1134       auto &SymEntry = SymI->second;
1135 
1136       // Move symbol to the emitted state.
1137       assert(SymEntry.getState() == SymbolState::Resolved &&
1138              "Emitting from state other than Resolved");
1139       SymEntry.setState(SymbolState::Emitted);
1140 
1141       auto MII = MaterializingInfos.find(Name);
1142       assert(MII != MaterializingInfos.end() &&
1143              "Missing MaterializingInfo entry");
1144       auto &MI = MII->second;
1145 
1146       // For each dependant, transfer this node's emitted dependencies to
1147       // it. If the dependant node is ready (i.e. has no unemitted
1148       // dependencies) then notify any pending queries.
1149       for (auto &KV : MI.Dependants) {
1150         auto &DependantJD = *KV.first;
1151         auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
1152         for (auto &DependantName : KV.second) {
1153           auto DependantMII =
1154               DependantJD.MaterializingInfos.find(DependantName);
1155           assert(DependantMII != DependantJD.MaterializingInfos.end() &&
1156                  "Dependant should have MaterializingInfo");
1157 
1158           auto &DependantMI = DependantMII->second;
1159 
1160           // Remove the dependant's dependency on this node.
1161           assert(DependantMI.UnemittedDependencies.count(this) &&
1162                  "Dependant does not have an unemitted dependencies record for "
1163                  "this JITDylib");
1164           assert(DependantMI.UnemittedDependencies[this].count(Name) &&
1165                  "Dependant does not count this symbol as a dependency?");
1166 
1167           DependantMI.UnemittedDependencies[this].erase(Name);
1168           if (DependantMI.UnemittedDependencies[this].empty())
1169             DependantMI.UnemittedDependencies.erase(this);
1170 
1171           // Transfer unemitted dependencies from this node to the dependant.
1172           DependantJD.transferEmittedNodeDependencies(DependantMI,
1173                                                       DependantName, MI);
1174 
1175           auto DependantSymI = DependantJD.Symbols.find(DependantName);
1176           assert(DependantSymI != DependantJD.Symbols.end() &&
1177                  "Dependant has no entry in the Symbols table");
1178           auto &DependantSymEntry = DependantSymI->second;
1179 
1180           // If the dependant is emitted and this node was the last of its
1181           // unemitted dependencies then the dependant node is now ready, so
1182           // notify any pending queries on the dependant node.
1183           if (DependantSymEntry.getState() == SymbolState::Emitted &&
1184               DependantMI.UnemittedDependencies.empty()) {
1185             assert(DependantMI.Dependants.empty() &&
1186                    "Dependants should be empty by now");
1187 
1188             // Since this dependant is now ready, we erase its MaterializingInfo
1189             // and update its materializing state.
1190             DependantSymEntry.setState(SymbolState::Ready);
1191             DependantJDReadySymbols.push_back(DependantName);
1192 
1193             for (auto &Q : DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
1194               Q->notifySymbolMetRequiredState(
1195                   DependantName, DependantSymI->second.getSymbol());
1196               if (Q->isComplete())
1197                 CompletedQueries.insert(Q);
1198               Q->removeQueryDependence(DependantJD, DependantName);
1199             }
1200           }
1201         }
1202       }
1203 
1204       auto &ThisJDReadySymbols = ReadySymbols[this];
1205       MI.Dependants.clear();
1206       if (MI.UnemittedDependencies.empty()) {
1207         SymI->second.setState(SymbolState::Ready);
1208         ThisJDReadySymbols.push_back(Name);
1209         for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
1210           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1211           if (Q->isComplete())
1212             CompletedQueries.insert(Q);
1213           Q->removeQueryDependence(*this, Name);
1214         }
1215       }
1216     }
1217   });
1218 
1219   assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
1220          "Can't fail symbols and completed queries at the same time");
1221 
1222   // If we failed any symbols then return an error.
1223   if (!SymbolsInErrorState.empty()) {
1224     auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1225     (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1226     return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1227   }
1228 
1229   // Otherwise notify all the completed queries.
1230   for (auto &Q : CompletedQueries) {
1231     assert(Q->isComplete() && "Q is not complete");
1232     Q->handleComplete();
1233   }
1234 
1235   return Error::success();
1236 }
1237 
1238 void JITDylib::notifyFailed(FailedSymbolsWorklist Worklist) {
1239   AsynchronousSymbolQuerySet FailedQueries;
1240   auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1241 
1242   // Failing no symbols is a no-op.
1243   if (Worklist.empty())
1244     return;
1245 
1246   auto &ES = Worklist.front().first->getExecutionSession();
1247 
1248   ES.runSessionLocked([&]() {
1249     while (!Worklist.empty()) {
1250       assert(Worklist.back().first && "Failed JITDylib can not be null");
1251       auto &JD = *Worklist.back().first;
1252       auto Name = std::move(Worklist.back().second);
1253       Worklist.pop_back();
1254 
1255       (*FailedSymbolsMap)[&JD].insert(Name);
1256 
1257       assert(JD.Symbols.count(Name) && "No symbol table entry for Name");
1258       auto &Sym = JD.Symbols[Name];
1259 
1260       // Move the symbol into the error state.
1261       // Note that this may be redundant: The symbol might already have been
1262       // moved to this state in response to the failure of a dependence.
1263       Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
1264 
1265       // FIXME: Come up with a sane mapping of state to
1266       // presence-of-MaterializingInfo so that we can assert presence / absence
1267       // here, rather than testing it.
1268       auto MII = JD.MaterializingInfos.find(Name);
1269 
1270       if (MII == JD.MaterializingInfos.end())
1271         continue;
1272 
1273       auto &MI = MII->second;
1274 
1275       // Move all dependants to the error state and disconnect from them.
1276       for (auto &KV : MI.Dependants) {
1277         auto &DependantJD = *KV.first;
1278         for (auto &DependantName : KV.second) {
1279           assert(DependantJD.Symbols.count(DependantName) &&
1280                  "No symbol table entry for DependantName");
1281           auto &DependantSym = DependantJD.Symbols[DependantName];
1282           DependantSym.setFlags(DependantSym.getFlags() |
1283                                 JITSymbolFlags::HasError);
1284 
1285           assert(DependantJD.MaterializingInfos.count(DependantName) &&
1286                  "No MaterializingInfo for dependant");
1287           auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
1288 
1289           auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
1290           assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
1291                  "No UnemittedDependencies entry for this JITDylib");
1292           assert(UnemittedDepI->second.count(Name) &&
1293                  "No UnemittedDependencies entry for this symbol");
1294           UnemittedDepI->second.erase(Name);
1295           if (UnemittedDepI->second.empty())
1296             DependantMI.UnemittedDependencies.erase(UnemittedDepI);
1297 
1298           // If this symbol is already in the emitted state then we need to
1299           // take responsibility for failing its queries, so add it to the
1300           // worklist.
1301           if (DependantSym.getState() == SymbolState::Emitted) {
1302             assert(DependantMI.Dependants.empty() &&
1303                    "Emitted symbol should not have dependants");
1304             Worklist.push_back(std::make_pair(&DependantJD, DependantName));
1305           }
1306         }
1307       }
1308       MI.Dependants.clear();
1309 
1310       // Disconnect from all unemitted depenencies.
1311       for (auto &KV : MI.UnemittedDependencies) {
1312         auto &UnemittedDepJD = *KV.first;
1313         for (auto &UnemittedDepName : KV.second) {
1314           auto UnemittedDepMII =
1315               UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
1316           assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
1317                  "Missing MII for unemitted dependency");
1318           assert(UnemittedDepMII->second.Dependants.count(&JD) &&
1319                  "JD not listed as a dependant of unemitted dependency");
1320           assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&
1321                  "Name is not listed as a dependant of unemitted dependency");
1322           UnemittedDepMII->second.Dependants[&JD].erase(Name);
1323           if (UnemittedDepMII->second.Dependants[&JD].empty())
1324             UnemittedDepMII->second.Dependants.erase(&JD);
1325         }
1326       }
1327       MI.UnemittedDependencies.clear();
1328 
1329       // Collect queries to be failed for this MII.
1330       AsynchronousSymbolQueryList ToDetach;
1331       for (auto &Q : MII->second.pendingQueries()) {
1332         // Add the query to the list to be failed and detach it.
1333         FailedQueries.insert(Q);
1334         ToDetach.push_back(Q);
1335       }
1336       for (auto &Q : ToDetach)
1337         Q->detach();
1338 
1339       assert(MI.Dependants.empty() &&
1340              "Can not delete MaterializingInfo with dependants still attached");
1341       assert(MI.UnemittedDependencies.empty() &&
1342              "Can not delete MaterializingInfo with unemitted dependencies "
1343              "still attached");
1344       assert(!MI.hasQueriesPending() &&
1345              "Can not delete MaterializingInfo with queries pending");
1346       JD.MaterializingInfos.erase(MII);
1347     }
1348   });
1349 
1350   for (auto &Q : FailedQueries)
1351     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbolsMap));
1352 }
1353 
1354 void JITDylib::setSearchOrder(JITDylibSearchOrder NewSearchOrder,
1355                               bool SearchThisJITDylibFirst) {
1356   ES.runSessionLocked([&]() {
1357     if (SearchThisJITDylibFirst) {
1358       SearchOrder.clear();
1359       if (NewSearchOrder.empty() || NewSearchOrder.front().first != this)
1360         SearchOrder.push_back(
1361             std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
1362       SearchOrder.insert(SearchOrder.end(), NewSearchOrder.begin(),
1363                          NewSearchOrder.end());
1364     } else
1365       SearchOrder = std::move(NewSearchOrder);
1366   });
1367 }
1368 
1369 void JITDylib::addToSearchOrder(JITDylib &JD,
1370                                 JITDylibLookupFlags JDLookupFlags) {
1371   ES.runSessionLocked([&]() { SearchOrder.push_back({&JD, JDLookupFlags}); });
1372 }
1373 
1374 void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
1375                                     JITDylibLookupFlags JDLookupFlags) {
1376   ES.runSessionLocked([&]() {
1377     for (auto &KV : SearchOrder)
1378       if (KV.first == &OldJD) {
1379         KV = {&NewJD, JDLookupFlags};
1380         break;
1381       }
1382   });
1383 }
1384 
1385 void JITDylib::removeFromSearchOrder(JITDylib &JD) {
1386   ES.runSessionLocked([&]() {
1387     auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
1388                           [&](const JITDylibSearchOrder::value_type &KV) {
1389                             return KV.first == &JD;
1390                           });
1391     if (I != SearchOrder.end())
1392       SearchOrder.erase(I);
1393   });
1394 }
1395 
1396 Error JITDylib::remove(const SymbolNameSet &Names) {
1397   return ES.runSessionLocked([&]() -> Error {
1398     using SymbolMaterializerItrPair =
1399         std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1400     std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1401     SymbolNameSet Missing;
1402     SymbolNameSet Materializing;
1403 
1404     for (auto &Name : Names) {
1405       auto I = Symbols.find(Name);
1406 
1407       // Note symbol missing.
1408       if (I == Symbols.end()) {
1409         Missing.insert(Name);
1410         continue;
1411       }
1412 
1413       // Note symbol materializing.
1414       if (I->second.isInMaterializationPhase()) {
1415         Materializing.insert(Name);
1416         continue;
1417       }
1418 
1419       auto UMII = I->second.hasMaterializerAttached()
1420                       ? UnmaterializedInfos.find(Name)
1421                       : UnmaterializedInfos.end();
1422       SymbolsToRemove.push_back(std::make_pair(I, UMII));
1423     }
1424 
1425     // If any of the symbols are not defined, return an error.
1426     if (!Missing.empty())
1427       return make_error<SymbolsNotFound>(std::move(Missing));
1428 
1429     // If any of the symbols are currently materializing, return an error.
1430     if (!Materializing.empty())
1431       return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
1432 
1433     // Remove the symbols.
1434     for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1435       auto UMII = SymbolMaterializerItrPair.second;
1436 
1437       // If there is a materializer attached, call discard.
1438       if (UMII != UnmaterializedInfos.end()) {
1439         UMII->second->MU->doDiscard(*this, UMII->first);
1440         UnmaterializedInfos.erase(UMII);
1441       }
1442 
1443       auto SymI = SymbolMaterializerItrPair.first;
1444       Symbols.erase(SymI);
1445     }
1446 
1447     return Error::success();
1448   });
1449 }
1450 
1451 Expected<SymbolFlagsMap>
1452 JITDylib::lookupFlags(LookupKind K, JITDylibLookupFlags JDLookupFlags,
1453                       SymbolLookupSet LookupSet) {
1454   return ES.runSessionLocked([&, this]() -> Expected<SymbolFlagsMap> {
1455     SymbolFlagsMap Result;
1456     lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1457 
1458     // Run any definition generators.
1459     for (auto &DG : DefGenerators) {
1460 
1461       // Bail out early if we found everything.
1462       if (LookupSet.empty())
1463         break;
1464 
1465       // Run this generator.
1466       if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, LookupSet))
1467         return std::move(Err);
1468 
1469       // Re-try the search.
1470       lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1471     }
1472 
1473     return Result;
1474   });
1475 }
1476 
1477 void JITDylib::lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K,
1478                                JITDylibLookupFlags JDLookupFlags,
1479                                SymbolLookupSet &LookupSet) {
1480 
1481   LookupSet.forEachWithRemoval(
1482       [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1483         auto I = Symbols.find(Name);
1484         if (I == Symbols.end())
1485           return false;
1486         assert(!Result.count(Name) && "Symbol already present in Flags map");
1487         Result[Name] = I->second.getFlags();
1488         return true;
1489       });
1490 }
1491 
1492 Error JITDylib::lodgeQuery(MaterializationUnitList &MUs,
1493                            std::shared_ptr<AsynchronousSymbolQuery> &Q,
1494                            LookupKind K, JITDylibLookupFlags JDLookupFlags,
1495                            SymbolLookupSet &Unresolved) {
1496   assert(Q && "Query can not be null");
1497 
1498   if (auto Err = lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved))
1499     return Err;
1500 
1501   // Run any definition generators.
1502   for (auto &DG : DefGenerators) {
1503 
1504     // Bail out early if we have resolved everything.
1505     if (Unresolved.empty())
1506       break;
1507 
1508     // Run the generator.
1509     if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, Unresolved))
1510       return Err;
1511 
1512     // Lodge query. This can not fail as any new definitions were added
1513     // by the generator under the session locked. Since they can't have
1514     // started materializing yet they can not have failed.
1515     cantFail(lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved));
1516   }
1517 
1518   return Error::success();
1519 }
1520 
1521 Error JITDylib::lodgeQueryImpl(MaterializationUnitList &MUs,
1522                                std::shared_ptr<AsynchronousSymbolQuery> &Q,
1523                                LookupKind K, JITDylibLookupFlags JDLookupFlags,
1524                                SymbolLookupSet &Unresolved) {
1525 
1526   return Unresolved.forEachWithRemoval(
1527       [&](const SymbolStringPtr &Name,
1528           SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
1529         // Search for name in symbols. If not found then continue without
1530         // removal.
1531         auto SymI = Symbols.find(Name);
1532         if (SymI == Symbols.end())
1533           return false;
1534 
1535         // If this is a non exported symbol and we're matching exported symbols
1536         // only then skip this symbol without removal.
1537         if (!SymI->second.getFlags().isExported() &&
1538             JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly)
1539           return false;
1540 
1541         // If we matched against this symbol but it is in the error state then
1542         // bail out and treat it as a failure to materialize.
1543         if (SymI->second.getFlags().hasError()) {
1544           auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1545           (*FailedSymbolsMap)[this] = {Name};
1546           return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
1547         }
1548 
1549         // If this symbol already meets the required state for then notify the
1550         // query, then remove the symbol and continue.
1551         if (SymI->second.getState() >= Q->getRequiredState()) {
1552           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1553           return true;
1554         }
1555 
1556         // Otherwise this symbol does not yet meet the required state. Check
1557         // whether it has a materializer attached, and if so prepare to run it.
1558         if (SymI->second.hasMaterializerAttached()) {
1559           assert(SymI->second.getAddress() == 0 &&
1560                  "Symbol not resolved but already has address?");
1561           auto UMII = UnmaterializedInfos.find(Name);
1562           assert(UMII != UnmaterializedInfos.end() &&
1563                  "Lazy symbol should have UnmaterializedInfo");
1564           auto MU = std::move(UMII->second->MU);
1565           assert(MU != nullptr && "Materializer should not be null");
1566 
1567           // Move all symbols associated with this MaterializationUnit into
1568           // materializing state.
1569           for (auto &KV : MU->getSymbols()) {
1570             auto SymK = Symbols.find(KV.first);
1571             SymK->second.setMaterializerAttached(false);
1572             SymK->second.setState(SymbolState::Materializing);
1573             UnmaterializedInfos.erase(KV.first);
1574           }
1575 
1576           // Add MU to the list of MaterializationUnits to be materialized.
1577           MUs.push_back(std::move(MU));
1578         }
1579 
1580         // Add the query to the PendingQueries list and continue, deleting the
1581         // element.
1582         assert(SymI->second.isInMaterializationPhase() &&
1583                "By this line the symbol should be materializing");
1584         auto &MI = MaterializingInfos[Name];
1585         MI.addQuery(Q);
1586         Q->addQueryDependence(*this, Name);
1587         return true;
1588       });
1589 }
1590 
1591 Expected<SymbolNameSet>
1592 JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
1593                        SymbolNameSet Names) {
1594   assert(Q && "Query can not be null");
1595 
1596   ES.runOutstandingMUs();
1597 
1598   bool QueryComplete = false;
1599   std::vector<std::unique_ptr<MaterializationUnit>> MUs;
1600 
1601   SymbolLookupSet Unresolved(Names);
1602   auto Err = ES.runSessionLocked([&, this]() -> Error {
1603     QueryComplete = lookupImpl(Q, MUs, Unresolved);
1604 
1605     // Run any definition generators.
1606     for (auto &DG : DefGenerators) {
1607 
1608       // Bail out early if we have resolved everything.
1609       if (Unresolved.empty())
1610         break;
1611 
1612       assert(!QueryComplete && "query complete but unresolved symbols remain?");
1613       if (auto Err = DG->tryToGenerate(LookupKind::Static, *this,
1614                                        JITDylibLookupFlags::MatchAllSymbols,
1615                                        Unresolved))
1616         return Err;
1617 
1618       if (!Unresolved.empty())
1619         QueryComplete = lookupImpl(Q, MUs, Unresolved);
1620     }
1621     return Error::success();
1622   });
1623 
1624   if (Err)
1625     return std::move(Err);
1626 
1627   assert((MUs.empty() || !QueryComplete) &&
1628          "If action flags are set, there should be no work to do (so no MUs)");
1629 
1630   if (QueryComplete)
1631     Q->handleComplete();
1632 
1633   // FIXME: Swap back to the old code below once RuntimeDyld works with
1634   //        callbacks from asynchronous queries.
1635   // Add MUs to the OutstandingMUs list.
1636   {
1637     std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex);
1638     for (auto &MU : MUs)
1639       ES.OutstandingMUs.push_back(make_pair(this, std::move(MU)));
1640   }
1641   ES.runOutstandingMUs();
1642 
1643   // Dispatch any required MaterializationUnits for materialization.
1644   // for (auto &MU : MUs)
1645   //  ES.dispatchMaterialization(*this, std::move(MU));
1646 
1647   SymbolNameSet RemainingSymbols;
1648   for (auto &KV : Unresolved)
1649     RemainingSymbols.insert(KV.first);
1650 
1651   return RemainingSymbols;
1652 }
1653 
1654 bool JITDylib::lookupImpl(
1655     std::shared_ptr<AsynchronousSymbolQuery> &Q,
1656     std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
1657     SymbolLookupSet &Unresolved) {
1658   bool QueryComplete = false;
1659 
1660   std::vector<SymbolStringPtr> ToRemove;
1661   Unresolved.forEachWithRemoval(
1662       [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1663         // Search for the name in Symbols. Skip without removing if not found.
1664         auto SymI = Symbols.find(Name);
1665         if (SymI == Symbols.end())
1666           return false;
1667 
1668         // If the symbol is already in the required state then notify the query
1669         // and remove.
1670         if (SymI->second.getState() >= Q->getRequiredState()) {
1671           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1672           if (Q->isComplete())
1673             QueryComplete = true;
1674           return true;
1675         }
1676 
1677         // If the symbol is lazy, get the MaterialiaztionUnit for it.
1678         if (SymI->second.hasMaterializerAttached()) {
1679           assert(SymI->second.getAddress() == 0 &&
1680                  "Lazy symbol should not have a resolved address");
1681           auto UMII = UnmaterializedInfos.find(Name);
1682           assert(UMII != UnmaterializedInfos.end() &&
1683                  "Lazy symbol should have UnmaterializedInfo");
1684           auto MU = std::move(UMII->second->MU);
1685           assert(MU != nullptr && "Materializer should not be null");
1686 
1687           // Kick all symbols associated with this MaterializationUnit into
1688           // materializing state.
1689           for (auto &KV : MU->getSymbols()) {
1690             auto SymK = Symbols.find(KV.first);
1691             assert(SymK != Symbols.end() && "Missing symbol table entry");
1692             SymK->second.setState(SymbolState::Materializing);
1693             SymK->second.setMaterializerAttached(false);
1694             UnmaterializedInfos.erase(KV.first);
1695           }
1696 
1697           // Add MU to the list of MaterializationUnits to be materialized.
1698           MUs.push_back(std::move(MU));
1699         }
1700 
1701         // Add the query to the PendingQueries list.
1702         assert(SymI->second.isInMaterializationPhase() &&
1703                "By this line the symbol should be materializing");
1704         auto &MI = MaterializingInfos[Name];
1705         MI.addQuery(Q);
1706         Q->addQueryDependence(*this, Name);
1707         return true;
1708       });
1709 
1710   return QueryComplete;
1711 }
1712 
1713 void JITDylib::dump(raw_ostream &OS) {
1714   ES.runSessionLocked([&, this]() {
1715     OS << "JITDylib \"" << JITDylibName << "\" (ES: "
1716        << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
1717        << "Search order: " << SearchOrder << "\n"
1718        << "Symbol table:\n";
1719 
1720     for (auto &KV : Symbols) {
1721       OS << "    \"" << *KV.first << "\": ";
1722       if (auto Addr = KV.second.getAddress())
1723         OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags()
1724            << " ";
1725       else
1726         OS << "<not resolved> ";
1727 
1728       OS << KV.second.getState();
1729 
1730       if (KV.second.hasMaterializerAttached()) {
1731         OS << " (Materializer ";
1732         auto I = UnmaterializedInfos.find(KV.first);
1733         assert(I != UnmaterializedInfos.end() &&
1734                "Lazy symbol should have UnmaterializedInfo");
1735         OS << I->second->MU.get() << ")\n";
1736       } else
1737         OS << "\n";
1738     }
1739 
1740     if (!MaterializingInfos.empty())
1741       OS << "  MaterializingInfos entries:\n";
1742     for (auto &KV : MaterializingInfos) {
1743       OS << "    \"" << *KV.first << "\":\n"
1744          << "      " << KV.second.pendingQueries().size()
1745          << " pending queries: { ";
1746       for (const auto &Q : KV.second.pendingQueries())
1747         OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1748       OS << "}\n      Dependants:\n";
1749       for (auto &KV2 : KV.second.Dependants)
1750         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1751       OS << "      Unemitted Dependencies:\n";
1752       for (auto &KV2 : KV.second.UnemittedDependencies)
1753         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1754     }
1755   });
1756 }
1757 
1758 void JITDylib::MaterializingInfo::addQuery(
1759     std::shared_ptr<AsynchronousSymbolQuery> Q) {
1760 
1761   auto I = std::lower_bound(
1762       PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1763       [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
1764         return V->getRequiredState() <= S;
1765       });
1766   PendingQueries.insert(I.base(), std::move(Q));
1767 }
1768 
1769 void JITDylib::MaterializingInfo::removeQuery(
1770     const AsynchronousSymbolQuery &Q) {
1771   // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
1772   auto I =
1773       std::find_if(PendingQueries.begin(), PendingQueries.end(),
1774                    [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
1775                      return V.get() == &Q;
1776                    });
1777   assert(I != PendingQueries.end() &&
1778          "Query is not attached to this MaterializingInfo");
1779   PendingQueries.erase(I);
1780 }
1781 
1782 JITDylib::AsynchronousSymbolQueryList
1783 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1784   AsynchronousSymbolQueryList Result;
1785   while (!PendingQueries.empty()) {
1786     if (PendingQueries.back()->getRequiredState() > RequiredState)
1787       break;
1788 
1789     Result.push_back(std::move(PendingQueries.back()));
1790     PendingQueries.pop_back();
1791   }
1792 
1793   return Result;
1794 }
1795 
1796 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1797     : ES(ES), JITDylibName(std::move(Name)) {
1798   SearchOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
1799 }
1800 
1801 Error JITDylib::defineImpl(MaterializationUnit &MU) {
1802   SymbolNameSet Duplicates;
1803   std::vector<SymbolStringPtr> ExistingDefsOverridden;
1804   std::vector<SymbolStringPtr> MUDefsOverridden;
1805 
1806   for (const auto &KV : MU.getSymbols()) {
1807     auto I = Symbols.find(KV.first);
1808 
1809     if (I != Symbols.end()) {
1810       if (KV.second.isStrong()) {
1811         if (I->second.getFlags().isStrong() ||
1812             I->second.getState() > SymbolState::NeverSearched)
1813           Duplicates.insert(KV.first);
1814         else {
1815           assert(I->second.getState() == SymbolState::NeverSearched &&
1816                  "Overridden existing def should be in the never-searched "
1817                  "state");
1818           ExistingDefsOverridden.push_back(KV.first);
1819         }
1820       } else
1821         MUDefsOverridden.push_back(KV.first);
1822     }
1823   }
1824 
1825   // If there were any duplicate definitions then bail out.
1826   if (!Duplicates.empty())
1827     return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
1828 
1829   // Discard any overridden defs in this MU.
1830   for (auto &S : MUDefsOverridden)
1831     MU.doDiscard(*this, S);
1832 
1833   // Discard existing overridden defs.
1834   for (auto &S : ExistingDefsOverridden) {
1835 
1836     auto UMII = UnmaterializedInfos.find(S);
1837     assert(UMII != UnmaterializedInfos.end() &&
1838            "Overridden existing def should have an UnmaterializedInfo");
1839     UMII->second->MU->doDiscard(*this, S);
1840   }
1841 
1842   // Finally, add the defs from this MU.
1843   for (auto &KV : MU.getSymbols()) {
1844     auto &SymEntry = Symbols[KV.first];
1845     SymEntry.setFlags(KV.second);
1846     SymEntry.setState(SymbolState::NeverSearched);
1847     SymEntry.setMaterializerAttached(true);
1848   }
1849 
1850   return Error::success();
1851 }
1852 
1853 void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
1854                                  const SymbolNameSet &QuerySymbols) {
1855   for (auto &QuerySymbol : QuerySymbols) {
1856     assert(MaterializingInfos.count(QuerySymbol) &&
1857            "QuerySymbol does not have MaterializingInfo");
1858     auto &MI = MaterializingInfos[QuerySymbol];
1859     MI.removeQuery(Q);
1860   }
1861 }
1862 
1863 void JITDylib::transferEmittedNodeDependencies(
1864     MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
1865     MaterializingInfo &EmittedMI) {
1866   for (auto &KV : EmittedMI.UnemittedDependencies) {
1867     auto &DependencyJD = *KV.first;
1868     SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
1869 
1870     for (auto &DependencyName : KV.second) {
1871       auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1872 
1873       // Do not add self dependencies.
1874       if (&DependencyMI == &DependantMI)
1875         continue;
1876 
1877       // If we haven't looked up the dependencies for DependencyJD yet, do it
1878       // now and cache the result.
1879       if (!UnemittedDependenciesOnDependencyJD)
1880         UnemittedDependenciesOnDependencyJD =
1881             &DependantMI.UnemittedDependencies[&DependencyJD];
1882 
1883       DependencyMI.Dependants[this].insert(DependantName);
1884       UnemittedDependenciesOnDependencyJD->insert(DependencyName);
1885     }
1886   }
1887 }
1888 
1889 Platform::~Platform() {}
1890 
1891 Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
1892     ExecutionSession &ES,
1893     const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1894 
1895   DenseMap<JITDylib *, SymbolMap> CompoundResult;
1896   Error CompoundErr = Error::success();
1897   std::mutex LookupMutex;
1898   std::condition_variable CV;
1899   uint64_t Count = InitSyms.size();
1900 
1901   LLVM_DEBUG({
1902     dbgs() << "Issuing init-symbol lookup:\n";
1903     for (auto &KV : InitSyms)
1904       dbgs() << "  " << KV.first->getName() << ": " << KV.second << "\n";
1905   });
1906 
1907   for (auto &KV : InitSyms) {
1908     auto *JD = KV.first;
1909     auto Names = std::move(KV.second);
1910     ES.lookup(
1911         LookupKind::Static,
1912         JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}),
1913         std::move(Names), SymbolState::Ready,
1914         [&, JD](Expected<SymbolMap> Result) {
1915           {
1916             std::lock_guard<std::mutex> Lock(LookupMutex);
1917             --Count;
1918             if (Result) {
1919               assert(!CompoundResult.count(JD) &&
1920                      "Duplicate JITDylib in lookup?");
1921               CompoundResult[JD] = std::move(*Result);
1922             } else
1923               CompoundErr =
1924                   joinErrors(std::move(CompoundErr), Result.takeError());
1925           }
1926           CV.notify_one();
1927         },
1928         NoDependenciesToRegister);
1929   }
1930 
1931   std::unique_lock<std::mutex> Lock(LookupMutex);
1932   CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
1933 
1934   if (CompoundErr)
1935     return std::move(CompoundErr);
1936 
1937   return std::move(CompoundResult);
1938 }
1939 
1940 ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP)
1941     : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {
1942 }
1943 
1944 JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) {
1945   return runSessionLocked([&, this]() -> JITDylib * {
1946     for (auto &JD : JDs)
1947       if (JD->getName() == Name)
1948         return JD.get();
1949     return nullptr;
1950   });
1951 }
1952 
1953 JITDylib &ExecutionSession::createBareJITDylib(std::string Name) {
1954   assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");
1955   return runSessionLocked([&, this]() -> JITDylib & {
1956     JDs.push_back(
1957         std::unique_ptr<JITDylib>(new JITDylib(*this, std::move(Name))));
1958     return *JDs.back();
1959   });
1960 }
1961 
1962 Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {
1963   auto &JD = createBareJITDylib(Name);
1964   if (P)
1965     if (auto Err = P->setupJITDylib(JD))
1966       return std::move(Err);
1967   return JD;
1968 }
1969 
1970 void ExecutionSession::legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err) {
1971   assert(!!Err && "Error should be in failure state");
1972 
1973   bool SendErrorToQuery;
1974   runSessionLocked([&]() {
1975     Q.detach();
1976     SendErrorToQuery = Q.canStillFail();
1977   });
1978 
1979   if (SendErrorToQuery)
1980     Q.handleFailed(std::move(Err));
1981   else
1982     reportError(std::move(Err));
1983 }
1984 
1985 Expected<SymbolMap> ExecutionSession::legacyLookup(
1986     LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
1987     SymbolState RequiredState,
1988     RegisterDependenciesFunction RegisterDependencies) {
1989 #if LLVM_ENABLE_THREADS
1990   // In the threaded case we use promises to return the results.
1991   std::promise<SymbolMap> PromisedResult;
1992   Error ResolutionError = Error::success();
1993   auto NotifyComplete = [&](Expected<SymbolMap> R) {
1994     if (R)
1995       PromisedResult.set_value(std::move(*R));
1996     else {
1997       ErrorAsOutParameter _(&ResolutionError);
1998       ResolutionError = R.takeError();
1999       PromisedResult.set_value(SymbolMap());
2000     }
2001   };
2002 #else
2003   SymbolMap Result;
2004   Error ResolutionError = Error::success();
2005 
2006   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2007     ErrorAsOutParameter _(&ResolutionError);
2008     if (R)
2009       Result = std::move(*R);
2010     else
2011       ResolutionError = R.takeError();
2012   };
2013 #endif
2014 
2015   auto Query = std::make_shared<AsynchronousSymbolQuery>(
2016       SymbolLookupSet(Names), RequiredState, std::move(NotifyComplete));
2017   // FIXME: This should be run session locked along with the registration code
2018   // and error reporting below.
2019   SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
2020 
2021   // If the query was lodged successfully then register the dependencies,
2022   // otherwise fail it with an error.
2023   if (UnresolvedSymbols.empty())
2024     RegisterDependencies(Query->QueryRegistrations);
2025   else {
2026     bool DeliverError = runSessionLocked([&]() {
2027       Query->detach();
2028       return Query->canStillFail();
2029     });
2030     auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols));
2031     if (DeliverError)
2032       Query->handleFailed(std::move(Err));
2033     else
2034       reportError(std::move(Err));
2035   }
2036 
2037 #if LLVM_ENABLE_THREADS
2038   auto ResultFuture = PromisedResult.get_future();
2039   auto Result = ResultFuture.get();
2040   if (ResolutionError)
2041     return std::move(ResolutionError);
2042   return std::move(Result);
2043 
2044 #else
2045   if (ResolutionError)
2046     return std::move(ResolutionError);
2047 
2048   return Result;
2049 #endif
2050 }
2051 
2052 void ExecutionSession::lookup(
2053     LookupKind K, const JITDylibSearchOrder &SearchOrder,
2054     SymbolLookupSet Symbols, SymbolState RequiredState,
2055     SymbolsResolvedCallback NotifyComplete,
2056     RegisterDependenciesFunction RegisterDependencies) {
2057 
2058   LLVM_DEBUG({
2059     runSessionLocked([&]() {
2060       dbgs() << "Looking up " << Symbols << " in " << SearchOrder
2061              << " (required state: " << RequiredState << ")\n";
2062     });
2063   });
2064 
2065   // lookup can be re-entered recursively if running on a single thread. Run any
2066   // outstanding MUs in case this query depends on them, otherwise this lookup
2067   // will starve waiting for a result from an MU that is stuck in the queue.
2068   runOutstandingMUs();
2069 
2070   auto Unresolved = std::move(Symbols);
2071   std::map<JITDylib *, MaterializationUnitList> CollectedMUsMap;
2072   auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
2073                                                      std::move(NotifyComplete));
2074   bool QueryComplete = false;
2075 
2076   auto LodgingErr = runSessionLocked([&]() -> Error {
2077     auto LodgeQuery = [&]() -> Error {
2078       for (auto &KV : SearchOrder) {
2079         assert(KV.first && "JITDylibList entries must not be null");
2080         assert(!CollectedMUsMap.count(KV.first) &&
2081                "JITDylibList should not contain duplicate entries");
2082 
2083         auto &JD = *KV.first;
2084         auto JDLookupFlags = KV.second;
2085         if (auto Err = JD.lodgeQuery(CollectedMUsMap[&JD], Q, K, JDLookupFlags,
2086                                      Unresolved))
2087           return Err;
2088       }
2089 
2090       // Strip any weakly referenced symbols that were not found.
2091       Unresolved.forEachWithRemoval(
2092           [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) {
2093             if (Flags == SymbolLookupFlags::WeaklyReferencedSymbol) {
2094               Q->dropSymbol(Name);
2095               return true;
2096             }
2097             return false;
2098           });
2099 
2100       if (!Unresolved.empty())
2101         return make_error<SymbolsNotFound>(Unresolved.getSymbolNames());
2102 
2103       return Error::success();
2104     };
2105 
2106     if (auto Err = LodgeQuery()) {
2107       // Query failed.
2108 
2109       // Disconnect the query from its dependencies.
2110       Q->detach();
2111 
2112       // Replace the MUs.
2113       for (auto &KV : CollectedMUsMap)
2114         for (auto &MU : KV.second)
2115           KV.first->replace(std::move(MU));
2116 
2117       return Err;
2118     }
2119 
2120     // Query lodged successfully.
2121 
2122     // Record whether this query is fully ready / resolved. We will use
2123     // this to call handleFullyResolved/handleFullyReady outside the session
2124     // lock.
2125     QueryComplete = Q->isComplete();
2126 
2127     // Call the register dependencies function.
2128     if (RegisterDependencies && !Q->QueryRegistrations.empty())
2129       RegisterDependencies(Q->QueryRegistrations);
2130 
2131     return Error::success();
2132   });
2133 
2134   if (LodgingErr) {
2135     Q->handleFailed(std::move(LodgingErr));
2136     return;
2137   }
2138 
2139   if (QueryComplete)
2140     Q->handleComplete();
2141 
2142   // Move the MUs to the OutstandingMUs list, then materialize.
2143   {
2144     std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2145 
2146     for (auto &KV : CollectedMUsMap)
2147       for (auto &MU : KV.second)
2148         OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU)));
2149   }
2150 
2151   runOutstandingMUs();
2152 }
2153 
2154 Expected<SymbolMap>
2155 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2156                          const SymbolLookupSet &Symbols, LookupKind K,
2157                          SymbolState RequiredState,
2158                          RegisterDependenciesFunction RegisterDependencies) {
2159 #if LLVM_ENABLE_THREADS
2160   // In the threaded case we use promises to return the results.
2161   std::promise<SymbolMap> PromisedResult;
2162   Error ResolutionError = Error::success();
2163 
2164   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2165     if (R)
2166       PromisedResult.set_value(std::move(*R));
2167     else {
2168       ErrorAsOutParameter _(&ResolutionError);
2169       ResolutionError = R.takeError();
2170       PromisedResult.set_value(SymbolMap());
2171     }
2172   };
2173 
2174 #else
2175   SymbolMap Result;
2176   Error ResolutionError = Error::success();
2177 
2178   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2179     ErrorAsOutParameter _(&ResolutionError);
2180     if (R)
2181       Result = std::move(*R);
2182     else
2183       ResolutionError = R.takeError();
2184   };
2185 #endif
2186 
2187   // Perform the asynchronous lookup.
2188   lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
2189          RegisterDependencies);
2190 
2191 #if LLVM_ENABLE_THREADS
2192   auto ResultFuture = PromisedResult.get_future();
2193   auto Result = ResultFuture.get();
2194 
2195   if (ResolutionError)
2196     return std::move(ResolutionError);
2197 
2198   return std::move(Result);
2199 
2200 #else
2201   if (ResolutionError)
2202     return std::move(ResolutionError);
2203 
2204   return Result;
2205 #endif
2206 }
2207 
2208 Expected<JITEvaluatedSymbol>
2209 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2210                          SymbolStringPtr Name, SymbolState RequiredState) {
2211   SymbolLookupSet Names({Name});
2212 
2213   if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
2214                               RequiredState, NoDependenciesToRegister)) {
2215     assert(ResultMap->size() == 1 && "Unexpected number of results");
2216     assert(ResultMap->count(Name) && "Missing result for symbol");
2217     return std::move(ResultMap->begin()->second);
2218   } else
2219     return ResultMap.takeError();
2220 }
2221 
2222 Expected<JITEvaluatedSymbol>
2223 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,
2224                          SymbolState RequiredState) {
2225   return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
2226 }
2227 
2228 Expected<JITEvaluatedSymbol>
2229 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,
2230                          SymbolState RequiredState) {
2231   return lookup(SearchOrder, intern(Name), RequiredState);
2232 }
2233 
2234 void ExecutionSession::dump(raw_ostream &OS) {
2235   runSessionLocked([this, &OS]() {
2236     for (auto &JD : JDs)
2237       JD->dump(OS);
2238   });
2239 }
2240 
2241 void ExecutionSession::runOutstandingMUs() {
2242   while (1) {
2243     std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>> JITDylibAndMU;
2244 
2245     {
2246       std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2247       if (!OutstandingMUs.empty()) {
2248         JITDylibAndMU = std::move(OutstandingMUs.back());
2249         OutstandingMUs.pop_back();
2250       }
2251     }
2252 
2253     if (JITDylibAndMU.first) {
2254       assert(JITDylibAndMU.second && "JITDylib, but no MU?");
2255       dispatchMaterialization(*JITDylibAndMU.first,
2256                               std::move(JITDylibAndMU.second));
2257     } else
2258       break;
2259   }
2260 }
2261 
2262 } // End namespace orc.
2263 } // End namespace llvm.
2264