brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · 643ea67 Raw
183 lines · cpp
1//===------ StubsTests.cpp - Unit tests for generic stub generation -------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/STLExtras.h"10#include "llvm/ExecutionEngine/JITLink/JITLink.h"11#include "llvm/ExecutionEngine/JITLink/aarch64.h"12#include "llvm/ExecutionEngine/JITLink/loongarch.h"13#include "llvm/ExecutionEngine/JITLink/x86.h"14#include "llvm/ExecutionEngine/JITLink/x86_64.h"15#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"16#include "llvm/Support/Memory.h"17 18#include "llvm/Testing/Support/Error.h"19#include "gtest/gtest.h"20 21using namespace llvm;22using namespace llvm::jitlink;23 24static std::pair<Symbol &, Symbol &>25GenerateStub(LinkGraph &G, size_t PointerSize, Edge::Kind PointerEdgeKind) {26  auto &FuncSymbol = G.addAbsoluteSymbol("Func", orc::ExecutorAddr(0x2000), 0,27                                         Linkage::Strong, Scope::Default, true);28 29  // Create a section for pointer symbols.30  auto &PointersSec =31      G.createSection("__pointers", orc::MemProt::Read | orc::MemProt::Write);32 33  // Create a section for jump stubs symbols.34  auto &StubsSec =35      G.createSection("__stubs", orc::MemProt::Read | orc::MemProt::Write);36 37  auto AnonymousPtrCreator = getAnonymousPointerCreator(G.getTargetTriple());38  EXPECT_TRUE(AnonymousPtrCreator);39 40  auto &PointerSym = AnonymousPtrCreator(G, PointersSec, &FuncSymbol, 0);41  EXPECT_EQ(std::distance(PointerSym.getBlock().edges().begin(),42                          PointerSym.getBlock().edges().end()),43            1U);44  auto &DeltaEdge = *PointerSym.getBlock().edges().begin();45  EXPECT_EQ(DeltaEdge.getKind(), PointerEdgeKind);46  EXPECT_EQ(&DeltaEdge.getTarget(), &FuncSymbol);47  EXPECT_EQ(PointerSym.getBlock().getSize(), PointerSize);48  EXPECT_TRUE(all_of(PointerSym.getBlock().getContent(),49                     [](char x) { return x == 0; }));50 51  auto PtrJumpStubCreator = getPointerJumpStubCreator(G.getTargetTriple());52  EXPECT_TRUE(PtrJumpStubCreator);53  auto &StubSym = PtrJumpStubCreator(G, StubsSec, PointerSym);54  return {PointerSym, StubSym};55}56 57TEST(StubsTest, StubsGeneration_x86_64) {58  const char PointerJumpStubContent[6] = {59      static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};60  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),61              Triple("x86_64-apple-darwin"), SubtargetFeatures(),62              getGenericEdgeKindName);63  auto [PointerSym, StubSym] = GenerateStub(G, 8U, x86_64::Pointer64);64 65  EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(),66                          StubSym.getBlock().edges().end()),67            1U);68  auto &JumpEdge = *StubSym.getBlock().edges().begin();69  EXPECT_EQ(JumpEdge.getKind(), x86_64::BranchPCRel32);70  EXPECT_EQ(&JumpEdge.getTarget(), &PointerSym);71  EXPECT_EQ(StubSym.getBlock().getContent(),72            ArrayRef<char>(PointerJumpStubContent));73}74 75TEST(StubsTest, StubsGeneration_aarch64) {76  const char PointerJumpStubContent[12] = {77      0x10, 0x00, 0x00, (char)0x90u, // ADRP x16, <imm>@page2178      0x10, 0x02, 0x40, (char)0xf9u, // LDR x16, [x16, <imm>@pageoff12]79      0x00, 0x02, 0x1f, (char)0xd6u  // BR  x1680  };81  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),82              Triple("aarch64-linux-gnu"), SubtargetFeatures(),83              getGenericEdgeKindName);84  auto [PointerSym, StubSym] = GenerateStub(G, 8U, aarch64::Pointer64);85 86  EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(),87                          StubSym.getBlock().edges().end()),88            2U);89  auto &AdrpHighEdge = *StubSym.getBlock().edges().begin();90  auto &LdrEdge = *++StubSym.getBlock().edges().begin();91  EXPECT_EQ(AdrpHighEdge.getKind(), aarch64::Page21);92  EXPECT_EQ(&AdrpHighEdge.getTarget(), &PointerSym);93  EXPECT_EQ(LdrEdge.getKind(), aarch64::PageOffset12);94  EXPECT_EQ(&LdrEdge.getTarget(), &PointerSym);95  EXPECT_EQ(StubSym.getBlock().getContent(),96            ArrayRef<char>(PointerJumpStubContent));97}98 99TEST(StubsTest, StubsGeneration_x86) {100  const char PointerJumpStubContent[6] = {101      static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};102  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),103              Triple("i386-unknown-linux-gnu"), SubtargetFeatures(),104              getGenericEdgeKindName);105  auto [PointerSym, StubSym] = GenerateStub(G, 4U, x86::Pointer32);106 107  EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(),108                          StubSym.getBlock().edges().end()),109            1U);110  auto &JumpEdge = *StubSym.getBlock().edges().begin();111  EXPECT_EQ(JumpEdge.getKind(), x86::Pointer32);112  EXPECT_EQ(&JumpEdge.getTarget(), &PointerSym);113  EXPECT_EQ(StubSym.getBlock().getContent(),114            ArrayRef<char>(PointerJumpStubContent));115}116 117TEST(StubsTest, StubsGeneration_loongarch32) {118  const char PointerJumpStubContent[12] = {119      0x14,120      0x00,121      0x00,122      0x1a, // pcalau12i $t8, %page20(imm)123      static_cast<char>(0x94),124      0x02,125      static_cast<char>(0x80),126      0x28, // ld.d $t8, $t8, %pageoff12(imm)127      static_cast<char>(0x80),128      0x02,129      0x00,130      0x4c // jr $t8131  };132  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),133              Triple("loongarch32"), SubtargetFeatures(),134              getGenericEdgeKindName);135  auto [PointerSym, StubSym] = GenerateStub(G, 4U, loongarch::Pointer32);136 137  EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(),138                          StubSym.getBlock().edges().end()),139            2U);140  auto &PageHighEdge = *StubSym.getBlock().edges().begin();141  auto &PageLowEdge = *++StubSym.getBlock().edges().begin();142  EXPECT_EQ(PageHighEdge.getKind(), loongarch::Page20);143  EXPECT_EQ(&PageHighEdge.getTarget(), &PointerSym);144  EXPECT_EQ(PageLowEdge.getKind(), loongarch::PageOffset12);145  EXPECT_EQ(&PageLowEdge.getTarget(), &PointerSym);146  EXPECT_EQ(StubSym.getBlock().getContent(),147            ArrayRef<char>(PointerJumpStubContent));148}149 150TEST(StubsTest, StubsGeneration_loongarch64) {151  const char PointerJumpStubContent[12] = {152      0x14,153      0x00,154      0x00,155      0x1a, // pcalau12i $t8, %page20(imm)156      static_cast<char>(0x94),157      0x02,158      static_cast<char>(0xc0),159      0x28, // ld.d $t8, $t8, %pageoff12(imm)160      static_cast<char>(0x80),161      0x02,162      0x00,163      0x4c // jr $t8164  };165 166  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),167              Triple("loongarch64"), SubtargetFeatures(),168              getGenericEdgeKindName);169  auto [PointerSym, StubSym] = GenerateStub(G, 8U, loongarch::Pointer64);170 171  EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(),172                          StubSym.getBlock().edges().end()),173            2U);174  auto &PageHighEdge = *StubSym.getBlock().edges().begin();175  auto &PageLowEdge = *++StubSym.getBlock().edges().begin();176  EXPECT_EQ(PageHighEdge.getKind(), loongarch::Page20);177  EXPECT_EQ(&PageHighEdge.getTarget(), &PointerSym);178  EXPECT_EQ(PageLowEdge.getKind(), loongarch::PageOffset12);179  EXPECT_EQ(&PageLowEdge.getTarget(), &PointerSym);180  EXPECT_EQ(StubSym.getBlock().getContent(),181            ArrayRef<char>(PointerJumpStubContent));182}183