//===------- AArch64Tests.cpp - Unit tests for the AArch64 backend --------===// // // 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 #include #include "gtest/gtest.h" using namespace llvm; using namespace llvm::jitlink; using namespace llvm::jitlink::aarch64; TEST(AArch64, EmptyLinkGraph) { LinkGraph G("foo", std::make_shared(), Triple("arm64-apple-darwin"), SubtargetFeatures(), getEdgeKindName); EXPECT_EQ(G.getName(), "foo"); EXPECT_EQ(G.getTargetTriple().str(), "arm64-apple-darwin"); EXPECT_EQ(G.getPointerSize(), 8U); EXPECT_EQ(G.getEndianness(), llvm::endianness::little); EXPECT_TRUE(G.external_symbols().empty()); EXPECT_TRUE(G.absolute_symbols().empty()); EXPECT_TRUE(G.defined_symbols().empty()); EXPECT_TRUE(G.blocks().empty()); } TEST(AArch64, GOTAndStubs) { LinkGraph G("foo", std::make_shared(), Triple("arm64-apple-darwin"), SubtargetFeatures(), getEdgeKindName); auto &External = G.addExternalSymbol("external", 0, false); // First table accesses. We expect the graph to be empty: EXPECT_EQ(G.findSectionByName(GOTTableManager::getSectionName()), nullptr); EXPECT_EQ(G.findSectionByName(PLTTableManager::getSectionName()), nullptr); { // Create first GOT and PLT table managers and request a PLT stub. This // should force creation of both a PLT stub and GOT entry. GOTTableManager GOT(G); PLTTableManager PLT(G, GOT); PLT.getEntryForTarget(G, External); } auto *GOTSec = G.findSectionByName(GOTTableManager::getSectionName()); EXPECT_NE(GOTSec, nullptr); if (GOTSec) { // Expect one entry in the GOT now. EXPECT_EQ(GOTSec->symbols_size(), 1U); EXPECT_EQ(GOTSec->blocks_size(), 1U); } auto *PLTSec = G.findSectionByName(PLTTableManager::getSectionName()); EXPECT_NE(PLTSec, nullptr); if (PLTSec) { // Expect one entry in the PLT. EXPECT_EQ(PLTSec->symbols_size(), 1U); EXPECT_EQ(PLTSec->blocks_size(), 1U); } { // Create second GOT and PLT table managers and request a PLT stub. This // should force creation of both a PLT stub and GOT entry. GOTTableManager GOT(G); PLTTableManager PLT(G, GOT); PLT.getEntryForTarget(G, External); } EXPECT_EQ(G.findSectionByName(GOTTableManager::getSectionName()), GOTSec); if (GOTSec) { // Expect the same one entry in the GOT. EXPECT_EQ(GOTSec->symbols_size(), 1U); EXPECT_EQ(GOTSec->blocks_size(), 1U); } EXPECT_EQ(G.findSectionByName(PLTTableManager::getSectionName()), PLTSec); if (PLTSec) { // Expect the same one entry in the GOT. EXPECT_EQ(PLTSec->symbols_size(), 1U); EXPECT_EQ(PLTSec->blocks_size(), 1U); } }