summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h31
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/Core.h390
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h13
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/Speculation.h35
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLink.cpp10
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp27
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h2
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp27
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Core.cpp637
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp84
-rw-r--r--llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp5
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LLJIT.cpp4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp6
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Legacy.cpp3
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp27
-rw-r--r--llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp13
-rw-r--r--llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_references.s19
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink.cpp12
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp198
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp9
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp11
22 files changed, 1007 insertions, 560 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index aebd55563e6..7470cca4980 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -324,14 +324,14 @@ private:
}
static Symbol &constructExternal(void *SymStorage, Addressable &Base,
- StringRef Name, JITTargetAddress Size) {
+ StringRef Name, JITTargetAddress Size,
+ Linkage L) {
assert(SymStorage && "Storage cannot be null");
assert(!Base.isDefined() &&
"Cannot create external symbol from defined block");
assert(!Name.empty() && "External symbol name cannot be empty");
auto *Sym = reinterpret_cast<Symbol *>(SymStorage);
- new (Sym) Symbol(Base, 0, Name, Size, Linkage::Strong, Scope::Default,
- false, false);
+ new (Sym) Symbol(Base, 0, Name, Size, L, Scope::Default, false, false);
return *Sym;
}
@@ -477,7 +477,7 @@ public:
/// Set the linkage for this Symbol.
void setLinkage(Linkage L) {
- assert((L == Linkage::Strong || (Base->isDefined() && !Name.empty())) &&
+ assert((L == Linkage::Strong || (!Base->isAbsolute() && !Name.empty())) &&
"Linkage can only be applied to defined named symbols");
this->L = static_cast<uint8_t>(L);
}
@@ -849,9 +849,14 @@ public:
/// Add an external symbol.
/// Some formats (e.g. ELF) allow Symbols to have sizes. For Symbols whose
/// size is not known, you should substitute '0'.
- Symbol &addExternalSymbol(StringRef Name, uint64_t Size) {
- auto &Sym = Symbol::constructExternal(
- Allocator.Allocate<Symbol>(), createAddressable(0, false), Name, Size);
+ /// For external symbols Linkage determines whether the symbol must be
+ /// present during lookup: Externals with strong linkage must be found or
+ /// an error will be emitted. Externals with weak linkage are permitted to
+ /// be undefined, in which case they are assigned a value of 0.
+ Symbol &addExternalSymbol(StringRef Name, uint64_t Size, Linkage L) {
+ auto &Sym =
+ Symbol::constructExternal(Allocator.Allocate<Symbol>(),
+ createAddressable(0, false), Name, Size, L);
ExternalSymbols.insert(&Sym);
return Sym;
}
@@ -1189,6 +1194,14 @@ struct PassConfiguration {
LinkGraphPassList PostFixupPasses;
};
+/// Flags for symbol lookup.
+///
+/// FIXME: These basically duplicate orc::SymbolLookupFlags -- We should merge
+/// the two types once we have an OrcSupport library.
+enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol };
+
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF);
+
/// A map of symbol names to resolved addresses.
using AsyncLookupResult = DenseMap<StringRef, JITEvaluatedSymbol>;
@@ -1223,6 +1236,8 @@ createLookupContinuation(Continuation Cont) {
/// Holds context for a single jitLink invocation.
class JITLinkContext {
public:
+ using LookupMap = DenseMap<StringRef, SymbolLookupFlags>;
+
/// Destroy a JITLinkContext.
virtual ~JITLinkContext();
@@ -1240,7 +1255,7 @@ public:
/// Called by JITLink to resolve external symbols. This method is passed a
/// lookup continutation which it must call with a result to continue the
/// linking process.
- virtual void lookup(const DenseSet<StringRef> &Symbols,
+ virtual void lookup(const LookupMap &Symbols,
std::unique_ptr<JITLinkAsyncLookupContinuation> LC) = 0;
/// Called by JITLink once all defined symbols in the graph have been assigned
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
index 4f22a4c3879..8f92b7ab766 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -45,8 +45,11 @@ using VModuleKey = uint64_t;
// efficiency).
using SymbolNameSet = DenseSet<SymbolStringPtr>;
+/// A vector of symbol names.
+using SymbolNameVector = std::vector<SymbolStringPtr>;
+
/// A map from symbol names (as SymbolStringPtrs) to JITSymbols
-/// (address/flags pairs).
+/// (address/flags pairs).
using SymbolMap = DenseMap<SymbolStringPtr, JITEvaluatedSymbol>;
/// A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
@@ -55,8 +58,244 @@ using SymbolFlagsMap = DenseMap<SymbolStringPtr, JITSymbolFlags>;
/// A map from JITDylibs to sets of symbols.
using SymbolDependenceMap = DenseMap<JITDylib *, SymbolNameSet>;
-/// A list of (JITDylib*, bool) pairs.
-using JITDylibSearchList = std::vector<std::pair<JITDylib *, bool>>;
+/// Lookup flags that apply to each dylib in the search order for a lookup.
+///
+/// If MatchHiddenSymbolsOnly is used (the default) for a given dylib, then
+/// only symbols in that Dylib's interface will be searched. If
+/// MatchHiddenSymbols is used then symbols with hidden visibility will match
+/// as well.
+enum class JITDylibLookupFlags { MatchExportedSymbolsOnly, MatchAllSymbols };
+
+/// Lookup flags that apply to each symbol in a lookup.
+///
+/// If RequiredSymbol is used (the default) for a given symbol then that symbol
+/// must be found during the lookup or the lookup will fail returning a
+/// SymbolNotFound error. If WeaklyReferencedSymbol is used and the given
+/// symbol is not found then the query will continue, and no result for the
+/// missing symbol will be present in the result (assuming the rest of the
+/// lookup succeeds).
+enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol };
+
+/// Describes the kind of lookup being performed. The lookup kind is passed to
+/// symbol generators (if they're invoked) to help them determine what
+/// definitions to generate.
+///
+/// Static -- Lookup is being performed as-if at static link time (e.g.
+/// generators representing static archives should pull in new
+/// definitions).
+///
+/// DLSym -- Lookup is being performed as-if at runtime (e.g. generators
+/// representing static archives should not pull in new definitions).
+enum class LookupKind { Static, DLSym };
+
+/// A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search
+/// order during symbol lookup.
+using JITDylibSearchOrder =
+ std::vector<std::pair<JITDylib *, JITDylibLookupFlags>>;
+
+/// Convenience function for creating a search order from an ArrayRef of
+/// JITDylib*, all with the same flags.
+inline JITDylibSearchOrder makeJITDylibSearchOrder(
+ ArrayRef<JITDylib *> JDs,
+ JITDylibLookupFlags Flags = JITDylibLookupFlags::MatchExportedSymbolsOnly) {
+ JITDylibSearchOrder O;
+ O.reserve(JDs.size());
+ for (auto *JD : JDs)
+ O.push_back(std::make_pair(JD, Flags));
+ return O;
+}
+
+/// A set of symbols to look up, each associated with a SymbolLookupFlags
+/// value.
+///
+/// This class is backed by a vector and optimized for fast insertion,
+/// deletion and iteration. It does not guarantee a stable order between
+/// operations, and will not automatically detect duplicate elements (they
+/// can be manually checked by calling the validate method).
+class SymbolLookupSet {
+public:
+ using value_type = std::pair<SymbolStringPtr, SymbolLookupFlags>;
+ using UnderlyingVector = std::vector<value_type>;
+ using iterator = UnderlyingVector::iterator;
+ using const_iterator = UnderlyingVector::const_iterator;
+
+ SymbolLookupSet() = default;
+
+ explicit SymbolLookupSet(
+ SymbolStringPtr Name,
+ SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+ add(std::move(Name), Flags);
+ }
+
+ /// Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
+ explicit SymbolLookupSet(
+ std::initializer_list<SymbolStringPtr> Names,
+ SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+ Symbols.reserve(Names.size());
+ for (auto &Name : Names)
+ add(std::move(Name), Flags);
+ }
+
+ /// Construct a SymbolLookupSet from a SymbolNameSet with the given
+ /// Flags used for each value.
+ explicit SymbolLookupSet(
+ const SymbolNameSet &Names,
+ SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+ Symbols.reserve(Names.size());
+ for (const auto &Name : Names)
+ add(Name, Flags);
+ }
+
+ /// Construct a SymbolLookupSet from a vector of symbols with the given Flags
+ /// used for each value.
+ /// If the ArrayRef contains duplicates it is up to the client to remove these
+ /// before using this instance for lookup.
+ explicit SymbolLookupSet(
+ ArrayRef<SymbolStringPtr> Names,
+ SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+ Symbols.reserve(Names.size());
+ for (const auto &Name : Names)
+ add(Name, Flags);
+ }
+
+ /// Add an element to the set. The client is responsible for checking that
+ /// duplicates are not added.
+ void add(SymbolStringPtr Name,
+ SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
+ Symbols.push_back(std::make_pair(std::move(Name), Flags));
+ }
+
+ bool empty() const { return Symbols.empty(); }
+ UnderlyingVector::size_type size() const { return Symbols.size(); }
+ iterator begin() { return Symbols.begin(); }
+ iterator end() { return Symbols.end(); }
+ const_iterator begin() const { return Symbols.begin(); }
+ const_iterator end() const { return Symbols.end(); }
+
+ /// Removes the Ith element of the vector, replacing it with the last element.
+ void remove(UnderlyingVector::size_type I) {
+ std::swap(Symbols[I], Symbols.back());
+ Symbols.pop_back();
+ }
+
+ /// Removes the element pointed to by the given iterator. This iterator and
+ /// all subsequent ones (including end()) are invalidated.
+ void remove(iterator I) { remove(I - begin()); }
+
+ /// Removes all elements matching the given predicate, which must be callable
+ /// as bool(const SymbolStringPtr &, SymbolLookupFlags Flags).
+ template <typename PredFn> void remove_if(PredFn &&Pred) {
+ UnderlyingVector::size_type I = 0;
+ while (I != Symbols.size()) {
+ const auto &Name = Symbols[I].first;
+ auto Flags = Symbols[I].second;
+ if (Pred(Name, Flags))
+ remove(I);
+ else
+ ++I;
+ }
+ }
+
+ /// Loop over the elements of this SymbolLookupSet, applying the Body function
+ /// to each one. Body must be callable as
+ /// bool(const SymbolStringPtr &, SymbolLookupFlags).
+ /// If Body returns true then the element just passed in is removed from the
+ /// set. If Body returns false then the element is retained.
+ template <typename BodyFn>
+ auto forEachWithRemoval(BodyFn &&Body) -> typename std::enable_if<
+ std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
+ std::declval<SymbolLookupFlags>())),
+ bool>::value>::type {
+ UnderlyingVector::size_type I = 0;
+ while (I != Symbols.size()) {
+ const auto &Name = Symbols[I].first;
+ auto Flags = Symbols[I].second;
+ if (Body(Name, Flags))
+ remove(I);
+ else
+ ++I;
+ }
+ }
+
+ /// Loop over the elements of this SymbolLookupSet, applying the Body function
+ /// to each one. Body must be callable as
+ /// Expected<bool>(const SymbolStringPtr &, SymbolLookupFlags).
+ /// If Body returns a failure value, the loop exits immediately. If Body
+ /// returns true then the element just passed in is removed from the set. If
+ /// Body returns false then the element is retained.
+ template <typename BodyFn>
+ auto forEachWithRemoval(BodyFn &&Body) -> typename std::enable_if<
+ std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
+ std::declval<SymbolLookupFlags>())),
+ Expected<bool>>::value,
+ Error>::type {
+ UnderlyingVector::size_type I = 0;
+ while (I != Symbols.size()) {
+ const auto &Name = Symbols[I].first;
+ auto Flags = Symbols[I].second;
+ auto Remove = Body(Name, Flags);
+ if (!Remove)
+ return Remove.takeError();
+ if (*Remove)
+ remove(I);
+ else
+ ++I;
+ }
+ return Error::success();
+ }
+
+ /// Construct a SymbolNameVector from this instance by dropping the Flags
+ /// values.
+ SymbolNameVector getSymbolNames() const {
+ SymbolNameVector Names;
+ Names.reserve(Symbols.size());
+ for (auto &KV : Symbols)
+ Names.push_back(KV.first);
+ return Names;
+ }
+
+ /// Sort the lookup set by pointer value. This sort is fast but sensitive to
+ /// allocation order and so should not be used where a consistent order is
+ /// required.
+ void sortByAddress() {
+ llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
+ return LHS.first < RHS.first;
+ });
+ }
+
+ /// Sort the lookup set lexicographically. This sort is slow but the order
+ /// is unaffected by allocation order.
+ void sortByName() {
+ llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
+ return *LHS.first < *RHS.first;
+ });
+ }
+
+ /// Remove any duplicate elements. If a SymbolLookupSet is not duplicate-free
+ /// by construction, this method can be used to turn it into a proper set.
+ void removeDuplicates() {
+ sortByAddress();
+ auto LastI = std::unique(Symbols.begin(), Symbols.end());
+ Symbols.erase(LastI, Symbols.end());
+ }
+
+#ifndef NDEBUG
+ /// Returns true if this set contains any duplicates. This should only be used
+ /// in assertions.
+ bool containsDuplicates() {
+ if (Symbols.size() < 2)
+ return false;
+ sortByAddress();
+ for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
+ if (Symbols[I].first == Symbols[I - 1].first)
+ return true;
+ return true;
+ }
+#endif
+
+private:
+ UnderlyingVector Symbols;
+};
struct SymbolAliasMapEntry {
SymbolAliasMapEntry() = default;
@@ -76,6 +315,9 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
/// Render a SymbolNameSet.
raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols);
+/// Render a SymbolNameVector.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols);
+
/// Render a SymbolFlagsMap entry.
raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV);
@@ -98,8 +340,25 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
/// Render a MaterializationUnit.
raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU);
-/// Render a JITDylibSearchList.
-raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs);
+//// Render a JITDylibLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS,
+ const JITDylibLookupFlags &JDLookupFlags);
+
+/// Rendar a SymbolLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags);
+
+/// Render a JITDylibLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
+
+/// Render a SymbolLookupSet entry.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet::value_type &KV);
+
+/// Render a SymbolLookupSet.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet);
+
+/// Render a JITDylibSearchOrder.
+raw_ostream &operator<<(raw_ostream &OS,
+ const JITDylibSearchOrder &SearchOrder);
/// Render a SymbolAliasMap.
raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
@@ -107,6 +366,9 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
/// Render a SymbolState.
raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
+/// Render a LookupKind.
+raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
+
/// Callback to notify client that symbols have been resolved.
using SymbolsResolvedCallback = unique_function<void(Expected<SymbolMap>)>;
@@ -139,12 +401,13 @@ public:
static char ID;
SymbolsNotFound(SymbolNameSet Symbols);
+ SymbolsNotFound(SymbolNameVector Symbols);
std::error_code convertToErrorCode() const override;
void log(raw_ostream &OS) const override;
- const SymbolNameSet &getSymbols() const { return Symbols; }
+ const SymbolNameVector &getSymbols() const { return Symbols; }
private:
- SymbolNameSet Symbols;
+ SymbolNameVector Symbols;
};
/// Used to notify clients that a set of symbols could not be removed.
@@ -376,7 +639,8 @@ public:
/// Note: Care must be taken that no sets of aliases form a cycle, as such
/// a cycle will result in a deadlock when any symbol in the cycle is
/// resolved.
- ReExportsMaterializationUnit(JITDylib *SourceJD, bool MatchNonExported,
+ ReExportsMaterializationUnit(JITDylib *SourceJD,
+ JITDylibLookupFlags SourceJDLookupFlags,
SymbolAliasMap Aliases, VModuleKey K);
StringRef getName() const override;
@@ -387,7 +651,7 @@ private:
static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
JITDylib *SourceJD = nullptr;
- bool MatchNonExported = false;
+ JITDylibLookupFlags SourceJDLookupFlags;
SymbolAliasMap Aliases;
};
@@ -405,25 +669,26 @@ private:
inline std::unique_ptr<ReExportsMaterializationUnit>
symbolAliases(SymbolAliasMap Aliases, VModuleKey K = VModuleKey()) {
return std::make_unique<ReExportsMaterializationUnit>(
- nullptr, true, std::move(Aliases), std::move(K));
+ nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases),
+ std::move(K));
}
/// Create a materialization unit for re-exporting symbols from another JITDylib
/// with alternative names/flags.
-/// If MatchNonExported is true then non-exported symbols from SourceJD can be
-/// re-exported. If it is false, attempts to re-export a non-exported symbol
-/// will result in a "symbol not found" error.
+/// SourceJD will be searched using the given JITDylibLookupFlags.
inline std::unique_ptr<ReExportsMaterializationUnit>
reexports(JITDylib &SourceJD, SymbolAliasMap Aliases,
- bool MatchNonExported = false, VModuleKey K = VModuleKey()) {
+ JITDylibLookupFlags SourceJDLookupFlags =
+ JITDylibLookupFlags::MatchExportedSymbolsOnly,
+ VModuleKey K = VModuleKey()) {
return std::make_unique<ReExportsMaterializationUnit>(
- &SourceJD, MatchNonExported, std::move(Aliases), std::move(K));
+ &SourceJD, SourceJDLookupFlags, std::move(Aliases), std::move(K));
}
/// Build a SymbolAliasMap for the common case where you want to re-export
/// symbols from another JITDylib with the same linkage/flags.
Expected<SymbolAliasMap>
-buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols);
+buildSimpleReexportsAAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols);
/// Represents the state that a symbol has reached during materialization.
enum class SymbolState : uint8_t {
@@ -448,7 +713,7 @@ public:
/// Create a query for the given symbols. The NotifyComplete
/// callback will be called once all queried symbols reach the given
/// minimum state.
- AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
+ AsynchronousSymbolQuery(const SymbolLookupSet &Symbols,
SymbolState RequiredState,
SymbolsResolvedCallback NotifyComplete);
@@ -456,6 +721,15 @@ public:
void notifySymbolMetRequiredState(const SymbolStringPtr &Name,
JITEvaluatedSymbol Sym);
+ /// Remove a symbol from the query. This is used to drop weakly referenced
+ /// symbols that are not found.
+ void dropSymbol(const SymbolStringPtr &Name) {
+ assert(ResolvedSymbols.count(Name) &&
+ "Redundant removal of weakly-referenced symbol");
+ ResolvedSymbols.erase(Name);
+ --OutstandingSymbolsCount;
+ }
+
/// Returns true if all symbols covered by this query have been
/// resolved.
bool isComplete() const { return OutstandingSymbolsCount == 0; }
@@ -497,11 +771,21 @@ class JITDylib {
friend class ExecutionSession;
friend class MaterializationResponsibility;
public:
+ /// Definition generators can be attached to JITDylibs to generate new
+ /// definitions for otherwise unresolved symbols during lookup.
class DefinitionGenerator {
public:
virtual ~DefinitionGenerator();
- virtual Expected<SymbolNameSet>
- tryToGenerate(JITDylib &Parent, const SymbolNameSet &Names) = 0;
+
+ /// DefinitionGenerators should override this method to insert new
+ /// definitions into the parent JITDylib. K specifies the kind of this
+ /// lookup. JD specifies the target JITDylib being searched, and
+ /// JDLookupFlags specifies whether the search should match against
+ /// hidden symbols. Finally, Symbols describes the set of unresolved
+ /// symbols and their associated lookup flags.
+ virtual Error tryToGenerate(LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) = 0;
};
using AsynchronousSymbolQuerySet =
@@ -552,18 +836,20 @@ public:
/// as the first in the search order (instead of this dylib) ensures that
/// definitions within this dylib resolve to the lazy-compiling stubs,
/// rather than immediately materializing the definitions in this dylib.
- void setSearchOrder(JITDylibSearchList NewSearchOrder,
- bool SearchThisJITDylibFirst = true,
- bool MatchNonExportedInThisDylib = true);
+ void setSearchOrder(JITDylibSearchOrder NewSearchOrder,
+ bool SearchThisJITDylibFirst = true);
/// Add the given JITDylib to the search order for definitions in this
/// JITDylib.
- void addToSearchOrder(JITDylib &JD, bool MatcNonExported = false);
+ void addToSearchOrder(JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags =
+ JITDylibLookupFlags::MatchExportedSymbolsOnly);
/// Replace OldJD with NewJD in the search order if OldJD is present.
/// Otherwise this operation is a no-op.
void replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
- bool MatchNonExported = false);
+ JITDylibLookupFlags JDLookupFlags =
+ JITDylibLookupFlags::MatchExportedSymbolsOnly);
/// Remove the given JITDylib from the search order for this JITDylib if it is
/// present. Otherwise this operation is a no-op.
@@ -572,7 +858,7 @@ public:
/// Do something with the search order (run under the session lock).
template <typename Func>
auto withSearchOrderDo(Func &&F)
- -> decltype(F(std::declval<const JITDylibSearchList &>()));
+ -> decltype(F(std::declval<const JITDylibSearchOrder &>()));
/// Define all symbols provided by the materialization unit to be part of this
/// JITDylib.
@@ -605,8 +891,11 @@ public:
Error remove(const SymbolNameSet &Names);
/// Search the given JITDylib for the symbols in Symbols. If found, store
- /// the flags for each symbol in Flags. Returns any unresolved symbols.
- Expected<SymbolFlagsMap> lookupFlags(const SymbolNameSet &Names);
+ /// the flags for each symbol in Flags. If any required symbols are not found
+ /// then an error will be returned.
+ Expected<SymbolFlagsMap> lookupFlags(LookupKind K,
+ JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet LookupSet);
/// Dump current JITDylib state to OS.
void dump(raw_ostream &OS);
@@ -709,20 +998,23 @@ private:
Error defineImpl(MaterializationUnit &MU);
- Expected<SymbolNameSet> lookupFlagsImpl(SymbolFlagsMap &Flags,
- const SymbolNameSet &Names);
+ void lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K,
+ JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &Unresolved);
- Error lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved, bool MatchNonExported,
- MaterializationUnitList &MUs);
+ Error lodgeQuery(MaterializationUnitList &MUs,
+ std::shared_ptr<AsynchronousSymbolQuery> &Q, LookupKind K,
+ JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &Unresolved);
- Error lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved, bool MatchNonExported,
- MaterializationUnitList &MUs);
+ Error lodgeQueryImpl(MaterializationUnitList &MUs,
+ std::shared_ptr<AsynchronousSymbolQuery> &Q,
+ LookupKind K, JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &Unresolved);
bool lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
- SymbolNameSet &Unresolved);
+ SymbolLookupSet &Unresolved);
void detachQueryHelper(AsynchronousSymbolQuery &Q,
const SymbolNameSet &QuerySymbols);
@@ -754,7 +1046,7 @@ private:
UnmaterializedInfosMap UnmaterializedInfos;
MaterializingInfosMap MaterializingInfos;
std::vector<std::unique_ptr<DefinitionGenerator>> DefGenerators;
- JITDylibSearchList SearchOrder;
+ JITDylibSearchOrder SearchOrder;
};
/// An ExecutionSession represents a running JIT program.
@@ -863,8 +1155,9 @@ public:
/// dependenant symbols for this query (e.g. it is being made by a top level
/// client to get an address to call) then the value NoDependenciesToRegister
/// can be used.
- void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
- SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete,
+ void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder,
+ SymbolLookupSet Symbols, SymbolState RequiredState,
+ SymbolsResolvedCallback NotifyComplete,
RegisterDependenciesFunction RegisterDependencies);
/// Blocking version of lookup above. Returns the resolved symbol map.
@@ -874,8 +1167,9 @@ public:
/// or an error occurs. If WaitUntilReady is false and an error occurs
/// after resolution, the function will return a success value, but the
/// error will be reported via reportErrors.
- Expected<SymbolMap> lookup(const JITDylibSearchList &SearchOrder,
- const SymbolNameSet &Symbols,
+ Expected<SymbolMap> lookup(const JITDylibSearchOrder &SearchOrder,
+ const SymbolLookupSet &Symbols,
+ LookupKind K = LookupKind::Static,
SymbolState RequiredState = SymbolState::Ready,
RegisterDependenciesFunction RegisterDependencies =
NoDependenciesToRegister);
@@ -883,7 +1177,7 @@ public:
/// Convenience version of blocking lookup.
/// Searches each of the JITDylibs in the search order in turn for the given
/// symbol.
- Expected<JITEvaluatedSymbol> lookup(const JITDylibSearchList &SearchOrder,
+ Expected<JITEvaluatedSymbol> lookup(const JITDylibSearchOrder &SearchOrder,
SymbolStringPtr Symbol);
/// Convenience version of blocking lookup.
@@ -951,7 +1245,7 @@ GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) {
template <typename Func>
auto JITDylib::withSearchOrderDo(Func &&F)
- -> decltype(F(std::declval<const JITDylibSearchList &>())) {
+ -> decltype(F(std::declval<const JITDylibSearchOrder &>())) {
return ES.runSessionLocked([&]() { return F(SearchOrder); });
}
@@ -997,15 +1291,17 @@ public:
/// Create a reexports generator. If an Allow predicate is passed, only
/// symbols for which the predicate returns true will be reexported. If no
/// Allow predicate is passed, all symbols will be exported.
- ReexportsGenerator(JITDylib &SourceJD, bool MatchNonExported = false,
+ ReexportsGenerator(JITDylib &SourceJD,
+ JITDylibLookupFlags SourceJDLookupFlags,
SymbolPredicate Allow = SymbolPredicate());
- Expected<SymbolNameSet> tryToGenerate(JITDylib &JD,
- const SymbolNameSet &Names) override;
+ Error tryToGenerate(LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) override;
private:
JITDylib &SourceJD;
- bool MatchNonExported = false;
+ JITDylibLookupFlags SourceJDLookupFlags;
SymbolPredicate Allow;
};
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index b9bbace6f63..7d051ed9906 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -268,8 +268,9 @@ public:
return Load(nullptr, GlobalPrefix, std::move(Allow));
}
- Expected<SymbolNameSet> tryToGenerate(JITDylib &JD,
- const SymbolNameSet &Names) override;
+ Error tryToGenerate(LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &Symbols) override;
private:
sys::DynamicLibrary Dylib;
@@ -297,8 +298,9 @@ public:
static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer);
- Expected<SymbolNameSet> tryToGenerate(JITDylib &JD,
- const SymbolNameSet &Names) override;
+ Error tryToGenerate(LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &Symbols) override;
private:
StaticLibraryDefinitionGenerator(ObjectLayer &L,
@@ -307,8 +309,7 @@ private:
ObjectLayer &L;
std::unique_ptr<MemoryBuffer> ArchiveBuffer;
- object::Archive Archive;
- size_t UnrealizedObjects = 0;
+ std::unique_ptr<object::Archive> Archive;
};
} // end namespace orc
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
index 766a6b070f1..f6b86bb2316 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
@@ -100,23 +100,27 @@ private:
SymbolsInJD.insert(ImplSymbolName);
}
- DEBUG_WITH_TYPE("orc", for (auto &I
- : SpeculativeLookUpImpls) {
- llvm::dbgs() << "\n In " << I.first->getName() << " JITDylib ";
- for (auto &N : I.second)
- llvm::dbgs() << "\n Likely Symbol : " << N;
+ DEBUG_WITH_TYPE("orc", {
+ for (auto &I : SpeculativeLookUpImpls) {
+ llvm::dbgs() << "\n In " << I.first->getName() << " JITDylib ";
+ for (auto &N : I.second)
+ llvm::dbgs() << "\n Likely Symbol : " << N;
+ }
});
// for a given symbol, there may be no symbol qualified for speculatively
// compile try to fix this before jumping to this code if possible.
for (auto &LookupPair : SpeculativeLookUpImpls)
- ES.lookup(JITDylibSearchList({{LookupPair.first, true}}),
- LookupPair.second, SymbolState::Ready,
- [this](Expected<SymbolMap> Result) {
- if (auto Err = Result.takeError())
- ES.reportError(std::move(Err));
- },
- NoDependenciesToRegister);
+ ES.lookup(
+ LookupKind::Static,
+ makeJITDylibSearchOrder(LookupPair.first,
+ JITDylibLookupFlags::MatchAllSymbols),
+ SymbolLookupSet(LookupPair.second), SymbolState::Ready,
+ [this](Expected<SymbolMap> Result) {
+ if (auto Err = Result.takeError())
+ ES.reportError(std::move(Err));
+ },
+ NoDependenciesToRegister);
}
public:
@@ -151,8 +155,11 @@ public:
this->getES().reportError(ReadySymbol.takeError());
};
// Include non-exported symbols also.
- ES.lookup(JITDylibSearchList({{JD, true}}), SymbolNameSet({Target}),
- SymbolState::Ready, OnReadyFixUp, NoDependenciesToRegister);
+ ES.lookup(
+ LookupKind::Static,
+ makeJITDylibSearchOrder(JD, JITDylibLookupFlags::MatchAllSymbols),
+ SymbolLookupSet(Target, SymbolLookupFlags::WeaklyReferencedSymbol),
+ SymbolState::Ready, OnReadyFixUp, NoDependenciesToRegister);
}
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
index 9df79670d9f..6c924f88957 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
@@ -266,6 +266,16 @@ void LinkGraph::dump(raw_ostream &OS,
<< "\n";
}
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) {
+ switch (LF) {
+ case SymbolLookupFlags::RequiredSymbol:
+ return OS << "RequiredSymbol";
+ case SymbolLookupFlags::WeaklyReferencedSymbol:
+ return OS << "WeaklyReferencedSymbol";
+ }
+ llvm_unreachable("Unrecognized lookup flags");
+}
+
void JITLinkAsyncLookupContinuation::anchor() {}
JITLinkContext::~JITLinkContext() {}
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
index 9707b9624d9..7b594fd2c0e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
@@ -257,25 +257,35 @@ Error JITLinkerBase::allocateSegments(const SegmentLayoutMap &Layout) {
return Error::success();
}
-DenseSet<StringRef> JITLinkerBase::getExternalSymbolNames() const {
+JITLinkContext::LookupMap JITLinkerBase::getExternalSymbolNames() const {
// Identify unresolved external symbols.
- DenseSet<StringRef> UnresolvedExternals;
+ JITLinkContext::LookupMap UnresolvedExternals;
for (auto *Sym : G->external_symbols()) {
assert(Sym->getAddress() == 0 &&
"External has already been assigned an address");
assert(Sym->getName() != StringRef() && Sym->getName() != "" &&
"Externals must be named");
- UnresolvedExternals.insert(Sym->getName());
+ SymbolLookupFlags LookupFlags =
+ Sym->getLinkage() == Linkage::Weak
+ ? SymbolLookupFlags::WeaklyReferencedSymbol
+ : SymbolLookupFlags::RequiredSymbol;
+ UnresolvedExternals[Sym->getName()] = LookupFlags;
}
return UnresolvedExternals;
}
void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) {
for (auto *Sym : G->external_symbols()) {
+ assert(Sym->getOffset() == 0 &&
+ "External symbol is not at the start of its addressable block");
assert(Sym->getAddress() == 0 && "Symbol already resolved");
assert(!Sym->isDefined() && "Symbol being resolved is already defined");
- assert(Result.count(Sym->getName()) && "Missing resolution for symbol");
- Sym->getAddressable().setAddress(Result[Sym->getName()].getAddress());
+ auto ResultI = Result.find(Sym->getName());
+ if (ResultI != Result.end())
+ Sym->getAddressable().setAddress(ResultI->second.getAddress());
+ else
+ assert(Sym->getLinkage() == Linkage::Weak &&
+ "Failed to resolve non-weak reference");
}
LLVM_DEBUG({
@@ -285,8 +295,11 @@ void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) {
<< formatv("{0:x16}", Sym->getAddress()) << "\n";
});
assert(llvm::all_of(G->external_symbols(),
- [](Symbol *Sym) { return Sym->getAddress() != 0; }) &&
- "All symbols should have been resolved by this point");
+ [](Symbol *Sym) {
+ return Sym->getAddress() != 0 ||
+ Sym->getLinkage() == Linkage::Weak;
+ }) &&
+ "All strong external symbols should have been resolved by now");
}
void JITLinkerBase::deallocateAndBailOut(Error Err) {
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h
index 07dee6cee20..d5687b7afc9 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h
@@ -106,7 +106,7 @@ private:
SegmentLayoutMap layOutBlocks();
Error allocateSegments(const SegmentLayoutMap &Layout);
- DenseSet<StringRef> getExternalSymbolNames() const;
+ JITLinkContext::LookupMap getExternalSymbolNames() const;
void applyLookupResult(AsyncLookupResult LR);
void deallocateAndBailOut(Error Err);
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
index c1dc138ee70..1881bd0b287 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
@@ -321,7 +321,9 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
return make_error<JITLinkError>("Anonymous external symbol at "
"index " +
Twine(KV.first));
- NSym.GraphSymbol = &G->addExternalSymbol(*NSym.Name, 0);
+ NSym.GraphSymbol = &G->addExternalSymbol(
+ *NSym.Name, 0,
+ NSym.Desc & MachO::N_WEAK_REF ? Linkage::Weak : Linkage::Strong);
}
break;
case MachO::N_ABS:
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
index 75ddbc30445..b8e42922027 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
@@ -162,7 +162,8 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R,
return;
}
- R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), true));
+ R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables),
+ JITDylibLookupFlags::MatchAllSymbols));
R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
std::move(Callables), AliaseeImpls));
}
@@ -173,16 +174,20 @@ CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) {
if (I == DylibResources.end()) {
auto &ImplD = getExecutionSession().createJITDylib(
TargetD.getName() + ".impl", false);
- TargetD.withSearchOrderDo([&](const JITDylibSearchList &TargetSearchOrder) {
- auto NewSearchOrder = TargetSearchOrder;
- assert(!NewSearchOrder.empty() &&
- NewSearchOrder.front().first == &TargetD &&
- NewSearchOrder.front().second == true &&
- "TargetD must be at the front of its own search order and match "
- "non-exported symbol");
- NewSearchOrder.insert(std::next(NewSearchOrder.begin()), {&ImplD, true});
- ImplD.setSearchOrder(std::move(NewSearchOrder), false);
- });
+ TargetD.withSearchOrderDo(
+ [&](const JITDylibSearchOrder &TargetSearchOrder) {
+ auto NewSearchOrder = TargetSearchOrder;
+ assert(
+ !NewSearchOrder.empty() &&
+ NewSearchOrder.front().first == &TargetD &&
+ NewSearchOrder.front().second ==
+ JITDylibLookupFlags::MatchAllSymbols &&
+ "TargetD must be at the front of its own search order and match "
+ "non-exported symbol");
+ NewSearchOrder.insert(std::next(NewSearchOrder.begin()),
+ {&ImplD, JITDylibLookupFlags::MatchAllSymbols});
+ ImplD.setSearchOrder(std::move(NewSearchOrder), false);
+ });
PerDylibResources PDR(ImplD, BuildIndirectStubsManager());
I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first;
}
diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp
index 9e024ba0f10..0814ec1c5f8 100644
--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/Core.h"
+
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/IR/Mangler.h"
@@ -77,16 +79,19 @@ bool flagsMatchCLOpts(const JITSymbolFlags &Flags) {
#endif // NDEBUG
}
-// Prints a set of items, filtered by an user-supplied predicate.
-template <typename Set, typename Pred = PrintAll<typename Set::value_type>>
-class SetPrinter {
+// Prints a sequence of items, filtered by an user-supplied predicate.
+template <typename Sequence,
+ typename Pred = PrintAll<typename Sequence::value_type>>
+class SequencePrinter {
public:
- SetPrinter(const Set &S, Pred ShouldPrint = Pred())
- : S(S), ShouldPrint(std::move(ShouldPrint)) {}
+ SequencePrinter(const Sequence &S, char OpenSeq, char CloseSeq,
+ Pred ShouldPrint = Pred())
+ : S(S), OpenSeq(OpenSeq), CloseSeq(CloseSeq),
+ ShouldPrint(std::move(ShouldPrint)) {}
void printTo(llvm::raw_ostream &OS) const {
bool PrintComma = false;
- OS << "{";
+ OS << OpenSeq;
for (auto &E : S) {
if (ShouldPrint(E)) {
if (PrintComma)
@@ -95,23 +100,26 @@ public:
PrintComma = true;
}
}
- OS << " }";
+ OS << ' ' << CloseSeq;
}
private:
- const Set &S;
+ const Sequence &S;
+ char OpenSeq;
+ char CloseSeq;
mutable Pred ShouldPrint;
};
-template <typename Set, typename Pred>
-SetPrinter<Set, Pred> printSet(const Set &S, Pred P = Pred()) {
- return SetPrinter<Set, Pred>(S, std::move(P));
+template <typename Sequence, typename Pred>
+SequencePrinter<Sequence, Pred> printSequence(const Sequence &S, char OpenSeq,
+ char CloseSeq, Pred P = Pred()) {
+ return SequencePrinter<Sequence, Pred>(S, OpenSeq, CloseSeq, std::move(P));
}
-// Render a SetPrinter by delegating to its printTo method.
-template <typename Set, typename Pred>
+// Render a SequencePrinter by delegating to its printTo method.
+template <typename Sequence, typename Pred>
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
- const SetPrinter<Set, Pred> &Printer) {
+ const SequencePrinter<Sequence, Pred> &Printer) {
Printer.printTo(OS);
return OS;
}
@@ -147,7 +155,11 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym) {
}
raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) {
- return OS << printSet(Symbols, PrintAll<SymbolStringPtr>());
+ return OS << printSequence(Symbols, '{', '}', PrintAll<SymbolStringPtr>());
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols) {
+ return OS << printSequence(Symbols, '[', ']', PrintAll<SymbolStringPtr>());
}
raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
@@ -182,11 +194,13 @@ raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) {
}
raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) {
- return OS << printSet(SymbolFlags, PrintSymbolFlagsMapElemsMatchingCLOpts());
+ return OS << printSequence(SymbolFlags, '{', '}',
+ PrintSymbolFlagsMapElemsMatchingCLOpts());
}
raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) {
- return OS << printSet(Symbols, PrintSymbolMapElemsMatchingCLOpts());
+ return OS << printSequence(Symbols, '{', '}',
+ PrintSymbolMapElemsMatchingCLOpts());
}
raw_ostream &operator<<(raw_ostream &OS,
@@ -195,7 +209,8 @@ raw_ostream &operator<<(raw_ostream &OS,
}
raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) {
- return OS << printSet(Deps, PrintAll<SymbolDependenceMap::value_type>());
+ return OS << printSequence(Deps, '{', '}',
+ PrintAll<SymbolDependenceMap::value_type>());
}
raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) {
@@ -205,16 +220,59 @@ raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) {
return OS << ")";
}
-raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs) {
+raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K) {
+ switch (K) {
+ case LookupKind::Static:
+ return OS << "Static";
+ case LookupKind::DLSym:
+ return OS << "DLSym";
+ }
+ llvm_unreachable("Invalid lookup kind");
+}
+
+raw_ostream &operator<<(raw_ostream &OS,
+ const JITDylibLookupFlags &JDLookupFlags) {
+ switch (JDLookupFlags) {
+ case JITDylibLookupFlags::MatchExportedSymbolsOnly:
+ return OS << "MatchExportedSymbolsOnly";
+ case JITDylibLookupFlags::MatchAllSymbols:
+ return OS << "MatchAllSymbols";
+ }
+ llvm_unreachable("Invalid JITDylib lookup flags");
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags) {
+ switch (LookupFlags) {
+ case SymbolLookupFlags::RequiredSymbol:
+ return OS << "RequiredSymbol";
+ case SymbolLookupFlags::WeaklyReferencedSymbol:
+ return OS << "WeaklyReferencedSymbol";
+ }
+ llvm_unreachable("Invalid symbol lookup flags");
+}
+
+raw_ostream &operator<<(raw_ostream &OS,
+ const SymbolLookupSet::value_type &KV) {
+ return OS << "(" << KV.first << ", " << KV.second << ")";
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet) {
+ return OS << printSequence(LookupSet, '{', '}',
+ PrintAll<SymbolLookupSet::value_type>());
+}
+
+raw_ostream &operator<<(raw_ostream &OS,
+ const JITDylibSearchOrder &SearchOrder) {
OS << "[";
- if (!JDs.empty()) {
- assert(JDs.front().first && "JITDylibList entries must not be null");
- OS << " (\"" << JDs.front().first->getName() << "\", "
- << (JDs.front().second ? "true" : "false") << ")";
- for (auto &KV : make_range(std::next(JDs.begin()), JDs.end())) {
+ if (!SearchOrder.empty()) {
+ assert(SearchOrder.front().first &&
+ "JITDylibList entries must not be null");
+ OS << " (\"" << SearchOrder.front().first->getName() << "\", "
+ << SearchOrder.begin()->second << ")";
+ for (auto &KV :
+ make_range(std::next(SearchOrder.begin(), 1), SearchOrder.end())) {
assert(KV.first && "JITDylibList entries must not be null");
- OS << ", (\"" << KV.first->getName() << "\", "
- << (KV.second ? "true" : "false") << ")";
+ OS << ", (\"" << KV.first->getName() << "\", " << KV.second << ")";
}
}
OS << " ]";
@@ -262,7 +320,13 @@ void FailedToMaterialize::log(raw_ostream &OS) const {
OS << "Failed to materialize symbols: " << *Symbols;
}
-SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols)
+SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) {
+ for (auto &Sym : Symbols)
+ this->Symbols.push_back(Sym);
+ assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
+}
+
+SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols)
: Symbols(std::move(Symbols)) {
assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
}
@@ -289,7 +353,7 @@ void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const {
}
AsynchronousSymbolQuery::AsynchronousSymbolQuery(
- const SymbolNameSet &Symbols, SymbolState RequiredState,
+ const SymbolLookupSet &Symbols, SymbolState RequiredState,
SymbolsResolvedCallback NotifyComplete)
: NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
assert(RequiredState >= SymbolState::Resolved &&
@@ -298,8 +362,8 @@ AsynchronousSymbolQuery::AsynchronousSymbolQuery(
OutstandingSymbolsCount = Symbols.size();
- for (auto &S : Symbols)
- ResolvedSymbols[S] = nullptr;
+ for (auto &KV : Symbols)
+ ResolvedSymbols[KV.first] = nullptr;
}
void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
@@ -511,10 +575,10 @@ AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
}
ReExportsMaterializationUnit::ReExportsMaterializationUnit(
- JITDylib *SourceJD, bool MatchNonExported, SymbolAliasMap Aliases,
- VModuleKey K)
+ JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
+ SymbolAliasMap Aliases, VModuleKey K)
: MaterializationUnit(extractFlags(Aliases), std::move(K)),
- SourceJD(SourceJD), MatchNonExported(MatchNonExported),
+ SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
Aliases(std::move(Aliases)) {}
StringRef ReExportsMaterializationUnit::getName() const {
@@ -551,7 +615,7 @@ void ReExportsMaterializationUnit::materialize(
if (!Aliases.empty()) {
if (SourceJD)
- R.replace(reexports(*SourceJD, std::move(Aliases), MatchNonExported));
+ R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
else
R.replace(symbolAliases(std::move(Aliases)));
}
@@ -572,11 +636,11 @@ void ReExportsMaterializationUnit::materialize(
// be waitin on a symbol that it itself had to resolve. Usually this will just
// involve one round and a single query.
- std::vector<std::pair<SymbolNameSet, std::shared_ptr<OnResolveInfo>>>
+ std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
QueryInfos;
while (!RequestedAliases.empty()) {
SymbolNameSet ResponsibilitySymbols;
- SymbolNameSet QuerySymbols;
+ SymbolLookupSet QuerySymbols;
SymbolAliasMap QueryAliases;
// Collect as many aliases as we can without including a chain.
@@ -587,7 +651,7 @@ void ReExportsMaterializationUnit::materialize(
continue;
ResponsibilitySymbols.insert(KV.first);
- QuerySymbols.insert(KV.second.Aliasee);
+ QuerySymbols.add(KV.second.Aliasee);
QueryAliases[KV.first] = std::move(KV.second);
}
@@ -657,8 +721,9 @@ void ReExportsMaterializationUnit::materialize(
}
};
- ES.lookup(JITDylibSearchList({{&SrcJD, MatchNonExported}}), QuerySymbols,
- SymbolState::Resolved, std::move(OnComplete),
+ ES.lookup(LookupKind::Static,
+ JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
+ QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
std::move(RegisterDependencies));
}
}
@@ -681,16 +746,16 @@ ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
Expected<SymbolAliasMap>
buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
- auto Flags = SourceJD.lookupFlags(Symbols);
+ SymbolLookupSet LookupSet(Symbols);
+ auto Flags = SourceJD.lookupFlags(
+ LookupKind::Static, JITDylibLookupFlags::MatchAllSymbols, LookupSet);
if (!Flags)
return Flags.takeError();
- if (Flags->size() != Symbols.size()) {
- SymbolNameSet Unresolved = Symbols;
- for (auto &KV : *Flags)
- Unresolved.erase(KV.first);
- return make_error<SymbolsNotFound>(std::move(Unresolved));
+ if (!LookupSet.empty()) {
+ LookupSet.sortByName();
+ return make_error<SymbolsNotFound>(LookupSet.getSymbolNames());
}
SymbolAliasMap Result;
@@ -703,32 +768,32 @@ buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
}
ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
- bool MatchNonExported,
+ JITDylibLookupFlags SourceJDLookupFlags,
SymbolPredicate Allow)
- : SourceJD(SourceJD), MatchNonExported(MatchNonExported),
+ : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
Allow(std::move(Allow)) {}
-Expected<SymbolNameSet>
-ReexportsGenerator::tryToGenerate(JITDylib &JD, const SymbolNameSet &Names) {
- orc::SymbolNameSet Added;
- orc::SymbolAliasMap AliasMap;
-
- auto Flags = SourceJD.lookupFlags(Names);
+Error ReexportsGenerator::tryToGenerate(LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) {
+ assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
+ // Use lookupFlags to find the subset of symbols that match our lookup.
+ auto Flags = SourceJD.lookupFlags(K, JDLookupFlags, LookupSet);
if (!Flags)
return Flags.takeError();
- for (auto &KV : *Flags) {
- if (Allow && !Allow(KV.first))
- continue;
- AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
- Added.insert(KV.first);
- }
+ // Create an alias map.
+ orc::SymbolAliasMap AliasMap;
+ for (auto &KV : *Flags)
+ if (!Allow || Allow(KV.first))
+ AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
- if (!Added.empty())
- cantFail(JD.define(reexports(SourceJD, AliasMap, MatchNonExported)));
+ if (AliasMap.empty())
+ return Error::success();
- return Added;
+ // Define the re-exports.
+ return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
}
JITDylib::DefinitionGenerator::~DefinitionGenerator() {}
@@ -1252,41 +1317,41 @@ void JITDylib::notifyFailed(FailedSymbolsWorklist Worklist) {
Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbolsMap));
}
-void JITDylib::setSearchOrder(JITDylibSearchList NewSearchOrder,
- bool SearchThisJITDylibFirst,
- bool MatchNonExportedInThisDylib) {
- if (SearchThisJITDylibFirst) {
- if (NewSearchOrder.empty() || NewSearchOrder.front().first != this)
- NewSearchOrder.insert(NewSearchOrder.begin(),
- {this, MatchNonExportedInThisDylib});
- }
-
- ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); });
-}
-
-void JITDylib::addToSearchOrder(JITDylib &JD, bool MatchNonExported) {
+void JITDylib::setSearchOrder(JITDylibSearchOrder NewSearchOrder,
+ bool SearchThisJITDylibFirst) {
ES.runSessionLocked([&]() {
- SearchOrder.push_back({&JD, MatchNonExported});
+ if (SearchThisJITDylibFirst) {
+ SearchOrder.clear();
+ if (NewSearchOrder.empty() || NewSearchOrder.front().first != this)
+ SearchOrder.push_back(
+ std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
+ SearchOrder.insert(SearchOrder.end(), NewSearchOrder.begin(),
+ NewSearchOrder.end());
+ } else
+ SearchOrder = std::move(NewSearchOrder);
});
}
+void JITDylib::addToSearchOrder(JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags) {
+ ES.runSessionLocked([&]() { SearchOrder.push_back({&JD, JDLookupFlags}); });
+}
+
void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
- bool MatchNonExported) {
+ JITDylibLookupFlags JDLookupFlags) {
ES.runSessionLocked([&]() {
- auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
- [&](const JITDylibSearchList::value_type &KV) {
- return KV.first == &OldJD;
- });
-
- if (I != SearchOrder.end())
- *I = {&NewJD, MatchNonExported};
+ for (auto &KV : SearchOrder)
+ if (KV.first == &OldJD) {
+ KV = {&NewJD, JDLookupFlags};
+ break;
+ }
});
}
void JITDylib::removeFromSearchOrder(JITDylib &JD) {
ES.runSessionLocked([&]() {
auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
- [&](const JITDylibSearchList::value_type &KV) {
+ [&](const JITDylibSearchOrder::value_type &KV) {
return KV.first == &JD;
});
if (I != SearchOrder.end())
@@ -1349,63 +1414,54 @@ Error JITDylib::remove(const SymbolNameSet &Names) {
});
}
-Expected<SymbolFlagsMap> JITDylib::lookupFlags(const SymbolNameSet &Names) {
+Expected<SymbolFlagsMap>
+JITDylib::lookupFlags(LookupKind K, JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet LookupSet) {
return ES.runSessionLocked([&, this]() -> Expected<SymbolFlagsMap> {
SymbolFlagsMap Result;
- auto Unresolved = lookupFlagsImpl(Result, Names);
- if (!Unresolved)
- return Unresolved.takeError();
+ lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
- /// Run any definition generators.
+ // Run any definition generators.
for (auto &DG : DefGenerators) {
- // Bail out early if we've resolved everything.
- if (Unresolved->empty())
+ // Bail out early if we found everything.
+ if (LookupSet.empty())
break;
// Run this generator.
- auto NewDefs = DG->tryToGenerate(*this, *Unresolved);
- if (!NewDefs)
- return NewDefs.takeError();
-
- if (!NewDefs->empty()) {
- auto Unresolved2 = lookupFlagsImpl(Result, *NewDefs);
- if (!Unresolved2)
- return Unresolved2.takeError();
- (void)Unresolved2;
- assert(Unresolved2->empty() &&
- "All fallback defs should have been found by lookupFlagsImpl");
- }
+ if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, LookupSet))
+ return std::move(Err);
- for (auto &Name : *NewDefs)
- Unresolved->erase(Name);
+ // Re-try the search.
+ lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
}
+
return Result;
});
}
-Expected<SymbolNameSet> JITDylib::lookupFlagsImpl(SymbolFlagsMap &Flags,
- const SymbolNameSet &Names) {
- SymbolNameSet Unresolved;
+void JITDylib::lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K,
+ JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &LookupSet) {
- for (auto &Name : Names) {
- auto I = Symbols.find(Name);
- if (I != Symbols.end()) {
- assert(!Flags.count(Name) && "Symbol already present in Flags map");
- Flags[Name] = I->second.getFlags();
- } else
- Unresolved.insert(Name);
- }
-
- return Unresolved;
+ LookupSet.forEachWithRemoval(
+ [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
+ auto I = Symbols.find(Name);
+ if (I == Symbols.end())
+ return false;
+ assert(!Result.count(Name) && "Symbol already present in Flags map");
+ Result[Name] = I->second.getFlags();
+ return true;
+ });
}
-Error JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved, bool MatchNonExported,
- MaterializationUnitList &MUs) {
+Error JITDylib::lodgeQuery(MaterializationUnitList &MUs,
+ std::shared_ptr<AsynchronousSymbolQuery> &Q,
+ LookupKind K, JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &Unresolved) {
assert(Q && "Query can not be null");
- if (auto Err = lodgeQueryImpl(Q, Unresolved, MatchNonExported, MUs))
+ if (auto Err = lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved))
return Err;
// Run any definition generators.
@@ -1416,104 +1472,86 @@ Error JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
break;
// Run the generator.
- auto NewDefs = DG->tryToGenerate(*this, Unresolved);
-
- // If the generator returns an error then bail out.
- if (!NewDefs)
- return NewDefs.takeError();
-
- // If the generator was able to generate new definitions for any of the
- // unresolved symbols then lodge the query against them.
- if (!NewDefs->empty()) {
- for (auto &D : *NewDefs)
- Unresolved.erase(D);
-
- // Lodge query. This can not fail as any new definitions were added
- // by the generator under the session locked. Since they can't have
- // started materializing yet the can not have failed.
- cantFail(lodgeQueryImpl(Q, *NewDefs, MatchNonExported, MUs));
+ if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, Unresolved))
+ return Err;
- assert(NewDefs->empty() &&
- "All fallback defs should have been found by lookupImpl");
- }
+ // Lodge query. This can not fail as any new definitions were added
+ // by the generator under the session locked. Since they can't have
+ // started materializing yet they can not have failed.
+ cantFail(lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved));
}
return Error::success();
}
-Error JITDylib::lodgeQueryImpl(
- std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved,
- bool MatchNonExported,
- std::vector<std::unique_ptr<MaterializationUnit>> &MUs) {
-
- std::vector<SymbolStringPtr> ToRemove;
- for (auto Name : Unresolved) {
-
- // Search for the name in Symbols. Skip it if not found.
- auto SymI = Symbols.find(Name);
- if (SymI == Symbols.end())
- continue;
-
- // If this is a non exported symbol and we're skipping those then skip it.
- if (!SymI->second.getFlags().isExported() && !MatchNonExported)
- continue;
-
- // If we matched against Name in JD, mark it to be removed from the
- // Unresolved set.
- ToRemove.push_back(Name);
-
- // If we matched against this symbol but it is in the error state then
- // bail out and treat it as a failure to materialize.
- if (SymI->second.getFlags().hasError()) {
- auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
- (*FailedSymbolsMap)[this] = {Name};
- return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
- }
-
- // If this symbol already meets the required state for then notify the
- // query and continue.
- if (SymI->second.getState() >= Q->getRequiredState()) {
- Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
- continue;
- }
-
- // Otherwise this symbol does not yet meet the required state. Check whether
- // it has a materializer attached, and if so prepare to run it.
- if (SymI->second.hasMaterializerAttached()) {
- assert(SymI->second.getAddress() == 0 &&
- "Symbol not resolved but already has address?");
- auto UMII = UnmaterializedInfos.find(Name);
- assert(UMII != UnmaterializedInfos.end() &&
- "Lazy symbol should have UnmaterializedInfo");
- auto MU = std::move(UMII->second->MU);
- assert(MU != nullptr && "Materializer should not be null");
-
- // Move all symbols associated with this MaterializationUnit into
- // materializing state.
- for (auto &KV : MU->getSymbols()) {
- auto SymK = Symbols.find(KV.first);
- SymK->second.setMaterializerAttached(false);
- SymK->second.setState(SymbolState::Materializing);
- UnmaterializedInfos.erase(KV.first);
- }
+Error JITDylib::lodgeQueryImpl(MaterializationUnitList &MUs,
+ std::shared_ptr<AsynchronousSymbolQuery> &Q,
+ LookupKind K, JITDylibLookupFlags JDLookupFlags,
+ SymbolLookupSet &Unresolved) {
+
+ return Unresolved.forEachWithRemoval(
+ [&](const SymbolStringPtr &Name,
+ SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
+ // Search for name in symbols. If not found then continue without
+ // removal.
+ auto SymI = Symbols.find(Name);
+ if (SymI == Symbols.end())
+ return false;
+
+ // If this is a non exported symbol and we're matching exported symbols
+ // only then skip this symbol without removal.
+ if (!SymI->second.getFlags().isExported() &&
+ JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly)
+ return false;
+
+ // If we matched against this symbol but it is in the error state then
+ // bail out and treat it as a failure to materialize.
+ if (SymI->second.getFlags().hasError()) {
+ auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
+ (*FailedSymbolsMap)[this] = {Name};
+ return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
+ }
- // Add MU to the list of MaterializationUnits to be materialized.
- MUs.push_back(std::move(MU));
- }
+ // If this symbol already meets the required state for then notify the
+ // query, then remove the symbol and continue.
+ if (SymI->second.getState() >= Q->getRequiredState()) {
+ Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
+ return true;
+ }
- // Add the query to the PendingQueries list.
- assert(SymI->second.isInMaterializationPhase() &&
- "By this line the symbol should be materializing");
- auto &MI = MaterializingInfos[Name];
- MI.addQuery(Q);
- Q->addQueryDependence(*this, Name);
- }
+ // Otherwise this symbol does not yet meet the required state. Check
+ // whether it has a materializer attached, and if so prepare to run it.
+ if (SymI->second.hasMaterializerAttached()) {
+ assert(SymI->second.getAddress() == 0 &&
+ "Symbol not resolved but already has address?");
+ auto UMII = UnmaterializedInfos.find(Name);
+ assert(UMII != UnmaterializedInfos.end() &&
+ "Lazy symbol should have UnmaterializedInfo");
+ auto MU = std::move(UMII->second->MU);
+ assert(MU != nullptr && "Materializer should not be null");
+
+ // Move all symbols associated with this MaterializationUnit into
+ // materializing state.
+ for (auto &KV : MU->getSymbols()) {
+ auto SymK = Symbols.find(KV.first);
+ SymK->second.setMaterializerAttached(false);
+ SymK->second.setState(SymbolState::Materializing);
+ UnmaterializedInfos.erase(KV.first);
+ }
- // Remove any symbols that we found.
- for (auto &Name : ToRemove)
- Unresolved.erase(Name);
+ // Add MU to the list of MaterializationUnits to be materialized.
+ MUs.push_back(std::move(MU));
+ }
- return Error::success();
+ // Add the query to the PendingQueries list and continue, deleting the
+ // element.
+ assert(SymI->second.isInMaterializationPhase() &&
+ "By this line the symbol should be materializing");
+ auto &MI = MaterializingInfos[Name];
+ MI.addQuery(Q);
+ Q->addQueryDependence(*this, Name);
+ return true;
+ });
}
Expected<SymbolNameSet>
@@ -1526,7 +1564,7 @@ JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
bool QueryComplete = false;
std::vector<std::unique_ptr<MaterializationUnit>> MUs;
- SymbolNameSet Unresolved = std::move(Names);
+ SymbolLookupSet Unresolved(Names);
auto Err = ES.runSessionLocked([&, this]() -> Error {
QueryComplete = lookupImpl(Q, MUs, Unresolved);
@@ -1538,16 +1576,13 @@ JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
break;
assert(!QueryComplete && "query complete but unresolved symbols remain?");
- auto NewDefs = DG->tryToGenerate(*this, Unresolved);
- if (!NewDefs)
- return NewDefs.takeError();
- if (!NewDefs->empty()) {
- for (auto &D : *NewDefs)
- Unresolved.erase(D);
- QueryComplete = lookupImpl(Q, MUs, *NewDefs);
- assert(NewDefs->empty() &&
- "All fallback defs should have been found by lookupImpl");
- }
+ if (auto Err = DG->tryToGenerate(LookupKind::Static, *this,
+ JITDylibLookupFlags::MatchAllSymbols,
+ Unresolved))
+ return Err;
+
+ if (!Unresolved.empty())
+ QueryComplete = lookupImpl(Q, MUs, Unresolved);
}
return Error::success();
});
@@ -1575,68 +1610,68 @@ JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
// for (auto &MU : MUs)
// ES.dispatchMaterialization(*this, std::move(MU));
- return Unresolved;
+ SymbolNameSet RemainingSymbols;
+ for (auto &KV : Unresolved)
+ RemainingSymbols.insert(KV.first);
+
+ return RemainingSymbols;
}
bool JITDylib::lookupImpl(
std::shared_ptr<AsynchronousSymbolQuery> &Q,
std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
- SymbolNameSet &Unresolved) {
+ SymbolLookupSet &Unresolved) {
bool QueryComplete = false;
std::vector<SymbolStringPtr> ToRemove;
- for (auto Name : Unresolved) {
-
- // Search for the name in Symbols. Skip it if not found.
- auto SymI = Symbols.find(Name);
- if (SymI == Symbols.end())
- continue;
-
- // If we found Name, mark it to be removed from the Unresolved set.
- ToRemove.push_back(Name);
-
- if (SymI->second.getState() >= Q->getRequiredState()) {
- Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
- if (Q->isComplete())
- QueryComplete = true;
- continue;
- }
-
- // If the symbol is lazy, get the MaterialiaztionUnit for it.
- if (SymI->second.hasMaterializerAttached()) {
- assert(SymI->second.getAddress() == 0 &&
- "Lazy symbol should not have a resolved address");
- auto UMII = UnmaterializedInfos.find(Name);
- assert(UMII != UnmaterializedInfos.end() &&
- "Lazy symbol should have UnmaterializedInfo");
- auto MU = std::move(UMII->second->MU);
- assert(MU != nullptr && "Materializer should not be null");
-
- // Kick all symbols associated with this MaterializationUnit into
- // materializing state.
- for (auto &KV : MU->getSymbols()) {
- auto SymK = Symbols.find(KV.first);
- assert(SymK != Symbols.end() && "Missing symbol table entry");
- SymK->second.setState(SymbolState::Materializing);
- SymK->second.setMaterializerAttached(false);
- UnmaterializedInfos.erase(KV.first);
- }
+ Unresolved.forEachWithRemoval(
+ [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
+ // Search for the name in Symbols. Skip without removing if not found.
+ auto SymI = Symbols.find(Name);
+ if (SymI == Symbols.end())
+ return false;
+
+ // If the symbol is already in the required state then notify the query
+ // and remove.
+ if (SymI->second.getState() >= Q->getRequiredState()) {
+ Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
+ if (Q->isComplete())
+ QueryComplete = true;
+ return true;
+ }
- // Add MU to the list of MaterializationUnits to be materialized.
- MUs.push_back(std::move(MU));
- }
+ // If the symbol is lazy, get the MaterialiaztionUnit for it.
+ if (SymI->second.hasMaterializerAttached()) {
+ assert(SymI->second.getAddress() == 0 &&
+ "Lazy symbol should not have a resolved address");
+ auto UMII = UnmaterializedInfos.find(Name);
+ assert(UMII != UnmaterializedInfos.end() &&
+ "Lazy symbol should have UnmaterializedInfo");
+ auto MU = std::move(UMII->second->MU);
+ assert(MU != nullptr && "Materializer should not be null");
+
+ // Kick all symbols associated with this MaterializationUnit into
+ // materializing state.
+ for (auto &KV : MU->getSymbols()) {
+ auto SymK = Symbols.find(KV.first);
+ assert(SymK != Symbols.end() && "Missing symbol table entry");
+ SymK->second.setState(SymbolState::Materializing);
+ SymK->second.setMaterializerAttached(false);
+ UnmaterializedInfos.erase(KV.first);
+ }
- // Add the query to the PendingQueries list.
- assert(SymI->second.isInMaterializationPhase() &&
- "By this line the symbol should be materializing");
- auto &MI = MaterializingInfos[Name];
- MI.addQuery(Q);
- Q->addQueryDependence(*this, Name);
- }
+ // Add MU to the list of MaterializationUnits to be materialized.
+ MUs.push_back(std::move(MU));
+ }
- // Remove any marked symbols from the Unresolved set.
- for (auto &Name : ToRemove)
- Unresolved.erase(Name);
+ // Add the query to the PendingQueries list.
+ assert(SymI->second.isInMaterializationPhase() &&
+ "By this line the symbol should be materializing");
+ auto &MI = MaterializingInfos[Name];
+ MI.addQuery(Q);
+ Q->addQueryDependence(*this, Name);
+ return true;
+ });
return QueryComplete;
}
@@ -1645,11 +1680,7 @@ void JITDylib::dump(raw_ostream &OS) {
ES.runSessionLocked([&, this]() {
OS << "JITDylib \"" << JITDylibName << "\" (ES: "
<< format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
- << "Search order: [";
- for (auto &KV : SearchOrder)
- OS << " (\"" << KV.first->getName() << "\", "
- << (KV.second ? "all" : "exported only") << ")";
- OS << " ]\n"
+ << "Search order: " << SearchOrder << "\n"
<< "Symbol table:\n";
for (auto &KV : Symbols) {
@@ -1730,7 +1761,7 @@ JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
: ES(ES), JITDylibName(std::move(Name)) {
- SearchOrder.push_back({this, true});
+ SearchOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
}
Error JITDylib::defineImpl(MaterializationUnit &MU) {
@@ -1898,7 +1929,7 @@ Expected<SymbolMap> ExecutionSession::legacyLookup(
#endif
auto Query = std::make_shared<AsynchronousSymbolQuery>(
- Names, RequiredState, std::move(NotifyComplete));
+ SymbolLookupSet(Names), RequiredState, std::move(NotifyComplete));
// FIXME: This should be run session locked along with the registration code
// and error reporting below.
SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
@@ -1935,8 +1966,9 @@ Expected<SymbolMap> ExecutionSession::legacyLookup(
}
void ExecutionSession::lookup(
- const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
- SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete,
+ LookupKind K, const JITDylibSearchOrder &SearchOrder,
+ SymbolLookupSet Symbols, SymbolState RequiredState,
+ SymbolsResolvedCallback NotifyComplete,
RegisterDependenciesFunction RegisterDependencies) {
LLVM_DEBUG({
@@ -1965,14 +1997,24 @@ void ExecutionSession::lookup(
"JITDylibList should not contain duplicate entries");
auto &JD = *KV.first;
- auto MatchNonExported = KV.second;
- if (auto Err = JD.lodgeQuery(Q, Unresolved, MatchNonExported,
- CollectedMUsMap[&JD]))
+ auto JDLookupFlags = KV.second;
+ if (auto Err = JD.lodgeQuery(CollectedMUsMap[&JD], Q, K, JDLookupFlags,
+ Unresolved))
return Err;
}
+ // Strip any weakly referenced symbols that were not found.
+ Unresolved.forEachWithRemoval(
+ [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) {
+ if (Flags == SymbolLookupFlags::WeaklyReferencedSymbol) {
+ Q->dropSymbol(Name);
+ return true;
+ }
+ return false;
+ });
+
if (!Unresolved.empty())
- return make_error<SymbolsNotFound>(std::move(Unresolved));
+ return make_error<SymbolsNotFound>(Unresolved.getSymbolNames());
return Error::success();
};
@@ -2026,8 +2068,8 @@ void ExecutionSession::lookup(
}
Expected<SymbolMap>
-ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
- const SymbolNameSet &Symbols,
+ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
+ const SymbolLookupSet &Symbols, LookupKind K,
SymbolState RequiredState,
RegisterDependenciesFunction RegisterDependencies) {
#if LLVM_ENABLE_THREADS
@@ -2059,7 +2101,7 @@ ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
#endif
// Perform the asynchronous lookup.
- lookup(SearchOrder, Symbols, RequiredState, NotifyComplete,
+ lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
RegisterDependencies);
#if LLVM_ENABLE_THREADS
@@ -2080,12 +2122,12 @@ ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
}
Expected<JITEvaluatedSymbol>
-ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
+ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
SymbolStringPtr Name) {
- SymbolNameSet Names({Name});
+ SymbolLookupSet Names({Name});
- if (auto ResultMap = lookup(SearchOrder, std::move(Names), SymbolState::Ready,
- NoDependenciesToRegister)) {
+ if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
+ SymbolState::Ready, NoDependenciesToRegister)) {
assert(ResultMap->size() == 1 && "Unexpected number of results");
assert(ResultMap->count(Name) && "Missing result for symbol");
return std::move(ResultMap->begin()->second);
@@ -2096,14 +2138,7 @@ ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
Expected<JITEvaluatedSymbol>
ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder,
SymbolStringPtr Name) {
- SymbolNameSet Names({Name});
-
- JITDylibSearchList FullSearchOrder;
- FullSearchOrder.reserve(SearchOrder.size());
- for (auto *JD : SearchOrder)
- FullSearchOrder.push_back({JD, false});
-
- return lookup(FullSearchOrder, Name);
+ return lookup(makeJITDylibSearchOrder(SearchOrder), Name);
}
Expected<JITEvaluatedSymbol>
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index 4a886ac0597..4a3482242db 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -118,19 +118,17 @@ void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) {
Error CtorDtorRunner::run() {
using CtorDtorTy = void (*)();
- SymbolNameSet Names;
-
- for (auto &KV : CtorDtorsByPriority) {
- for (auto &Name : KV.second) {
- auto Added = Names.insert(Name).second;
- (void)Added;
- assert(Added && "Ctor/Dtor names clashed");
- }
- }
+ SymbolLookupSet LookupSet;
+ for (auto &KV : CtorDtorsByPriority)
+ for (auto &Name : KV.second)
+ LookupSet.add(Name);
+ assert(!LookupSet.containsDuplicates() &&
+ "Ctor/Dtor list contains duplicates");
auto &ES = JD.getExecutionSession();
- if (auto CtorDtorMap =
- ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names))) {
+ if (auto CtorDtorMap = ES.lookup(
+ makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols),
+ std::move(LookupSet))) {
for (auto &KV : CtorDtorsByPriority) {
for (auto &Name : KV.second) {
assert(CtorDtorMap->count(Name) && "No entry for Name");
@@ -190,15 +188,16 @@ DynamicLibrarySearchGenerator::Load(const char *FileName, char GlobalPrefix,
std::move(Lib), GlobalPrefix, std::move(Allow));
}
-Expected<SymbolNameSet>
-DynamicLibrarySearchGenerator::tryToGenerate(JITDylib &JD,
- const SymbolNameSet &Names) {
- orc::SymbolNameSet Added;
+Error DynamicLibrarySearchGenerator::tryToGenerate(
+ LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &Symbols) {
orc::SymbolMap NewSymbols;
bool HasGlobalPrefix = (GlobalPrefix != '\0');
- for (auto &Name : Names) {
+ for (auto &KV : Symbols) {
+ auto &Name = KV.first;
+
if ((*Name).empty())
continue;
@@ -211,20 +210,16 @@ DynamicLibrarySearchGenerator::tryToGenerate(JITDylib &JD,
std::string Tmp((*Name).data() + HasGlobalPrefix,
(*Name).size() - HasGlobalPrefix);
if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) {
- Added.insert(Name);
NewSymbols[Name] = JITEvaluatedSymbol(
static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)),
JITSymbolFlags::Exported);
}
}
- // Add any new symbols to JD. Since the generator is only called for symbols
- // that are not already defined, this will never trigger a duplicate
- // definition error, so we can wrap this call in a 'cantFail'.
- if (!NewSymbols.empty())
- cantFail(JD.define(absoluteSymbols(std::move(NewSymbols))));
+ if (NewSymbols.empty())
+ return Error::success();
- return Added;
+ return JD.define(absoluteSymbols(std::move(NewSymbols)));
}
Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
@@ -251,15 +246,24 @@ StaticLibraryDefinitionGenerator::Create(
return std::move(ADG);
}
-Expected<SymbolNameSet>
-StaticLibraryDefinitionGenerator::tryToGenerate(JITDylib &JD,
- const SymbolNameSet &Names) {
+Error StaticLibraryDefinitionGenerator::tryToGenerate(
+ LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &Symbols) {
+
+ // Don't materialize symbols from static archives unless this is a static
+ // lookup.
+ if (K != LookupKind::Static)
+ return Error::success();
+
+ // Bail out early if we've already freed the archive.
+ if (!Archive)
+ return Error::success();
DenseSet<std::pair<StringRef, StringRef>> ChildBufferInfos;
- SymbolNameSet NewDefs;
- for (const auto &Name : Names) {
- auto Child = Archive.findSym(*Name);
+ for (const auto &KV : Symbols) {
+ const auto &Name = KV.first;
+ auto Child = Archive->findSym(*Name);
if (!Child)
return Child.takeError();
if (*Child == None)
@@ -269,7 +273,6 @@ StaticLibraryDefinitionGenerator::tryToGenerate(JITDylib &JD,
return ChildBuffer.takeError();
ChildBufferInfos.insert(
{ChildBuffer->getBuffer(), ChildBuffer->getBufferIdentifier()});
- NewDefs.insert(Name);
}
for (auto ChildBufferInfo : ChildBufferInfos) {
@@ -278,31 +281,16 @@ StaticLibraryDefinitionGenerator::tryToGenerate(JITDylib &JD,
if (auto Err =
L.add(JD, MemoryBuffer::getMemBuffer(ChildBufferRef), VModuleKey()))
- return std::move(Err);
-
- --UnrealizedObjects;
+ return Err;
}
- return NewDefs;
+ return Error::success();
}
StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator(
ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, Error &Err)
: L(L), ArchiveBuffer(std::move(ArchiveBuffer)),
- Archive(*this->ArchiveBuffer, Err) {
-
- if (Err)
- return;
-
- Error Err2 = Error::success();
- for (auto _ : Archive.children(Err2)) {
- (void)_;
- ++UnrealizedObjects;
- }
-
- // No need to check this: We will leave it to the caller.
- Err = std::move(Err2);
-}
+ Archive(std::make_unique<object::Archive>(*this->ArchiveBuffer, Err)) {}
} // End namespace orc.
} // End namespace llvm.
diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index 0295db7633d..440935ffe9f 100644
--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -101,7 +101,10 @@ JITTargetAddress JITCompileCallbackManager::executeCompileCallback(
Name = I->second;
}
- if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name))
+ if (auto Sym =
+ ES.lookup(makeJITDylibSearchOrder(
+ &CallbacksJD, JITDylibLookupFlags::MatchAllSymbols),
+ Name))
return Sym->getAddress();
else {
llvm::dbgs() << "Didn't find callback.\n";
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index 03f22e0c2a2..fb5515ca64d 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -56,7 +56,9 @@ Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
StringRef Name) {
- return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
+ return ES->lookup(
+ makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols),
+ ES->intern(Name));
}
std::unique_ptr<ObjectLayer>
diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
index 93aabd817d6..aab490feb8e 100644
--- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
@@ -50,8 +50,10 @@ LazyCallThroughManager::callThroughToSymbol(JITTargetAddress TrampolineAddr) {
SourceJD = I->second.first;
SymbolName = I->second.second;
}
- auto LookupResult =
- ES.lookup(JITDylibSearchList({{SourceJD, true}}), SymbolName);
+
+ auto LookupResult = ES.lookup(
+ makeJITDylibSearchOrder(SourceJD, JITDylibLookupFlags::MatchAllSymbols),
+ SymbolName);
if (!LookupResult) {
ES.reportError(LookupResult.takeError());
diff --git a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp
index 9f9a6730b2c..67b804c3728 100644
--- a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp
@@ -37,7 +37,8 @@ void JITSymbolResolverAdapter::lookup(const LookupSet &Symbols,
};
auto Q = std::make_shared<AsynchronousSymbolQuery>(
- InternedSymbols, SymbolState::Resolved, std::move(OnResolvedWithUnwrap));
+ SymbolLookupSet(InternedSymbols), SymbolState::Resolved,
+ std::move(OnResolvedWithUnwrap));
auto Unresolved = R.lookup(Q, InternedSymbols);
if (Unresolved.empty()) {
diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
index 874decb2ade..be0ce4a1d75 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -47,18 +47,28 @@ public:
MR.failMaterialization();
}
- void lookup(const DenseSet<StringRef> &Symbols,
+ void lookup(const LookupMap &Symbols,
std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
- JITDylibSearchList SearchOrder;
+ JITDylibSearchOrder SearchOrder;
MR.getTargetJITDylib().withSearchOrderDo(
- [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
+ [&](const JITDylibSearchOrder &O) { SearchOrder = O; });
auto &ES = Layer.getExecutionSession();
- SymbolNameSet InternedSymbols;
- for (auto &S : Symbols)
- InternedSymbols.insert(ES.intern(S));
+ SymbolLookupSet LookupSet;
+ for (auto &KV : Symbols) {
+ orc::SymbolLookupFlags LookupFlags;
+ switch (KV.second) {
+ case jitlink::SymbolLookupFlags::RequiredSymbol:
+ LookupFlags = orc::SymbolLookupFlags::RequiredSymbol;
+ break;
+ case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol:
+ LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol;
+ break;
+ }
+ LookupSet.add(ES.intern(KV.first), LookupFlags);
+ }
// OnResolve -- De-intern the symbols and pass the result to the linker.
auto OnResolve = [this, LookupContinuation = std::move(LC)](
@@ -74,8 +84,9 @@ public:
}
};
- ES.lookup(SearchOrder, std::move(InternedSymbols), SymbolState::Resolved,
- std::move(OnResolve), [this](const SymbolDependenceMap &Deps) {
+ ES.lookup(LookupKind::Static, SearchOrder, std::move(LookupSet),
+ SymbolState::Resolved, std::move(OnResolve),
+ [this](const SymbolDependenceMap &Deps) {
registerDependencies(Deps);
});
}
diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
index 939cd539d1f..3344bd4d53f 100644
--- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
@@ -19,11 +19,11 @@ public:
void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) {
auto &ES = MR.getTargetJITDylib().getExecutionSession();
- SymbolNameSet InternedSymbols;
+ SymbolLookupSet InternedSymbols;
// Intern the requested symbols: lookup takes interned strings.
for (auto &S : Symbols)
- InternedSymbols.insert(ES.intern(S));
+ InternedSymbols.add(ES.intern(S));
// Build an OnResolve callback to unwrap the interned strings and pass them
// to the OnResolved callback.
@@ -46,11 +46,12 @@ public:
MR.addDependenciesForAll(Deps);
};
- JITDylibSearchList SearchOrder;
+ JITDylibSearchOrder SearchOrder;
MR.getTargetJITDylib().withSearchOrderDo(
- [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
- ES.lookup(SearchOrder, InternedSymbols, SymbolState::Resolved,
- std::move(OnResolvedWithUnwrap), RegisterDependencies);
+ [&](const JITDylibSearchOrder &JDs) { SearchOrder = JDs; });
+ ES.lookup(LookupKind::Static, SearchOrder, InternedSymbols,
+ SymbolState::Resolved, std::move(OnResolvedWithUnwrap),
+ RegisterDependencies);
}
Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_references.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_references.s
new file mode 100644
index 00000000000..20fa5536302
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_references.s
@@ -0,0 +1,19 @@
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t/macho_weak_refs.o %s
+# RUN: llvm-jitlink -noexec -check-name=jitlink-check-bar-present -define-abs bar=0x1 -check=%s %t/macho_weak_refs.o
+# RUN: llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=%s %t/macho_weak_refs.o
+
+# Test weak reference handling by linking with and without a definition of 'bar' available.
+
+ .section __TEXT,__text,regular,pure_instructions
+ .build_version macos, 10, 14 sdk_version 10, 14
+ .globl _main
+ .p2align 4, 0x90
+_main:
+# jitlink-check-bar-present: *{8}(got_addr(macho_weak_refs.o, bar)) = bar
+# jitlink-check-bar-absent: *{8}(got_addr(macho_weak_refs.o, bar)) = 0
+ cmpq $0, bar@GOTPCREL(%rip)
+
+ .weak_reference bar
+
+.subsections_via_symbols
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 251e79cf56d..003a333d956 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -57,6 +57,10 @@ static cl::list<std::string>
cl::ZeroOrMore);
static cl::opt<std::string>
+ CheckName("check-name", cl::desc("Name of checks to match against"),
+ cl::init("jitlink-check"));
+
+static cl::opt<std::string>
EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
cl::init(""));
@@ -604,11 +608,12 @@ Error loadObjects(Session &S) {
// Set every dylib to link against every other, in command line order.
for (auto *JD : S.JDSearchOrder) {
- JITDylibSearchList O;
+ auto LookupFlags = JITDylibLookupFlags::MatchExportedSymbolsOnly;
+ JITDylibSearchOrder O;
for (auto *JD2 : S.JDSearchOrder) {
if (JD2 == JD)
continue;
- O.push_back(std::make_pair(JD2, false));
+ O.push_back(std::make_pair(JD2, LookupFlags));
}
JD->setSearchOrder(std::move(O));
}
@@ -741,10 +746,11 @@ Error runChecks(Session &S) {
S.TT.isLittleEndian() ? support::little : support::big,
Disassembler.get(), InstPrinter.get(), dbgs());
+ std::string CheckLineStart = "# " + CheckName + ":";
for (auto &CheckFile : CheckFiles) {
auto CheckerFileBuf =
ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(CheckFile)));
- if (!Checker.checkAllRulesInBuffer("# jitlink-check:", &*CheckerFileBuf))
+ if (!Checker.checkAllRulesInBuffer(CheckLineStart, &*CheckerFileBuf))
ExitOnErr(make_error<StringError>(
"Some checks in " + CheckFile + " failed", inconvertibleErrorCode()));
}
diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
index 3e16a50d07b..68a6d2ed2ca 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
@@ -43,8 +43,9 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
})));
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- OnCompletion, NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Ready, OnCompletion,
+ NoDependenciesToRegister);
EXPECT_FALSE(OnCompletionRun) << "Should not have been resolved yet";
@@ -67,7 +68,7 @@ TEST_F(CoreAPIsStandardTest, ExecutionSessionFailQuery) {
OnCompletionRun = true;
};
- AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), SymbolState::Ready,
+ AsynchronousSymbolQuery Q(SymbolLookupSet(Foo), SymbolState::Ready,
OnCompletion);
ES.legacyFailQuery(Q,
@@ -84,8 +85,8 @@ TEST_F(CoreAPIsStandardTest, EmptyLookup) {
OnCompletionRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {}, SymbolState::Ready,
- OnCompletion, NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD), SymbolLookupSet(),
+ SymbolState::Ready, OnCompletion, NoDependenciesToRegister);
EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run for empty query";
}
@@ -131,7 +132,8 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
bool OnCompletionRun = false;
ES.lookup(
- JITDylibSearchList({{&JD, false}}), {Foo, Baz}, SymbolState::Ready,
+ LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet({Foo, Baz}), SymbolState::Ready,
[&](Expected<SymbolMap> Result) {
cantFail(Result.takeError());
OnCompletionRun = true;
@@ -179,7 +181,7 @@ TEST_F(CoreAPIsStandardTest, ChainedJITDylibLookup) {
bool OnCompletionRun = false;
auto Q = std::make_shared<AsynchronousSymbolQuery>(
- SymbolNameSet({Foo}), SymbolState::Ready,
+ SymbolLookupSet({Foo}), SymbolState::Ready,
[&](Expected<SymbolMap> Result) {
cantFail(std::move(Result));
OnCompletionRun = true;
@@ -200,8 +202,8 @@ TEST_F(CoreAPIsStandardTest, LookupWithHiddenSymbols) {
cantFail(JD2.define(absoluteSymbols({{Bar, QuxSym}})));
/// Try a blocking lookup.
- auto Result = cantFail(
- ES.lookup(JITDylibSearchList({{&JD, false}, {&JD2, false}}), {Foo, Bar}));
+ auto Result = cantFail(ES.lookup(makeJITDylibSearchOrder({&JD, &JD2}),
+ SymbolLookupSet({Foo, Bar})));
EXPECT_EQ(Result.size(), 2U) << "Unexpected number of results";
EXPECT_EQ(Result.count(Foo), 1U) << "Missing result for \"Foo\"";
@@ -226,9 +228,9 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) {
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
cantFail(JD.define(std::move(MU)));
- SymbolNameSet Names({Foo, Bar, Baz});
-
- auto SymbolFlags = cantFail(JD.lookupFlags(Names));
+ auto SymbolFlags = cantFail(JD.lookupFlags(
+ LookupKind::Static, JITDylibLookupFlags::MatchExportedSymbolsOnly,
+ SymbolLookupSet({Foo, Bar, Baz})));
EXPECT_EQ(SymbolFlags.size(), 2U)
<< "Returned symbol flags contains unexpected results";
@@ -245,20 +247,24 @@ TEST_F(CoreAPIsStandardTest, LookupWithGeneratorFailure) {
class BadGenerator : public JITDylib::DefinitionGenerator {
public:
- Expected<SymbolNameSet> tryToGenerate(JITDylib &,
- const SymbolNameSet &) override {
+ Error tryToGenerate(LookupKind K, JITDylib &, JITDylibLookupFlags,
+ const SymbolLookupSet &) override {
return make_error<StringError>("BadGenerator", inconvertibleErrorCode());
}
};
JD.addGenerator(std::make_unique<BadGenerator>());
- EXPECT_THAT_ERROR(JD.lookupFlags({Foo}).takeError(), Failed<StringError>())
+ EXPECT_THAT_ERROR(
+ JD.lookupFlags(LookupKind::Static,
+ JITDylibLookupFlags::MatchExportedSymbolsOnly,
+ SymbolLookupSet(Foo))
+ .takeError(),
+ Failed<StringError>())
<< "Generator failure did not propagate through lookupFlags";
EXPECT_THAT_ERROR(
- ES.lookup(JITDylibSearchList({{&JD, false}}), SymbolNameSet({Foo}))
- .takeError(),
+ ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet(Foo)).takeError(),
Failed<StringError>())
<< "Generator failure did not propagate through lookup";
}
@@ -269,7 +275,8 @@ TEST_F(CoreAPIsStandardTest, TestBasicAliases) {
{Qux, {Bar, JITSymbolFlags::Weak}}})));
cantFail(JD.define(absoluteSymbols({{Qux, QuxSym}})));
- auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz, Qux});
+ auto Result =
+ ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Baz, Qux}));
EXPECT_TRUE(!!Result) << "Unexpected lookup failure";
EXPECT_EQ(Result->count(Baz), 1U) << "No result for \"baz\"";
EXPECT_EQ(Result->count(Qux), 1U) << "No result for \"qux\"";
@@ -284,7 +291,8 @@ TEST_F(CoreAPIsStandardTest, TestChainedAliases) {
cantFail(JD.define(symbolAliases(
{{Baz, {Bar, BazSym.getFlags()}}, {Bar, {Foo, BarSym.getFlags()}}})));
- auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar, Baz});
+ auto Result =
+ ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Bar, Baz}));
EXPECT_TRUE(!!Result) << "Unexpected lookup failure";
EXPECT_EQ(Result->count(Bar), 1U) << "No result for \"bar\"";
EXPECT_EQ(Result->count(Baz), 1U) << "No result for \"baz\"";
@@ -303,7 +311,7 @@ TEST_F(CoreAPIsStandardTest, TestBasicReExports) {
cantFail(JD2.define(reexports(JD, {{Bar, {Foo, BarSym.getFlags()}}})));
- auto Result = cantFail(ES.lookup(JITDylibSearchList({{&JD2, false}}), Bar));
+ auto Result = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD2), Bar));
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
<< "Re-export Bar for symbol Foo should match FooSym's address";
}
@@ -329,7 +337,7 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {
cantFail(JD2.define(reexports(
JD, {{Baz, {Foo, BazSym.getFlags()}}, {Qux, {Bar, QuxSym.getFlags()}}})));
- auto Result = cantFail(ES.lookup(JITDylibSearchList({{&JD2, false}}), Baz));
+ auto Result = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD2), Baz));
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
<< "Re-export Baz for symbol Foo should match FooSym's address";
@@ -344,13 +352,16 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) {
auto Filter = [this](SymbolStringPtr Name) { return Name != Bar; };
- JD.addGenerator(std::make_unique<ReexportsGenerator>(JD2, false, Filter));
+ JD.addGenerator(std::make_unique<ReexportsGenerator>(
+ JD2, JITDylibLookupFlags::MatchExportedSymbolsOnly, Filter));
- auto Flags = cantFail(JD.lookupFlags({Foo, Bar, Baz}));
+ auto Flags = cantFail(JD.lookupFlags(
+ LookupKind::Static, JITDylibLookupFlags::MatchExportedSymbolsOnly,
+ SymbolLookupSet({Foo, Bar, Baz})));
EXPECT_EQ(Flags.size(), 1U) << "Unexpected number of results";
EXPECT_EQ(Flags[Foo], FooSym.getFlags()) << "Unexpected flags for Foo";
- auto Result = cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
+ auto Result = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD), Foo));
EXPECT_EQ(Result.getAddress(), FooSym.getAddress())
<< "Incorrect reexported symbol address";
@@ -370,8 +381,9 @@ TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
FooReady = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- OnCompletion, NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet({Foo}), SymbolState::Ready, OnCompletion,
+ NoDependenciesToRegister);
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Foo})}});
EXPECT_THAT_ERROR(FooR->notifyResolved({{Foo, FooSym}}), Succeeded())
@@ -430,11 +442,13 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
// Issue lookups for Foo. Use NoDependenciesToRegister: We're going to add
// the dependencies manually below.
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Resolved,
std::move(OnFooResolution), NoDependenciesToRegister);
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- std::move(OnFooReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Ready, std::move(OnFooReady),
+ NoDependenciesToRegister);
bool BarResolved = false;
bool BarReady = false;
@@ -448,11 +462,13 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
BarReady = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Resolved,
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Bar), SymbolState::Resolved,
std::move(OnBarResolution), NoDependenciesToRegister);
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
- std::move(OnBarReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Bar), SymbolState::Ready, std::move(OnBarReady),
+ NoDependenciesToRegister);
bool BazResolved = false;
bool BazReady = false;
@@ -467,11 +483,13 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
BazReady = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Resolved,
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Baz), SymbolState::Resolved,
std::move(OnBazResolution), NoDependenciesToRegister);
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Ready,
- std::move(OnBazReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Baz), SymbolState::Ready, std::move(OnBazReady),
+ NoDependenciesToRegister);
// Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
@@ -551,8 +569,9 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) {
OnFooReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- std::move(OnFooReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Ready, std::move(OnFooReady),
+ NoDependenciesToRegister);
bool OnBarReadyRun = false;
auto OnBarReady = [&](Expected<SymbolMap> Result) {
@@ -560,8 +579,9 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) {
OnBarReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
- std::move(OnBarReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Bar), SymbolState::Ready, std::move(OnBarReady),
+ NoDependenciesToRegister);
// Add a dependency by Foo on Bar.
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
@@ -614,8 +634,9 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
OnFooReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- std::move(OnFooReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Ready, std::move(OnFooReady),
+ NoDependenciesToRegister);
bool OnBarReadyRun = false;
auto OnBarReady = [&](Expected<SymbolMap> Result) {
@@ -623,8 +644,9 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) {
OnBarReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
- std::move(OnBarReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Bar), SymbolState::Ready, std::move(OnBarReady),
+ NoDependenciesToRegister);
// Add a dependency by Foo on Bar and vice-versa.
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
@@ -678,8 +700,9 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
OnFooReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- std::move(OnFooReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Ready, std::move(OnFooReady),
+ NoDependenciesToRegister);
bool OnBarReadyRun = false;
auto OnBarReady = [&](Expected<SymbolMap> Result) {
@@ -687,8 +710,9 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) {
OnBarReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
- std::move(OnBarReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Bar), SymbolState::Ready, std::move(OnBarReady),
+ NoDependenciesToRegister);
// Fail bar.
BarR->failMaterialization();
@@ -742,8 +766,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) {
OnFooReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- std::move(OnFooReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Ready, std::move(OnFooReady),
+ NoDependenciesToRegister);
bool OnBarReadyRun = false;
auto OnBarReady = [&](Expected<SymbolMap> Result) {
@@ -751,8 +776,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) {
OnBarReadyRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
- std::move(OnBarReady), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Bar), SymbolState::Ready, std::move(OnBarReady),
+ NoDependenciesToRegister);
// Add a dependency by Foo on Bar and vice-versa.
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
@@ -854,8 +880,6 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
cantFail(JD.define(MU));
cantFail(JD.define(absoluteSymbols({{Bar, BarSym}})));
- SymbolNameSet Names({Foo});
-
bool OnCompletionRun = false;
auto OnCompletion = [&](Expected<SymbolMap> Result) {
@@ -867,8 +891,9 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {
OnCompletionRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), Names, SymbolState::Ready,
- std::move(OnCompletion), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Ready, std::move(OnCompletion),
+ NoDependenciesToRegister);
EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
@@ -910,8 +935,9 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
OnCompletionRun = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
- std::move(OnCompletion), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Bar), SymbolState::Ready, std::move(OnCompletion),
+ NoDependenciesToRegister);
EXPECT_TRUE(OnCompletionRun) << "OnCompletion not run";
EXPECT_TRUE(BarMaterialized) << "Bar was not materialized at all";
@@ -938,13 +964,13 @@ TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) {
});
cantFail(JD.define(MU));
- cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
+ cantFail(ES.lookup(makeJITDylibSearchOrder(&JD), Foo));
// Assert that materialization is complete by now.
ExpectNoMoreMaterialization = true;
// Look up bar to verify that no further materialization happens.
- auto BarResult = cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Bar));
+ auto BarResult = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD), Bar));
EXPECT_EQ(BarResult.getAddress(), BarSym.getAddress())
<< "Expected Bar == BarSym";
}
@@ -955,19 +981,19 @@ TEST_F(CoreAPIsStandardTest, GeneratorTest) {
class TestGenerator : public JITDylib::DefinitionGenerator {
public:
TestGenerator(SymbolMap Symbols) : Symbols(std::move(Symbols)) {}
- Expected<SymbolNameSet> tryToGenerate(JITDylib &JD,
- const SymbolNameSet &Names) {
+ Error tryToGenerate(LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &Names) {
SymbolMap NewDefs;
- SymbolNameSet NewNames;
- for (auto &Name : Names) {
- if (Symbols.count(Name)) {
+ for (const auto &KV : Names) {
+ const auto &Name = KV.first;
+ if (Symbols.count(Name))
NewDefs[Name] = Symbols[Name];
- NewNames.insert(Name);
- }
}
+
cantFail(JD.define(absoluteSymbols(std::move(NewDefs))));
- return NewNames;
+ return Error::success();
};
private:
@@ -976,8 +1002,8 @@ TEST_F(CoreAPIsStandardTest, GeneratorTest) {
JD.addGenerator(std::make_unique<TestGenerator>(SymbolMap({{Bar, BarSym}})));
- auto Result =
- cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Bar}));
+ auto Result = cantFail(
+ ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo, Bar})));
EXPECT_EQ(Result.count(Bar), 1U) << "Expected to find fallback def for 'bar'";
EXPECT_EQ(Result[Bar].getAddress(), BarSym.getAddress())
@@ -995,7 +1021,7 @@ TEST_F(CoreAPIsStandardTest, FailResolution) {
cantFail(JD.define(MU));
SymbolNameSet Names({Foo, Bar});
- auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), Names);
+ auto Result = ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet(Names));
EXPECT_FALSE(!!Result) << "Expected failure";
if (!Result) {
@@ -1028,8 +1054,8 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) {
cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})));
ES.lookup(
- JITDylibSearchList({{&JD, false}}), SymbolNameSet({Baz}),
- SymbolState::Resolved,
+ LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet({Baz}), SymbolState::Resolved,
[&R](Expected<SymbolMap> Result) {
// Called when "baz" is resolved. We don't actually depend
// on or care about baz, but use it to trigger failure of
@@ -1046,8 +1072,8 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) {
cantFail(JD.define(MU));
- SymbolNameSet Names({Foo, Bar});
- auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), Names);
+ auto Result =
+ ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo, Bar}));
EXPECT_THAT_EXPECTED(std::move(Result), Failed())
<< "Unexpected success while trying to test error propagation";
@@ -1066,8 +1092,8 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) {
bool QueryHandlerRun = false;
ES.lookup(
- JITDylibSearchList({{&JD, false}}), SymbolNameSet({Foo, Bar}),
- SymbolState::Resolved,
+ LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet({Foo, Bar}), SymbolState::Resolved,
[&](Expected<SymbolMap> Result) {
EXPECT_THAT_EXPECTED(std::move(Result), Failed())
<< "Expected query to fail";
@@ -1087,8 +1113,7 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
cantFail(JD.define(MU));
- auto FooLookupResult =
- cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
+ auto FooLookupResult = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD), Foo));
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
<< "lookup returned an incorrect address";
@@ -1108,8 +1133,7 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
- auto FooLookupResult =
- cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
+ auto FooLookupResult = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD), Foo));
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
<< "lookup returned an incorrect address";
@@ -1157,16 +1181,14 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) {
EXPECT_FALSE(FooMaterialized) << "Foo should not be materialized yet";
EXPECT_FALSE(BarMaterialized) << "Bar should not be materialized yet";
- auto FooSymResult =
- cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Foo));
+ auto FooSymResult = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD), Foo));
EXPECT_EQ(FooSymResult.getAddress(), FooSym.getAddress())
<< "Address mismatch for Foo";
EXPECT_TRUE(FooMaterialized) << "Foo should be materialized now";
EXPECT_FALSE(BarMaterialized) << "Bar still should not be materialized";
- auto BarSymResult =
- cantFail(ES.lookup(JITDylibSearchList({{&JD, false}}), Bar));
+ auto BarSymResult = cantFail(ES.lookup(makeJITDylibSearchOrder(&JD), Bar));
EXPECT_EQ(BarSymResult.getAddress(), BarSym.getAddress())
<< "Address mismatch for Bar";
EXPECT_TRUE(BarMaterialized) << "Bar should be materialized now";
@@ -1186,7 +1208,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) {
cantFail(JD.define(MU));
- auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Bar});
+ auto Result =
+ ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo, Bar}));
EXPECT_TRUE(!!Result) << "Result should be a success value";
EXPECT_EQ(Result->count(Foo), 1U) << "\"Foo\" entry missing";
@@ -1216,8 +1239,9 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) {
cantFail(std::move(Result));
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
- std::move(OnCompletion), NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet({Foo}), SymbolState::Ready, std::move(OnCompletion),
+ NoDependenciesToRegister);
auto MU2 = std::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
diff --git a/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
index f79d721b812..7b6d4b078fb 100644
--- a/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
@@ -24,7 +24,9 @@ TEST_F(LegacyAPIsStandardTest, TestLambdaSymbolResolver) {
auto Resolver = createSymbolResolver(
[&](const SymbolNameSet &Symbols) {
- auto FlagsMap = cantFail(JD.lookupFlags(Symbols));
+ auto FlagsMap = cantFail(JD.lookupFlags(
+ LookupKind::Static, JITDylibLookupFlags::MatchExportedSymbolsOnly,
+ SymbolLookupSet(Symbols)));
SymbolNameSet Result;
for (auto &KV : FlagsMap)
if (!KV.second.isStrong())
@@ -57,7 +59,7 @@ TEST_F(LegacyAPIsStandardTest, TestLambdaSymbolResolver) {
};
auto Q = std::make_shared<AsynchronousSymbolQuery>(
- SymbolNameSet({Foo, Bar}), SymbolState::Resolved, OnCompletion);
+ SymbolLookupSet({Foo, Bar}), SymbolState::Resolved, OnCompletion);
auto Unresolved =
Resolver->lookup(std::move(Q), SymbolNameSet({Foo, Bar, Baz}));
@@ -111,7 +113,8 @@ TEST_F(LegacyAPIsStandardTest, LegacyLookupHelpersFn) {
<< "Wrong flags for bar";
};
- AsynchronousSymbolQuery Q({Foo, Bar}, SymbolState::Resolved, OnCompletion);
+ AsynchronousSymbolQuery Q(SymbolLookupSet({Foo, Bar}), SymbolState::Resolved,
+ OnCompletion);
auto Unresolved =
lookupWithLegacyFn(ES, Q, SymbolNameSet({Foo, Bar, Baz}), LegacyLookup);
diff --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
index ecb8cf65393..f1c0da6a9ab 100644
--- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
@@ -63,8 +63,9 @@ static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
ObjLayer.setProcessAllSections(ProcessAllSections);
cantFail(ObjLayer.add(JD, std::move(Obj), ES.allocateVModule()));
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
- OnResolveDoNothing, NoDependenciesToRegister);
+ ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD),
+ SymbolLookupSet(Foo), SymbolState::Resolved, OnResolveDoNothing,
+ NoDependenciesToRegister);
return DebugSectionSeen;
}
@@ -160,7 +161,8 @@ TEST(RTDyldObjectLinkingLayerTest, TestOverrideObjectFlags) {
cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
ES.lookup(
- JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+ LookupKind::Static, makeJITDylibSearchOrder(&JD), SymbolLookupSet(Foo),
+ SymbolState::Resolved,
[](Expected<SymbolMap> R) { cantFail(std::move(R)); },
NoDependenciesToRegister);
}
@@ -225,7 +227,8 @@ TEST(RTDyldObjectLinkingLayerTest, TestAutoClaimResponsibilityForSymbols) {
cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
ES.lookup(
- JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+ LookupKind::Static, makeJITDylibSearchOrder(&JD), SymbolLookupSet(Foo),
+ SymbolState::Resolved,
[](Expected<SymbolMap> R) { cantFail(std::move(R)); },
NoDependenciesToRegister);
}
OpenPOWER on IntegriCloud