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" 10 11 using namespace llvm; 12 using namespace llvm::orc; 13 using namespace llvm::jitlink; 14 15 static int initialTarget() { return 42; } 16 static int middleTarget() { return 13; } 17 static int finalTarget() { return 53; } 18 19 class JITLinkRedirectionManagerTest : public testing::Test { 20 public: 21 ~JITLinkRedirectionManagerTest() { 22 if (ES) 23 if (auto Err = ES->endSession()) 24 ES->reportError(std::move(Err)); 25 } 26 27 protected: 28 void SetUp() override { 29 OrcNativeTarget::initialize(); 30 31 auto JTMB = JITTargetMachineBuilder::detectHost(); 32 // Bail out if we can not detect the host. 33 if (!JTMB) { 34 consumeError(JTMB.takeError()); 35 GTEST_SKIP(); 36 } 37 auto DLOrErr = JTMB->getDefaultDataLayoutForTarget(); 38 if (!DLOrErr) { 39 consumeError(DLOrErr.takeError()); 40 GTEST_SKIP(); 41 } 42 43 // COFF-ARM64 is not supported yet 44 auto Triple = JTMB->getTargetTriple(); 45 if (Triple.isOSBinFormatCOFF() && Triple.isAArch64()) 46 GTEST_SKIP(); 47 48 if (Triple.isPPC()) 49 GTEST_SKIP(); 50 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)); 58 } 59 JITDylib *JD{nullptr}; 60 std::unique_ptr<ExecutionSession> ES; 61 std::unique_ptr<ObjectLinkingLayer> ObjLinkingLayer; 62 std::unique_ptr<DataLayout> DL; 63 }; 64 65 TEST_F(JITLinkRedirectionManagerTest, BasicRedirectionOperation) { 66 auto RM = JITLinkRedirectableSymbolManager::Create(*ObjLinkingLayer); 67 // Bail out if we can not create 68 if (!RM) { 69 consumeError(RM.takeError()); 70 GTEST_SKIP(); 71 } 72 73 auto MakeTarget = [](int (*Fn)()) { 74 return ExecutorSymbolDef(ExecutorAddr::fromPtr(Fn), 75 JITSymbolFlags::Exported | 76 JITSymbolFlags::Callable); 77 }; 78 79 auto RedirectableSymbol = ES->intern("RedirectableTarget"); 80 EXPECT_THAT_ERROR((*RM)->createRedirectableSymbols( 81 JD->getDefaultResourceTracker(), 82 {{RedirectableSymbol, MakeTarget(initialTarget)}}), 83 Succeeded()); 84 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"; 89 90 EXPECT_THAT_ERROR( 91 (*RM)->redirect(*JD, {{RedirectableSymbol, MakeTarget(middleTarget)}}), 92 Succeeded()); 93 Result = RTPtr(); 94 EXPECT_EQ(Result, 13) << "Failed to call middle redirected target"; 95 96 EXPECT_THAT_ERROR( 97 (*RM)->redirect(*JD, {{RedirectableSymbol, MakeTarget(finalTarget)}}), 98 Succeeded()); 99 Result = RTPtr(); 100 EXPECT_EQ(Result, 53) << "Failed to call redirected target"; 101 } 102