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