blob: ebe99d483527cb5f846bb8a4a187e0906ccf3b4f [file] [log] [blame]
Lang Hamesc1275e72018-09-26 04:18:30 +00001#include "OrcTestCommon.h"
Lang Hamesd435ce42018-09-30 19:12:23 +00002#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
Lang Hamesc1275e72018-09-26 04:18:30 +00003#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
4#include "gtest/gtest.h"
5
6using namespace llvm;
7using namespace llvm::orc;
8
9class LazyReexportsTest : public CoreAPIsBasedStandardTest {};
10
11static int dummyTarget() { return 42; }
12
13TEST_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).
20
21 auto JTMB = JITTargetMachineBuilder::detectHost();
22
23 // Bail out if we can not detect the host.
24 if (!JTMB) {
25 consumeError(JTMB.takeError());
26 return;
27 }
28
29 // Bail out if we can not build a local call-through manager.
30 auto LCTM = createLocalLazyCallThroughManager(JTMB->getTargetTriple(), ES, 0);
31 if (!LCTM) {
32 consumeError(LCTM.takeError());
33 return;
34 }
35
Lang Hames71d781c2018-09-30 23:18:24 +000036 auto DummyTarget = ES.intern("DummyTarget");
Lang Hamesc1275e72018-09-26 04:18:30 +000037
38 bool DummyTargetMaterialized = false;
39
40 cantFail(JD.define(llvm::make_unique<SimpleMaterializationUnit>(
41 SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}),
42 [&](MaterializationResponsibility R) {
43 DummyTargetMaterialized = true;
44 R.resolve(
45 {{DummyTarget,
46 JITEvaluatedSymbol(static_cast<JITTargetAddress>(
47 reinterpret_cast<uintptr_t>(&dummyTarget)),
48 JITSymbolFlags::Exported)}});
49 R.emit();
50 })));
51
52 unsigned NotifyResolvedCount = 0;
53 auto NotifyResolved = LazyCallThroughManager::createNotifyResolvedFunction(
54 [&](JITDylib &JD, const SymbolStringPtr &SymbolName,
55 JITTargetAddress ResolvedAddr) {
56 ++NotifyResolvedCount;
57 return Error::success();
58 });
59
60 auto CallThroughTrampoline = cantFail((*LCTM)->getCallThroughTrampoline(
61 JD, DummyTarget, std::move(NotifyResolved)));
62
63 auto CTTPtr = reinterpret_cast<int (*)()>(
64 static_cast<uintptr_t>(CallThroughTrampoline));
65
66 // Call twice to verify nothing unexpected happens on redundant calls.
67 auto Result = CTTPtr();
68 (void)CTTPtr();
69
70 EXPECT_TRUE(DummyTargetMaterialized)
71 << "CallThrough did not materialize target";
72 EXPECT_EQ(NotifyResolvedCount, 1U)
73 << "CallThrough should have generated exactly one 'NotifyResolved' call";
74 EXPECT_EQ(Result, 42) << "Failed to call through to target";
75}