brintos

brintos / llvm-project-archived public Read only

0
0
Text · 85.2 KiB · aa5b292 Raw
2152 lines · cpp
1//===- DWARFDebugLineTest.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 "llvm/DebugInfo/DWARF/DWARFDebugLine.h"10#include "DwarfGenerator.h"11#include "DwarfUtils.h"12#include "llvm/DebugInfo/DWARF/DWARFContext.h"13#include "llvm/Object/ObjectFile.h"14#include "llvm/Testing/Support/Error.h"15#include "gtest/gtest.h"16 17// AIX doesn't support the debug_addr section18#ifdef _AIX19#define NO_SUPPORT_DEBUG_ADDR20#endif21 22using namespace llvm;23using namespace dwarf;24using namespace dwarfgen;25using namespace object;26using namespace utils;27using namespace testing;28 29namespace {30struct CommonFixture {31  CommonFixture()32      : LineData("", true, 0), Recoverable(Error::success()),33        RecordRecoverable(std::bind(&CommonFixture::recordRecoverable, this,34                                    std::placeholders::_1)),35        Unrecoverable(Error::success()),36        RecordUnrecoverable(std::bind(&CommonFixture::recordUnrecoverable, this,37                                      std::placeholders::_1)){};38 39  ~CommonFixture() {40    EXPECT_FALSE(Recoverable);41    EXPECT_FALSE(Unrecoverable);42  }43 44  // Note: ASSERT_THAT_EXPECTED cannot be used in a non-void function, so45  // setupGenerator() is split into two.46  void setupGeneratorImpl(uint16_t Version, uint8_t AddrSize) {47    AddressSize = AddrSize;48    Triple T = getDefaultTargetTripleForAddrSize(AddressSize ? AddressSize : 8);49    if (!isConfigurationSupported(T))50      return;51    auto ExpectedGenerator = Generator::create(T, Version);52    ASSERT_THAT_EXPECTED(ExpectedGenerator, Succeeded());53    Gen = std::move(*ExpectedGenerator);54  }55 56  bool setupGenerator(uint16_t Version = 4, uint8_t AddrSize = 8) {57    setupGeneratorImpl(Version, AddrSize);58    return Gen != nullptr;59  }60 61  void generate() {62    Context = createContext();63    assert(Context != nullptr && "test state is not valid");64    const DWARFObject &Obj = Context->getDWARFObj();65    uint8_t TargetAddrSize = AddressSize == 0 ? 8 : AddressSize;66    LineData = DWARFDataExtractor(67        Obj, Obj.getLineSection(),68        getDefaultTargetTripleForAddrSize(TargetAddrSize).isLittleEndian(),69        AddressSize);70  }71 72  std::unique_ptr<DWARFContext> createContext() {73    assert(Gen != nullptr && "Generator is not set up");74    StringRef FileBytes = Gen->generate();75    MemoryBufferRef FileBuffer(FileBytes, "dwarf");76    auto Obj = object::ObjectFile::createObjectFile(FileBuffer);77    if (Obj)78      return DWARFContext::create(**Obj);79    return nullptr;80  }81 82  DWARFDebugLine::SectionParser setupParser() {83    LineTable &LT = Gen->addLineTable(DWARF32);84    LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});85    LT.addStandardOpcode(DW_LNS_copy, {});86    LT.addByte(0xaa);87    LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});88 89    LineTable &LT2 = Gen->addLineTable(DWARF64);90    LT2.addExtendedOpcode(9, DW_LNE_set_address,91                          {{0x11223344, LineTable::Quad}});92    LT2.addStandardOpcode(DW_LNS_copy, {});93    LT2.addByte(0xbb);94    LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});95 96    generate();97 98    return DWARFDebugLine::SectionParser(LineData, *Context, Units);99  }100 101  void recordRecoverable(Error Err) {102    Recoverable = joinErrors(std::move(Recoverable), std::move(Err));103  }104  void recordUnrecoverable(Error Err) {105    Unrecoverable = joinErrors(std::move(Unrecoverable), std::move(Err));106  }107 108  Expected<const DWARFDebugLine::LineTable *>109  getOrParseLineTableFatalErrors(uint64_t Offset = 0) {110    auto ExpectedLineTable = Line.getOrParseLineTable(111        LineData, Offset, *Context, nullptr, RecordRecoverable);112    EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());113    return ExpectedLineTable;114  }115 116  uint8_t AddressSize;117  std::unique_ptr<Generator> Gen;118  std::unique_ptr<DWARFContext> Context;119  DWARFDataExtractor LineData;120  DWARFDebugLine Line;121  Error Recoverable;122  std::function<void(Error)> RecordRecoverable;123  Error Unrecoverable;124  std::function<void(Error)> RecordUnrecoverable;125 126  SmallVector<std::unique_ptr<DWARFUnit>, 2> Units;127};128 129// Fixtures must derive from "Test", but parameterised fixtures from130// "TestWithParam". It does not seem possible to inherit from both, so we share131// the common state in a separate class, inherited by the two fixture classes.132struct DebugLineBasicFixture : public Test, public CommonFixture {};133 134struct DebugLineParameterisedFixture135    : public TestWithParam<std::pair<uint16_t, DwarfFormat>>,136      public CommonFixture {137  void SetUp() override { std::tie(Version, Format) = GetParam(); }138 139  uint16_t Version;140  DwarfFormat Format;141};142 143void checkDefaultPrologue(uint16_t Version, DwarfFormat Format,144                          DWARFDebugLine::Prologue Prologue,145                          uint64_t BodyLength) {146  // Check version specific fields and values.147  uint64_t UnitLength;148  uint64_t PrologueLength;149  switch (Version) {150  case 4:151    PrologueLength = 36;152    UnitLength = PrologueLength + 2;153    EXPECT_EQ(Prologue.MaxOpsPerInst, 1u);154    break;155  case 2:156  case 3:157    PrologueLength = 35;158    UnitLength = PrologueLength + 2;159    break;160  case 5:161    PrologueLength = 42;162    UnitLength = PrologueLength + 4;163    EXPECT_EQ(Prologue.getAddressSize(), 8u);164    EXPECT_EQ(Prologue.SegSelectorSize, 0u);165    break;166  default:167    llvm_unreachable("unsupported DWARF version");168  }169  UnitLength += BodyLength + (Format == DWARF32 ? 4 : 8);170 171  EXPECT_EQ(Prologue.TotalLength, UnitLength);172  EXPECT_EQ(Prologue.PrologueLength, PrologueLength);173  EXPECT_EQ(Prologue.MinInstLength, 1u);174  EXPECT_EQ(Prologue.DefaultIsStmt, 1u);175  EXPECT_EQ(Prologue.LineBase, -5);176  EXPECT_EQ(Prologue.LineRange, 14u);177  EXPECT_EQ(Prologue.OpcodeBase, 13u);178  std::vector<uint8_t> ExpectedLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1};179  EXPECT_EQ(Prologue.StandardOpcodeLengths, ExpectedLengths);180  ASSERT_EQ(Prologue.IncludeDirectories.size(), 1u);181  ASSERT_EQ(Prologue.IncludeDirectories[0].getForm(), DW_FORM_string);182  EXPECT_STREQ(*toString(Prologue.IncludeDirectories[0]), "a dir");183  ASSERT_EQ(Prologue.FileNames.size(), 1u);184  ASSERT_EQ(Prologue.FileNames[0].Name.getForm(), DW_FORM_string);185  ASSERT_EQ(Prologue.FileNames[0].DirIdx, 0u);186  EXPECT_STREQ(*toString(Prologue.FileNames[0].Name), "a file");187}188 189TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffset) {190  if (!setupGenerator())191    GTEST_SKIP();192  generate();193 194  EXPECT_THAT_EXPECTED(195      getOrParseLineTableFatalErrors(0),196      FailedWithMessage(197          "offset 0x00000000 is not a valid debug line section offset"));198  // Repeat to show that an error is reported each time.199  EXPECT_THAT_EXPECTED(200      getOrParseLineTableFatalErrors(0),201      FailedWithMessage(202          "offset 0x00000000 is not a valid debug line section offset"));203 204  // Show that an error is reported for later offsets too.205  EXPECT_THAT_EXPECTED(206      getOrParseLineTableFatalErrors(1),207      FailedWithMessage(208          "offset 0x00000001 is not a valid debug line section offset"));209}210 211TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) {212  if (!setupGenerator())213    GTEST_SKIP();214 215  LineTable &LT = Gen->addLineTable();216  LT.setCustomPrologue({{0, LineTable::Byte}});217 218  generate();219 220  EXPECT_THAT_EXPECTED(221      getOrParseLineTableFatalErrors(0),222      FailedWithMessage(223          "parsing line table prologue at offset 0x00000000: "224          "unexpected end of data at offset 0x1 while reading [0x0, 0x4)"));225 226  EXPECT_THAT_EXPECTED(227      getOrParseLineTableFatalErrors(1),228      FailedWithMessage(229          "offset 0x00000001 is not a valid debug line section offset"));230}231 232#ifdef NO_SUPPORT_DEBUG_ADDR233TEST_P(DebugLineParameterisedFixture, DISABLED_PrologueGetLength) {234#else235TEST_P(DebugLineParameterisedFixture, PrologueGetLength) {236#endif237  if (!setupGenerator(Version))238    GTEST_SKIP();239  LineTable &LT = Gen->addLineTable(Format);240  DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();241  LT.setPrologue(Prologue);242  generate();243 244  // + 10 for sizes of DWARF-32 unit length, version, prologue length.245  uint64_t ExpectedLength = Prologue.PrologueLength + 10;246  if (Version == 5)247    // Add address and segment selector size fields.248    ExpectedLength += 2;249  if (Format == DWARF64)250    // Unit length grows by 8, prologue length by 4.251    ExpectedLength += 12;252 253  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,254                                                    nullptr, RecordRecoverable);255  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());256  EXPECT_EQ((*ExpectedLineTable)->Prologue.getLength(), ExpectedLength);257}258 259#ifdef NO_SUPPORT_DEBUG_ADDR260TEST_P(DebugLineParameterisedFixture, DISABLED_GetOrParseLineTableValidTable) {261#else262TEST_P(DebugLineParameterisedFixture, GetOrParseLineTableValidTable) {263#endif264  if (!setupGenerator(Version))265    GTEST_SKIP();266 267  SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +268               (Format == DWARF64 ? "DWARF64" : "DWARF32"));269 270  LineTable &LT = Gen->addLineTable(Format);271  LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});272  LT.addStandardOpcode(DW_LNS_copy, {});273  LT.addByte(0xaa);274  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});275 276  LineTable &LT2 = Gen->addLineTable(Format);277  LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x11223344, LineTable::Quad}});278  LT2.addStandardOpcode(DW_LNS_copy, {});279  LT2.addByte(0xbb);280  LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});281  LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x55667788, LineTable::Quad}});282  LT2.addStandardOpcode(DW_LNS_copy, {});283  LT2.addByte(0xcc);284  LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});285 286  generate();287 288  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,289                                                    nullptr, RecordRecoverable);290  ASSERT_TRUE(ExpectedLineTable.operator bool());291  EXPECT_FALSE(Recoverable);292  const DWARFDebugLine::LineTable *Expected = *ExpectedLineTable;293  checkDefaultPrologue(Version, Format, Expected->Prologue, 16);294  EXPECT_EQ(Expected->Sequences.size(), 1u);295 296  uint64_t SecondOffset =297      Expected->Prologue.sizeofTotalLength() + Expected->Prologue.TotalLength;298  Recoverable = Error::success();299  auto ExpectedLineTable2 = Line.getOrParseLineTable(300      LineData, SecondOffset, *Context, nullptr, RecordRecoverable);301  ASSERT_TRUE(ExpectedLineTable2.operator bool());302  EXPECT_FALSE(Recoverable);303  const DWARFDebugLine::LineTable *Expected2 = *ExpectedLineTable2;304  checkDefaultPrologue(Version, Format, Expected2->Prologue, 32);305  EXPECT_EQ(Expected2->Sequences.size(), 2u);306 307  EXPECT_NE(Expected, Expected2);308 309  // Check that if the same offset is requested, the exact same pointer is310  // returned.311  Recoverable = Error::success();312  auto ExpectedLineTable3 = Line.getOrParseLineTable(313      LineData, 0, *Context, nullptr, RecordRecoverable);314  ASSERT_TRUE(ExpectedLineTable3.operator bool());315  EXPECT_FALSE(Recoverable);316  EXPECT_EQ(Expected, *ExpectedLineTable3);317 318  Recoverable = Error::success();319  auto ExpectedLineTable4 = Line.getOrParseLineTable(320      LineData, SecondOffset, *Context, nullptr, RecordRecoverable);321  ASSERT_TRUE(ExpectedLineTable4.operator bool());322  EXPECT_FALSE(Recoverable);323  EXPECT_EQ(Expected2, *ExpectedLineTable4);324 325  // TODO: Add tests that show that the body of the programs have been read326  // correctly.327}328 329#ifdef NO_SUPPORT_DEBUG_ADDR330TEST_P(DebugLineParameterisedFixture, DISABLED_ClearLineValidTable) {331#else332TEST_P(DebugLineParameterisedFixture, ClearLineValidTable) {333#endif334  if (!setupGenerator(Version))335    GTEST_SKIP();336 337  SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +338               (Format == DWARF64 ? "DWARF64" : "DWARF32"));339 340  LineTable &LT = Gen->addLineTable(Format);341  LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});342  LT.addStandardOpcode(DW_LNS_copy, {});343  LT.addByte(0xaa);344  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});345 346  LineTable &LT2 = Gen->addLineTable(Format);347  LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x11223344, LineTable::Quad}});348  LT2.addStandardOpcode(DW_LNS_copy, {});349  LT2.addByte(0xbb);350  LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});351  LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x55667788, LineTable::Quad}});352  LT2.addStandardOpcode(DW_LNS_copy, {});353  LT2.addByte(0xcc);354  LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});355 356  generate();357 358  // Check that we have what we expect before calling clearLineTable().359  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,360                                                    nullptr, RecordRecoverable);361  ASSERT_TRUE((bool)ExpectedLineTable);362  EXPECT_FALSE(Recoverable);363  const DWARFDebugLine::LineTable *Expected = *ExpectedLineTable;364  checkDefaultPrologue(Version, Format, Expected->Prologue, 16);365  EXPECT_EQ(Expected->Sequences.size(), 1u);366 367  uint64_t SecondOffset =368      Expected->Prologue.sizeofTotalLength() + Expected->Prologue.TotalLength;369  Recoverable = Error::success();370  auto ExpectedLineTable2 = Line.getOrParseLineTable(371      LineData, SecondOffset, *Context, nullptr, RecordRecoverable);372  ASSERT_TRUE((bool)ExpectedLineTable2);373  EXPECT_FALSE(Recoverable);374  const DWARFDebugLine::LineTable *Expected2 = *ExpectedLineTable2;375  checkDefaultPrologue(Version, Format, Expected2->Prologue, 32);376  EXPECT_EQ(Expected2->Sequences.size(), 2u);377 378  // Check that we no longer get the line tables after clearLineTable().379  Line.clearLineTable(0);380  Line.clearLineTable(SecondOffset);381  EXPECT_EQ(Line.getLineTable(0), nullptr);382  EXPECT_EQ(Line.getLineTable(SecondOffset), nullptr);383 384  // Check that if the same offset is requested, the contents match what we385  // had before.386  Recoverable = Error::success();387  auto ExpectedLineTable3 = Line.getOrParseLineTable(388      LineData, 0, *Context, nullptr, RecordRecoverable);389  ASSERT_TRUE((bool)ExpectedLineTable3);390  EXPECT_FALSE(Recoverable);391  const DWARFDebugLine::LineTable *Expected3 = *ExpectedLineTable3;392  checkDefaultPrologue(Version, Format, Expected3->Prologue, 16);393  EXPECT_EQ(Expected3->Sequences.size(), 1u);394 395  Recoverable = Error::success();396  auto ExpectedLineTable4 = Line.getOrParseLineTable(397      LineData, SecondOffset, *Context, nullptr, RecordRecoverable);398  ASSERT_TRUE((bool)ExpectedLineTable4);399  EXPECT_FALSE(Recoverable);400  const DWARFDebugLine::LineTable *Expected4 = *ExpectedLineTable4;401  checkDefaultPrologue(Version, Format, Expected4->Prologue, 32);402  EXPECT_EQ(Expected4->Sequences.size(), 2u);403}404 405TEST_F(DebugLineBasicFixture, ErrorForReservedLength) {406  if (!setupGenerator())407    GTEST_SKIP();408 409  LineTable &LT = Gen->addLineTable();410  LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});411 412  generate();413 414  EXPECT_THAT_EXPECTED(415      getOrParseLineTableFatalErrors(),416      FailedWithMessage(417          "parsing line table prologue at offset 0x00000000: unsupported "418          "reserved unit length of value 0xfffffff0"));419}420 421struct DebugLineUnsupportedVersionFixture : public TestWithParam<uint16_t>,422                                            public CommonFixture {423  void SetUp() override { Version = GetParam(); }424 425  uint16_t Version;426};427 428TEST_P(DebugLineUnsupportedVersionFixture, ErrorForUnsupportedVersion) {429  if (!setupGenerator())430    GTEST_SKIP();431 432  LineTable &LT = Gen->addLineTable();433  LT.setCustomPrologue(434      {{LineTable::Half, LineTable::Long}, {Version, LineTable::Half}});435 436  generate();437 438  EXPECT_THAT_EXPECTED(439      getOrParseLineTableFatalErrors(),440      FailedWithMessage("parsing line table prologue at offset 0x00000000: "441                        "unsupported version " +442                        std::to_string(Version)));443}444 445INSTANTIATE_TEST_SUITE_P(UnsupportedVersionTestParams,446                         DebugLineUnsupportedVersionFixture,447                         Values(/*1 below min */ 1, /* 1 above max */ 6,448                                /* Maximum possible */ 0xffff));449 450#ifdef NO_SUPPORT_DEBUG_ADDR451TEST_F(DebugLineBasicFixture, DISABLED_ErrorForInvalidV5IncludeDirTable) {452#else453TEST_F(DebugLineBasicFixture, ErrorForInvalidV5IncludeDirTable) {454#endif455  if (!setupGenerator(5))456    GTEST_SKIP();457 458  LineTable &LT = Gen->addLineTable();459  LT.setCustomPrologue({460      {19, LineTable::Long}, // unit length461      {5, LineTable::Half},  // version462      {8, LineTable::Byte},  // addr size463      {0, LineTable::Byte},  // segment selector size464      {11, LineTable::Long}, // prologue length465      {1, LineTable::Byte},  // min instruction length466      {1, LineTable::Byte},  // max ops per instruction467      {1, LineTable::Byte},  // default is_stmt468      {0, LineTable::Byte},  // line base469      {14, LineTable::Byte}, // line range470      {2, LineTable::Byte},  // opcode base (small to reduce the amount of471                             // setup required).472      {0, LineTable::Byte},  // standard opcode lengths473      {0, LineTable::Byte},  // directory entry format count (should not be474                             // zero).475      {0, LineTable::ULEB},  // directories count476      {0, LineTable::Byte},  // file name entry format count477      {0, LineTable::ULEB}   // file name entry count478  });479 480  generate();481 482  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,483                                                    nullptr, RecordRecoverable);484  EXPECT_THAT_EXPECTED(ExpectedLineTable, Succeeded());485 486  EXPECT_THAT_ERROR(487      std::move(Recoverable),488      FailedWithMessage(489          "parsing line table prologue at 0x00000000 found an invalid "490          "directory or file table description at 0x00000014",491          "failed to parse entry content descriptions because no path was "492          "found"));493}494 495#ifdef NO_SUPPORT_DEBUG_ADDR496TEST_P(DebugLineParameterisedFixture, DISABLED_ErrorForTooLargePrologueLength) {497#else498TEST_P(DebugLineParameterisedFixture, ErrorForTooLargePrologueLength) {499#endif500  if (!setupGenerator(Version))501    GTEST_SKIP();502 503  SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +504               (Format == DWARF64 ? "DWARF64" : "DWARF32"));505 506  LineTable &LT = Gen->addLineTable(Format);507  DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();508  ++Prologue.PrologueLength;509  LT.setPrologue(Prologue);510 511  generate();512 513  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,514                                                    nullptr, RecordRecoverable);515  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());516  DWARFDebugLine::LineTable Result(**ExpectedLineTable);517  // Undo the earlier modification so that it can be compared against a518  // "default" prologue.519  --Result.Prologue.PrologueLength;520  checkDefaultPrologue(Version, Format, Result.Prologue, 0);521 522  uint64_t ExpectedEnd =523      Prologue.TotalLength + 1 + Prologue.sizeofTotalLength();524  EXPECT_THAT_ERROR(525      std::move(Recoverable),526      FailedWithMessage(527          ("unknown data in line table prologue at offset 0x00000000: "528           "parsing ended (at offset 0x000000" +529           Twine::utohexstr(ExpectedEnd - 1) +530           ") before reaching the prologue end at offset 0x000000" +531           Twine::utohexstr(ExpectedEnd))532              .str()));533}534 535#ifdef NO_SUPPORT_DEBUG_ADDR536TEST_P(DebugLineParameterisedFixture, DISABLED_ErrorForTooShortPrologueLength) {537#else538TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) {539#endif540  if (!setupGenerator(Version))541    GTEST_SKIP();542 543  SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +544               (Format == DWARF64 ? "DWARF64" : "DWARF32"));545 546  LineTable &LT = Gen->addLineTable(Format);547  DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();548  Prologue.PrologueLength -= 2;549  LT.setPrologue(Prologue);550 551  generate();552 553  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,554                                                    nullptr, RecordRecoverable);555  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());556  DWARFDebugLine::LineTable Result(**ExpectedLineTable);557 558  // Parsing will stop before reading a complete file entry.559  ASSERT_EQ(Result.Prologue.IncludeDirectories.size(), 1u);560  EXPECT_EQ(toStringRef(Result.Prologue.IncludeDirectories[0]), "a dir");561  EXPECT_EQ(Result.Prologue.FileNames.size(), 0u);562 563  // The exact place where the parsing will stop depends on the structure of the564  // prologue and the last complete field we are able to read. Before V5 we stop565  // before reading the file length. In V5, we stop before the filename.566  uint64_t ExpectedEnd = Prologue.TotalLength + Prologue.sizeofTotalLength() -567                         (Version < 5 ? 2 : 8);568  std::vector<std::string> Errs;569  Errs.emplace_back(570      (Twine("parsing line table prologue at 0x00000000 found an invalid "571             "directory or file table description at 0x000000") +572       Twine::utohexstr(ExpectedEnd))573          .str());574  if (Version < 5) {575    Errs.emplace_back("file names table was not null terminated before the end "576                      "of the prologue");577  } else {578    Errs.emplace_back(579        "failed to parse file entry because extracting the form value failed");580  }581  EXPECT_THAT_ERROR(std::move(Recoverable),582                    FailedWithMessageArray(testing::ElementsAreArray(Errs)));583}584 585INSTANTIATE_TEST_SUITE_P(586    LineTableTestParams, DebugLineParameterisedFixture,587    Values(std::make_pair(588               2, DWARF32), // Test lower-bound of v2-3 fields and DWARF32.589           std::make_pair(3, DWARF32), // Test upper-bound of v2-3 fields.590           std::make_pair(4, DWARF64), // Test v4 fields and DWARF64.591           std::make_pair(5, DWARF32), std::make_pair(5, DWARF64)));592 593TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthSmallerThanExpected) {594  if (!setupGenerator())595    GTEST_SKIP();596 597  LineTable &LT = Gen->addLineTable();598  LT.addByte(0xaa);599  // The Length should be 1 + sizeof(ULEB) for a set discriminator opcode.600  // The operand will be read for both the discriminator opcode and then parsed601  // again as DW_LNS_negate_stmt, to respect the claimed length.602  LT.addExtendedOpcode(1, DW_LNE_set_discriminator,603                       {{DW_LNS_negate_stmt, LineTable::ULEB}});604  LT.addByte(0xbb);605  LT.addStandardOpcode(DW_LNS_const_add_pc, {});606  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});607 608  generate();609 610  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,611                                                    nullptr, RecordRecoverable);612  EXPECT_THAT_ERROR(std::move(Recoverable),613                    FailedWithMessage("unexpected line op length at offset "614                                      "0x00000031 expected 0x01 found 0x02"));615  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());616  ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u);617  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);618  EXPECT_EQ((*ExpectedLineTable)->Rows[1].IsStmt, 0u);619  EXPECT_EQ((*ExpectedLineTable)->Rows[1].Discriminator, DW_LNS_negate_stmt);620}621 622TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthLargerThanExpected) {623  if (!setupGenerator())624    GTEST_SKIP();625 626  LineTable &LT = Gen->addLineTable();627  LT.addByte(0xaa);628  LT.addStandardOpcode(DW_LNS_const_add_pc, {});629  // The Length should be 1 for an end sequence opcode.630  LT.addExtendedOpcode(2, DW_LNE_end_sequence, {});631  // The negate statement opcode will be skipped.632  LT.addStandardOpcode(DW_LNS_negate_stmt, {});633  LT.addByte(0xbb);634  LT.addStandardOpcode(DW_LNS_const_add_pc, {});635  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});636 637  generate();638 639  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,640                                                    nullptr, RecordRecoverable);641  EXPECT_THAT_ERROR(std::move(Recoverable),642                    FailedWithMessage("unexpected line op length at offset "643                                      "0x00000032 expected 0x02 found 0x01"));644  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());645  ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 4u);646  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 2u);647  ASSERT_EQ((*ExpectedLineTable)->Sequences[1].FirstRowIndex, 2u);648  EXPECT_EQ((*ExpectedLineTable)->Rows[2].IsStmt, 1u);649}650 651TEST_F(DebugLineBasicFixture, ErrorForUnitLengthTooLarge) {652  if (!setupGenerator())653    GTEST_SKIP();654 655  LineTable &Padding = Gen->addLineTable();656  // Add some padding to show that a non-zero offset is handled correctly.657  Padding.setCustomPrologue({{0, LineTable::Byte}});658  LineTable &LT = Gen->addLineTable();659  LT.addStandardOpcode(DW_LNS_copy, {});660  LT.addStandardOpcode(DW_LNS_const_add_pc, {});661  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});662  DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();663  // Set the total length to 1 higher than the actual length.664  ++Prologue.TotalLength;665  LT.setPrologue(Prologue);666 667  generate();668 669  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 1, *Context,670                                                    nullptr, RecordRecoverable);671  EXPECT_THAT_ERROR(672      std::move(Recoverable),673      FailedWithMessage("line table program with offset 0x00000001 has length "674                        "0x00000034 but only 0x00000033 bytes are available"));675  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());676  EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 2u);677  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);678}679 680TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) {681  if (!setupGenerator(4, 8))682    GTEST_SKIP();683 684  LineTable &LT = Gen->addLineTable();685  // The line data extractor expects size 8 (Quad) addresses.686  uint64_t Addr1 = 0x11223344;687  LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});688  LT.addStandardOpcode(DW_LNS_copy, {});689  // Show that the expected address size is unchanged, so later valid lines690  // don't cause a problem.691  uint64_t Addr2 = 0x1122334455667788;692  LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}});693  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});694 695  generate();696 697  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,698                                                    nullptr, RecordRecoverable);699  EXPECT_THAT_ERROR(std::move(Recoverable),700                    FailedWithMessage("mismatching address size at offset "701                                      "0x00000030 expected 0x08 found 0x04"));702  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());703  ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);704  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);705  EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1);706  EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2);707}708 709TEST_F(DebugLineBasicFixture,710       ErrorForMismatchedAddressSizeUnsetInitialAddress) {711  if (!setupGenerator(4, 0))712    GTEST_SKIP();713 714  LineTable &LT = Gen->addLineTable();715  uint64_t Addr1 = 0x11223344;716  LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});717  LT.addStandardOpcode(DW_LNS_copy, {});718  uint64_t Addr2 = 0x1122334455667788;719  LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}});720  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});721 722  generate();723 724  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,725                                                    nullptr, RecordRecoverable);726  EXPECT_THAT_ERROR(std::move(Recoverable),727                    FailedWithMessage("mismatching address size at offset "728                                      "0x00000038 expected 0x04 found 0x08"));729  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());730  ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);731  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);732  EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1);733  EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2);734}735 736TEST_F(DebugLineBasicFixture,737       ErrorForUnsupportedAddressSizeInSetAddressLength) {738  // Use DWARF v4, and 0 for data extractor address size so that the address739  // size is derived from the opcode length.740  if (!setupGenerator(4, 0))741    GTEST_SKIP();742 743  LineTable &LT = Gen->addLineTable();744  // 4 == length of the extended opcode, i.e. 1 for the opcode itself and 3 for745  // the Half (2) + Byte (1) operand, representing the unsupported address size.746  LT.addExtendedOpcode(4, DW_LNE_set_address,747                       {{0x1234, LineTable::Half}, {0x56, LineTable::Byte}});748  LT.addStandardOpcode(DW_LNS_copy, {});749  // Special opcode to ensure the address has changed between the first and last750  // row in the sequence. Without this, the sequence will not be recorded.751  LT.addByte(0xaa);752  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});753 754  generate();755 756  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,757                                                    nullptr, RecordRecoverable);758  EXPECT_THAT_ERROR(759      std::move(Recoverable),760      FailedWithMessage("address size 0x03 of DW_LNE_set_address opcode at "761                        "offset 0x00000030 is unsupported"));762  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());763  ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u);764  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);765  // Show that the set address opcode is ignored in this case.766  EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, 0u);767}768 769TEST_F(DebugLineBasicFixture, ErrorForAddressSizeGreaterThanByteSize) {770  // Use DWARF v4, and 0 for data extractor address size so that the address771  // size is derived from the opcode length.772  if (!setupGenerator(4, 0))773    GTEST_SKIP();774 775  LineTable &LT = Gen->addLineTable();776  // Specifically use an operand size that has a trailing byte of a supported777  // size (8), so that any potential truncation would result in a valid size.778  std::vector<LineTable::ValueAndLength> Operands(0x108);779  LT.addExtendedOpcode(Operands.size() + 1, DW_LNE_set_address, Operands);780  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});781 782  generate();783 784  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,785                                                    nullptr, RecordRecoverable);786  EXPECT_THAT_ERROR(787      std::move(Recoverable),788      FailedWithMessage("address size 0x108 of DW_LNE_set_address opcode at "789                        "offset 0x00000031 is unsupported"));790  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());791}792 793#ifdef NO_SUPPORT_DEBUG_ADDR794TEST_F(DebugLineBasicFixture,795       DISABLED_ErrorForUnsupportedAddressSizeDefinedInHeader) {796#else797TEST_F(DebugLineBasicFixture, ErrorForUnsupportedAddressSizeDefinedInHeader) {798#endif799  // Use 0 for data extractor address size so that it does not clash with the800  // header address size.801  if (!setupGenerator(5, 0))802    GTEST_SKIP();803 804  LineTable &LT = Gen->addLineTable();805  // AddressSize + 1 == length of the extended opcode, i.e. 1 for the opcode806  // itself and 9 for the Quad (8) + Byte (1) operand representing the807  // unsupported address size.808  uint8_t AddressSize = 9;809  LT.addExtendedOpcode(AddressSize + 1, DW_LNE_set_address,810                       {{0x12345678, LineTable::Quad}, {0, LineTable::Byte}});811  LT.addStandardOpcode(DW_LNS_copy, {});812  // Special opcode to ensure the address has changed between the first and last813  // row in the sequence. Without this, the sequence will not be recorded.814  LT.addByte(0xaa);815  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});816  DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();817  Prologue.FormParams.AddrSize = AddressSize;818  LT.setPrologue(Prologue);819 820  generate();821 822  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,823                                                    nullptr, RecordRecoverable);824  EXPECT_THAT_ERROR(825      std::move(Recoverable),826      FailedWithMessage("parsing line table prologue at offset 0x00000000: "827                        "invalid address size 9",828                        "address size 0x09 of DW_LNE_set_address opcode at "829                        "offset 0x00000038 is unsupported"));830  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());831  ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u);832  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);833  // Show that the set address opcode is ignored in this case.834  EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, 0u);835}836 837TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) {838  if (!setupGenerator())839    GTEST_SKIP();840 841  LineTable &LT = Gen->addLineTable();842  LT.addExtendedOpcode(9, DW_LNE_set_address,843                       {{0x1122334455667788, LineTable::Quad}});844  LT.addStandardOpcode(DW_LNS_copy, {});845  LT.addByte(0xaa);846  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});847  LT.addExtendedOpcode(9, DW_LNE_set_address,848                       {{0x99aabbccddeeff00, LineTable::Quad}});849  LT.addStandardOpcode(DW_LNS_copy, {});850  LT.addByte(0xbb);851  LT.addByte(0xcc);852 853  generate();854 855  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,856                                                    nullptr, RecordRecoverable);857  EXPECT_THAT_ERROR(std::move(Recoverable),858                    FailedWithMessage("last sequence in debug line table at "859                                      "offset 0x00000000 is not terminated"));860  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());861  EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 6u);862  // The unterminated sequence is not added to the sequence list.863  EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);864}865 866struct AdjustAddressFixtureBase : public CommonFixture {867  virtual ~AdjustAddressFixtureBase() = default;868 869  // Create and update the prologue as specified by the subclass, then return870  // the length of the table.871  virtual uint64_t editPrologue(LineTable &LT) = 0;872 873  virtual uint64_t getAdjustedAddr(uint64_t Base, uint64_t ConstIncrs,874                                   uint64_t SpecialIncrs,875                                   uint64_t AdvanceIncrs) {876    return Base + ConstIncrs + SpecialIncrs + AdvanceIncrs;877  }878 879  virtual uint64_t getAdjustedLine(uint64_t Base, uint64_t Incr) {880    return Base + Incr;881  }882 883  uint64_t setupNoProblemTable() {884    LineTable &NoProblem = Gen->addLineTable();885    NoProblem.addExtendedOpcode(9, DW_LNE_set_address,886                                {{0xabcd, LineTable::Quad}});887    NoProblem.addExtendedOpcode(1, DW_LNE_end_sequence, {});888    return editPrologue(NoProblem);889  }890 891  uint64_t setupConstAddPcFirstTable() {892    LineTable &ConstAddPCFirst = Gen->addLineTable();893    ConstAddPCFirst.addExtendedOpcode(9, DW_LNE_set_address,894                                      {{ConstAddPCAddr, LineTable::Quad}});895    ConstAddPCFirst.addStandardOpcode(DW_LNS_const_add_pc, {});896    ConstAddPCFirst.addStandardOpcode(DW_LNS_const_add_pc, {});897    ConstAddPCFirst.addStandardOpcode(DW_LNS_advance_pc,898                                      {{0x10, LineTable::ULEB}});899    ConstAddPCFirst.addByte(0x21); // Special opcode, +1 op, +1 line.900    ConstAddPCFirst.addExtendedOpcode(1, DW_LNE_end_sequence, {});901    return editPrologue(ConstAddPCFirst);902  }903 904  uint64_t setupSpecialFirstTable() {905    LineTable &SpecialFirst = Gen->addLineTable();906    SpecialFirst.addExtendedOpcode(9, DW_LNE_set_address,907                                   {{SpecialAddr, LineTable::Quad}});908    SpecialFirst.addByte(0x22); // Special opcode, +1 op, +2 line.909    SpecialFirst.addStandardOpcode(DW_LNS_const_add_pc, {});910    SpecialFirst.addStandardOpcode(DW_LNS_advance_pc,911                                   {{0x20, LineTable::ULEB}});912    SpecialFirst.addByte(0x23); // Special opcode, +1 op, +3 line.913    SpecialFirst.addExtendedOpcode(1, DW_LNE_end_sequence, {});914    return editPrologue(SpecialFirst);915  }916 917  uint64_t setupAdvancePcFirstTable() {918    LineTable &AdvancePCFirst = Gen->addLineTable();919    AdvancePCFirst.addExtendedOpcode(9, DW_LNE_set_address,920                                     {{AdvancePCAddr, LineTable::Quad}});921    AdvancePCFirst.addStandardOpcode(DW_LNS_advance_pc,922                                     {{0x30, LineTable::ULEB}});923    AdvancePCFirst.addStandardOpcode(DW_LNS_const_add_pc, {});924    AdvancePCFirst.addStandardOpcode(DW_LNS_advance_pc,925                                     {{0x40, LineTable::ULEB}});926    AdvancePCFirst.addByte(0x24); // Special opcode, +1 op, +4 line.927    AdvancePCFirst.addExtendedOpcode(1, DW_LNE_end_sequence, {});928    return editPrologue(AdvancePCFirst);929  }930 931  void setupTables(bool AddAdvancePCFirstTable) {932    LineTable &Padding = Gen->addLineTable();933    Padding.setCustomPrologue({{0, LineTable::Byte}});934    NoProblemOffset = 1;935 936    // Show that no warning is generated for the case where no937    // DW_LNS_const_add_pc or special opcode is used.938    ConstAddPCOffset = setupNoProblemTable() + NoProblemOffset;939 940    // Show that the warning is emitted for the first DW_LNS_const_add_pc opcode941    // and then not again.942    SpecialOffset = setupConstAddPcFirstTable() + ConstAddPCOffset;943 944    // Show that the warning is emitted for the first special opcode and then945    // not again.946    AdvancePCOffset = setupSpecialFirstTable() + SpecialOffset;947 948    // Show that the warning is emitted for the first DW_LNS_advance_pc opcode949    // (if requested) and then not again.950    if (AddAdvancePCFirstTable)951      setupAdvancePcFirstTable();952  }953 954  Expected<const DWARFDebugLine::LineTable *>955  checkTable(uint64_t Offset, StringRef OpcodeType, const Twine &MsgSuffix) {956    auto ExpectedTable = Line.getOrParseLineTable(LineData, Offset, *Context,957                                                  nullptr, RecordRecoverable);958    EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());959    if (!IsErrorExpected) {960      EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());961    } else {962      if (!ExpectedTable)963        return ExpectedTable;964      uint64_t ExpectedOffset = Offset +965                                (*ExpectedTable)->Prologue.getLength() +966                                11; // 11 == size of DW_LNE_set_address.967      std::string OffsetHex = Twine::utohexstr(Offset).str();968      std::string OffsetZeroes = std::string(8 - OffsetHex.size(), '0');969      std::string ExpectedHex = Twine::utohexstr(ExpectedOffset).str();970      std::string ExpectedZeroes = std::string(8 - ExpectedHex.size(), '0');971      EXPECT_THAT_ERROR(972          std::move(Recoverable),973          FailedWithMessage(("line table program at offset 0x" + OffsetZeroes +974                             OffsetHex + " contains a " + OpcodeType +975                             " opcode at offset 0x" + ExpectedZeroes +976                             ExpectedHex + ", " + MsgSuffix)977                                .str()));978    }979    return ExpectedTable;980  }981 982  void runTest(bool CheckAdvancePC, Twine MsgSuffix) {983    if (!setupGenerator(Version))984      GTEST_SKIP();985 986    setupTables(/*AddAdvancePCFirstTable=*/CheckAdvancePC);987 988    generate();989 990    auto ExpectedNoProblem = Line.getOrParseLineTable(991        LineData, NoProblemOffset, *Context, nullptr, RecordRecoverable);992    EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());993    EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());994    ASSERT_THAT_EXPECTED(ExpectedNoProblem, Succeeded());995 996    auto ExpectedConstAddPC =997        checkTable(ConstAddPCOffset, "DW_LNS_const_add_pc", MsgSuffix);998    ASSERT_THAT_EXPECTED(ExpectedConstAddPC, Succeeded());999    ASSERT_EQ((*ExpectedConstAddPC)->Rows.size(), 2u);1000    EXPECT_EQ((*ExpectedConstAddPC)->Rows[0].Address.Address,1001              getAdjustedAddr(ConstAddPCAddr, ConstIncr * 2, 0x1, 0x10));1002    EXPECT_EQ((*ExpectedConstAddPC)->Rows[0].Line, getAdjustedLine(1, 1));1003    EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());1004 1005    auto ExpectedSpecial = checkTable(SpecialOffset, "special", MsgSuffix);1006    ASSERT_THAT_EXPECTED(ExpectedSpecial, Succeeded());1007    ASSERT_EQ((*ExpectedSpecial)->Rows.size(), 3u);1008    EXPECT_EQ((*ExpectedSpecial)->Rows[0].Address.Address,1009              getAdjustedAddr(SpecialAddr, 0, 1, 0));1010    EXPECT_EQ((*ExpectedSpecial)->Rows[0].Line, getAdjustedLine(1, 2));1011    EXPECT_EQ((*ExpectedSpecial)->Rows[1].Address.Address,1012              getAdjustedAddr(SpecialAddr, ConstIncr, 0x2, 0x20));1013    EXPECT_EQ((*ExpectedSpecial)->Rows[1].Line, getAdjustedLine(1, 5));1014    EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());1015 1016    if (!CheckAdvancePC)1017      return;1018 1019    auto ExpectedAdvancePC =1020        checkTable(AdvancePCOffset, "DW_LNS_advance_pc", MsgSuffix);1021    ASSERT_THAT_EXPECTED(ExpectedAdvancePC, Succeeded());1022    ASSERT_EQ((*ExpectedAdvancePC)->Rows.size(), 2u);1023    EXPECT_EQ((*ExpectedAdvancePC)->Rows[0].Address.Address,1024              getAdjustedAddr(AdvancePCAddr, ConstIncr, 0x1, 0x70));1025    EXPECT_EQ((*ExpectedAdvancePC)->Rows[0].Line, getAdjustedLine(1, 4));1026  }1027 1028  uint64_t ConstIncr = 0x11;1029  uint64_t ConstAddPCAddr = 0x1234;1030  uint64_t SpecialAddr = 0x5678;1031  uint64_t AdvancePCAddr = 0xabcd;1032  uint64_t NoProblemOffset;1033  uint64_t ConstAddPCOffset;1034  uint64_t SpecialOffset;1035  uint64_t AdvancePCOffset;1036 1037  uint16_t Version = 4;1038  bool IsErrorExpected;1039};1040 1041struct OpIndexFixture : Test, CommonFixture {1042  void createPrologue(LineTable &LT, uint8_t MaxOpsPerInst,1043                      uint8_t MinInstLength) {1044    DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();1045    Prologue.MaxOpsPerInst = MaxOpsPerInst;1046    Prologue.MinInstLength = MinInstLength;1047    LT.setPrologue(Prologue);1048  }1049};1050 1051TEST_F(OpIndexFixture, OpIndexAdvance) {1052  if (!setupGenerator(4, 4))1053    GTEST_SKIP();1054 1055  uint8_t MaxOpsPerInst = 13;1056  uint8_t MinInstLength = 4;1057 1058  LineTable &LT = Gen->addLineTable();1059 1060  // Row 0-2: Different locations for one bundle set up using special opcodes.1061  LT.addExtendedOpcode(5, DW_LNE_set_address, {{0x20, LineTable::Long}});1062  LT.addByte(0x13); // Special opcode, +1 line.1063  LT.addByte(0x23); // Special opcode, +3 line, +1 op-index.1064  LT.addByte(0x3a); // Special opcode, -2 line, +3 op-index.1065 1066  // Row 3: New bundle, set up using DW_LNS_advance pc.1067  // Operation advance 0x84, which gives +40 addr, +2 op-index1068  LT.addStandardOpcode(DW_LNS_advance_line, {{100, LineTable::SLEB}});1069  LT.addStandardOpcode(DW_LNS_advance_pc, {{0x84, LineTable::ULEB}});1070  LT.addStandardOpcode(DW_LNS_copy, {}); // Create new row.1071 1072  // Row 4: New bundle, set up using a single special opcode.1073  LT.addByte(0x71); // Special opcode, +4 addr, -3 line, -6 op-index.1074 1075  // Row 5: New bundle, set up using using DW_LNS_const_add_pc.1076  // Corresponds to advancing address and op-index using special opcode 255,1077  // which gives +4 addr, +4 op-index.1078  LT.addStandardOpcode(DW_LNS_advance_line, {{10, LineTable::SLEB}});1079  LT.addStandardOpcode(DW_LNS_const_add_pc, {});1080  LT.addStandardOpcode(DW_LNS_copy, {}); // Create new row.1081 1082  // Row 6: End sequence to have the input well-formed.1083  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});1084 1085  createPrologue(LT, MaxOpsPerInst, MinInstLength);1086 1087  generate();1088 1089  auto VerifyRow = [](const DWARFDebugLine::Row &Row, uint64_t Address,1090                      uint8_t OpIndex, uint32_t Line) {1091    EXPECT_EQ(Row.Address.Address, Address);1092    EXPECT_EQ(Row.OpIndex, OpIndex);1093    EXPECT_EQ(Row.Line, Line);1094  };1095 1096  auto Table = Line.getOrParseLineTable(LineData, 0, *Context, nullptr,1097                                        RecordRecoverable);1098  EXPECT_THAT_ERROR(1099      std::move(Recoverable),1100      FailedWithMessage("line table program at offset 0x00000000 contains a "1101                        "special opcode at offset 0x00000035, but the prologue "1102                        "maximum_operations_per_instruction value is 13, which "1103                        "is experimentally supported, so line number "1104                        "information may be incorrect"));1105  EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());1106  ASSERT_THAT_EXPECTED(Table, Succeeded());1107 1108  ASSERT_EQ((*Table)->Rows.size(), 7u);1109 1110  VerifyRow((*Table)->Rows[0], 0x20, 0, 2);1111  VerifyRow((*Table)->Rows[1], 0x20, 1, 5);1112  VerifyRow((*Table)->Rows[2], 0x20, 4, 3);1113  VerifyRow((*Table)->Rows[3], 0x48, 6, 103);1114  VerifyRow((*Table)->Rows[4], 0x4c, 0, 100);1115  VerifyRow((*Table)->Rows[5], 0x50, 4, 110);1116}1117 1118TEST_F(OpIndexFixture, OpIndexReset) {1119  if (!setupGenerator(4, 4))1120    GTEST_SKIP();1121 1122  uint8_t MaxOpsPerInst = 13;1123  uint8_t MinInstLength = 4;1124 1125  LineTable &LT = Gen->addLineTable();1126 1127  // Row 0: Just set op-index to some value > 0.1128  LT.addExtendedOpcode(5, DW_LNE_set_address, {{0, LineTable::Long}});1129  LT.addByte(0x20); // Special opcode, +1 op-index1130 1131  // Row 1: DW_LNE_fixed_advance_pc should set op-index to 0.1132  LT.addStandardOpcode(DW_LNS_fixed_advance_pc, {{10, LineTable::Half}});1133  LT.addStandardOpcode(DW_LNS_copy, {}); // Create new row.1134 1135  // Row 2: Just set op-index to some value > 0.1136  LT.addByte(0x66); // Special opcode, +6 op-index1137 1138  // Row 3: DW_LNE_set_address should set op-index to 0.1139  LT.addExtendedOpcode(5, DW_LNE_set_address, {{20, LineTable::Long}});1140  LT.addStandardOpcode(DW_LNS_copy, {}); // Create new row.1141 1142  // Row 4: Just set op-index to some value > 0.1143  LT.addByte(0xba); // Special opcode, +12 op-index1144 1145  // Row 5: End sequence (op-index unchanged for this row)...1146  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});1147 1148  // Row 6: ... but shall be reset after the DW_LNE_end_sequence row.1149  LT.addStandardOpcode(DW_LNS_copy, {}); // Create new row.1150 1151  // Row 7: End sequence to have the input well-formed.1152  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});1153 1154  createPrologue(LT, MaxOpsPerInst, MinInstLength);1155 1156  generate();1157 1158  auto Table = Line.getOrParseLineTable(LineData, 0, *Context, nullptr,1159                                        RecordRecoverable);1160  EXPECT_THAT_ERROR(1161      std::move(Recoverable),1162      FailedWithMessage("line table program at offset 0x00000000 contains a "1163                        "special opcode at offset 0x00000035, but the prologue "1164                        "maximum_operations_per_instruction value is 13, which "1165                        "is experimentally supported, so line number "1166                        "information may be incorrect"));1167  EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());1168  ASSERT_THAT_EXPECTED(Table, Succeeded());1169 1170  ASSERT_EQ((*Table)->Rows.size(), 8u);1171  EXPECT_EQ((*Table)->Rows[0].OpIndex, 1u);1172  EXPECT_EQ((*Table)->Rows[1].OpIndex, 0u); // DW_LNS_fixed_advance_pc.1173  EXPECT_EQ((*Table)->Rows[2].OpIndex, 6u);1174  EXPECT_EQ((*Table)->Rows[3].OpIndex, 0u); // DW_LNE_set_address.1175  EXPECT_EQ((*Table)->Rows[4].OpIndex, 12u);1176  EXPECT_EQ((*Table)->Rows[5].OpIndex, 12u);1177  EXPECT_EQ((*Table)->Rows[6].OpIndex, 0u); // row after DW_LNE_end_sequence.1178  EXPECT_EQ((*Table)->Rows[7].OpIndex, 0u);1179}1180 1181TEST_F(OpIndexFixture, MaxOpsZeroDwarf3) {1182  if (!setupGenerator(3, 4))1183    GTEST_SKIP();1184 1185  LineTable &LT = Gen->addLineTable();1186  LT.addStandardOpcode(DW_LNS_const_add_pc, {}); // Just some opcode to advance.1187  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); //1188  createPrologue(LT, /*MaxOpsPerInst=*/0, /*MinInstLength=*/1);1189  generate();1190 1191  auto Table = Line.getOrParseLineTable(LineData, 0, *Context, nullptr,1192                                        RecordRecoverable);1193  EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());1194  EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());1195  ASSERT_THAT_EXPECTED(Table, Succeeded());1196}1197 1198TEST_F(OpIndexFixture, MaxOpsZeroDwarf4) {1199  if (!setupGenerator(4, 4))1200    GTEST_SKIP();1201 1202  LineTable &LT = Gen->addLineTable();1203  LT.addStandardOpcode(DW_LNS_const_add_pc, {}); // Just some opcode to advance.1204  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); //1205  createPrologue(LT, /*MaxOpsPerInst=*/0, /*MinInstLength=*/1);1206  generate();1207 1208  auto Table = Line.getOrParseLineTable(LineData, 0, *Context, nullptr,1209                                        RecordRecoverable);1210  EXPECT_THAT_ERROR(1211      std::move(Recoverable),1212      FailedWithMessage(1213          "line table program at offset 0x00000000 contains a "1214          "DW_LNS_const_add_pc opcode at offset 0x0000002e, but "1215          "the prologue maximum_operations_per_instruction value "1216          "is 0, which is invalid. Assuming a value of 1 instead"));1217  EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded());1218  ASSERT_THAT_EXPECTED(Table, Succeeded());1219}1220 1221struct LineRangeFixture : TestWithParam<std::tuple<uint8_t, bool>>,1222                          AdjustAddressFixtureBase {1223  void SetUp() override { std::tie(LineRange, IsErrorExpected) = GetParam(); }1224 1225  uint64_t editPrologue(LineTable &LT) override {1226    DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();1227    Prologue.LineRange = LineRange;1228    LT.setPrologue(Prologue);1229    return Prologue.TotalLength + Prologue.sizeofTotalLength();1230  }1231 1232  uint64_t getAdjustedAddr(uint64_t Base, uint64_t ConstIncr,1233                           uint64_t SpecialIncr,1234                           uint64_t AdvanceIncr) override {1235    if (LineRange == 0)1236      return Base + AdvanceIncr;1237    return AdjustAddressFixtureBase::getAdjustedAddr(Base, ConstIncr,1238                                                     SpecialIncr, AdvanceIncr);1239  }1240 1241  uint64_t getAdjustedLine(uint64_t Base, uint64_t Incr) override {1242    return LineRange != 01243               ? AdjustAddressFixtureBase::getAdjustedLine(Base, Incr)1244               : Base;1245  }1246 1247  uint8_t LineRange;1248};1249 1250TEST_P(LineRangeFixture, LineRangeProblemsReportedCorrectly) {1251  runTest(/*CheckAdvancePC=*/false,1252          "but the prologue line_range value is 0. The address and line will "1253          "not be adjusted");1254}1255 1256INSTANTIATE_TEST_SUITE_P(1257    LineRangeParams, LineRangeFixture,1258    Values(std::make_tuple(0, true),     // Test zero value (error).1259           std::make_tuple(14, false))); // Test non-zero value (no error).1260 1261struct BadMinInstLenFixture : TestWithParam<std::tuple<uint8_t, bool>>,1262                              AdjustAddressFixtureBase {1263  void SetUp() override {1264    std::tie(MinInstLength, IsErrorExpected) = GetParam();1265  }1266 1267  uint64_t editPrologue(LineTable &LT) override {1268    DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();1269    Prologue.MinInstLength = MinInstLength;1270    LT.setPrologue(Prologue);1271    return Prologue.TotalLength + Prologue.sizeofTotalLength();1272  }1273 1274  uint64_t getAdjustedAddr(uint64_t Base, uint64_t ConstIncr,1275                           uint64_t SpecialIncr,1276                           uint64_t AdvanceIncr) override {1277    return MinInstLength != 0 ? AdjustAddressFixtureBase::getAdjustedAddr(1278                                    Base, ConstIncr, SpecialIncr, AdvanceIncr)1279                              : Base;1280  }1281 1282  uint8_t MinInstLength;1283};1284 1285TEST_P(BadMinInstLenFixture, MinInstLengthProblemsReportedCorrectly) {1286  runTest(/*CheckAdvancePC=*/true,1287          "but the prologue minimum_instruction_length value is 0, which "1288          "prevents any address advancing");1289}1290 1291INSTANTIATE_TEST_SUITE_P(1292    BadMinInstLenParams, BadMinInstLenFixture,1293    Values(std::make_tuple(0, true),    // Test zero value (error).1294           std::make_tuple(1, false))); // Test non-zero value (no error).1295 1296TEST_F(DebugLineBasicFixture, ParserParsesCorrectly) {1297  if (!setupGenerator())1298    GTEST_SKIP();1299 1300  DWARFDebugLine::SectionParser Parser = setupParser();1301 1302  EXPECT_EQ(Parser.getOffset(), 0u);1303  ASSERT_FALSE(Parser.done());1304 1305  DWARFDebugLine::LineTable Parsed =1306      Parser.parseNext(RecordRecoverable, RecordUnrecoverable);1307  checkDefaultPrologue(4, DWARF32, Parsed.Prologue, 16);1308  EXPECT_EQ(Parsed.Sequences.size(), 1u);1309  EXPECT_EQ(Parser.getOffset(), 62u);1310  ASSERT_FALSE(Parser.done());1311 1312  DWARFDebugLine::LineTable Parsed2 =1313      Parser.parseNext(RecordRecoverable, RecordUnrecoverable);1314  checkDefaultPrologue(4, DWARF64, Parsed2.Prologue, 16);1315  EXPECT_EQ(Parsed2.Sequences.size(), 1u);1316  EXPECT_EQ(Parser.getOffset(), 136u);1317  EXPECT_TRUE(Parser.done());1318 1319  EXPECT_FALSE(Recoverable);1320  EXPECT_FALSE(Unrecoverable);1321}1322 1323TEST_F(DebugLineBasicFixture, ParserSkipsCorrectly) {1324  if (!setupGenerator())1325    GTEST_SKIP();1326 1327  DWARFDebugLine::SectionParser Parser = setupParser();1328 1329  EXPECT_EQ(Parser.getOffset(), 0u);1330  ASSERT_FALSE(Parser.done());1331 1332  Parser.skip(RecordRecoverable, RecordUnrecoverable);1333  EXPECT_EQ(Parser.getOffset(), 62u);1334  ASSERT_FALSE(Parser.done());1335 1336  Parser.skip(RecordRecoverable, RecordUnrecoverable);1337  EXPECT_EQ(Parser.getOffset(), 136u);1338  EXPECT_TRUE(Parser.done());1339 1340  EXPECT_FALSE(Recoverable);1341  EXPECT_FALSE(Unrecoverable);1342}1343 1344TEST_F(DebugLineBasicFixture, ParserAlwaysDoneForEmptySection) {1345  if (!setupGenerator())1346    GTEST_SKIP();1347 1348  generate();1349  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1350 1351  EXPECT_TRUE(Parser.done());1352}1353 1354TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenParsing) {1355  if (!setupGenerator())1356    GTEST_SKIP();1357 1358  LineTable &LT = Gen->addLineTable();1359  LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});1360  Gen->addLineTable();1361  generate();1362 1363  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1364  Parser.parseNext(RecordRecoverable, RecordUnrecoverable);1365 1366  EXPECT_EQ(Parser.getOffset(), 0u);1367  EXPECT_TRUE(Parser.done());1368  EXPECT_FALSE(Recoverable);1369 1370  EXPECT_THAT_ERROR(1371      std::move(Unrecoverable),1372      FailedWithMessage(1373          "parsing line table prologue at offset 0x00000000: unsupported "1374          "reserved unit length of value 0xfffffff0"));1375}1376 1377TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenSkipping) {1378  if (!setupGenerator())1379    GTEST_SKIP();1380 1381  LineTable &LT = Gen->addLineTable();1382  LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});1383  Gen->addLineTable();1384  generate();1385 1386  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1387  Parser.skip(RecordRecoverable, RecordUnrecoverable);1388 1389  EXPECT_EQ(Parser.getOffset(), 0u);1390  EXPECT_TRUE(Parser.done());1391  EXPECT_FALSE(Recoverable);1392 1393  EXPECT_THAT_ERROR(1394      std::move(Unrecoverable),1395      FailedWithMessage(1396          "parsing line table prologue at offset 0x00000000: unsupported "1397          "reserved unit length of value 0xfffffff0"));1398}1399 1400TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {1401  if (!setupGenerator())1402    GTEST_SKIP();1403 1404  LineTable &LT = Gen->addLineTable(DWARF32);1405  LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}});1406  LineTable &LT2 = Gen->addLineTable(DWARF32);1407  LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}});1408  generate();1409 1410  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1411  Parser.parseNext(RecordRecoverable, RecordUnrecoverable);1412  ASSERT_FALSE(Parser.done());1413  Parser.parseNext(RecordRecoverable, RecordUnrecoverable);1414 1415  EXPECT_TRUE(Parser.done());1416  EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());1417 1418  EXPECT_THAT_ERROR(1419      std::move(Unrecoverable),1420      FailedWithMessage("parsing line table prologue at offset 0x00000000: "1421                        "unsupported version 0",1422                        "parsing line table prologue at offset 0x00000006: "1423                        "unsupported version 1"));1424}1425 1426TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) {1427  if (!setupGenerator())1428    GTEST_SKIP();1429 1430  LineTable &LT = Gen->addLineTable(DWARF32);1431  LT.addExtendedOpcode(0x42, DW_LNE_end_sequence, {});1432  LineTable &LT2 = Gen->addLineTable(DWARF32);1433  LT2.addExtendedOpcode(9, DW_LNE_set_address,1434                        {{0x1234567890abcdef, LineTable::Quad}});1435  LT2.addStandardOpcode(DW_LNS_copy, {});1436  LT2.addByte(0xbb);1437  generate();1438 1439  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1440  Parser.parseNext(RecordRecoverable, RecordUnrecoverable);1441  EXPECT_FALSE(Unrecoverable);1442  ASSERT_FALSE(Parser.done());1443  EXPECT_THAT_ERROR(std::move(Recoverable),1444                    FailedWithMessage("unexpected line op length at offset "1445                                      "0x00000030 expected 0x42 found 0x01"));1446 1447  // Reset the error state so that it does not confuse the next set of checks.1448  Unrecoverable = Error::success();1449  Parser.parseNext(RecordRecoverable, RecordUnrecoverable);1450 1451  EXPECT_TRUE(Parser.done());1452  EXPECT_THAT_ERROR(std::move(Recoverable),1453                    FailedWithMessage("last sequence in debug line table at "1454                                      "offset 0x00000031 is not terminated"));1455  EXPECT_FALSE(Unrecoverable);1456}1457 1458TEST_F(DebugLineBasicFixture,1459       ParserReportsPrologueErrorsInEachTableWhenSkipping) {1460  if (!setupGenerator())1461    GTEST_SKIP();1462 1463  LineTable &LT = Gen->addLineTable(DWARF32);1464  LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}});1465  LineTable &LT2 = Gen->addLineTable(DWARF32);1466  LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}});1467  generate();1468 1469  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1470  Parser.skip(RecordRecoverable, RecordUnrecoverable);1471  ASSERT_FALSE(Parser.done());1472  Parser.skip(RecordRecoverable, RecordUnrecoverable);1473 1474  EXPECT_TRUE(Parser.done());1475  EXPECT_FALSE(Recoverable);1476 1477  EXPECT_THAT_ERROR(1478      std::move(Unrecoverable),1479      FailedWithMessage("parsing line table prologue at offset 0x00000000: "1480                        "unsupported version 0",1481                        "parsing line table prologue at offset 0x00000006: "1482                        "unsupported version 1"));1483}1484 1485TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) {1486  if (!setupGenerator())1487    GTEST_SKIP();1488 1489  LineTable &LT = Gen->addLineTable(DWARF32);1490  LT.addExtendedOpcode(42, DW_LNE_end_sequence, {});1491  generate();1492 1493  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1494  Parser.skip(RecordRecoverable, RecordUnrecoverable);1495 1496  EXPECT_TRUE(Parser.done());1497  EXPECT_FALSE(Recoverable);1498  EXPECT_FALSE(Unrecoverable);1499}1500 1501#ifdef NO_SUPPORT_DEBUG_ADDR1502TEST_F(DebugLineBasicFixture, DISABLED_VerboseOutput) {1503#else1504TEST_F(DebugLineBasicFixture, VerboseOutput) {1505#endif1506  if (!setupGenerator(5))1507    GTEST_SKIP();1508 1509  LineTable &LT = Gen->addLineTable();1510  LT.addByte(0); // Extended opcode with zero length.1511  LT.addByte(0);1512  // Zero-value extended opcode.1513  LT.addExtendedOpcode(2, 0, {{1, LineTable::Byte}});1514  // Unknown extended opcode.1515  LT.addExtendedOpcode(2, 0x42, {{1, LineTable::Byte}});1516  LT.addExtendedOpcode(9, DW_LNE_set_address,1517                       {{0x123456789abcdef, LineTable::Quad}});1518  LT.addExtendedOpcode(6, DW_LNE_define_file,1519                       {{'a', LineTable::Byte},1520                        {'\0', LineTable::Byte},1521                        {2, LineTable::ULEB},1522                        {3, LineTable::ULEB},1523                        {4, LineTable::ULEB}});1524  LT.addExtendedOpcode(2, DW_LNE_set_discriminator, {{0x7f, LineTable::ULEB}});1525  LT.addStandardOpcode(DW_LNS_copy, {});1526  LT.addStandardOpcode(DW_LNS_advance_pc, {{11, LineTable::ULEB}});1527  LT.addStandardOpcode(DW_LNS_advance_line, {{22, LineTable::SLEB}});1528  LT.addStandardOpcode(DW_LNS_set_file, {{33, LineTable::ULEB}});1529  LT.addStandardOpcode(DW_LNS_set_column, {{44, LineTable::ULEB}});1530  LT.addStandardOpcode(DW_LNS_negate_stmt, {});1531  LT.addStandardOpcode(DW_LNS_set_basic_block, {});1532  LT.addStandardOpcode(DW_LNS_const_add_pc, {});1533  LT.addStandardOpcode(DW_LNS_fixed_advance_pc, {{55, LineTable::Half}});1534  LT.addStandardOpcode(DW_LNS_set_prologue_end, {});1535  LT.addStandardOpcode(DW_LNS_set_epilogue_begin, {});1536  LT.addStandardOpcode(DW_LNS_set_isa, {{66, LineTable::ULEB}});1537  // Add unknown standard opcode with operands.1538  LT.addStandardOpcode(1539      0xd, {{1, LineTable::ULEB}, {0x123456789abcdef, LineTable::ULEB}});1540  // Add unknown standard opcode without operands.1541  LT.addStandardOpcode(0xe, {});1542  LT.addByte(0xff); // Special opcode.1543  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});1544 1545  // Adjust the prologue to account for the extra standard opcode.1546  DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();1547  Prologue.TotalLength += 2;1548  Prologue.PrologueLength += 2;1549  Prologue.OpcodeBase += 2;1550  Prologue.StandardOpcodeLengths.push_back(2);1551  Prologue.StandardOpcodeLengths.push_back(0);1552  LT.setPrologue(Prologue);1553 1554  generate();1555 1556  DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1557  std::string Output;1558  raw_string_ostream OS(Output);1559  Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS,1560                   /*Verbose=*/true);1561  StringRef OutputRef(Output);1562 1563  size_t Pos = 0;1564  auto NextLine = [&Pos, &OutputRef]() {1565    size_t EOL = OutputRef.find_first_of('\n', Pos);1566    StringRef Line = OutputRef.substr(Pos, EOL - Pos);1567    Pos = EOL + 1;1568    return Line;1569  };1570  EXPECT_EQ(NextLine(), "Line table prologue:");1571  EXPECT_EQ(NextLine(), "    total_length: 0x00000078");1572  EXPECT_EQ(NextLine(), "          format: DWARF32");1573  EXPECT_EQ(NextLine(), "         version: 5");1574  EXPECT_EQ(NextLine(), "    address_size: 8");1575  EXPECT_EQ(NextLine(), " seg_select_size: 0");1576  EXPECT_EQ(NextLine(), " prologue_length: 0x0000002c");1577  EXPECT_EQ(NextLine(), " min_inst_length: 1");1578  EXPECT_EQ(NextLine(), "max_ops_per_inst: 1");1579  EXPECT_EQ(NextLine(), " default_is_stmt: 1");1580  EXPECT_EQ(NextLine(), "       line_base: -5");1581  EXPECT_EQ(NextLine(), "      line_range: 14");1582  EXPECT_EQ(NextLine(), "     opcode_base: 15");1583  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_copy] = 0");1584  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_advance_pc] = 1");1585  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_advance_line] = 1");1586  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_file] = 1");1587  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_column] = 1");1588  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_negate_stmt] = 0");1589  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_basic_block] = 0");1590  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_const_add_pc] = 0");1591  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1");1592  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_prologue_end] = 0");1593  EXPECT_EQ(NextLine(),1594            "standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0");1595  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_isa] = 1");1596  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_unknown_d] = 2");1597  EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_unknown_e] = 0");1598  EXPECT_EQ(NextLine(), "include_directories[  0] = \"a dir\"");1599  EXPECT_EQ(NextLine(), "file_names[  0]:");1600  EXPECT_EQ(NextLine(), "           name: \"a file\"");1601  EXPECT_EQ(NextLine(), "      dir_index: 0");1602  EXPECT_EQ(NextLine(), "");1603  EXPECT_EQ(NextLine(), "            Address            Line   Column File   "1604                        "ISA Discriminator OpIndex Flags");1605  EXPECT_EQ(NextLine(), "            ------------------ ------ ------ ------ "1606                        "--- ------------- ------- -------------");1607  EXPECT_EQ(NextLine(),1608            "0x00000038: 00 Badly formed extended line op (length 0)");1609  EXPECT_EQ(NextLine(),1610            "0x0000003a: 00 Unrecognized extended op 0x00 length 2");1611  EXPECT_EQ(NextLine(),1612            "0x0000003e: 00 Unrecognized extended op 0x42 length 2");1613  EXPECT_EQ(NextLine(),1614            "0x00000042: 00 DW_LNE_set_address (0x0123456789abcdef)");1615  EXPECT_EQ(NextLine(), "0x0000004d: 00 DW_LNE_define_file (a, dir=2, "1616                        "mod_time=(0x0000000000000003), length=4)");1617  EXPECT_EQ(NextLine(), "0x00000055: 00 DW_LNE_set_discriminator (127)");1618  EXPECT_EQ(NextLine(), "0x00000059: 01 DW_LNS_copy");1619  EXPECT_EQ(NextLine(), "            0x0123456789abcdef      1      0      1   "1620                        "0           127       0  is_stmt");1621  EXPECT_EQ(NextLine(), "0x0000005a: 02 DW_LNS_advance_pc (addr += 11, "1622                        "op-index += 0)");1623  EXPECT_EQ(NextLine(), "0x0000005c: 03 DW_LNS_advance_line (23)");1624  EXPECT_EQ(NextLine(), "0x0000005e: 04 DW_LNS_set_file (33)");1625  EXPECT_EQ(NextLine(), "0x00000060: 05 DW_LNS_set_column (44)");1626  EXPECT_EQ(NextLine(), "0x00000062: 06 DW_LNS_negate_stmt");1627  EXPECT_EQ(NextLine(), "0x00000063: 07 DW_LNS_set_basic_block");1628  EXPECT_EQ(NextLine(),1629            "0x00000064: 08 DW_LNS_const_add_pc (addr += 0x0000000000000011, "1630            "op-index += 0)");1631  EXPECT_EQ(NextLine(), "0x00000065: 09 DW_LNS_fixed_advance_pc (addr += 0x0037"1632            ", op-index = 0)");1633  EXPECT_EQ(NextLine(), "0x00000068: 0a DW_LNS_set_prologue_end");1634  EXPECT_EQ(NextLine(), "0x00000069: 0b DW_LNS_set_epilogue_begin");1635  EXPECT_EQ(NextLine(), "0x0000006a: 0c DW_LNS_set_isa (66)");1636  EXPECT_EQ(NextLine(), "0x0000006c: 0d Unrecognized standard opcode "1637                        "(operands: 0x0000000000000001, 0x0123456789abcdef)");1638  EXPECT_EQ(NextLine(), "0x00000077: 0e Unrecognized standard opcode");1639  EXPECT_EQ(NextLine(), "0x00000078: ff address += 17,  line += -3,  "1640                        "op-index += 0");1641  EXPECT_EQ(NextLine(),1642            "            0x0123456789abce53     20     44     33  66           "1643            "  0       0  basic_block prologue_end epilogue_begin");1644  EXPECT_EQ(NextLine(), "0x00000079: 00 DW_LNE_end_sequence");1645  EXPECT_EQ(NextLine(), "            0x0123456789abce53     20     44     33  "1646                        "66             0       0  end_sequence");1647  EXPECT_EQ(NextLine(), "");1648  EXPECT_EQ(Output.size(), Pos);1649}1650 1651struct TruncatedPrologueFixture1652    : public TestWithParam<1653          std::tuple<uint64_t, uint64_t, uint16_t, DwarfFormat, StringRef>>,1654      public CommonFixture {1655  void SetUp() override {1656    std::tie(Length, ExpectedOffset, Version, Format, ExpectedErr) = GetParam();1657  }1658 1659  uint64_t Length;1660  uint64_t ExpectedOffset;1661  uint16_t Version;1662  DwarfFormat Format;1663  StringRef ExpectedErr;1664};1665 1666#ifdef NO_SUPPORT_DEBUG_ADDR1667TEST_P(TruncatedPrologueFixture, DISABLED_ErrorForTruncatedPrologue) {1668#else1669TEST_P(TruncatedPrologueFixture, ErrorForTruncatedPrologue) {1670#endif1671  if (!setupGenerator(Version))1672    GTEST_SKIP();1673 1674  LineTable &Padding = Gen->addLineTable();1675  // Add some padding to show that a non-zero offset is handled correctly.1676  Padding.setCustomPrologue({{0, LineTable::Byte}});1677 1678  // Add a table with only two standard opcodes - we don't need to test the full1679  // set.1680  LineTable &Table = Gen->addLineTable(Format);1681  DWARFDebugLine::Prologue InputPrologue = Table.createBasicPrologue();1682  InputPrologue.OpcodeBase = 3;1683  InputPrologue.StandardOpcodeLengths.resize(2);1684  Table.setPrologue(InputPrologue);1685 1686  generate();1687  // Truncate the data extractor to the specified length.1688  LineData = DWARFDataExtractor(LineData, Length);1689 1690  DWARFDebugLine::Prologue Prologue;1691  uint64_t Offset = 1;1692  Error Err = Prologue.parse(LineData, &Offset, RecordRecoverable, *Context);1693 1694  EXPECT_THAT_ERROR(std::move(Err), FailedWithMessage(ExpectedErr.str()));1695  EXPECT_EQ(Offset, ExpectedOffset);1696}1697 1698INSTANTIATE_TEST_SUITE_P(1699    TruncatedPrologueParams, TruncatedPrologueFixture,1700    Values(1701        // Truncated length:1702        std::make_tuple(1703            4, 1, 4, DWARF32,1704            "parsing line table prologue at offset 0x00000001: unexpected end "1705            "of data at offset 0x4 while reading [0x1, 0x5)"),1706        std::make_tuple(1707            4, 1, 4, DWARF64,1708            "parsing line table prologue at offset 0x00000001: unexpected end "1709            "of data at offset 0x4 while reading [0x1, 0x5)"),1710        std::make_tuple(1711            0xc, 1, 4, DWARF64,1712            "parsing line table prologue at offset 0x00000001: unexpected end "1713            "of data at offset 0xc while reading [0x5, 0xd)"),1714        // Truncated version:1715        std::make_tuple(1716            6, 5, 4, DWARF32,1717            "parsing line table prologue at offset 0x00000001: unexpected end "1718            "of data at offset 0x6 while reading [0x5, 0x7)"),1719        // Truncated address size:1720        std::make_tuple(1721            7, 7, 5, DWARF32,1722            "parsing line table prologue at offset 0x00000001: unexpected end "1723            "of data at offset 0x7 while reading [0x7, 0x8)"),1724        // Truncated segment selector size:1725        std::make_tuple(1726            8, 8, 5, DWARF32,1727            "parsing line table prologue at offset 0x00000001: unexpected end "1728            "of data at offset 0x8 while reading [0x8, 0x9)"),1729        // Truncated prologue length:1730        std::make_tuple(1731            0xa, 7, 4, DWARF32,1732            "parsing line table prologue at offset 0x00000001: unexpected end "1733            "of data at offset 0xa while reading [0x7, 0xb)"),1734        std::make_tuple(1735            0x16, 0xf, 4, DWARF64,1736            "parsing line table prologue at offset 0x00000001: unexpected end "1737            "of data at offset 0x16 while reading [0xf, 0x17)"),1738        // Truncated min instruction length:1739        std::make_tuple(1740            0xb, 0xb, 4, DWARF32,1741            "parsing line table prologue at offset 0x00000001: unexpected end "1742            "of data at offset 0xb while reading [0xb, 0xc)"),1743        // Truncated max ops per inst:1744        std::make_tuple(1745            0xc, 0xc, 4, DWARF32,1746            "parsing line table prologue at offset 0x00000001: unexpected end "1747            "of data at offset 0xc while reading [0xc, 0xd)"),1748        // Truncated default is stmt:1749        std::make_tuple(1750            0xd, 0xd, 4, DWARF32,1751            "parsing line table prologue at offset 0x00000001: unexpected end "1752            "of data at offset 0xd while reading [0xd, 0xe)"),1753        // Truncated line base:1754        std::make_tuple(1755            0xe, 0xe, 4, DWARF32,1756            "parsing line table prologue at offset 0x00000001: unexpected end "1757            "of data at offset 0xe while reading [0xe, 0xf)"),1758        // Truncated line range:1759        std::make_tuple(1760            0xf, 0xf, 4, DWARF32,1761            "parsing line table prologue at offset 0x00000001: unexpected end "1762            "of data at offset 0xf while reading [0xf, 0x10)"),1763        // Truncated opcode base:1764        std::make_tuple(1765            0x10, 0x10, 4, DWARF32,1766            "parsing line table prologue at offset 0x00000001: unexpected end "1767            "of data at offset 0x10 while reading [0x10, 0x11)"),1768        // Truncated first standard opcode:1769        std::make_tuple(1770            0x11, 0x11, 4, DWARF32,1771            "parsing line table prologue at offset 0x00000001: unexpected end "1772            "of data at offset 0x11 while reading [0x11, 0x12)"),1773        // Truncated second standard opcode:1774        std::make_tuple(1775            0x12, 0x12, 4, DWARF32,1776            "parsing line table prologue at offset 0x00000001: unexpected end "1777            "of data at offset 0x12 while reading [0x12, 0x13)")));1778 1779using ValueAndLengths = std::vector<LineTable::ValueAndLength>;1780 1781struct TruncatedOpcodeFixtureBase : public CommonFixture {1782  LineTable &setupTable() {1783    LineTable &LT = Gen->addLineTable();1784 1785    // Creating the prologue before adding any opcodes ensures that the unit1786    // length does not include the table body.1787    DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();1788 1789    // Add an unrecognised standard opcode, and adjust prologue properties1790    // accordingly.1791    Prologue.TotalLength += BodyLength + 1;1792    ++Prologue.PrologueLength;1793    ++Prologue.OpcodeBase;1794    Prologue.StandardOpcodeLengths.push_back(2);1795    LT.setPrologue(Prologue);1796 1797    return LT;1798  }1799 1800  void runTest(uint8_t OpcodeValue) {1801    generate();1802    DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);1803    std::string Output;1804    raw_string_ostream OS(Output);1805    Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS,1806                     /*Verbose=*/true);1807 1808    std::string LinePrefix =1809        ("0x0000002f: 0" + Twine::utohexstr(OpcodeValue) + " ").str();1810    StringRef OutputRef(Output);1811    StringRef OutputToCheck = OutputRef.split(LinePrefix).second;1812    // Each extended opcode ends with a new line and then the table ends with an1813    // additional blank line.1814    EXPECT_EQ((ExpectedOutput + "\n\n").str(), OutputToCheck);1815  }1816 1817  uint64_t BodyLength;1818  uint8_t Opcode;1819  ValueAndLengths Operands;1820  StringRef ExpectedOutput;1821  StringRef ExpectedErr;1822};1823 1824struct TruncatedStandardOpcodeFixture1825    : public TestWithParam<1826          std::tuple<uint64_t, uint8_t, ValueAndLengths, StringRef, StringRef>>,1827      public TruncatedOpcodeFixtureBase {1828  void SetUp() override {1829    std::tie(BodyLength, Opcode, Operands, ExpectedOutput, ExpectedErr) =1830        GetParam();1831  }1832};1833 1834struct TruncatedExtendedOpcodeFixture1835    : public TestWithParam<std::tuple<uint64_t, uint64_t, uint8_t,1836                                      ValueAndLengths, StringRef, StringRef>>,1837      public TruncatedOpcodeFixtureBase {1838  void SetUp() override {1839    std::tie(BodyLength, OpcodeLength, Opcode, Operands, ExpectedOutput,1840             ExpectedErr) = GetParam();1841  }1842 1843  uint64_t OpcodeLength;1844};1845 1846TEST_P(TruncatedExtendedOpcodeFixture, ErrorForTruncatedExtendedOpcode) {1847  if (!setupGenerator())1848    GTEST_SKIP();1849  LineTable &LT = setupTable();1850  LT.addExtendedOpcode(OpcodeLength, Opcode, Operands);1851  runTest(0);1852  EXPECT_THAT_ERROR(std::move(Recoverable),1853                    FailedWithMessage(ExpectedErr.str()));1854}1855 1856INSTANTIATE_TEST_SUITE_P(1857    TruncatedExtendedOpcodeParams, TruncatedExtendedOpcodeFixture,1858    Values(1859        // Truncated length:1860        std::make_tuple(1, 1, /*ArbitraryOpcode=*/0x7f, ValueAndLengths(), "",1861                        "unable to decode LEB128 at offset 0x00000030: "1862                        "malformed uleb128, extends past end"),1863        // Truncated opcode:1864        std::make_tuple(1865            2, 9, /*ArbitraryOpcode=*/0x7f, ValueAndLengths(), "",1866            "unexpected end of data at offset 0x31 while reading [0x31, 0x32)"),1867        // Truncated operands:1868        std::make_tuple(1869            3, 9, DW_LNE_set_address,1870            ValueAndLengths{{0x1234567890abcdef, LineTable::Quad}},1871            "DW_LNE_set_address",1872            "unexpected end of data at offset 0x32 while reading [0x32, 0x3a)"),1873        std::make_tuple(1874            10, 9, DW_LNE_set_address,1875            ValueAndLengths{{0x1234567878563412, LineTable::Quad}},1876            "DW_LNE_set_address (<parsing error> 12 34 56 78 78 56 34)",1877            "unexpected end of data at offset 0x39 while reading [0x32, 0x3a)"),1878        std::make_tuple(3, 6, DW_LNE_define_file,1879                        ValueAndLengths{{'a', LineTable::Byte},1880                                        {'\0', LineTable::Byte},1881                                        {1, LineTable::ULEB},1882                                        {1, LineTable::ULEB},1883                                        {1, LineTable::ULEB}},1884                        "DW_LNE_define_file",1885                        "no null terminated string at offset 0x32"),1886        std::make_tuple(5, 6, DW_LNE_define_file,1887                        ValueAndLengths{{'a', LineTable::Byte},1888                                        {'\0', LineTable::Byte},1889                                        {1, LineTable::ULEB},1890                                        {1, LineTable::ULEB},1891                                        {1, LineTable::ULEB}},1892                        "DW_LNE_define_file (<parsing error> 61 00)",1893                        "unable to decode LEB128 at offset 0x00000034: "1894                        "malformed uleb128, extends past end"),1895        std::make_tuple(6, 6, DW_LNE_define_file,1896                        ValueAndLengths{{'a', LineTable::Byte},1897                                        {'\0', LineTable::Byte},1898                                        {1, LineTable::ULEB},1899                                        {1, LineTable::ULEB},1900                                        {1, LineTable::ULEB}},1901                        "DW_LNE_define_file (<parsing error> 61 00 01)",1902                        "unable to decode LEB128 at offset 0x00000035: "1903                        "malformed uleb128, extends past end"),1904        std::make_tuple(7, 6, DW_LNE_define_file,1905                        ValueAndLengths{{'a', LineTable::Byte},1906                                        {'\0', LineTable::Byte},1907                                        {1, LineTable::ULEB},1908                                        {1, LineTable::ULEB},1909                                        {1, LineTable::ULEB}},1910                        "DW_LNE_define_file (<parsing error> 61 00 01 01)",1911                        "unable to decode LEB128 at offset 0x00000036: "1912                        "malformed uleb128, extends past end"),1913        std::make_tuple(3, 2, DW_LNE_set_discriminator,1914                        ValueAndLengths{{1, LineTable::ULEB}},1915                        "DW_LNE_set_discriminator",1916                        "unable to decode LEB128 at offset 0x00000032: "1917                        "malformed uleb128, extends past end"),1918        std::make_tuple(1919            6, 5, /*Unknown=*/0x7f,1920            ValueAndLengths{{0x12343412, LineTable::Long}},1921            "Unrecognized extended op 0x7f length 5 (<parsing error> 12 34 34)",1922            "unexpected end of data at offset 0x35 while reading [0x32, "1923            "0x36)")));1924 1925TEST_P(TruncatedStandardOpcodeFixture, ErrorForTruncatedStandardOpcode) {1926  if (!setupGenerator())1927    GTEST_SKIP();1928  LineTable &LT = setupTable();1929  LT.addStandardOpcode(Opcode, Operands);1930  runTest(Opcode);1931  EXPECT_THAT_ERROR(std::move(Unrecoverable),1932                    FailedWithMessage(ExpectedErr.str()));1933}1934 1935INSTANTIATE_TEST_SUITE_P(1936    TruncatedStandardOpcodeParams, TruncatedStandardOpcodeFixture,1937    Values(1938        std::make_tuple(2, DW_LNS_advance_pc,1939                        ValueAndLengths{{0x100, LineTable::ULEB}},1940                        "DW_LNS_advance_pc",1941                        "unable to decode LEB128 at offset 0x00000030: "1942                        "malformed uleb128, extends past end"),1943        std::make_tuple(2, DW_LNS_advance_line,1944                        ValueAndLengths{{0x200, LineTable::SLEB}},1945                        "DW_LNS_advance_line",1946                        "unable to decode LEB128 at offset 0x00000030: "1947                        "malformed sleb128, extends past end"),1948        std::make_tuple(2, DW_LNS_set_file,1949                        ValueAndLengths{{0x300, LineTable::ULEB}},1950                        "DW_LNS_set_file",1951                        "unable to decode LEB128 at offset 0x00000030: "1952                        "malformed uleb128, extends past end"),1953        std::make_tuple(2, DW_LNS_set_column,1954                        ValueAndLengths{{0x400, LineTable::ULEB}},1955                        "DW_LNS_set_column",1956                        "unable to decode LEB128 at offset 0x00000030: "1957                        "malformed uleb128, extends past end"),1958        std::make_tuple(1959            2, DW_LNS_fixed_advance_pc,1960            ValueAndLengths{{0x500, LineTable::Half}},1961            "DW_LNS_fixed_advance_pc",1962            "unexpected end of data at offset 0x31 while reading [0x30, 0x32)"),1963        std::make_tuple(2, DW_LNS_set_isa,1964                        ValueAndLengths{{0x600, LineTable::ULEB}},1965                        "DW_LNS_set_isa",1966                        "unable to decode LEB128 at offset 0x00000030: "1967                        "malformed uleb128, extends past end"),1968        std::make_tuple(2, 0xd,1969                        ValueAndLengths{{0x700, LineTable::ULEB},1970                                        {0x800, LineTable::ULEB}},1971                        "Unrecognized standard opcode",1972                        "unable to decode LEB128 at offset 0x00000030: "1973                        "malformed uleb128, extends past end"),1974        std::make_tuple(1975            4, 0xd,1976            ValueAndLengths{{0x900, LineTable::ULEB}, {0xa00, LineTable::ULEB}},1977            "Unrecognized standard opcode (operands: 0x0000000000000900)",1978            "unable to decode LEB128 at offset 0x00000032: "1979            "malformed uleb128, extends past end")));1980 1981#ifdef NO_SUPPORT_DEBUG_ADDR1982TEST_F(DebugLineBasicFixture, DISABLED_PrintPathsProperly) {1983#else1984TEST_F(DebugLineBasicFixture, PrintPathsProperly) {1985#endif1986  if (!setupGenerator(5))1987    GTEST_SKIP();1988 1989  LineTable &LT = Gen->addLineTable();1990  DWARFDebugLine::Prologue P = LT.createBasicPrologue();1991  P.IncludeDirectories.push_back(1992      DWARFFormValue::createFromPValue(DW_FORM_string, "b dir"));1993  P.FileNames.push_back(DWARFDebugLine::FileNameEntry());1994  P.FileNames.back().Name =1995      DWARFFormValue::createFromPValue(DW_FORM_string, "b file");1996  P.FileNames.back().DirIdx = 1;1997  P.TotalLength += 14;1998  P.PrologueLength += 14;1999  LT.setPrologue(P);2000  generate();2001 2002  auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,2003                                                    nullptr, RecordRecoverable);2004  EXPECT_THAT_EXPECTED(ExpectedLineTable, Succeeded());2005  std::string Result;2006  // DWARF 5 stores the compilation directory in two places: the Compilation2007  // Unit and the directory table entry 0, and implementations are free to use2008  // one or the other. This copy serves as the one stored in the CU.2009  StringRef CompDir = "a dir";2010  EXPECT_FALSE(2011      (*ExpectedLineTable)2012          ->Prologue.getFileNameByIndex(2013              1, CompDir, DILineInfoSpecifier::FileLineInfoKind::None, Result));2014  EXPECT_TRUE((*ExpectedLineTable)2015                  ->Prologue.getFileNameByIndex(2016                      1, CompDir,2017                      DILineInfoSpecifier::FileLineInfoKind::RawValue, Result));2018  EXPECT_TRUE((*ExpectedLineTable)2019                  ->Prologue.getFileNameByIndex(2020                      1, CompDir,2021                      DILineInfoSpecifier::FileLineInfoKind::BaseNameOnly,2022                      Result));2023  EXPECT_STREQ(Result.c_str(), "b file");2024  EXPECT_TRUE((*ExpectedLineTable)2025                  ->Prologue.getFileNameByIndex(2026                      1, CompDir,2027                      DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath,2028                      Result));2029  EXPECT_THAT(Result.c_str(), MatchesRegex("b dir.b file"));2030  EXPECT_TRUE((*ExpectedLineTable)2031                  ->Prologue.getFileNameByIndex(2032                      1, CompDir,2033                      DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,2034                      Result));2035  EXPECT_THAT(Result.c_str(), MatchesRegex("a dir.b dir.b file"));2036}2037 2038/// Test that lookupAddressRange correctly filters rows based on2039/// a statement-sequence offset (simulating DW_AT_LLVM_stmt_sequence).2040///2041/// This test verifies that:2042/// 1. When a statement-sequence offset is provided, lookupAddressRange2043///    only returns rows from the sequence starting at that offset.2044/// 2. When an invalid statement-sequence offset is provided, no rows2045///    are returned.2046/// 3. When no statement-sequence offset is provided, all matching rows2047///    in the table are returned.2048///2049/// We build a line table with two sequences at the same address range2050/// but different line numbers. Then we try lookups with various statement-2051/// sequence offsets to check the filtering logic.2052TEST_F(DebugLineBasicFixture, LookupAddressRangeWithStmtSequenceOffset) {2053  if (!setupGenerator())2054    GTEST_SKIP();2055 2056  // Create a line table that has two sequences covering [0x1000, 0x1004).2057  // Each sequence has two rows: addresses at 0x1000 and 0x1004, but2058  // they differ by line numbers (100 vs. 200, etc.).2059  //2060  // We'll pretend the first sequence starts at offset 0x2e in the line table,2061  // the second at 0x42, and we'll also test an invalid offset 0x66.2062 2063  LineTable &LT = Gen->addLineTable();2064 2065  // First sequence at offset 0x2e: addresses 0x1000(Ln=100), 0x1004(Ln=101)2066  LT.addExtendedOpcode(9, DW_LNE_set_address, {{0x1000U, LineTable::Quad}});2067  LT.addStandardOpcode(DW_LNS_set_prologue_end, {});2068  // Advance the line register by 99 (so line=100) and copy.2069  LT.addStandardOpcode(DW_LNS_advance_line, {{99, LineTable::SLEB}});2070  LT.addStandardOpcode(DW_LNS_copy, {});2071  // 0x4b is a special opcode: address += 4, line += 1 (so line=101).2072  LT.addByte(0x4b);2073  // End this sequence.2074  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});2075 2076  // Second sequence at offset 0x42: addresses 0x1000(Ln=200), 0x1004(Ln=201)2077  LT.addExtendedOpcode(9, DW_LNE_set_address, {{0x1000U, LineTable::Quad}});2078  LT.addStandardOpcode(DW_LNS_set_prologue_end, {});2079  LT.addStandardOpcode(DW_LNS_advance_line, {{199, LineTable::SLEB}});2080  LT.addStandardOpcode(DW_LNS_copy, {});2081  // 0x4b again: address += 4, line += 1 (so line=201).2082  LT.addByte(0x4b);2083  // End this second sequence.2084  LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});2085 2086  // Generate the DWARF data.2087  generate();2088 2089  // Parse the line table.2090  auto ExpectedLineTable =2091      Line.getOrParseLineTable(LineData, /*Offset=*/0, *Context,2092                               /*DwarfUnit=*/nullptr, RecordRecoverable);2093  ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());2094  const auto *Table = *ExpectedLineTable;2095 2096  // The table should have two sequences, each starting at our chosen offsets.2097  ASSERT_EQ(Table->Sequences.size(), 2u);2098 2099  // 1) Try looking up with an invalid offset (simulating an invalid2100  //    DW_AT_LLVM_stmt_sequence). We expect no rows.2101  {2102    std::vector<uint32_t> Rows;2103    bool Found = Table->lookupAddressRange(2104        {0x1000, object::SectionedAddress::UndefSection}, /*Size=*/1, Rows,2105        /*StmtSequenceOffset=*/0x66); // invalid offset2106    EXPECT_FALSE(Found);2107    EXPECT_TRUE(Rows.empty());2108  }2109 2110  // 2) Look up using the offset 0x2e (our first sequence). We expect2111  //    to get the rows from that sequence only (which for 0x1000 is row #0).2112  {2113    std::vector<uint32_t> Rows;2114    bool Found = Table->lookupAddressRange(2115        {0x1000, object::SectionedAddress::UndefSection}, /*Size=*/1, Rows,2116        /*StmtSequenceOffset=*/0x2e);2117    EXPECT_TRUE(Found);2118    ASSERT_EQ(Rows.size(), 1u);2119    // The first sequence's first row is index 0.2120    EXPECT_EQ(Rows[0], 0u);2121  }2122 2123  // 3) Look up using the offset 0x42 (second sequence). For address 0x10002124  //    in that second sequence, we should see row #2.2125  {2126    std::vector<uint32_t> Rows;2127    bool Found = Table->lookupAddressRange(2128        {0x1000, object::SectionedAddress::UndefSection}, /*Size=*/1, Rows,2129        /*StmtSequenceOffset=*/0x42);2130    EXPECT_TRUE(Found);2131    ASSERT_EQ(Rows.size(), 1u);2132    // The second sequence's first row is index 2 in the table.2133    EXPECT_EQ(Rows[0], 3u);2134  }2135 2136  // 4) Look up with no statement-sequence offset specified.2137  //    We should get rows from both sequences for address 0x1000.2138  {2139    std::vector<uint32_t> Rows;2140    bool Found = Table->lookupAddressRange(2141        {0x1000, object::SectionedAddress::UndefSection}, /*Size=*/1, Rows,2142        std::nullopt /* no filter */);2143    EXPECT_TRUE(Found);2144    // The first sequence's row is #0, second's row is #2, so both should2145    // appear.2146    ASSERT_EQ(Rows.size(), 2u);2147    EXPECT_EQ(Rows[0], 0u);2148    EXPECT_EQ(Rows[1], 3u);2149  }2150}2151} // end anonymous namespace2152