108 lines · cpp
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 11using namespace llvm;12using namespace llvm::orc;13using namespace llvm::jitlink;14 15static int initialTarget() { return 42; }16static int middleTarget() { return 13; }17static int finalTarget() { return 53; }18 19class JITLinkRedirectionManagerTest : public testing::Test {20public:21 ~JITLinkRedirectionManagerTest() override {22 if (ES)23 if (auto Err = ES->endSession())24 ES->reportError(std::move(Err));25 }26 27protected: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 yet44 auto Triple = JTMB->getTargetTriple();45 if (Triple.isOSBinFormatCOFF() && Triple.isAArch64())46 GTEST_SKIP();47 48 if (Triple.isPPC())49 GTEST_SKIP();50 51 auto PageSize = sys::Process::getPageSize();52 if (!PageSize) {53 consumeError(PageSize.takeError());54 GTEST_SKIP();55 }56 57 ES = std::make_unique<ExecutionSession>(58 std::make_unique<UnsupportedExecutorProcessControl>(59 nullptr, nullptr, JTMB->getTargetTriple().getTriple(), *PageSize));60 JD = &ES->createBareJITDylib("main");61 ObjLinkingLayer = std::make_unique<ObjectLinkingLayer>(62 *ES, std::make_unique<InProcessMemoryManager>(*PageSize));63 DL = std::make_unique<DataLayout>(std::move(*DLOrErr));64 }65 JITDylib *JD{nullptr};66 std::unique_ptr<ExecutionSession> ES;67 std::unique_ptr<ObjectLinkingLayer> ObjLinkingLayer;68 std::unique_ptr<DataLayout> DL;69};70 71TEST_F(JITLinkRedirectionManagerTest, BasicRedirectionOperation) {72 auto RM = JITLinkRedirectableSymbolManager::Create(*ObjLinkingLayer);73 // Bail out if we can not create74 if (!RM) {75 consumeError(RM.takeError());76 GTEST_SKIP();77 }78 79 auto MakeTarget = [](int (*Fn)()) {80 return ExecutorSymbolDef(ExecutorAddr::fromPtr(Fn),81 JITSymbolFlags::Exported |82 JITSymbolFlags::Callable);83 };84 85 auto RedirectableSymbol = ES->intern("RedirectableTarget");86 EXPECT_THAT_ERROR((*RM)->createRedirectableSymbols(87 JD->getDefaultResourceTracker(),88 {{RedirectableSymbol, MakeTarget(initialTarget)}}),89 Succeeded());90 91 auto RTDef = cantFail(ES->lookup({JD}, RedirectableSymbol));92 auto RTPtr = RTDef.getAddress().toPtr<int (*)()>();93 auto Result = RTPtr();94 EXPECT_EQ(Result, 42) << "Failed to call initial target";95 96 EXPECT_THAT_ERROR(97 (*RM)->redirect(*JD, {{RedirectableSymbol, MakeTarget(middleTarget)}}),98 Succeeded());99 Result = RTPtr();100 EXPECT_EQ(Result, 13) << "Failed to call middle redirected target";101 102 EXPECT_THAT_ERROR(103 (*RM)->redirect(*JD, {{RedirectableSymbol, MakeTarget(finalTarget)}}),104 Succeeded());105 Result = RTPtr();106 EXPECT_EQ(Result, 53) << "Failed to call redirected target";107}108