1*380e746bSIgor Kudrin //===- llvm/unittest/CodeGen/AsmPrinterDwarfTest.cpp ----------------------===// 2*380e746bSIgor Kudrin // 3*380e746bSIgor Kudrin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*380e746bSIgor Kudrin // See https://llvm.org/LICENSE.txt for license information. 5*380e746bSIgor Kudrin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*380e746bSIgor Kudrin // 7*380e746bSIgor Kudrin //===----------------------------------------------------------------------===// 8*380e746bSIgor Kudrin 9*380e746bSIgor Kudrin #include "TestAsmPrinter.h" 10*380e746bSIgor Kudrin #include "llvm/CodeGen/AsmPrinter.h" 11*380e746bSIgor Kudrin #include "llvm/MC/MCContext.h" 12*380e746bSIgor Kudrin #include "llvm/MC/MCSectionELF.h" 13*380e746bSIgor Kudrin #include "llvm/Testing/Support/Error.h" 14*380e746bSIgor Kudrin 15*380e746bSIgor Kudrin using namespace llvm; 16*380e746bSIgor Kudrin using testing::_; 17*380e746bSIgor Kudrin using testing::SaveArg; 18*380e746bSIgor Kudrin 19*380e746bSIgor Kudrin namespace { 20*380e746bSIgor Kudrin 21*380e746bSIgor Kudrin class AsmPrinterFixtureBase : public testing::Test { 22*380e746bSIgor Kudrin void setupTestPrinter(const std::string &TripleStr, unsigned DwarfVersion, 23*380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 24*380e746bSIgor Kudrin auto ExpectedTestPrinter = 25*380e746bSIgor Kudrin TestAsmPrinter::create(TripleStr, DwarfVersion, DwarfFormat); 26*380e746bSIgor Kudrin ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded()); 27*380e746bSIgor Kudrin TestPrinter = std::move(ExpectedTestPrinter.get()); 28*380e746bSIgor Kudrin } 29*380e746bSIgor Kudrin 30*380e746bSIgor Kudrin protected: 31*380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 32*380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 33*380e746bSIgor Kudrin setupTestPrinter(TripleStr, DwarfVersion, DwarfFormat); 34*380e746bSIgor Kudrin return TestPrinter != nullptr; 35*380e746bSIgor Kudrin } 36*380e746bSIgor Kudrin 37*380e746bSIgor Kudrin std::unique_ptr<TestAsmPrinter> TestPrinter; 38*380e746bSIgor Kudrin }; 39*380e746bSIgor Kudrin 40*380e746bSIgor Kudrin class AsmPrinterEmitDwarfSymbolReferenceTest : public AsmPrinterFixtureBase { 41*380e746bSIgor Kudrin protected: 42*380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 43*380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 44*380e746bSIgor Kudrin if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 45*380e746bSIgor Kudrin return false; 46*380e746bSIgor Kudrin 47*380e746bSIgor Kudrin // Create a symbol which will be emitted in the tests and associate it 48*380e746bSIgor Kudrin // with a section because that is required in some code paths. 49*380e746bSIgor Kudrin 50*380e746bSIgor Kudrin Val = TestPrinter->getCtx().createTempSymbol(); 51*380e746bSIgor Kudrin Sec = TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0); 52*380e746bSIgor Kudrin SecBeginSymbol = Sec->getBeginSymbol(); 53*380e746bSIgor Kudrin TestPrinter->getMS().SwitchSection(Sec); 54*380e746bSIgor Kudrin TestPrinter->getMS().emitLabel(Val); 55*380e746bSIgor Kudrin return true; 56*380e746bSIgor Kudrin } 57*380e746bSIgor Kudrin 58*380e746bSIgor Kudrin MCSymbol *Val = nullptr; 59*380e746bSIgor Kudrin MCSection *Sec = nullptr; 60*380e746bSIgor Kudrin MCSymbol *SecBeginSymbol = nullptr; 61*380e746bSIgor Kudrin }; 62*380e746bSIgor Kudrin 63*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFF) { 64*380e746bSIgor Kudrin if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32)) 65*380e746bSIgor Kudrin return; 66*380e746bSIgor Kudrin 67*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), EmitCOFFSecRel32(Val, 0)); 68*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, false); 69*380e746bSIgor Kudrin } 70*380e746bSIgor Kudrin 71*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFFForceOffset) { 72*380e746bSIgor Kudrin if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32)) 73*380e746bSIgor Kudrin return; 74*380e746bSIgor Kudrin 75*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), 76*380e746bSIgor Kudrin emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4)); 77*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, true); 78*380e746bSIgor Kudrin } 79*380e746bSIgor Kudrin 80*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32) { 81*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 82*380e746bSIgor Kudrin return; 83*380e746bSIgor Kudrin 84*380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 85*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _)) 86*380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 87*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, false); 88*380e746bSIgor Kudrin 89*380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 90*380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 91*380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val); 92*380e746bSIgor Kudrin } 93*380e746bSIgor Kudrin 94*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32ForceOffset) { 95*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 96*380e746bSIgor Kudrin return; 97*380e746bSIgor Kudrin 98*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), 99*380e746bSIgor Kudrin emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4)); 100*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, true); 101*380e746bSIgor Kudrin } 102*380e746bSIgor Kudrin 103*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64) { 104*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 105*380e746bSIgor Kudrin return; 106*380e746bSIgor Kudrin 107*380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 108*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _)) 109*380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 110*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, false); 111*380e746bSIgor Kudrin 112*380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 113*380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 114*380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val); 115*380e746bSIgor Kudrin } 116*380e746bSIgor Kudrin 117*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64ForceOffset) { 118*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 119*380e746bSIgor Kudrin return; 120*380e746bSIgor Kudrin 121*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), 122*380e746bSIgor Kudrin emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 8)); 123*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfSymbolReference(Val, true); 124*380e746bSIgor Kudrin } 125*380e746bSIgor Kudrin 126*380e746bSIgor Kudrin class AsmPrinterEmitDwarfStringOffsetTest : public AsmPrinterFixtureBase { 127*380e746bSIgor Kudrin protected: 128*380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 129*380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 130*380e746bSIgor Kudrin if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 131*380e746bSIgor Kudrin return false; 132*380e746bSIgor Kudrin 133*380e746bSIgor Kudrin Val.Index = DwarfStringPoolEntry::NotIndexed; 134*380e746bSIgor Kudrin Val.Symbol = TestPrinter->getCtx().createTempSymbol(); 135*380e746bSIgor Kudrin Val.Offset = 42; 136*380e746bSIgor Kudrin return true; 137*380e746bSIgor Kudrin } 138*380e746bSIgor Kudrin 139*380e746bSIgor Kudrin DwarfStringPoolEntry Val; 140*380e746bSIgor Kudrin }; 141*380e746bSIgor Kudrin 142*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF32) { 143*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 144*380e746bSIgor Kudrin return; 145*380e746bSIgor Kudrin 146*380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 147*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _)) 148*380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 149*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 150*380e746bSIgor Kudrin 151*380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 152*380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 153*380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol); 154*380e746bSIgor Kudrin } 155*380e746bSIgor Kudrin 156*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, 157*380e746bSIgor Kudrin DWARF32NoRelocationsAcrossSections) { 158*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 159*380e746bSIgor Kudrin return; 160*380e746bSIgor Kudrin 161*380e746bSIgor Kudrin TestPrinter->setDwarfUsesRelocationsAcrossSections(false); 162*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 4)); 163*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 164*380e746bSIgor Kudrin } 165*380e746bSIgor Kudrin 166*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF64) { 167*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 168*380e746bSIgor Kudrin return; 169*380e746bSIgor Kudrin 170*380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 171*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _)) 172*380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 173*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 174*380e746bSIgor Kudrin 175*380e746bSIgor Kudrin const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0); 176*380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 177*380e746bSIgor Kudrin EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol); 178*380e746bSIgor Kudrin } 179*380e746bSIgor Kudrin 180*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfStringOffsetTest, 181*380e746bSIgor Kudrin DWARF64NoRelocationsAcrossSections) { 182*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 183*380e746bSIgor Kudrin return; 184*380e746bSIgor Kudrin 185*380e746bSIgor Kudrin TestPrinter->setDwarfUsesRelocationsAcrossSections(false); 186*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 8)); 187*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfStringOffset(Val); 188*380e746bSIgor Kudrin } 189*380e746bSIgor Kudrin 190*380e746bSIgor Kudrin class AsmPrinterEmitDwarfOffsetTest : public AsmPrinterFixtureBase { 191*380e746bSIgor Kudrin protected: 192*380e746bSIgor Kudrin bool init(const std::string &TripleStr, unsigned DwarfVersion, 193*380e746bSIgor Kudrin dwarf::DwarfFormat DwarfFormat) { 194*380e746bSIgor Kudrin if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) 195*380e746bSIgor Kudrin return false; 196*380e746bSIgor Kudrin 197*380e746bSIgor Kudrin Label = TestPrinter->getCtx().createTempSymbol(); 198*380e746bSIgor Kudrin return true; 199*380e746bSIgor Kudrin } 200*380e746bSIgor Kudrin 201*380e746bSIgor Kudrin MCSymbol *Label = nullptr; 202*380e746bSIgor Kudrin uint64_t Offset = 42; 203*380e746bSIgor Kudrin }; 204*380e746bSIgor Kudrin 205*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF32) { 206*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) 207*380e746bSIgor Kudrin return; 208*380e746bSIgor Kudrin 209*380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 210*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _)) 211*380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 212*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfOffset(Label, Offset); 213*380e746bSIgor Kudrin 214*380e746bSIgor Kudrin const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0); 215*380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 216*380e746bSIgor Kudrin EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add); 217*380e746bSIgor Kudrin 218*380e746bSIgor Kudrin const MCSymbolRefExpr *ActualLHS = 219*380e746bSIgor Kudrin dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS()); 220*380e746bSIgor Kudrin ASSERT_NE(ActualLHS, nullptr); 221*380e746bSIgor Kudrin EXPECT_EQ(&(ActualLHS->getSymbol()), Label); 222*380e746bSIgor Kudrin 223*380e746bSIgor Kudrin const MCConstantExpr *ActualRHS = 224*380e746bSIgor Kudrin dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS()); 225*380e746bSIgor Kudrin ASSERT_NE(ActualRHS, nullptr); 226*380e746bSIgor Kudrin EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset); 227*380e746bSIgor Kudrin } 228*380e746bSIgor Kudrin 229*380e746bSIgor Kudrin TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF64) { 230*380e746bSIgor Kudrin if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64)) 231*380e746bSIgor Kudrin return; 232*380e746bSIgor Kudrin 233*380e746bSIgor Kudrin const MCExpr *Arg0 = nullptr; 234*380e746bSIgor Kudrin EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _)) 235*380e746bSIgor Kudrin .WillOnce(SaveArg<0>(&Arg0)); 236*380e746bSIgor Kudrin TestPrinter->getAP()->emitDwarfOffset(Label, Offset); 237*380e746bSIgor Kudrin 238*380e746bSIgor Kudrin const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0); 239*380e746bSIgor Kudrin ASSERT_NE(ActualArg0, nullptr); 240*380e746bSIgor Kudrin EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add); 241*380e746bSIgor Kudrin 242*380e746bSIgor Kudrin const MCSymbolRefExpr *ActualLHS = 243*380e746bSIgor Kudrin dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS()); 244*380e746bSIgor Kudrin ASSERT_NE(ActualLHS, nullptr); 245*380e746bSIgor Kudrin EXPECT_EQ(&(ActualLHS->getSymbol()), Label); 246*380e746bSIgor Kudrin 247*380e746bSIgor Kudrin const MCConstantExpr *ActualRHS = 248*380e746bSIgor Kudrin dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS()); 249*380e746bSIgor Kudrin ASSERT_NE(ActualRHS, nullptr); 250*380e746bSIgor Kudrin EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset); 251*380e746bSIgor Kudrin } 252*380e746bSIgor Kudrin 253*380e746bSIgor Kudrin } // end namespace 254