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