brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · d0991e6 Raw
431 lines · cpp
1//===- llvm/unittest/CodeGen/AsmPrinterDwarfTest.cpp ----------------------===//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 "TestAsmPrinter.h"10#include "llvm/BinaryFormat/ELF.h"11#include "llvm/CodeGen/AsmPrinter.h"12#include "llvm/CodeGen/AsmPrinterHandler.h"13#include "llvm/CodeGen/DebugHandlerBase.h"14#include "llvm/CodeGen/MachineModuleInfo.h"15#include "llvm/IR/LegacyPassManager.h"16#include "llvm/IR/Module.h"17#include "llvm/IR/PassManager.h"18#include "llvm/MC/MCContext.h"19#include "llvm/MC/MCSectionELF.h"20#include "llvm/Target/TargetMachine.h"21#include "llvm/Testing/Support/Error.h"22 23using namespace llvm;24using testing::_;25using testing::DoAll;26using testing::InSequence;27using testing::SaveArg;28 29namespace {30 31class AsmPrinterFixtureBase : public testing::Test {32  void setupTestPrinter(const std::string &TripleStr, unsigned DwarfVersion,33                        dwarf::DwarfFormat DwarfFormat) {34    auto ExpectedTestPrinter =35        TestAsmPrinter::create(TripleStr, DwarfVersion, DwarfFormat);36    ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded());37    TestPrinter = std::move(ExpectedTestPrinter.get());38  }39 40protected:41  bool init(const std::string &TripleStr, unsigned DwarfVersion,42            dwarf::DwarfFormat DwarfFormat) {43    setupTestPrinter(TripleStr, DwarfVersion, DwarfFormat);44    return TestPrinter != nullptr;45  }46 47  std::unique_ptr<TestAsmPrinter> TestPrinter;48};49 50class AsmPrinterEmitDwarfSymbolReferenceTest : public AsmPrinterFixtureBase {51protected:52  bool init(const std::string &TripleStr, unsigned DwarfVersion,53            dwarf::DwarfFormat DwarfFormat) {54    if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))55      return false;56 57    // AsmPrinter::emitDwarfSymbolReference(Label, true) gets the associated58    // section from `Label` to find its BeginSymbol.59    // Prepare the test symbol `Val` accordingly.60 61    Val = TestPrinter->getCtx().createTempSymbol();62    MCSection *Sec =63        TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0);64    SecBeginSymbol = Sec->getBeginSymbol();65    TestPrinter->getMS().switchSection(Sec);66    Val->setFragment(&Sec->getDummyFragment());67 68    return true;69  }70 71  MCSymbol *Val = nullptr;72  MCSymbol *SecBeginSymbol = nullptr;73};74 75TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFF) {76  if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))77    GTEST_SKIP();78 79  EXPECT_CALL(TestPrinter->getMS(), emitCOFFSecRel32(Val, 0));80  TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);81}82 83TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFFForceOffset) {84  if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))85    GTEST_SKIP();86 87  EXPECT_CALL(TestPrinter->getMS(),88              emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));89  TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);90}91 92TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32) {93  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))94    GTEST_SKIP();95 96  const MCExpr *Arg0 = nullptr;97  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))98      .WillOnce(SaveArg<0>(&Arg0));99  TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);100 101  const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);102  ASSERT_NE(ActualArg0, nullptr);103  EXPECT_EQ(&(ActualArg0->getSymbol()), Val);104}105 106TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32ForceOffset) {107  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))108    GTEST_SKIP();109 110  EXPECT_CALL(TestPrinter->getMS(),111              emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));112  TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);113}114 115TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64) {116  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))117    GTEST_SKIP();118 119  const MCExpr *Arg0 = nullptr;120  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))121      .WillOnce(SaveArg<0>(&Arg0));122  TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);123 124  const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);125  ASSERT_NE(ActualArg0, nullptr);126  EXPECT_EQ(&(ActualArg0->getSymbol()), Val);127}128 129TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64ForceOffset) {130  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))131    GTEST_SKIP();132 133  EXPECT_CALL(TestPrinter->getMS(),134              emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 8));135  TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);136}137 138class AsmPrinterEmitDwarfStringOffsetTest : public AsmPrinterFixtureBase {139protected:140  bool init(const std::string &TripleStr, unsigned DwarfVersion,141            dwarf::DwarfFormat DwarfFormat) {142    if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))143      return false;144 145    Val.Index = DwarfStringPoolEntry::NotIndexed;146    Val.Symbol = TestPrinter->getCtx().createTempSymbol();147    Val.Offset = 42;148    return true;149  }150 151  DwarfStringPoolEntry Val;152};153 154TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF32) {155  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))156    GTEST_SKIP();157 158  const MCExpr *Arg0 = nullptr;159  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))160      .WillOnce(SaveArg<0>(&Arg0));161  TestPrinter->getAP()->emitDwarfStringOffset(Val);162 163  const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);164  ASSERT_NE(ActualArg0, nullptr);165  EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);166}167 168TEST_F(AsmPrinterEmitDwarfStringOffsetTest,169       DWARF32NoRelocationsAcrossSections) {170  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))171    GTEST_SKIP();172 173  TestPrinter->setDwarfUsesRelocationsAcrossSections(false);174  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 4));175  TestPrinter->getAP()->emitDwarfStringOffset(Val);176}177 178TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF64) {179  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))180    GTEST_SKIP();181 182  const MCExpr *Arg0 = nullptr;183  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))184      .WillOnce(SaveArg<0>(&Arg0));185  TestPrinter->getAP()->emitDwarfStringOffset(Val);186 187  const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);188  ASSERT_NE(ActualArg0, nullptr);189  EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);190}191 192TEST_F(AsmPrinterEmitDwarfStringOffsetTest,193       DWARF64NoRelocationsAcrossSections) {194  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))195    GTEST_SKIP();196 197  TestPrinter->setDwarfUsesRelocationsAcrossSections(false);198  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 8));199  TestPrinter->getAP()->emitDwarfStringOffset(Val);200}201 202class AsmPrinterEmitDwarfOffsetTest : public AsmPrinterFixtureBase {203protected:204  bool init(const std::string &TripleStr, unsigned DwarfVersion,205            dwarf::DwarfFormat DwarfFormat) {206    if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))207      return false;208 209    Label = TestPrinter->getCtx().createTempSymbol();210    return true;211  }212 213  MCSymbol *Label = nullptr;214  uint64_t Offset = 42;215};216 217TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF32) {218  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))219    GTEST_SKIP();220 221  const MCExpr *Arg0 = nullptr;222  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))223      .WillOnce(SaveArg<0>(&Arg0));224  TestPrinter->getAP()->emitDwarfOffset(Label, Offset);225 226  const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);227  ASSERT_NE(ActualArg0, nullptr);228  EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);229 230  const MCSymbolRefExpr *ActualLHS =231      dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());232  ASSERT_NE(ActualLHS, nullptr);233  EXPECT_EQ(&(ActualLHS->getSymbol()), Label);234 235  const MCConstantExpr *ActualRHS =236      dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());237  ASSERT_NE(ActualRHS, nullptr);238  EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);239}240 241TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF64) {242  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))243    GTEST_SKIP();244 245  const MCExpr *Arg0 = nullptr;246  EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))247      .WillOnce(SaveArg<0>(&Arg0));248  TestPrinter->getAP()->emitDwarfOffset(Label, Offset);249 250  const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);251  ASSERT_NE(ActualArg0, nullptr);252  EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);253 254  const MCSymbolRefExpr *ActualLHS =255      dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());256  ASSERT_NE(ActualLHS, nullptr);257  EXPECT_EQ(&(ActualLHS->getSymbol()), Label);258 259  const MCConstantExpr *ActualRHS =260      dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());261  ASSERT_NE(ActualRHS, nullptr);262  EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);263}264 265class AsmPrinterEmitDwarfLengthOrOffsetTest : public AsmPrinterFixtureBase {266protected:267  uint64_t Val = 42;268};269 270TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF32) {271  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))272    GTEST_SKIP();273 274  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));275  TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);276}277 278TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF64) {279  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))280    GTEST_SKIP();281 282  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));283  TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);284}285 286class AsmPrinterGetUnitLengthFieldByteSizeTest : public AsmPrinterFixtureBase {287};288 289TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF32) {290  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))291    GTEST_SKIP();292 293  EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 4u);294}295 296TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF64) {297  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))298    GTEST_SKIP();299 300  EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 12u);301}302 303class AsmPrinterEmitDwarfUnitLengthAsIntTest : public AsmPrinterFixtureBase {304protected:305  uint64_t Val = 42;306};307 308TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF32) {309  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))310    GTEST_SKIP();311 312  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));313  TestPrinter->getAP()->emitDwarfUnitLength(Val, "");314}315 316TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF64) {317  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))318    GTEST_SKIP();319 320  InSequence S;321  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));322  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));323 324  TestPrinter->getAP()->emitDwarfUnitLength(Val, "");325}326 327class AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest328    : public AsmPrinterFixtureBase {329protected:330  bool init(const std::string &TripleStr, unsigned DwarfVersion,331            dwarf::DwarfFormat DwarfFormat) {332    if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))333      return false;334 335    return true;336  }337};338 339TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF32) {340  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))341    GTEST_SKIP();342 343  InSequence S;344  const MCSymbol *Hi = nullptr;345  const MCSymbol *Lo = nullptr;346  EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 4))347      .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo)));348  MCSymbol *LTmp = nullptr;349  EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _))350      .WillOnce(SaveArg<0>(&LTmp));351 352  MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", "");353  EXPECT_NE(Lo, nullptr);354  EXPECT_EQ(Lo, LTmp);355  EXPECT_NE(Hi, nullptr);356  EXPECT_EQ(Hi, HTmp);357}358 359TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF64) {360  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))361    GTEST_SKIP();362 363  InSequence S;364  const MCSymbol *Hi = nullptr;365  const MCSymbol *Lo = nullptr;366  EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));367  EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 8))368      .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo)));369  MCSymbol *LTmp = nullptr;370  EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _))371      .WillOnce(SaveArg<0>(&LTmp));372 373  MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", "");374  EXPECT_NE(Lo, nullptr);375  EXPECT_EQ(Lo, LTmp);376  EXPECT_NE(Hi, nullptr);377  EXPECT_EQ(Hi, HTmp);378}379 380class AsmPrinterHandlerTest : public AsmPrinterFixtureBase {381  class TestHandler : public AsmPrinterHandler {382    AsmPrinterHandlerTest &Test;383 384  public:385    TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {}386    ~TestHandler() override = default;387    void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}388    void beginModule(Module *M) override { Test.BeginCount++; }389    void endModule() override { Test.EndCount++; }390    void beginFunction(const MachineFunction *MF) override {}391    void endFunction(const MachineFunction *MF) override {}392    void beginInstruction(const MachineInstr *MI) override {}393    void endInstruction() override {}394  };395 396protected:397  bool init(const std::string &TripleStr, unsigned DwarfVersion,398            dwarf::DwarfFormat DwarfFormat) {399    if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))400      return false;401 402    auto *AP = TestPrinter->getAP();403    AP->addAsmPrinterHandler(std::make_unique<TestHandler>(*this));404    TargetMachine *TM = &AP->TM;405    legacy::PassManager PM;406    PM.add(new MachineModuleInfoWrapperPass(TM));407    PM.add(TestPrinter->releaseAP()); // Takes ownership of destroying AP408    LLVMContext Context;409    std::unique_ptr<Module> M(new Module("TestModule", Context));410    M->setDataLayout(TM->createDataLayout());411    PM.run(*M);412    // Now check that we can run it twice.413    AP->addAsmPrinterHandler(std::make_unique<TestHandler>(*this));414    PM.run(*M);415    return true;416  }417 418  int BeginCount = 0;419  int EndCount = 0;420};421 422TEST_F(AsmPrinterHandlerTest, Basic) {423  if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))424    GTEST_SKIP();425 426  ASSERT_EQ(BeginCount, 3);427  ASSERT_EQ(EndCount, 3);428}429 430} // end namespace431