//===-- COFFLinkGraphTests.cpp - Unit tests for COFF LinkGraph utils ------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "JITLinkTestUtils.h" #include "llvm/ExecutionEngine/JITLink/COFF.h" #include "llvm/ExecutionEngine/JITLink/JITLink.h" #include "gtest/gtest.h" using namespace llvm; using namespace llvm::jitlink; TEST(COFFLinkGraphTest, GetImageBaseSymbolReturnsNullWhenMissing) { LinkGraph G("foo", std::make_shared(), Triple("x86_64-pc-windows-msvc"), SubtargetFeatures(), getGenericEdgeKindName); GetImageBaseSymbol GetIB; EXPECT_EQ(GetIB(G), nullptr); } TEST(COFFLinkGraphTest, GetImageBaseSymbolFindsExternal) { LinkGraph G("foo", std::make_shared(), Triple("x86_64-pc-windows-msvc"), SubtargetFeatures(), getGenericEdgeKindName); auto &ExtSym = G.addExternalSymbol(G.intern("__ImageBase"), 0, false); GetImageBaseSymbol GetIB; EXPECT_EQ(GetIB(G), &ExtSym); } TEST(COFFLinkGraphTest, GetImageBaseSymbolFindsAbsolute) { LinkGraph G("foo", std::make_shared(), Triple("x86_64-pc-windows-msvc"), SubtargetFeatures(), getGenericEdgeKindName); auto &AbsSym = G.addAbsoluteSymbol(G.intern("__ImageBase"), orc::ExecutorAddr(0x1000), 0, Linkage::Strong, Scope::Default, true); GetImageBaseSymbol GetIB; EXPECT_EQ(GetIB(G), &AbsSym); } TEST(COFFLinkGraphTest, GetImageBaseSymbolFindsDefined) { LinkGraph G("foo", std::make_shared(), Triple("x86_64-pc-windows-msvc"), SubtargetFeatures(), getGenericEdgeKindName); auto &Sec = G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write); auto &B = G.createContentBlock(Sec, BlockContent, orc::ExecutorAddr(0x2000), 8, 0); auto &DefSym = G.addDefinedSymbol(B, 0, G.intern("__ImageBase"), 4, Linkage::Strong, Scope::Default, false, false); GetImageBaseSymbol GetIB; EXPECT_EQ(GetIB(G), &DefSym); } TEST(COFFLinkGraphTest, GetImageBaseSymbolCachesResult) { LinkGraph G("foo", std::make_shared(), Triple("x86_64-pc-windows-msvc"), SubtargetFeatures(), getGenericEdgeKindName); auto &ExtSym = G.addExternalSymbol(G.intern("__ImageBase"), 0, false); GetImageBaseSymbol GetIB; EXPECT_EQ(GetIB(G), &ExtSym); // Remove the symbol -- cached result should still be returned. G.removeExternalSymbol(ExtSym); EXPECT_EQ(GetIB(G), &ExtSym); } TEST(COFFLinkGraphTest, GetImageBaseSymbolReset) { LinkGraph G("foo", std::make_shared(), Triple("x86_64-pc-windows-msvc"), SubtargetFeatures(), getGenericEdgeKindName); GetImageBaseSymbol GetIB; EXPECT_EQ(GetIB(G), nullptr); // Add a symbol and reset -- should now find it. auto &ExtSym = G.addExternalSymbol(G.intern("__ImageBase"), 0, false); GetIB.reset(); EXPECT_EQ(GetIB(G), &ExtSym); // Reset with an explicit cache value of nullptr -- should return nullptr // without searching. GetIB.reset(nullptr); EXPECT_EQ(GetIB(G), nullptr); } TEST(COFFLinkGraphTest, GetImageBaseSymbolCustomName) { LinkGraph G("foo", std::make_shared(), Triple("x86_64-pc-windows-msvc"), SubtargetFeatures(), getGenericEdgeKindName); G.addExternalSymbol(G.intern("__ImageBase"), 0, false); auto &CustomSym = G.addExternalSymbol(G.intern("__CustomBase"), 0, false); GetImageBaseSymbol GetIB("__CustomBase"); EXPECT_EQ(GetIB(G), &CustomSym); }