1 #include "OrcTestCommon.h"
2 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
3 #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
4 #include "gtest/gtest.h"
7 using namespace llvm::orc
;
9 class LazyReexportsTest
: public CoreAPIsBasedStandardTest
{};
11 static int dummyTarget() { return 42; }
13 TEST_F(LazyReexportsTest
, BasicLocalCallThroughManagerOperation
) {
14 // Create a callthrough manager for the host (if possible) and verify that
15 // a call to the lazy call-through:
16 // (1) Materializes the MU. This verifies that the symbol was looked up, and
17 // that we didn't arrive at the target via some other path
18 // (2) Returns the expected value (which we take as proof that the call
19 // reached the target).
21 auto JTMB
= JITTargetMachineBuilder::detectHost();
23 // Bail out if we can not detect the host.
25 consumeError(JTMB
.takeError());
29 // Bail out if we can not build a local call-through manager.
30 auto LCTM
= createLocalLazyCallThroughManager(JTMB
->getTargetTriple(), ES
, 0);
32 consumeError(LCTM
.takeError());
36 auto DummyTarget
= ES
.intern("DummyTarget");
38 bool DummyTargetMaterialized
= false;
40 cantFail(JD
.define(std::make_unique
<SimpleMaterializationUnit
>(
41 SymbolFlagsMap({{DummyTarget
, JITSymbolFlags::Exported
}}),
42 [&](MaterializationResponsibility R
) {
43 DummyTargetMaterialized
= true;
44 // No dependencies registered, can't fail.
45 cantFail(R
.notifyResolved(
47 JITEvaluatedSymbol(static_cast<JITTargetAddress
>(
48 reinterpret_cast<uintptr_t>(&dummyTarget
)),
49 JITSymbolFlags::Exported
)}}));
50 cantFail(R
.notifyEmitted());
53 unsigned NotifyResolvedCount
= 0;
54 auto NotifyResolved
= LazyCallThroughManager::createNotifyResolvedFunction(
55 [&](JITDylib
&JD
, const SymbolStringPtr
&SymbolName
,
56 JITTargetAddress ResolvedAddr
) {
57 ++NotifyResolvedCount
;
58 return Error::success();
61 auto CallThroughTrampoline
= cantFail((*LCTM
)->getCallThroughTrampoline(
62 JD
, DummyTarget
, std::move(NotifyResolved
)));
64 auto CTTPtr
= reinterpret_cast<int (*)()>(
65 static_cast<uintptr_t>(CallThroughTrampoline
));
67 // Call twice to verify nothing unexpected happens on redundant calls.
68 auto Result
= CTTPtr();
71 EXPECT_TRUE(DummyTargetMaterialized
)
72 << "CallThrough did not materialize target";
73 EXPECT_EQ(NotifyResolvedCount
, 1U)
74 << "CallThrough should have generated exactly one 'NotifyResolved' call";
75 EXPECT_EQ(Result
, 42) << "Failed to call through to target";