[llvm] 803c770 - [C-API][ORC] Add LLVMOrcExecutionSessionLookup -- generic async symbol lookup.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 13 16:37:47 PDT 2022
Author: Lang Hames
Date: 2022-06-13T16:37:35-07:00
New Revision: 803c770ee0a2833beba2365a269d36fb08cb6f5d
URL: https://github.com/llvm/llvm-project/commit/803c770ee0a2833beba2365a269d36fb08cb6f5d
DIFF: https://github.com/llvm/llvm-project/commit/803c770ee0a2833beba2365a269d36fb08cb6f5d.diff
LOG: [C-API][ORC] Add LLVMOrcExecutionSessionLookup -- generic async symbol lookup.
An API to wrap ExecutionSession::lookup, this allows C API clients to use async
lookup.
The immediate motivation for adding this is to simplify upcoming
definition-generator unit tests.
As we're adding more tests that need to convert between C and C++ flag values
this commit adds helper functions to support this. This patch also updates the
CAPIDefinitionGenerator to use these new utilities.
Added:
Modified:
llvm/include/llvm-c/Orc.h
llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm-c/Orc.h b/llvm/include/llvm-c/Orc.h
index 57478208a6d06..e843e76a6da0f 100644
--- a/llvm/include/llvm-c/Orc.h
+++ b/llvm/include/llvm-c/Orc.h
@@ -54,6 +54,7 @@ typedef uint64_t LLVMOrcExecutorAddress;
* Represents generic linkage flags for a symbol definition.
*/
typedef enum {
+ LLVMJITSymbolGenericFlagsNone = 0,
LLVMJITSymbolGenericFlagsExported = 1U << 0,
LLVMJITSymbolGenericFlagsWeak = 1U << 1,
LLVMJITSymbolGenericFlagsCallable = 1U << 2,
@@ -202,6 +203,22 @@ typedef enum {
LLVMOrcJITDylibLookupFlagsMatchAllSymbols
} LLVMOrcJITDylibLookupFlags;
+/**
+ * An element type for a JITDylib search order.
+ */
+typedef struct {
+ LLVMOrcJITDylibRef JD;
+ LLVMOrcJITDylibLookupFlags JDLookupFlags;
+} LLVMOrcCJITDylibSearchOrderElement;
+
+/**
+ * A JITDylib search order.
+ *
+ * The list is terminated with an element containing a null pointer for the JD
+ * field.
+ */
+typedef LLVMOrcCJITDylibSearchOrderElement *LLVMOrcCJITDylibSearchOrder;
+
/**
* Symbol lookup flags for lookup sets. This should be kept in sync with
* llvm::orc::SymbolLookupFlags.
@@ -494,6 +511,58 @@ void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP);
LLVMOrcSymbolStringPoolEntryRef
LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name);
+/**
+ * Callback type for ExecutionSession lookups.
+ *
+ * If Err is LLVMErrorSuccess then Result will contain a pointer to a
+ * list of ( SymbolStringPtr, JITEvaluatedSymbol ) pairs of length NumPairs.
+ *
+ * If Err is a failure value then Result and Ctx are undefined and should
+ * not be accessed. The Callback is responsible for handling the error
+ * value (e.g. by calling LLVMGetErrorMessage + LLVMDisposeErrorMessage).
+ *
+ * The caller retains ownership of the Result array and will release all
+ * contained symbol names. Clients are responsible for retaining any symbol
+ * names that they wish to hold after the function returns.
+ */
+typedef void (*LLVMOrcExecutionSessionLookupHandleResultFunction)(
+ LLVMErrorRef Err, LLVMOrcCSymbolMapPairs Result, size_t NumPairs,
+ void *Ctx);
+
+/**
+ * Look up symbols in an execution session.
+ *
+ * This is a wrapper around the general ExecutionSession::lookup function.
+ *
+ * The SearchOrder argument contains a list of (JITDylibs, JITDylibSearchFlags)
+ * pairs that describe the search order. The JITDylibs will be searched in the
+ * given order to try to find the symbols in the Symbols argument.
+ *
+ * The Symbols argument should contain a null-terminated array of
+ * (SymbolStringPtr, SymbolLookupFlags) pairs describing the symbols to be
+ * searched for. This function takes ownership of the elements of the Symbols
+ * array. The Name fields of the Symbols elements are taken to have been
+ * retained by the client for this function. The client should *not* release the
+ * Name fields, but are still responsible for destroying the array itself.
+ *
+ * The HandleResult function will be called once all searched for symbols have
+ * been found, or an error occurs. The HandleResult function will be passed an
+ * LLVMErrorRef indicating success or failure, and (on success) a
+ * null-terminated LLVMOrcCSymbolMapPairs array containing the function result,
+ * and the Ctx value passed to the lookup function.
+ *
+ * The client is fully responsible for managing the lifetime of the Ctx object.
+ * A common idiom is to allocate the context prior to the lookup and deallocate
+ * it in the handler.
+ *
+ * THIS API IS EXPERIMENTAL AND LIKELY TO CHANGE IN THE NEAR FUTURE!
+ */
+void LLVMOrcExecutionSessionLookup(
+ LLVMOrcExecutionSessionRef ES, LLVMOrcLookupKind K,
+ LLVMOrcCJITDylibSearchOrder SearchOrder, size_t SearchOrderSize,
+ LLVMOrcCLookupSet Symbols, size_t SymbolsSize,
+ LLVMOrcExecutionSessionLookupHandleResultFunction HandleResult, void *Ctx);
+
/**
* Increments the ref-count for a SymbolStringPool entry.
*/
@@ -547,7 +616,7 @@ void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU);
* unit. This function takes ownership of the elements of the Syms array. The
* Name fields of the array elements are taken to have been retained for this
* function. The client should *not* release the elements of the array, but is
- * still responsible for destroyingthe array itself.
+ * still responsible for destroying the array itself.
*
* The InitSym argument indicates whether or not this MaterializationUnit
* contains static initializers. If three are no static initializers (the common
@@ -701,7 +770,7 @@ LLVMOrcMaterializationResponsibilityGetRequestedSymbols(
*/
void LLVMOrcDisposeSymbols(LLVMOrcSymbolStringPoolEntryRef *Symbols);
-/*
+/**
* Notifies the target JITDylib that the given symbols have been resolved.
* This will update the given symbols' addresses in the JITDylib, and notify
* any pending queries on the given symbols of their resolution. The given
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
index 2f61b31ae3832..6dfd5548fcfdb 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
@@ -15,7 +15,6 @@
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
#include "MachOLinkGraphBuilder.h"
-#include "PerGraphGOTAndPLTStubsBuilder.h"
#define DEBUG_TYPE "jitlink"
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
index ca52d3ea3a5d0..0d1024ab14556 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
@@ -106,82 +106,6 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
-namespace llvm {
-namespace orc {
-
-class CAPIDefinitionGenerator final : public DefinitionGenerator {
-public:
- CAPIDefinitionGenerator(
- void *Ctx,
- LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
- : Ctx(Ctx), TryToGenerate(TryToGenerate) {}
-
- Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
- JITDylibLookupFlags JDLookupFlags,
- const SymbolLookupSet &LookupSet) override {
-
- // Take the lookup state.
- LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
-
- // Translate the lookup kind.
- LLVMOrcLookupKind CLookupKind;
- switch (K) {
- case LookupKind::Static:
- CLookupKind = LLVMOrcLookupKindStatic;
- break;
- case LookupKind::DLSym:
- CLookupKind = LLVMOrcLookupKindDLSym;
- break;
- }
-
- // Translate the JITDylibSearchFlags.
- LLVMOrcJITDylibLookupFlags CJDLookupFlags;
- switch (JDLookupFlags) {
- case JITDylibLookupFlags::MatchExportedSymbolsOnly:
- CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
- break;
- case JITDylibLookupFlags::MatchAllSymbols:
- CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
- break;
- }
-
- // Translate the lookup set.
- std::vector<LLVMOrcCLookupSetElement> CLookupSet;
- CLookupSet.reserve(LookupSet.size());
- for (auto &KV : LookupSet) {
- LLVMOrcSymbolLookupFlags SLF;
- LLVMOrcSymbolStringPoolEntryRef Name =
- ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
- switch (KV.second) {
- case SymbolLookupFlags::RequiredSymbol:
- SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol;
- break;
- case SymbolLookupFlags::WeaklyReferencedSymbol:
- SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
- break;
- }
- CLookupSet.push_back({Name, SLF});
- }
-
- // Run the C TryToGenerate function.
- auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
- ::wrap(&JD), CJDLookupFlags,
- CLookupSet.data(), CLookupSet.size()));
-
- // Restore the lookup state.
- OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
-
- return Err;
- }
-
-private:
- void *Ctx;
- LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
-};
-
-} // end namespace orc
-} // end namespace llvm
-
namespace {
class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit {
@@ -282,8 +206,128 @@ toSymbolDependenceMap(LLVMOrcCDependenceMapPairs Pairs, size_t NumPairs) {
return SDM;
}
+static LookupKind toLookupKind(LLVMOrcLookupKind K) {
+ switch (K) {
+ case LLVMOrcLookupKindStatic:
+ return LookupKind::Static;
+ case LLVMOrcLookupKindDLSym:
+ return LookupKind::DLSym;
+ }
+ llvm_unreachable("unrecognized LLVMOrcLookupKind value");
+}
+
+static LLVMOrcLookupKind fromLookupKind(LookupKind K) {
+ switch (K) {
+ case LookupKind::Static:
+ return LLVMOrcLookupKindStatic;
+ case LookupKind::DLSym:
+ return LLVMOrcLookupKindDLSym;
+ }
+ llvm_unreachable("unrecognized LookupKind value");
+}
+
+static JITDylibLookupFlags
+toJITDylibLookupFlags(LLVMOrcJITDylibLookupFlags LF) {
+ switch (LF) {
+ case LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly:
+ return JITDylibLookupFlags::MatchExportedSymbolsOnly;
+ case LLVMOrcJITDylibLookupFlagsMatchAllSymbols:
+ return JITDylibLookupFlags::MatchAllSymbols;
+ }
+ llvm_unreachable("unrecognized LLVMOrcJITDylibLookupFlags value");
+}
+
+static LLVMOrcJITDylibLookupFlags
+fromJITDylibLookupFlags(JITDylibLookupFlags LF) {
+ switch (LF) {
+ case JITDylibLookupFlags::MatchExportedSymbolsOnly:
+ return LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
+ case JITDylibLookupFlags::MatchAllSymbols:
+ return LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
+ }
+ llvm_unreachable("unrecognized JITDylibLookupFlags value");
+}
+
+static SymbolLookupFlags toSymbolLookupFlags(LLVMOrcSymbolLookupFlags SLF) {
+ switch (SLF) {
+ case LLVMOrcSymbolLookupFlagsRequiredSymbol:
+ return SymbolLookupFlags::RequiredSymbol;
+ case LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol:
+ return SymbolLookupFlags::WeaklyReferencedSymbol;
+ }
+ llvm_unreachable("unrecognized LLVMOrcSymbolLookupFlags value");
+}
+
+static LLVMOrcSymbolLookupFlags fromSymbolLookupFlags(SymbolLookupFlags SLF) {
+ switch (SLF) {
+ case SymbolLookupFlags::RequiredSymbol:
+ return LLVMOrcSymbolLookupFlagsRequiredSymbol;
+ case SymbolLookupFlags::WeaklyReferencedSymbol:
+ return LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
+ }
+ llvm_unreachable("unrecognized SymbolLookupFlags value");
+}
+
+static LLVMJITEvaluatedSymbol
+fromJITEvaluatedSymbol(const JITEvaluatedSymbol &S) {
+ return {S.getAddress(), fromJITSymbolFlags(S.getFlags())};
+}
+
} // end anonymous namespace
+namespace llvm {
+namespace orc {
+
+class CAPIDefinitionGenerator final : public DefinitionGenerator {
+public:
+ CAPIDefinitionGenerator(
+ void *Ctx,
+ LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
+ : Ctx(Ctx), TryToGenerate(TryToGenerate) {}
+
+ Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags,
+ const SymbolLookupSet &LookupSet) override {
+
+ // Take the lookup state.
+ LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
+
+ // Translate the lookup kind.
+ LLVMOrcLookupKind CLookupKind = fromLookupKind(K);
+
+ // Translate the JITDylibLookupFlags.
+ LLVMOrcJITDylibLookupFlags CJDLookupFlags =
+ fromJITDylibLookupFlags(JDLookupFlags);
+
+ // Translate the lookup set.
+ std::vector<LLVMOrcCLookupSetElement> CLookupSet;
+ CLookupSet.reserve(LookupSet.size());
+ for (auto &KV : LookupSet) {
+ LLVMOrcSymbolStringPoolEntryRef Name =
+ ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
+ LLVMOrcSymbolLookupFlags SLF = fromSymbolLookupFlags(KV.second);
+ CLookupSet.push_back({Name, SLF});
+ }
+
+ // Run the C TryToGenerate function.
+ auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
+ ::wrap(&JD), CJDLookupFlags,
+ CLookupSet.data(), CLookupSet.size()));
+
+ // Restore the lookup state.
+ OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
+
+ return Err;
+ }
+
+private:
+ void *Ctx;
+ LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
void LLVMOrcExecutionSessionSetErrorReporter(
LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
void *Ctx) {
@@ -307,6 +351,42 @@ LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) {
OrcV2CAPIHelper::moveFromSymbolStringPtr(unwrap(ES)->intern(Name)));
}
+void LLVMOrcExecutionSessionLookup(
+ LLVMOrcExecutionSessionRef ES, LLVMOrcLookupKind K,
+ LLVMOrcCJITDylibSearchOrder SearchOrder, size_t SearchOrderSize,
+ LLVMOrcCLookupSet Symbols, size_t SymbolsSize,
+ LLVMOrcExecutionSessionLookupHandleResultFunction HandleResult, void *Ctx) {
+ assert(ES && "ES cannot be null");
+ assert(SearchOrder && "SearchOrder cannot be null");
+ assert(Symbols && "Symbols cannot be null");
+ assert(HandleResult && "HandleResult cannot be null");
+
+ JITDylibSearchOrder SO;
+ for (size_t I = 0; I != SearchOrderSize; ++I)
+ SO.push_back({unwrap(SearchOrder[I].JD),
+ toJITDylibLookupFlags(SearchOrder[I].JDLookupFlags)});
+
+ SymbolLookupSet SLS;
+ for (size_t I = 0; I != SymbolsSize; ++I)
+ SLS.add(OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Symbols[I].Name)),
+ toSymbolLookupFlags(Symbols[I].LookupFlags));
+
+ unwrap(ES)->lookup(
+ toLookupKind(K), SO, std::move(SLS), SymbolState::Ready,
+ [HandleResult, Ctx](Expected<SymbolMap> Result) {
+ if (Result) {
+ SmallVector<LLVMOrcCSymbolMapPair> CResult;
+ for (auto &KV : *Result)
+ CResult.push_back(LLVMOrcCSymbolMapPair{
+ wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first)),
+ fromJITEvaluatedSymbol(KV.second)});
+ HandleResult(LLVMErrorSuccess, CResult.data(), CResult.size(), Ctx);
+ } else
+ HandleResult(wrap(Result.takeError()), nullptr, 0, Ctx);
+ },
+ NoDependenciesToRegister);
+}
+
void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
OrcV2CAPIHelper::retainPoolEntry(unwrap(S));
}
diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
index 0a18fda0d4e03..2660c8bf72b2b 100644
--- a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
@@ -18,7 +18,9 @@
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Testing/Support/Error.h"
#include <string>
using namespace llvm;
@@ -265,6 +267,146 @@ TEST_F(OrcCAPITestBase, MaterializationUnitCreation) {
ASSERT_EQ(Addr, OutAddr);
}
+struct ExecutionSessionLookupHelper {
+ bool ExpectSuccess = true;
+ bool CallbackReceived = false;
+ size_t NumExpectedPairs;
+ LLVMOrcCSymbolMapPair *ExpectedMapping;
+};
+
+static void executionSessionLookupHandlerCallback(LLVMErrorRef Err,
+ LLVMOrcCSymbolMapPairs Result,
+ size_t NumPairs,
+ void *RawCtx) {
+ auto *Ctx = static_cast<ExecutionSessionLookupHelper *>(RawCtx);
+ Ctx->CallbackReceived = true;
+ if (Ctx->ExpectSuccess) {
+ EXPECT_THAT_ERROR(unwrap(Err), Succeeded());
+ EXPECT_EQ(NumPairs, Ctx->NumExpectedPairs)
+ << "Expected " << Ctx->NumExpectedPairs << " entries in result, got "
+ << NumPairs;
+ auto ExpectedMappingEnd = Ctx->ExpectedMapping + Ctx->NumExpectedPairs;
+ for (unsigned I = 0; I != NumPairs; ++I) {
+ auto J =
+ std::find_if(Ctx->ExpectedMapping, ExpectedMappingEnd,
+ [N = Result[I].Name](const LLVMOrcCSymbolMapPair &Val) {
+ return Val.Name == N;
+ });
+ EXPECT_NE(J, ExpectedMappingEnd)
+ << "Missing symbol \""
+ << LLVMOrcSymbolStringPoolEntryStr(Result[I].Name) << "\"";
+ if (J != ExpectedMappingEnd) {
+ EXPECT_EQ(Result[I].Sym.Address, J->Sym.Address)
+ << "Result map for \"" << Result[I].Name
+ << "\"
diff ers from expected value: "
+ << formatv("{0:x} vs {1:x}", Result[I].Sym.Address, J->Sym.Address);
+ }
+ }
+ } else
+ EXPECT_THAT_ERROR(unwrap(Err), Failed());
+}
+
+TEST_F(OrcCAPITestBase, ExecutionSessionLookup_Success) {
+ // Test a successful generic lookup. We will look up three symbols over two
+ // JITDylibs: { "Foo" (Required), "Bar" (Weakly-ref), "Baz" (Required) } over
+ // { MainJITDylib (Exported-only), ExtraJD (All symbols) }.
+ //
+ // Foo will be defined as exported in MainJD.
+ // Bar will be defined as non-exported in MainJD.
+ // Baz will be defined as non-exported in ExtraJD.
+ //
+ // This will require (1) that we find the regular exported symbol Foo in
+ // MainJD, (2) that we *don't* find the non-exported symbol Bar in MainJD
+ // but also don't error (since it's weakly referenced), and (3) that we
+ // find the non-exported symbol Baz in ExtraJD (since we're searching all
+ // symbols in ExtraJD).
+
+ ExecutionSessionLookupHelper H;
+ LLVMOrcSymbolStringPoolEntryRef Foo = LLVMOrcLLJITMangleAndIntern(Jit, "Foo");
+ LLVMOrcSymbolStringPoolEntryRef Bar = LLVMOrcLLJITMangleAndIntern(Jit, "Bar");
+ LLVMOrcSymbolStringPoolEntryRef Baz = LLVMOrcLLJITMangleAndIntern(Jit, "Baz");
+
+ // Create ExtraJD.
+ LLVMOrcJITDylibRef ExtraJD = nullptr;
+ if (auto E = LLVMOrcExecutionSessionCreateJITDylib(ExecutionSession, &ExtraJD,
+ "ExtraJD")) {
+ FAIL() << "Unexpected error while creating JITDylib \"ExtraJD\" (triple = "
+ << TargetTriple << "): " << toString(E);
+ return;
+ }
+
+ // Add exported symbols "Foo" and "Bar" to Main JITDylib.
+ LLVMOrcRetainSymbolStringPoolEntry(Foo);
+ LLVMOrcRetainSymbolStringPoolEntry(Bar);
+ LLVMOrcCSymbolMapPair MainJDPairs[] = {
+ {Foo, {0x1, {LLVMJITSymbolGenericFlagsExported, 0}}},
+ {Bar, {0x2, {LLVMJITSymbolGenericFlagsNone, 0}}}};
+ LLVMOrcMaterializationUnitRef MainJDMU =
+ LLVMOrcAbsoluteSymbols(MainJDPairs, 2);
+ if (LLVMErrorRef E = LLVMOrcJITDylibDefine(MainDylib, MainJDMU))
+ FAIL() << "Unexpected error while adding MainDylib symbols (triple = "
+ << TargetTriple << "): " << toString(E);
+
+ // Add non-exported symbol "Baz" to ExtraJD.
+ LLVMOrcRetainSymbolStringPoolEntry(Baz);
+ LLVMOrcCSymbolMapPair ExtraJDPairs[] = {
+ {Baz, {0x3, {LLVMJITSymbolGenericFlagsNone, 0}}}};
+ LLVMOrcMaterializationUnitRef ExtraJDMU =
+ LLVMOrcAbsoluteSymbols(ExtraJDPairs, 1);
+ if (LLVMErrorRef E = LLVMOrcJITDylibDefine(ExtraJD, ExtraJDMU))
+ FAIL() << "Unexpected error while adding ExtraJD symbols (triple = "
+ << TargetTriple << "): " << toString(E);
+
+ // Create expected mapping for result:
+ LLVMOrcCSymbolMapPair ExpectedMapping[] = {
+ {Foo, {0x1, {LLVMJITSymbolGenericFlagsExported, 0}}},
+ {Baz, {0x3, {LLVMJITSymbolGenericFlagsNone, 0}}}};
+ H.ExpectedMapping = ExpectedMapping;
+ H.NumExpectedPairs = 2;
+
+ // Issue the lookup. We're using the default same-thread dispatch, so the
+ // handler should have run by the time we return from this call.
+ LLVMOrcCJITDylibSearchOrderElement SO[] = {
+ {MainDylib, LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly},
+ {ExtraJD, LLVMOrcJITDylibLookupFlagsMatchAllSymbols}};
+
+ LLVMOrcRetainSymbolStringPoolEntry(Foo);
+ LLVMOrcRetainSymbolStringPoolEntry(Bar);
+ LLVMOrcRetainSymbolStringPoolEntry(Baz);
+ LLVMOrcCLookupSetElement LS[] = {
+ {Foo, LLVMOrcSymbolLookupFlagsRequiredSymbol},
+ {Bar, LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol},
+ {Baz, LLVMOrcSymbolLookupFlagsRequiredSymbol}};
+ LLVMOrcExecutionSessionLookup(ExecutionSession, LLVMOrcLookupKindStatic, SO,
+ 2, LS, 3, executionSessionLookupHandlerCallback,
+ &H);
+
+ EXPECT_TRUE(H.CallbackReceived) << "Lookup callback never received";
+
+ // Release our local string ptrs.
+ LLVMOrcReleaseSymbolStringPoolEntry(Baz);
+ LLVMOrcReleaseSymbolStringPoolEntry(Bar);
+ LLVMOrcReleaseSymbolStringPoolEntry(Foo);
+}
+
+TEST_F(OrcCAPITestBase, ExecutionSessionLookup_Failure) {
+ // Test generic lookup failure case. We will look up a symbol in MainDylib
+ // without defining it. We expect this to result in a symbol-not-found error.
+
+ ExecutionSessionLookupHelper H;
+ H.ExpectSuccess = false;
+
+ LLVMOrcCJITDylibSearchOrderElement SO[] = {
+ {MainDylib, LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly}};
+ LLVMOrcCLookupSetElement LS[] = {{LLVMOrcLLJITMangleAndIntern(Jit, "Foo"),
+ LLVMOrcSymbolLookupFlagsRequiredSymbol}};
+ LLVMOrcExecutionSessionLookup(ExecutionSession, LLVMOrcLookupKindStatic, SO,
+ 1, LS, 1, executionSessionLookupHandlerCallback,
+ &H);
+
+ EXPECT_TRUE(H.CallbackReceived) << "Lookup callback never received";
+}
+
TEST_F(OrcCAPITestBase, DefinitionGenerators) {
LLVMOrcDefinitionGeneratorRef Gen =
LLVMOrcCreateCustomCAPIDefinitionGenerator(&definitionGeneratorFn,
More information about the llvm-commits
mailing list