1 #include "OrcTestCommon.h"
2 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
3 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
4 #include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"
5 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
6 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
7 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
8 #include "llvm/Testing/Support/Error.h"
9 #include "gtest/gtest.h"
12 using namespace llvm::orc
;
13 using namespace llvm::jitlink
;
15 static int initialTarget() { return 42; }
16 static int middleTarget() { return 13; }
17 static int finalTarget() { return 53; }
19 class JITLinkRedirectionManagerTest
: public testing::Test
{
21 ~JITLinkRedirectionManagerTest() {
23 if (auto Err
= ES
->endSession())
24 ES
->reportError(std::move(Err
));
28 void SetUp() override
{
29 OrcNativeTarget::initialize();
31 auto JTMB
= JITTargetMachineBuilder::detectHost();
32 // Bail out if we can not detect the host.
34 consumeError(JTMB
.takeError());
37 auto DLOrErr
= JTMB
->getDefaultDataLayoutForTarget();
39 consumeError(DLOrErr
.takeError());
43 // COFF-ARM64 is not supported yet
44 auto Triple
= JTMB
->getTargetTriple();
45 if (Triple
.isOSBinFormatCOFF() && Triple
.isAArch64())
51 ES
= std::make_unique
<ExecutionSession
>(
52 std::make_unique
<UnsupportedExecutorProcessControl
>(
53 nullptr, nullptr, JTMB
->getTargetTriple().getTriple()));
54 JD
= &ES
->createBareJITDylib("main");
55 ObjLinkingLayer
= std::make_unique
<ObjectLinkingLayer
>(
56 *ES
, std::make_unique
<InProcessMemoryManager
>(16384));
57 DL
= std::make_unique
<DataLayout
>(std::move(*DLOrErr
));
59 JITDylib
*JD
{nullptr};
60 std::unique_ptr
<ExecutionSession
> ES
;
61 std::unique_ptr
<ObjectLinkingLayer
> ObjLinkingLayer
;
62 std::unique_ptr
<DataLayout
> DL
;
65 TEST_F(JITLinkRedirectionManagerTest
, BasicRedirectionOperation
) {
66 auto RM
= JITLinkRedirectableSymbolManager::Create(*ObjLinkingLayer
);
67 // Bail out if we can not create
69 consumeError(RM
.takeError());
73 auto MakeTarget
= [](int (*Fn
)()) {
74 return ExecutorSymbolDef(ExecutorAddr::fromPtr(Fn
),
75 JITSymbolFlags::Exported
|
76 JITSymbolFlags::Callable
);
79 auto RedirectableSymbol
= ES
->intern("RedirectableTarget");
80 EXPECT_THAT_ERROR((*RM
)->createRedirectableSymbols(
81 JD
->getDefaultResourceTracker(),
82 {{RedirectableSymbol
, MakeTarget(initialTarget
)}}),
85 auto RTDef
= cantFail(ES
->lookup({JD
}, RedirectableSymbol
));
86 auto RTPtr
= RTDef
.getAddress().toPtr
<int (*)()>();
87 auto Result
= RTPtr();
88 EXPECT_EQ(Result
, 42) << "Failed to call initial target";
91 (*RM
)->redirect(*JD
, {{RedirectableSymbol
, MakeTarget(middleTarget
)}}),
94 EXPECT_EQ(Result
, 13) << "Failed to call middle redirected target";
97 (*RM
)->redirect(*JD
, {{RedirectableSymbol
, MakeTarget(finalTarget
)}}),
100 EXPECT_EQ(Result
, 53) << "Failed to call redirected target";