xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp (revision 2ccf7ed277df28651b94bbee9fccefdf22fb074f)
12c01b278SSunho Kim #include "OrcTestCommon.h"
22c01b278SSunho Kim #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
32c01b278SSunho Kim #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
42c01b278SSunho Kim #include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"
52c01b278SSunho Kim #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
62c01b278SSunho Kim #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
72c01b278SSunho Kim #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
82c01b278SSunho Kim #include "llvm/Testing/Support/Error.h"
92c01b278SSunho Kim #include "gtest/gtest.h"
102c01b278SSunho Kim 
112c01b278SSunho Kim using namespace llvm;
122c01b278SSunho Kim using namespace llvm::orc;
132c01b278SSunho Kim using namespace llvm::jitlink;
142c01b278SSunho Kim 
152c01b278SSunho Kim static int initialTarget() { return 42; }
162c01b278SSunho Kim static int middleTarget() { return 13; }
172c01b278SSunho Kim static int finalTarget() { return 53; }
182c01b278SSunho Kim 
192c01b278SSunho Kim class JITLinkRedirectionManagerTest : public testing::Test {
202c01b278SSunho Kim public:
212c01b278SSunho Kim   ~JITLinkRedirectionManagerTest() {
222c01b278SSunho Kim     if (ES)
232c01b278SSunho Kim       if (auto Err = ES->endSession())
242c01b278SSunho Kim         ES->reportError(std::move(Err));
252c01b278SSunho Kim   }
262c01b278SSunho Kim 
272c01b278SSunho Kim protected:
282c01b278SSunho Kim   void SetUp() override {
291d657cfeSLang Hames     OrcNativeTarget::initialize();
301d657cfeSLang Hames 
312c01b278SSunho Kim     auto JTMB = JITTargetMachineBuilder::detectHost();
322c01b278SSunho Kim     // Bail out if we can not detect the host.
332c01b278SSunho Kim     if (!JTMB) {
342c01b278SSunho Kim       consumeError(JTMB.takeError());
352c01b278SSunho Kim       GTEST_SKIP();
362c01b278SSunho Kim     }
37222d8fadSSunho Kim     auto DLOrErr = JTMB->getDefaultDataLayoutForTarget();
38222d8fadSSunho Kim     if (!DLOrErr) {
39222d8fadSSunho Kim       consumeError(DLOrErr.takeError());
40222d8fadSSunho Kim       GTEST_SKIP();
41222d8fadSSunho Kim     }
422c01b278SSunho Kim 
43e5f7e73dSSunho Kim     // COFF-ARM64 is not supported yet
44e5f7e73dSSunho Kim     auto Triple = JTMB->getTargetTriple();
45e5f7e73dSSunho Kim     if (Triple.isOSBinFormatCOFF() && Triple.isAArch64())
46e5f7e73dSSunho Kim       GTEST_SKIP();
47e5f7e73dSSunho Kim 
4839aae575SSunho Kim     if (Triple.isPPC())
4939aae575SSunho Kim       GTEST_SKIP();
5039aae575SSunho Kim 
512c01b278SSunho Kim     ES = std::make_unique<ExecutionSession>(
522c01b278SSunho Kim         std::make_unique<UnsupportedExecutorProcessControl>(
532c01b278SSunho Kim             nullptr, nullptr, JTMB->getTargetTriple().getTriple()));
542c01b278SSunho Kim     JD = &ES->createBareJITDylib("main");
552c01b278SSunho Kim     ObjLinkingLayer = std::make_unique<ObjectLinkingLayer>(
56188ede28SSunho Kim         *ES, std::make_unique<InProcessMemoryManager>(16384));
57222d8fadSSunho Kim     DL = std::make_unique<DataLayout>(std::move(*DLOrErr));
582c01b278SSunho Kim   }
592c01b278SSunho Kim   JITDylib *JD{nullptr};
602c01b278SSunho Kim   std::unique_ptr<ExecutionSession> ES;
612c01b278SSunho Kim   std::unique_ptr<ObjectLinkingLayer> ObjLinkingLayer;
622c01b278SSunho Kim   std::unique_ptr<DataLayout> DL;
632c01b278SSunho Kim };
642c01b278SSunho Kim 
652c01b278SSunho Kim TEST_F(JITLinkRedirectionManagerTest, BasicRedirectionOperation) {
66529c0913SLang Hames   auto RM = JITLinkRedirectableSymbolManager::Create(*ObjLinkingLayer);
672c01b278SSunho Kim   // Bail out if we can not create
682c01b278SSunho Kim   if (!RM) {
692c01b278SSunho Kim     consumeError(RM.takeError());
702c01b278SSunho Kim     GTEST_SKIP();
712c01b278SSunho Kim   }
722c01b278SSunho Kim 
73529c0913SLang Hames   auto MakeTarget = [](int (*Fn)()) {
74529c0913SLang Hames     return ExecutorSymbolDef(ExecutorAddr::fromPtr(Fn),
75529c0913SLang Hames                              JITSymbolFlags::Exported |
76529c0913SLang Hames                                  JITSymbolFlags::Callable);
772c01b278SSunho Kim   };
782c01b278SSunho Kim 
792c01b278SSunho Kim   auto RedirectableSymbol = ES->intern("RedirectableTarget");
80529c0913SLang Hames   EXPECT_THAT_ERROR((*RM)->createRedirectableSymbols(
81529c0913SLang Hames                         JD->getDefaultResourceTracker(),
82529c0913SLang Hames                         {{RedirectableSymbol, MakeTarget(initialTarget)}}),
832c01b278SSunho Kim                     Succeeded());
842c01b278SSunho Kim 
85*2ccf7ed2SJared Wyles   auto RTDef = cantFail(ES->lookup({JD}, RedirectableSymbol));
862c01b278SSunho Kim   auto RTPtr = RTDef.getAddress().toPtr<int (*)()>();
872c01b278SSunho Kim   auto Result = RTPtr();
882c01b278SSunho Kim   EXPECT_EQ(Result, 42) << "Failed to call initial target";
892c01b278SSunho Kim 
90529c0913SLang Hames   EXPECT_THAT_ERROR(
91529c0913SLang Hames       (*RM)->redirect(*JD, {{RedirectableSymbol, MakeTarget(middleTarget)}}),
922c01b278SSunho Kim       Succeeded());
932c01b278SSunho Kim   Result = RTPtr();
942c01b278SSunho Kim   EXPECT_EQ(Result, 13) << "Failed to call middle redirected target";
952c01b278SSunho Kim 
96529c0913SLang Hames   EXPECT_THAT_ERROR(
97529c0913SLang Hames       (*RM)->redirect(*JD, {{RedirectableSymbol, MakeTarget(finalTarget)}}),
982c01b278SSunho Kim       Succeeded());
992c01b278SSunho Kim   Result = RTPtr();
1002c01b278SSunho Kim   EXPECT_EQ(Result, 53) << "Failed to call redirected target";
1012c01b278SSunho Kim }
102