brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 6bb244c Raw
147 lines · cpp
1#include "OrcTestCommon.h"2#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"3#include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"4#include "llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h"5#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"6#include "llvm/ExecutionEngine/Orc/LLJIT.h"7#include "llvm/ExecutionEngine/Orc/LazyReexports.h"8#include "llvm/Testing/Support/Error.h"9#include "gtest/gtest.h"10 11using namespace llvm;12using namespace llvm::orc;13 14class LazyReexportsTest : public CoreAPIsBasedStandardTest {};15 16static int dummyTarget() { return 42; }17 18TEST_F(LazyReexportsTest, BasicLocalCallThroughManagerOperation) {19  // Create a callthrough manager for the host (if possible) and verify that20  // a call to the lazy call-through:21  // (1) Materializes the MU. This verifies that the symbol was looked up, and22  //     that we didn't arrive at the target via some other path23  // (2) Returns the expected value (which we take as proof that the call24  //     reached the target).25 26  auto JTMB = JITTargetMachineBuilder::detectHost();27 28  // Bail out if we can not detect the host.29  if (!JTMB) {30    consumeError(JTMB.takeError());31    GTEST_SKIP();32  }33 34  // Bail out if we can not build a local call-through manager.35  auto LCTM = createLocalLazyCallThroughManager(JTMB->getTargetTriple(), ES,36                                                ExecutorAddr());37  if (!LCTM) {38    consumeError(LCTM.takeError());39    GTEST_SKIP();40  }41 42  auto DummyTarget = ES.intern("DummyTarget");43 44  bool DummyTargetMaterialized = false;45 46  cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(47      SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}),48      [&](std::unique_ptr<MaterializationResponsibility> R) {49        DummyTargetMaterialized = true;50        // No dependencies registered, can't fail.51        cantFail(R->notifyResolved({{DummyTarget,52                                     {ExecutorAddr::fromPtr(&dummyTarget),53                                      JITSymbolFlags::Exported}}}));54        cantFail(R->notifyEmitted({}));55      })));56 57  unsigned NotifyResolvedCount = 0;58  auto NotifyResolved = [&](ExecutorAddr ResolvedAddr) {59    ++NotifyResolvedCount;60    return Error::success();61  };62 63  auto CallThroughTrampoline = cantFail((*LCTM)->getCallThroughTrampoline(64      JD, DummyTarget, std::move(NotifyResolved)));65 66  auto CTTPtr = CallThroughTrampoline.toPtr<int (*)()>();67 68  // Call twice to verify nothing unexpected happens on redundant calls.69  auto Result = CTTPtr();70  (void)CTTPtr();71 72  EXPECT_TRUE(DummyTargetMaterialized)73      << "CallThrough did not materialize target";74  EXPECT_EQ(NotifyResolvedCount, 1U)75      << "CallThrough should have generated exactly one 'NotifyResolved' call";76  EXPECT_EQ(Result, 42) << "Failed to call through to target";77}78 79static void *noReentry(void *) { abort(); }80 81TEST(JITLinkLazyReexportsTest, Basics) {82  OrcNativeTarget::initialize();83 84  auto J = LLJITBuilder().create();85  if (!J) {86    dbgs() << toString(J.takeError()) << "\n";87    // consumeError(J.takeError());88    GTEST_SKIP();89  }90  if (!isa<ObjectLinkingLayer>((*J)->getObjLinkingLayer()))91    GTEST_SKIP();92 93  auto &OLL = cast<ObjectLinkingLayer>((*J)->getObjLinkingLayer());94 95  auto RSMgr = JITLinkRedirectableSymbolManager::Create(OLL);96  if (!RSMgr) {97    dbgs() << "Boom for RSMgr\n";98    consumeError(RSMgr.takeError());99    GTEST_SKIP();100  }101 102  auto &ES = (*J)->getExecutionSession();103 104  auto &JD = ES.createBareJITDylib("JD");105  cantFail(JD.define(absoluteSymbols(106      {{ES.intern("__orc_rt_reentry"),107        {ExecutorAddr::fromPtr(&noReentry),108         JITSymbolFlags::Exported | JITSymbolFlags::Callable}}})));109 110  auto LRMgr = createJITLinkLazyReexportsManager(OLL, **RSMgr, JD);111  if (!LRMgr) {112    dbgs() << "Boom for LRMgr\n";113    consumeError(LRMgr.takeError());114    GTEST_SKIP();115  }116 117  auto Foo = ES.intern("foo");118  auto Bar = ES.intern("bar");119 120  auto RT = JD.createResourceTracker();121  cantFail(JD.define(122      lazyReexports(123          **LRMgr,124          {{Foo, {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Callable}}}),125      RT));126 127  // Check flags after adding Foo -> Bar lazy reexport.128  auto SF = cantFail(129      ES.lookupFlags(LookupKind::Static, makeJITDylibSearchOrder(&JD),130                     {{Foo, SymbolLookupFlags::WeaklyReferencedSymbol}}));131  EXPECT_EQ(SF.size(), 1U);132  EXPECT_TRUE(SF.count(Foo));133  EXPECT_EQ(SF[Foo], JITSymbolFlags::Exported | JITSymbolFlags::Callable);134 135  // Remove reexport without running it.136  if (auto Err = RT->remove()) {137    EXPECT_THAT_ERROR(std::move(Err), Succeeded());138    return;139  }140 141  // Check flags after adding Foo -> Bar lazy reexport.142  SF = cantFail(143      ES.lookupFlags(LookupKind::Static, makeJITDylibSearchOrder(&JD),144                     {{Foo, SymbolLookupFlags::WeaklyReferencedSymbol}}));145  EXPECT_EQ(SF.size(), 0U);146}147