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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "DwarfGenerator.h" 10 #include "DwarfUtils.h" 11 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 12 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 13 #include "llvm/Object/ObjectFile.h" 14 #include "llvm/Testing/Support/Error.h" 15 #include "gtest/gtest.h" 16 17 using namespace llvm; 18 using namespace dwarf; 19 using namespace dwarfgen; 20 using namespace object; 21 using namespace utils; 22 using namespace testing; 23 24 namespace { 25 struct CommonFixture { 26 CommonFixture() 27 : LineData("", true, 0), Recoverable(Error::success()), 28 RecordRecoverable(std::bind(&CommonFixture::recordRecoverable, this, 29 std::placeholders::_1)), 30 Unrecoverable(Error::success()), 31 RecordUnrecoverable(std::bind(&CommonFixture::recordUnrecoverable, this, 32 std::placeholders::_1)){}; 33 34 ~CommonFixture() { 35 EXPECT_FALSE(Recoverable); 36 EXPECT_FALSE(Unrecoverable); 37 } 38 39 bool setupGenerator(uint16_t Version = 4, uint8_t AddrSize = 8) { 40 AddressSize = AddrSize; 41 Triple T = 42 getDefaultTargetTripleForAddrSize(AddressSize == 0 ? 8 : AddressSize); 43 if (!isConfigurationSupported(T)) 44 return false; 45 auto ExpectedGenerator = Generator::create(T, Version); 46 if (ExpectedGenerator) 47 Gen.reset(ExpectedGenerator->release()); 48 return true; 49 } 50 51 void generate() { 52 Context = createContext(); 53 assert(Context != nullptr && "test state is not valid"); 54 const DWARFObject &Obj = Context->getDWARFObj(); 55 uint8_t TargetAddrSize = AddressSize == 0 ? 8 : AddressSize; 56 LineData = DWARFDataExtractor( 57 Obj, Obj.getLineSection(), 58 getDefaultTargetTripleForAddrSize(TargetAddrSize).isLittleEndian(), 59 AddressSize); 60 } 61 62 std::unique_ptr<DWARFContext> createContext() { 63 if (!Gen) 64 return nullptr; 65 StringRef FileBytes = Gen->generate(); 66 MemoryBufferRef FileBuffer(FileBytes, "dwarf"); 67 auto Obj = object::ObjectFile::createObjectFile(FileBuffer); 68 if (Obj) 69 return DWARFContext::create(**Obj); 70 return nullptr; 71 } 72 73 DWARFDebugLine::SectionParser setupParser() { 74 LineTable < = Gen->addLineTable(DWARF32); 75 LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}}); 76 LT.addStandardOpcode(DW_LNS_copy, {}); 77 LT.addByte(0xaa); 78 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 79 80 LineTable <2 = Gen->addLineTable(DWARF64); 81 LT2.addExtendedOpcode(9, DW_LNE_set_address, 82 {{0x11223344, LineTable::Quad}}); 83 LT2.addStandardOpcode(DW_LNS_copy, {}); 84 LT2.addByte(0xbb); 85 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 86 87 generate(); 88 89 return DWARFDebugLine::SectionParser(LineData, *Context, CUs, TUs); 90 } 91 92 void recordRecoverable(Error Err) { 93 Recoverable = joinErrors(std::move(Recoverable), std::move(Err)); 94 } 95 void recordUnrecoverable(Error Err) { 96 Unrecoverable = joinErrors(std::move(Unrecoverable), std::move(Err)); 97 } 98 99 Expected<const DWARFDebugLine::LineTable *> 100 getOrParseLineTableFatalErrors(uint64_t Offset = 0) { 101 auto ExpectedLineTable = Line.getOrParseLineTable( 102 LineData, Offset, *Context, nullptr, RecordRecoverable); 103 EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded()); 104 return ExpectedLineTable; 105 } 106 107 uint8_t AddressSize; 108 std::unique_ptr<Generator> Gen; 109 std::unique_ptr<DWARFContext> Context; 110 DWARFDataExtractor LineData; 111 DWARFDebugLine Line; 112 Error Recoverable; 113 std::function<void(Error)> RecordRecoverable; 114 Error Unrecoverable; 115 std::function<void(Error)> RecordUnrecoverable; 116 117 SmallVector<std::unique_ptr<DWARFUnit>, 2> CUs; 118 SmallVector<std::unique_ptr<DWARFUnit>, 2> TUs; 119 }; 120 121 // Fixtures must derive from "Test", but parameterised fixtures from 122 // "TestWithParam". It does not seem possible to inherit from both, so we share 123 // the common state in a separate class, inherited by the two fixture classes. 124 struct DebugLineBasicFixture : public Test, public CommonFixture {}; 125 126 struct DebugLineParameterisedFixture 127 : public TestWithParam<std::pair<uint16_t, DwarfFormat>>, 128 public CommonFixture { 129 void SetUp() { std::tie(Version, Format) = GetParam(); } 130 131 uint16_t Version; 132 DwarfFormat Format; 133 }; 134 135 void checkDefaultPrologue(uint16_t Version, DwarfFormat Format, 136 DWARFDebugLine::Prologue Prologue, 137 uint64_t BodyLength) { 138 // Check version specific fields and values. 139 uint64_t UnitLength; 140 uint64_t PrologueLength; 141 switch (Version) { 142 case 4: 143 PrologueLength = 36; 144 UnitLength = PrologueLength + 2; 145 EXPECT_EQ(Prologue.MaxOpsPerInst, 1u); 146 break; 147 case 2: 148 case 3: 149 PrologueLength = 35; 150 UnitLength = PrologueLength + 2; 151 break; 152 case 5: 153 PrologueLength = 42; 154 UnitLength = PrologueLength + 4; 155 EXPECT_EQ(Prologue.getAddressSize(), 8u); 156 EXPECT_EQ(Prologue.SegSelectorSize, 0u); 157 break; 158 default: 159 llvm_unreachable("unsupported DWARF version"); 160 } 161 UnitLength += BodyLength + (Format == DWARF32 ? 4 : 8); 162 163 EXPECT_EQ(Prologue.TotalLength, UnitLength); 164 EXPECT_EQ(Prologue.PrologueLength, PrologueLength); 165 EXPECT_EQ(Prologue.MinInstLength, 1u); 166 EXPECT_EQ(Prologue.DefaultIsStmt, 1u); 167 EXPECT_EQ(Prologue.LineBase, -5); 168 EXPECT_EQ(Prologue.LineRange, 14u); 169 EXPECT_EQ(Prologue.OpcodeBase, 13u); 170 std::vector<uint8_t> ExpectedLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1}; 171 EXPECT_EQ(Prologue.StandardOpcodeLengths, ExpectedLengths); 172 ASSERT_EQ(Prologue.IncludeDirectories.size(), 1u); 173 ASSERT_EQ(Prologue.IncludeDirectories[0].getForm(), DW_FORM_string); 174 EXPECT_STREQ(*Prologue.IncludeDirectories[0].getAsCString(), "a dir"); 175 ASSERT_EQ(Prologue.FileNames.size(), 1u); 176 ASSERT_EQ(Prologue.FileNames[0].Name.getForm(), DW_FORM_string); 177 ASSERT_EQ(Prologue.FileNames[0].DirIdx, 0u); 178 EXPECT_STREQ(*Prologue.FileNames[0].Name.getAsCString(), "a file"); 179 } 180 181 TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffset) { 182 if (!setupGenerator()) 183 return; 184 generate(); 185 186 EXPECT_THAT_EXPECTED( 187 getOrParseLineTableFatalErrors(0), 188 FailedWithMessage( 189 "offset 0x00000000 is not a valid debug line section offset")); 190 // Repeat to show that an error is reported each time. 191 EXPECT_THAT_EXPECTED( 192 getOrParseLineTableFatalErrors(0), 193 FailedWithMessage( 194 "offset 0x00000000 is not a valid debug line section offset")); 195 196 // Show that an error is reported for later offsets too. 197 EXPECT_THAT_EXPECTED( 198 getOrParseLineTableFatalErrors(1), 199 FailedWithMessage( 200 "offset 0x00000001 is not a valid debug line section offset")); 201 } 202 203 TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) { 204 if (!setupGenerator()) 205 return; 206 207 LineTable < = Gen->addLineTable(); 208 LT.setCustomPrologue({{0, LineTable::Byte}}); 209 210 generate(); 211 212 EXPECT_THAT_EXPECTED( 213 getOrParseLineTableFatalErrors(0), 214 FailedWithMessage( 215 "parsing line table prologue at offset 0x00000000: " 216 "unexpected end of data at offset 0x1 while reading [0x0, 0x4)")); 217 218 EXPECT_THAT_EXPECTED( 219 getOrParseLineTableFatalErrors(1), 220 FailedWithMessage( 221 "offset 0x00000001 is not a valid debug line section offset")); 222 } 223 224 TEST_P(DebugLineParameterisedFixture, PrologueGetLength) { 225 if (!setupGenerator(Version)) 226 return; 227 LineTable < = Gen->addLineTable(Format); 228 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 229 LT.setPrologue(Prologue); 230 generate(); 231 232 // + 10 for sizes of DWARF-32 unit length, version, prologue length. 233 uint64_t ExpectedLength = Prologue.PrologueLength + 10; 234 if (Version == 5) 235 // Add address and segment selector size fields. 236 ExpectedLength += 2; 237 if (Format == DWARF64) 238 // Unit length grows by 8, prologue length by 4. 239 ExpectedLength += 12; 240 241 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 242 nullptr, RecordRecoverable); 243 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 244 EXPECT_EQ((*ExpectedLineTable)->Prologue.getLength(), ExpectedLength); 245 } 246 247 TEST_P(DebugLineParameterisedFixture, GetOrParseLineTableValidTable) { 248 if (!setupGenerator(Version)) 249 return; 250 251 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " + 252 (Format == DWARF64 ? "DWARF64" : "DWARF32")); 253 254 LineTable < = Gen->addLineTable(Format); 255 LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}}); 256 LT.addStandardOpcode(DW_LNS_copy, {}); 257 LT.addByte(0xaa); 258 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 259 260 LineTable <2 = Gen->addLineTable(Format); 261 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x11223344, LineTable::Quad}}); 262 LT2.addStandardOpcode(DW_LNS_copy, {}); 263 LT2.addByte(0xbb); 264 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 265 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x55667788, LineTable::Quad}}); 266 LT2.addStandardOpcode(DW_LNS_copy, {}); 267 LT2.addByte(0xcc); 268 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 269 270 generate(); 271 272 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 273 nullptr, RecordRecoverable); 274 ASSERT_TRUE(ExpectedLineTable.operator bool()); 275 EXPECT_FALSE(Recoverable); 276 const DWARFDebugLine::LineTable *Expected = *ExpectedLineTable; 277 checkDefaultPrologue(Version, Format, Expected->Prologue, 16); 278 EXPECT_EQ(Expected->Sequences.size(), 1u); 279 280 uint64_t SecondOffset = 281 Expected->Prologue.sizeofTotalLength() + Expected->Prologue.TotalLength; 282 Recoverable = Error::success(); 283 auto ExpectedLineTable2 = Line.getOrParseLineTable( 284 LineData, SecondOffset, *Context, nullptr, RecordRecoverable); 285 ASSERT_TRUE(ExpectedLineTable2.operator bool()); 286 EXPECT_FALSE(Recoverable); 287 const DWARFDebugLine::LineTable *Expected2 = *ExpectedLineTable2; 288 checkDefaultPrologue(Version, Format, Expected2->Prologue, 32); 289 EXPECT_EQ(Expected2->Sequences.size(), 2u); 290 291 EXPECT_NE(Expected, Expected2); 292 293 // Check that if the same offset is requested, the exact same pointer is 294 // returned. 295 Recoverable = Error::success(); 296 auto ExpectedLineTable3 = Line.getOrParseLineTable( 297 LineData, 0, *Context, nullptr, RecordRecoverable); 298 ASSERT_TRUE(ExpectedLineTable3.operator bool()); 299 EXPECT_FALSE(Recoverable); 300 EXPECT_EQ(Expected, *ExpectedLineTable3); 301 302 Recoverable = Error::success(); 303 auto ExpectedLineTable4 = Line.getOrParseLineTable( 304 LineData, SecondOffset, *Context, nullptr, RecordRecoverable); 305 ASSERT_TRUE(ExpectedLineTable4.operator bool()); 306 EXPECT_FALSE(Recoverable); 307 EXPECT_EQ(Expected2, *ExpectedLineTable4); 308 309 // TODO: Add tests that show that the body of the programs have been read 310 // correctly. 311 } 312 313 TEST_F(DebugLineBasicFixture, ErrorForReservedLength) { 314 if (!setupGenerator()) 315 return; 316 317 LineTable < = Gen->addLineTable(); 318 LT.setCustomPrologue({{0xfffffff0, LineTable::Long}}); 319 320 generate(); 321 322 EXPECT_THAT_EXPECTED( 323 getOrParseLineTableFatalErrors(), 324 FailedWithMessage( 325 "parsing line table prologue at offset 0x00000000: unsupported " 326 "reserved unit length of value 0xfffffff0")); 327 } 328 329 struct DebugLineUnsupportedVersionFixture : public TestWithParam<uint16_t>, 330 public CommonFixture { 331 void SetUp() { Version = GetParam(); } 332 333 uint16_t Version; 334 }; 335 336 TEST_P(DebugLineUnsupportedVersionFixture, ErrorForUnsupportedVersion) { 337 if (!setupGenerator()) 338 return; 339 340 LineTable < = Gen->addLineTable(); 341 LT.setCustomPrologue( 342 {{LineTable::Half, LineTable::Long}, {Version, LineTable::Half}}); 343 344 generate(); 345 346 EXPECT_THAT_EXPECTED( 347 getOrParseLineTableFatalErrors(), 348 FailedWithMessage("parsing line table prologue at offset 0x00000000: " 349 "unsupported version " + 350 std::to_string(Version))); 351 } 352 353 INSTANTIATE_TEST_CASE_P(UnsupportedVersionTestParams, 354 DebugLineUnsupportedVersionFixture, 355 Values(/*1 below min */ 1, /* 1 above max */ 6, 356 /* Maximum possible */ 0xffff), ); 357 358 TEST_F(DebugLineBasicFixture, ErrorForInvalidV5IncludeDirTable) { 359 if (!setupGenerator(5)) 360 return; 361 362 LineTable < = Gen->addLineTable(); 363 LT.setCustomPrologue({ 364 {19, LineTable::Long}, // unit length 365 {5, LineTable::Half}, // version 366 {8, LineTable::Byte}, // addr size 367 {0, LineTable::Byte}, // segment selector size 368 {11, LineTable::Long}, // prologue length 369 {1, LineTable::Byte}, // min instruction length 370 {1, LineTable::Byte}, // max ops per instruction 371 {1, LineTable::Byte}, // default is_stmt 372 {0, LineTable::Byte}, // line base 373 {14, LineTable::Byte}, // line range 374 {2, LineTable::Byte}, // opcode base (small to reduce the amount of 375 // setup required). 376 {0, LineTable::Byte}, // standard opcode lengths 377 {0, LineTable::Byte}, // directory entry format count (should not be 378 // zero). 379 {0, LineTable::ULEB}, // directories count 380 {0, LineTable::Byte}, // file name entry format count 381 {0, LineTable::ULEB} // file name entry count 382 }); 383 384 generate(); 385 386 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 387 nullptr, RecordRecoverable); 388 EXPECT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 389 390 EXPECT_THAT_ERROR( 391 std::move(Recoverable), 392 FailedWithMessage( 393 "parsing line table prologue at 0x00000000 found an invalid " 394 "directory or file table description at 0x00000014", 395 "failed to parse entry content descriptions because no path was " 396 "found")); 397 } 398 399 TEST_P(DebugLineParameterisedFixture, ErrorForTooLargePrologueLength) { 400 if (!setupGenerator(Version)) 401 return; 402 403 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " + 404 (Format == DWARF64 ? "DWARF64" : "DWARF32")); 405 406 LineTable < = Gen->addLineTable(Format); 407 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 408 ++Prologue.PrologueLength; 409 LT.setPrologue(Prologue); 410 411 generate(); 412 413 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 414 nullptr, RecordRecoverable); 415 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 416 DWARFDebugLine::LineTable Result(**ExpectedLineTable); 417 // Undo the earlier modification so that it can be compared against a 418 // "default" prologue. 419 --Result.Prologue.PrologueLength; 420 checkDefaultPrologue(Version, Format, Result.Prologue, 0); 421 422 uint64_t ExpectedEnd = 423 Prologue.TotalLength + 1 + Prologue.sizeofTotalLength(); 424 EXPECT_THAT_ERROR( 425 std::move(Recoverable), 426 FailedWithMessage( 427 ("unknown data in line table prologue at offset 0x00000000: " 428 "parsing ended (at offset 0x000000" + 429 Twine::utohexstr(ExpectedEnd - 1) + 430 ") before reaching the prologue end at offset 0x000000" + 431 Twine::utohexstr(ExpectedEnd)) 432 .str())); 433 } 434 435 TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) { 436 if (!setupGenerator(Version)) 437 return; 438 439 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " + 440 (Format == DWARF64 ? "DWARF64" : "DWARF32")); 441 442 LineTable < = Gen->addLineTable(Format); 443 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 444 Prologue.PrologueLength -= 2; 445 LT.setPrologue(Prologue); 446 447 generate(); 448 449 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 450 nullptr, RecordRecoverable); 451 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 452 DWARFDebugLine::LineTable Result(**ExpectedLineTable); 453 454 // Parsing will stop before reading a complete file entry. 455 ASSERT_EQ(Result.Prologue.IncludeDirectories.size(), 1u); 456 EXPECT_EQ(toStringRef(Result.Prologue.IncludeDirectories[0]), "a dir"); 457 EXPECT_EQ(Result.Prologue.FileNames.size(), 0u); 458 459 // The exact place where the parsing will stop depends on the structure of the 460 // prologue and the last complete field we are able to read. Before V5 we stop 461 // before reading the file length. In V5, we stop before the filename. 462 uint64_t ExpectedEnd = Prologue.TotalLength + Prologue.sizeofTotalLength() - 463 (Version < 5 ? 2 : 8); 464 std::vector<std::string> Errs; 465 Errs.emplace_back( 466 (Twine("parsing line table prologue at 0x00000000 found an invalid " 467 "directory or file table description at 0x000000") + 468 Twine::utohexstr(ExpectedEnd)) 469 .str()); 470 if (Version < 5) { 471 Errs.emplace_back("file names table was not null terminated before the end " 472 "of the prologue"); 473 } else { 474 Errs.emplace_back( 475 "failed to parse file entry because extracting the form value failed"); 476 } 477 EXPECT_THAT_ERROR(std::move(Recoverable), 478 FailedWithMessageArray(testing::ElementsAreArray(Errs))); 479 } 480 481 INSTANTIATE_TEST_CASE_P( 482 LineTableTestParams, DebugLineParameterisedFixture, 483 Values(std::make_pair( 484 2, DWARF32), // Test lower-bound of v2-3 fields and DWARF32. 485 std::make_pair(3, DWARF32), // Test upper-bound of v2-3 fields. 486 std::make_pair(4, DWARF64), // Test v4 fields and DWARF64. 487 std::make_pair(5, DWARF32), std::make_pair(5, DWARF64)), ); 488 489 TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthSmallerThanExpected) { 490 if (!setupGenerator()) 491 return; 492 493 LineTable < = Gen->addLineTable(); 494 LT.addByte(0xaa); 495 // The Length should be 1 + sizeof(ULEB) for a set discriminator opcode. 496 // The operand will be read for both the discriminator opcode and then parsed 497 // again as DW_LNS_negate_stmt, to respect the claimed length. 498 LT.addExtendedOpcode(1, DW_LNE_set_discriminator, 499 {{DW_LNS_negate_stmt, LineTable::ULEB}}); 500 LT.addByte(0xbb); 501 LT.addStandardOpcode(DW_LNS_const_add_pc, {}); 502 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 503 504 generate(); 505 506 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 507 nullptr, RecordRecoverable); 508 EXPECT_THAT_ERROR(std::move(Recoverable), 509 FailedWithMessage("unexpected line op length at offset " 510 "0x00000031 expected 0x01 found 0x02")); 511 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 512 ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); 513 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); 514 EXPECT_EQ((*ExpectedLineTable)->Rows[1].IsStmt, 0u); 515 EXPECT_EQ((*ExpectedLineTable)->Rows[1].Discriminator, DW_LNS_negate_stmt); 516 } 517 518 TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthLargerThanExpected) { 519 if (!setupGenerator()) 520 return; 521 522 LineTable < = Gen->addLineTable(); 523 LT.addByte(0xaa); 524 LT.addStandardOpcode(DW_LNS_const_add_pc, {}); 525 // The Length should be 1 for an end sequence opcode. 526 LT.addExtendedOpcode(2, DW_LNE_end_sequence, {}); 527 // The negate statement opcode will be skipped. 528 LT.addStandardOpcode(DW_LNS_negate_stmt, {}); 529 LT.addByte(0xbb); 530 LT.addStandardOpcode(DW_LNS_const_add_pc, {}); 531 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 532 533 generate(); 534 535 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 536 nullptr, RecordRecoverable); 537 EXPECT_THAT_ERROR(std::move(Recoverable), 538 FailedWithMessage("unexpected line op length at offset " 539 "0x00000032 expected 0x02 found 0x01")); 540 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 541 ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 4u); 542 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 2u); 543 ASSERT_EQ((*ExpectedLineTable)->Sequences[1].FirstRowIndex, 2u); 544 EXPECT_EQ((*ExpectedLineTable)->Rows[2].IsStmt, 1u); 545 } 546 547 TEST_F(DebugLineBasicFixture, ErrorForUnitLengthTooLarge) { 548 if (!setupGenerator()) 549 return; 550 551 LineTable &Padding = Gen->addLineTable(); 552 // Add some padding to show that a non-zero offset is handled correctly. 553 Padding.setCustomPrologue({{0, LineTable::Byte}}); 554 LineTable < = Gen->addLineTable(); 555 LT.addStandardOpcode(DW_LNS_copy, {}); 556 LT.addStandardOpcode(DW_LNS_const_add_pc, {}); 557 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 558 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 559 // Set the total length to 1 higher than the actual length. 560 ++Prologue.TotalLength; 561 LT.setPrologue(Prologue); 562 563 generate(); 564 565 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 1, *Context, 566 nullptr, RecordRecoverable); 567 EXPECT_THAT_ERROR( 568 std::move(Recoverable), 569 FailedWithMessage("line table program with offset 0x00000001 has length " 570 "0x00000034 but only 0x00000033 bytes are available")); 571 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 572 EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 2u); 573 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); 574 } 575 576 TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) { 577 if (!setupGenerator(4, 8)) 578 return; 579 580 LineTable < = Gen->addLineTable(); 581 // The line data extractor expects size 8 (Quad) addresses. 582 uint64_t Addr1 = 0x11223344; 583 LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}}); 584 LT.addStandardOpcode(DW_LNS_copy, {}); 585 // Show that the expected address size is unchanged, so later valid lines 586 // don't cause a problem. 587 uint64_t Addr2 = 0x1122334455667788; 588 LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}}); 589 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 590 591 generate(); 592 593 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 594 nullptr, RecordRecoverable); 595 EXPECT_THAT_ERROR(std::move(Recoverable), 596 FailedWithMessage("mismatching address size at offset " 597 "0x00000030 expected 0x08 found 0x04")); 598 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 599 ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u); 600 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); 601 EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1); 602 EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2); 603 } 604 605 TEST_F(DebugLineBasicFixture, 606 ErrorForMismatchedAddressSizeUnsetInitialAddress) { 607 if (!setupGenerator(4, 0)) 608 return; 609 610 LineTable < = Gen->addLineTable(); 611 uint64_t Addr1 = 0x11223344; 612 LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}}); 613 LT.addStandardOpcode(DW_LNS_copy, {}); 614 uint64_t Addr2 = 0x1122334455667788; 615 LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}}); 616 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 617 618 generate(); 619 620 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 621 nullptr, RecordRecoverable); 622 EXPECT_THAT_ERROR(std::move(Recoverable), 623 FailedWithMessage("mismatching address size at offset " 624 "0x00000038 expected 0x04 found 0x08")); 625 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 626 ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u); 627 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); 628 EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, Addr1); 629 EXPECT_EQ((*ExpectedLineTable)->Rows[1].Address.Address, Addr2); 630 } 631 632 TEST_F(DebugLineBasicFixture, 633 ErrorForUnsupportedAddressSizeInSetAddressLength) { 634 // Use DWARF v4, and 0 for data extractor address size so that the address 635 // size is derived from the opcode length. 636 if (!setupGenerator(4, 0)) 637 return; 638 639 LineTable < = Gen->addLineTable(); 640 // 4 == length of the extended opcode, i.e. 1 for the opcode itself and 3 for 641 // the Half (2) + Byte (1) operand, representing the unsupported address size. 642 LT.addExtendedOpcode(4, DW_LNE_set_address, 643 {{0x1234, LineTable::Half}, {0x56, LineTable::Byte}}); 644 LT.addStandardOpcode(DW_LNS_copy, {}); 645 // Special opcode to ensure the address has changed between the first and last 646 // row in the sequence. Without this, the sequence will not be recorded. 647 LT.addByte(0xaa); 648 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 649 650 generate(); 651 652 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 653 nullptr, RecordRecoverable); 654 EXPECT_THAT_ERROR( 655 std::move(Recoverable), 656 FailedWithMessage("address size 0x03 of DW_LNE_set_address opcode at " 657 "offset 0x00000030 is unsupported")); 658 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 659 ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); 660 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); 661 // Show that the set address opcode is ignored in this case. 662 EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, 0u); 663 } 664 665 TEST_F(DebugLineBasicFixture, ErrorForAddressSizeGreaterThanByteSize) { 666 // Use DWARF v4, and 0 for data extractor address size so that the address 667 // size is derived from the opcode length. 668 if (!setupGenerator(4, 0)) 669 return; 670 671 LineTable < = Gen->addLineTable(); 672 // Specifically use an operand size that has a trailing byte of a supported 673 // size (8), so that any potential truncation would result in a valid size. 674 std::vector<LineTable::ValueAndLength> Operands(0x108); 675 LT.addExtendedOpcode(Operands.size() + 1, DW_LNE_set_address, Operands); 676 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 677 678 generate(); 679 680 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 681 nullptr, RecordRecoverable); 682 EXPECT_THAT_ERROR( 683 std::move(Recoverable), 684 FailedWithMessage("address size 0x108 of DW_LNE_set_address opcode at " 685 "offset 0x00000031 is unsupported")); 686 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 687 } 688 689 TEST_F(DebugLineBasicFixture, ErrorForUnsupportedAddressSizeDefinedInHeader) { 690 // Use 0 for data extractor address size so that it does not clash with the 691 // header address size. 692 if (!setupGenerator(5, 0)) 693 return; 694 695 LineTable < = Gen->addLineTable(); 696 // AddressSize + 1 == length of the extended opcode, i.e. 1 for the opcode 697 // itself and 9 for the Quad (8) + Byte (1) operand representing the 698 // unsupported address size. 699 uint8_t AddressSize = 9; 700 LT.addExtendedOpcode(AddressSize + 1, DW_LNE_set_address, 701 {{0x12345678, LineTable::Quad}, {0, LineTable::Byte}}); 702 LT.addStandardOpcode(DW_LNS_copy, {}); 703 // Special opcode to ensure the address has changed between the first and last 704 // row in the sequence. Without this, the sequence will not be recorded. 705 LT.addByte(0xaa); 706 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 707 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 708 Prologue.FormParams.AddrSize = AddressSize; 709 LT.setPrologue(Prologue); 710 711 generate(); 712 713 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 714 nullptr, RecordRecoverable); 715 EXPECT_THAT_ERROR( 716 std::move(Recoverable), 717 FailedWithMessage("address size 0x09 of DW_LNE_set_address opcode at " 718 "offset 0x00000038 is unsupported")); 719 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 720 ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); 721 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); 722 // Show that the set address opcode is ignored in this case. 723 EXPECT_EQ((*ExpectedLineTable)->Rows[0].Address.Address, 0u); 724 } 725 726 TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) { 727 if (!setupGenerator()) 728 return; 729 730 LineTable < = Gen->addLineTable(); 731 LT.addExtendedOpcode(9, DW_LNE_set_address, 732 {{0x1122334455667788, LineTable::Quad}}); 733 LT.addStandardOpcode(DW_LNS_copy, {}); 734 LT.addByte(0xaa); 735 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 736 LT.addExtendedOpcode(9, DW_LNE_set_address, 737 {{0x99aabbccddeeff00, LineTable::Quad}}); 738 LT.addStandardOpcode(DW_LNS_copy, {}); 739 LT.addByte(0xbb); 740 LT.addByte(0xcc); 741 742 generate(); 743 744 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 745 nullptr, RecordRecoverable); 746 EXPECT_THAT_ERROR(std::move(Recoverable), 747 FailedWithMessage("last sequence in debug line table at " 748 "offset 0x00000000 is not terminated")); 749 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 750 EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 6u); 751 // The unterminated sequence is not added to the sequence list. 752 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); 753 } 754 755 struct AdjustAddressFixtureBase : public CommonFixture { 756 virtual ~AdjustAddressFixtureBase() {} 757 758 // Create and update the prologue as specified by the subclass, then return 759 // the length of the table. 760 virtual uint64_t editPrologue(LineTable <) = 0; 761 762 virtual uint64_t getAdjustedAddr(uint64_t Base, uint64_t ConstIncrs, 763 uint64_t SpecialIncrs, 764 uint64_t AdvanceIncrs) { 765 return Base + ConstIncrs + SpecialIncrs + AdvanceIncrs; 766 } 767 768 virtual uint64_t getAdjustedLine(uint64_t Base, uint64_t Incr) { 769 return Base + Incr; 770 } 771 772 uint64_t setupNoProblemTable() { 773 LineTable &NoProblem = Gen->addLineTable(); 774 NoProblem.addExtendedOpcode(9, DW_LNE_set_address, 775 {{0xabcd, LineTable::Quad}}); 776 NoProblem.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 777 return editPrologue(NoProblem); 778 } 779 780 uint64_t setupConstAddPcFirstTable() { 781 LineTable &ConstAddPCFirst = Gen->addLineTable(); 782 ConstAddPCFirst.addExtendedOpcode(9, DW_LNE_set_address, 783 {{ConstAddPCAddr, LineTable::Quad}}); 784 ConstAddPCFirst.addStandardOpcode(DW_LNS_const_add_pc, {}); 785 ConstAddPCFirst.addStandardOpcode(DW_LNS_const_add_pc, {}); 786 ConstAddPCFirst.addStandardOpcode(DW_LNS_advance_pc, 787 {{0x10, LineTable::ULEB}}); 788 ConstAddPCFirst.addByte(0x21); // Special opcode, +1 op, +1 line. 789 ConstAddPCFirst.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 790 return editPrologue(ConstAddPCFirst); 791 } 792 793 uint64_t setupSpecialFirstTable() { 794 LineTable &SpecialFirst = Gen->addLineTable(); 795 SpecialFirst.addExtendedOpcode(9, DW_LNE_set_address, 796 {{SpecialAddr, LineTable::Quad}}); 797 SpecialFirst.addByte(0x22); // Special opcode, +1 op, +2 line. 798 SpecialFirst.addStandardOpcode(DW_LNS_const_add_pc, {}); 799 SpecialFirst.addStandardOpcode(DW_LNS_advance_pc, 800 {{0x20, LineTable::ULEB}}); 801 SpecialFirst.addByte(0x23); // Special opcode, +1 op, +3 line. 802 SpecialFirst.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 803 return editPrologue(SpecialFirst); 804 } 805 806 uint64_t setupAdvancePcFirstTable() { 807 LineTable &AdvancePCFirst = Gen->addLineTable(); 808 AdvancePCFirst.addExtendedOpcode(9, DW_LNE_set_address, 809 {{AdvancePCAddr, LineTable::Quad}}); 810 AdvancePCFirst.addStandardOpcode(DW_LNS_advance_pc, 811 {{0x30, LineTable::ULEB}}); 812 AdvancePCFirst.addStandardOpcode(DW_LNS_const_add_pc, {}); 813 AdvancePCFirst.addStandardOpcode(DW_LNS_advance_pc, 814 {{0x40, LineTable::ULEB}}); 815 AdvancePCFirst.addByte(0x24); // Special opcode, +1 op, +4 line. 816 AdvancePCFirst.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 817 return editPrologue(AdvancePCFirst); 818 } 819 820 void setupTables(bool AddAdvancePCFirstTable) { 821 LineTable &Padding = Gen->addLineTable(); 822 Padding.setCustomPrologue({{0, LineTable::Byte}}); 823 NoProblemOffset = 1; 824 825 // Show that no warning is generated for the case where no 826 // DW_LNS_const_add_pc or special opcode is used. 827 ConstAddPCOffset = setupNoProblemTable() + NoProblemOffset; 828 829 // Show that the warning is emitted for the first DW_LNS_const_add_pc opcode 830 // and then not again. 831 SpecialOffset = setupConstAddPcFirstTable() + ConstAddPCOffset; 832 833 // Show that the warning is emitted for the first special opcode and then 834 // not again. 835 AdvancePCOffset = setupSpecialFirstTable() + SpecialOffset; 836 837 // Show that the warning is emitted for the first DW_LNS_advance_pc opcode 838 // (if requested) and then not again. 839 if (AddAdvancePCFirstTable) 840 setupAdvancePcFirstTable(); 841 } 842 843 Expected<const DWARFDebugLine::LineTable *> 844 checkTable(uint64_t Offset, StringRef OpcodeType, const Twine &MsgSuffix) { 845 auto ExpectedTable = Line.getOrParseLineTable(LineData, Offset, *Context, 846 nullptr, RecordRecoverable); 847 EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded()); 848 if (!IsErrorExpected) { 849 EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded()); 850 } else { 851 if (!ExpectedTable) 852 return ExpectedTable; 853 uint64_t ExpectedOffset = Offset + 854 (*ExpectedTable)->Prologue.getLength() + 855 11; // 11 == size of DW_LNE_set_address. 856 std::string OffsetHex = Twine::utohexstr(Offset).str(); 857 std::string OffsetZeroes = std::string(8 - OffsetHex.size(), '0'); 858 std::string ExpectedHex = Twine::utohexstr(ExpectedOffset).str(); 859 std::string ExpectedZeroes = std::string(8 - ExpectedHex.size(), '0'); 860 EXPECT_THAT_ERROR( 861 std::move(Recoverable), 862 FailedWithMessage(("line table program at offset 0x" + OffsetZeroes + 863 OffsetHex + " contains a " + OpcodeType + 864 " opcode at offset 0x" + ExpectedZeroes + 865 ExpectedHex + ", " + MsgSuffix) 866 .str())); 867 } 868 return ExpectedTable; 869 } 870 871 void runTest(bool CheckAdvancePC, Twine MsgSuffix) { 872 if (!setupGenerator(Version)) 873 return; 874 875 setupTables(/*AddAdvancePCFirstTable=*/CheckAdvancePC); 876 877 generate(); 878 879 auto ExpectedNoProblem = Line.getOrParseLineTable( 880 LineData, NoProblemOffset, *Context, nullptr, RecordRecoverable); 881 EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded()); 882 EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded()); 883 ASSERT_THAT_EXPECTED(ExpectedNoProblem, Succeeded()); 884 885 auto ExpectedConstAddPC = 886 checkTable(ConstAddPCOffset, "DW_LNS_const_add_pc", MsgSuffix); 887 ASSERT_THAT_EXPECTED(ExpectedConstAddPC, Succeeded()); 888 ASSERT_EQ((*ExpectedConstAddPC)->Rows.size(), 2u); 889 EXPECT_EQ((*ExpectedConstAddPC)->Rows[0].Address.Address, 890 getAdjustedAddr(ConstAddPCAddr, ConstIncr * 2, 0x1, 0x10)); 891 EXPECT_EQ((*ExpectedConstAddPC)->Rows[0].Line, getAdjustedLine(1, 1)); 892 EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded()); 893 894 auto ExpectedSpecial = checkTable(SpecialOffset, "special", MsgSuffix); 895 ASSERT_THAT_EXPECTED(ExpectedSpecial, Succeeded()); 896 ASSERT_EQ((*ExpectedSpecial)->Rows.size(), 3u); 897 EXPECT_EQ((*ExpectedSpecial)->Rows[0].Address.Address, 898 getAdjustedAddr(SpecialAddr, 0, 1, 0)); 899 EXPECT_EQ((*ExpectedSpecial)->Rows[0].Line, getAdjustedLine(1, 2)); 900 EXPECT_EQ((*ExpectedSpecial)->Rows[1].Address.Address, 901 getAdjustedAddr(SpecialAddr, ConstIncr, 0x2, 0x20)); 902 EXPECT_EQ((*ExpectedSpecial)->Rows[1].Line, getAdjustedLine(1, 5)); 903 EXPECT_THAT_ERROR(std::move(Unrecoverable), Succeeded()); 904 905 if (!CheckAdvancePC) 906 return; 907 908 auto ExpectedAdvancePC = 909 checkTable(AdvancePCOffset, "DW_LNS_advance_pc", MsgSuffix); 910 ASSERT_THAT_EXPECTED(ExpectedAdvancePC, Succeeded()); 911 ASSERT_EQ((*ExpectedAdvancePC)->Rows.size(), 2u); 912 EXPECT_EQ((*ExpectedAdvancePC)->Rows[0].Address.Address, 913 getAdjustedAddr(AdvancePCAddr, ConstIncr, 0x1, 0x70)); 914 EXPECT_EQ((*ExpectedAdvancePC)->Rows[0].Line, getAdjustedLine(1, 4)); 915 } 916 917 uint64_t ConstIncr = 0x11; 918 uint64_t ConstAddPCAddr = 0x1234; 919 uint64_t SpecialAddr = 0x5678; 920 uint64_t AdvancePCAddr = 0xabcd; 921 uint64_t NoProblemOffset; 922 uint64_t ConstAddPCOffset; 923 uint64_t SpecialOffset; 924 uint64_t AdvancePCOffset; 925 926 uint16_t Version = 4; 927 bool IsErrorExpected; 928 }; 929 930 struct MaxOpsPerInstFixture 931 : TestWithParam<std::tuple<uint16_t, uint8_t, bool>>, 932 AdjustAddressFixtureBase { 933 void SetUp() override { 934 std::tie(Version, MaxOpsPerInst, IsErrorExpected) = GetParam(); 935 } 936 937 uint64_t editPrologue(LineTable <) override { 938 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 939 Prologue.MaxOpsPerInst = MaxOpsPerInst; 940 LT.setPrologue(Prologue); 941 return Prologue.TotalLength + Prologue.sizeofTotalLength(); 942 } 943 944 uint8_t MaxOpsPerInst; 945 }; 946 947 TEST_P(MaxOpsPerInstFixture, MaxOpsPerInstProblemsReportedCorrectly) { 948 runTest(/*CheckAdvancePC=*/true, 949 "but the prologue maximum_operations_per_instruction value is " + 950 Twine(unsigned(MaxOpsPerInst)) + 951 ", which is unsupported. Assuming a value of 1 instead"); 952 } 953 954 INSTANTIATE_TEST_CASE_P( 955 MaxOpsPerInstParams, MaxOpsPerInstFixture, 956 Values(std::make_tuple(3, 0, false), // Test for version < 4 (no error). 957 std::make_tuple(4, 0, true), // Test zero value for V4 (error). 958 std::make_tuple(4, 1, false), // Test good value for V4 (no error). 959 std::make_tuple( 960 4, 2, true)), ); // Test one higher than permitted V4 (error). 961 962 struct LineRangeFixture : TestWithParam<std::tuple<uint8_t, bool>>, 963 AdjustAddressFixtureBase { 964 void SetUp() override { std::tie(LineRange, IsErrorExpected) = GetParam(); } 965 966 uint64_t editPrologue(LineTable <) override { 967 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 968 Prologue.LineRange = LineRange; 969 LT.setPrologue(Prologue); 970 return Prologue.TotalLength + Prologue.sizeofTotalLength(); 971 } 972 973 uint64_t getAdjustedAddr(uint64_t Base, uint64_t ConstIncr, 974 uint64_t SpecialIncr, 975 uint64_t AdvanceIncr) override { 976 if (LineRange == 0) 977 return Base + AdvanceIncr; 978 return AdjustAddressFixtureBase::getAdjustedAddr(Base, ConstIncr, 979 SpecialIncr, AdvanceIncr); 980 } 981 982 uint64_t getAdjustedLine(uint64_t Base, uint64_t Incr) override { 983 return LineRange != 0 984 ? AdjustAddressFixtureBase::getAdjustedLine(Base, Incr) 985 : Base; 986 } 987 988 uint8_t LineRange; 989 }; 990 991 TEST_P(LineRangeFixture, LineRangeProblemsReportedCorrectly) { 992 runTest(/*CheckAdvancePC=*/false, 993 "but the prologue line_range value is 0. The address and line will " 994 "not be adjusted"); 995 } 996 997 INSTANTIATE_TEST_CASE_P( 998 LineRangeParams, LineRangeFixture, 999 Values(std::make_tuple(0, true), // Test zero value (error). 1000 std::make_tuple(14, false)), ); // Test non-zero value (no error). 1001 1002 struct BadMinInstLenFixture : TestWithParam<std::tuple<uint8_t, bool>>, 1003 AdjustAddressFixtureBase { 1004 void SetUp() override { 1005 std::tie(MinInstLength, IsErrorExpected) = GetParam(); 1006 } 1007 1008 uint64_t editPrologue(LineTable <) override { 1009 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 1010 Prologue.MinInstLength = MinInstLength; 1011 LT.setPrologue(Prologue); 1012 return Prologue.TotalLength + Prologue.sizeofTotalLength(); 1013 } 1014 1015 uint64_t getAdjustedAddr(uint64_t Base, uint64_t ConstIncr, 1016 uint64_t SpecialIncr, 1017 uint64_t AdvanceIncr) override { 1018 return MinInstLength != 0 ? AdjustAddressFixtureBase::getAdjustedAddr( 1019 Base, ConstIncr, SpecialIncr, AdvanceIncr) 1020 : Base; 1021 } 1022 1023 uint8_t MinInstLength; 1024 }; 1025 1026 TEST_P(BadMinInstLenFixture, MinInstLengthProblemsReportedCorrectly) { 1027 runTest(/*CheckAdvancePC=*/true, 1028 "but the prologue minimum_instruction_length value is 0, which " 1029 "prevents any address advancing"); 1030 } 1031 1032 INSTANTIATE_TEST_CASE_P( 1033 BadMinInstLenParams, BadMinInstLenFixture, 1034 Values(std::make_tuple(0, true), // Test zero value (error). 1035 std::make_tuple(1, false)), ); // Test non-zero value (no error). 1036 1037 TEST_F(DebugLineBasicFixture, ParserParsesCorrectly) { 1038 if (!setupGenerator()) 1039 return; 1040 1041 DWARFDebugLine::SectionParser Parser = setupParser(); 1042 1043 EXPECT_EQ(Parser.getOffset(), 0u); 1044 ASSERT_FALSE(Parser.done()); 1045 1046 DWARFDebugLine::LineTable Parsed = 1047 Parser.parseNext(RecordRecoverable, RecordUnrecoverable); 1048 checkDefaultPrologue(4, DWARF32, Parsed.Prologue, 16); 1049 EXPECT_EQ(Parsed.Sequences.size(), 1u); 1050 EXPECT_EQ(Parser.getOffset(), 62u); 1051 ASSERT_FALSE(Parser.done()); 1052 1053 DWARFDebugLine::LineTable Parsed2 = 1054 Parser.parseNext(RecordRecoverable, RecordUnrecoverable); 1055 checkDefaultPrologue(4, DWARF64, Parsed2.Prologue, 16); 1056 EXPECT_EQ(Parsed2.Sequences.size(), 1u); 1057 EXPECT_EQ(Parser.getOffset(), 136u); 1058 EXPECT_TRUE(Parser.done()); 1059 1060 EXPECT_FALSE(Recoverable); 1061 EXPECT_FALSE(Unrecoverable); 1062 } 1063 1064 TEST_F(DebugLineBasicFixture, ParserSkipsCorrectly) { 1065 if (!setupGenerator()) 1066 return; 1067 1068 DWARFDebugLine::SectionParser Parser = setupParser(); 1069 1070 EXPECT_EQ(Parser.getOffset(), 0u); 1071 ASSERT_FALSE(Parser.done()); 1072 1073 Parser.skip(RecordRecoverable, RecordUnrecoverable); 1074 EXPECT_EQ(Parser.getOffset(), 62u); 1075 ASSERT_FALSE(Parser.done()); 1076 1077 Parser.skip(RecordRecoverable, RecordUnrecoverable); 1078 EXPECT_EQ(Parser.getOffset(), 136u); 1079 EXPECT_TRUE(Parser.done()); 1080 1081 EXPECT_FALSE(Recoverable); 1082 EXPECT_FALSE(Unrecoverable); 1083 } 1084 1085 TEST_F(DebugLineBasicFixture, ParserAlwaysDoneForEmptySection) { 1086 if (!setupGenerator()) 1087 return; 1088 1089 generate(); 1090 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1091 1092 EXPECT_TRUE(Parser.done()); 1093 } 1094 1095 TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenParsing) { 1096 if (!setupGenerator()) 1097 return; 1098 1099 LineTable < = Gen->addLineTable(); 1100 LT.setCustomPrologue({{0xfffffff0, LineTable::Long}}); 1101 Gen->addLineTable(); 1102 generate(); 1103 1104 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1105 Parser.parseNext(RecordRecoverable, RecordUnrecoverable); 1106 1107 EXPECT_EQ(Parser.getOffset(), 0u); 1108 EXPECT_TRUE(Parser.done()); 1109 EXPECT_FALSE(Recoverable); 1110 1111 EXPECT_THAT_ERROR( 1112 std::move(Unrecoverable), 1113 FailedWithMessage( 1114 "parsing line table prologue at offset 0x00000000: unsupported " 1115 "reserved unit length of value 0xfffffff0")); 1116 } 1117 1118 TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenSkipping) { 1119 if (!setupGenerator()) 1120 return; 1121 1122 LineTable < = Gen->addLineTable(); 1123 LT.setCustomPrologue({{0xfffffff0, LineTable::Long}}); 1124 Gen->addLineTable(); 1125 generate(); 1126 1127 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1128 Parser.skip(RecordRecoverable, RecordUnrecoverable); 1129 1130 EXPECT_EQ(Parser.getOffset(), 0u); 1131 EXPECT_TRUE(Parser.done()); 1132 EXPECT_FALSE(Recoverable); 1133 1134 EXPECT_THAT_ERROR( 1135 std::move(Unrecoverable), 1136 FailedWithMessage( 1137 "parsing line table prologue at offset 0x00000000: unsupported " 1138 "reserved unit length of value 0xfffffff0")); 1139 } 1140 1141 TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) { 1142 if (!setupGenerator()) 1143 return; 1144 1145 LineTable < = Gen->addLineTable(DWARF32); 1146 LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}}); 1147 LineTable <2 = Gen->addLineTable(DWARF32); 1148 LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}}); 1149 generate(); 1150 1151 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1152 Parser.parseNext(RecordRecoverable, RecordUnrecoverable); 1153 ASSERT_FALSE(Parser.done()); 1154 Parser.parseNext(RecordRecoverable, RecordUnrecoverable); 1155 1156 EXPECT_TRUE(Parser.done()); 1157 EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded()); 1158 1159 EXPECT_THAT_ERROR( 1160 std::move(Unrecoverable), 1161 FailedWithMessage("parsing line table prologue at offset 0x00000000: " 1162 "unsupported version 0", 1163 "parsing line table prologue at offset 0x00000006: " 1164 "unsupported version 1")); 1165 } 1166 1167 TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) { 1168 if (!setupGenerator()) 1169 return; 1170 1171 LineTable < = Gen->addLineTable(DWARF32); 1172 LT.addExtendedOpcode(0x42, DW_LNE_end_sequence, {}); 1173 LineTable <2 = Gen->addLineTable(DWARF32); 1174 LT2.addExtendedOpcode(9, DW_LNE_set_address, 1175 {{0x1234567890abcdef, LineTable::Quad}}); 1176 LT2.addStandardOpcode(DW_LNS_copy, {}); 1177 LT2.addByte(0xbb); 1178 generate(); 1179 1180 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1181 Parser.parseNext(RecordRecoverable, RecordUnrecoverable); 1182 EXPECT_FALSE(Unrecoverable); 1183 ASSERT_FALSE(Parser.done()); 1184 EXPECT_THAT_ERROR(std::move(Recoverable), 1185 FailedWithMessage("unexpected line op length at offset " 1186 "0x00000030 expected 0x42 found 0x01")); 1187 1188 // Reset the error state so that it does not confuse the next set of checks. 1189 Unrecoverable = Error::success(); 1190 Parser.parseNext(RecordRecoverable, RecordUnrecoverable); 1191 1192 EXPECT_TRUE(Parser.done()); 1193 EXPECT_THAT_ERROR(std::move(Recoverable), 1194 FailedWithMessage("last sequence in debug line table at " 1195 "offset 0x00000031 is not terminated")); 1196 EXPECT_FALSE(Unrecoverable); 1197 } 1198 1199 TEST_F(DebugLineBasicFixture, 1200 ParserReportsPrologueErrorsInEachTableWhenSkipping) { 1201 if (!setupGenerator()) 1202 return; 1203 1204 LineTable < = Gen->addLineTable(DWARF32); 1205 LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}}); 1206 LineTable <2 = Gen->addLineTable(DWARF32); 1207 LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}}); 1208 generate(); 1209 1210 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1211 Parser.skip(RecordRecoverable, RecordUnrecoverable); 1212 ASSERT_FALSE(Parser.done()); 1213 Parser.skip(RecordRecoverable, RecordUnrecoverable); 1214 1215 EXPECT_TRUE(Parser.done()); 1216 EXPECT_FALSE(Recoverable); 1217 1218 EXPECT_THAT_ERROR( 1219 std::move(Unrecoverable), 1220 FailedWithMessage("parsing line table prologue at offset 0x00000000: " 1221 "unsupported version 0", 1222 "parsing line table prologue at offset 0x00000006: " 1223 "unsupported version 1")); 1224 } 1225 1226 TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) { 1227 if (!setupGenerator()) 1228 return; 1229 1230 LineTable < = Gen->addLineTable(DWARF32); 1231 LT.addExtendedOpcode(42, DW_LNE_end_sequence, {}); 1232 generate(); 1233 1234 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1235 Parser.skip(RecordRecoverable, RecordUnrecoverable); 1236 1237 EXPECT_TRUE(Parser.done()); 1238 EXPECT_FALSE(Recoverable); 1239 EXPECT_FALSE(Unrecoverable); 1240 } 1241 1242 TEST_F(DebugLineBasicFixture, VerboseOutput) { 1243 if (!setupGenerator(5)) 1244 return; 1245 1246 LineTable < = Gen->addLineTable(); 1247 LT.addByte(0); // Extended opcode with zero length. 1248 LT.addByte(0); 1249 // Zero-value extended opcode. 1250 LT.addExtendedOpcode(2, 0, {{1, LineTable::Byte}}); 1251 // Unknown extended opcode. 1252 LT.addExtendedOpcode(2, 0x42, {{1, LineTable::Byte}}); 1253 LT.addExtendedOpcode(9, DW_LNE_set_address, 1254 {{0x123456789abcdef, LineTable::Quad}}); 1255 LT.addExtendedOpcode(6, DW_LNE_define_file, 1256 {{'a', LineTable::Byte}, 1257 {'\0', LineTable::Byte}, 1258 {2, LineTable::ULEB}, 1259 {3, LineTable::ULEB}, 1260 {4, LineTable::ULEB}}); 1261 LT.addExtendedOpcode(2, DW_LNE_set_discriminator, {{0x7f, LineTable::ULEB}}); 1262 LT.addStandardOpcode(DW_LNS_copy, {}); 1263 LT.addStandardOpcode(DW_LNS_advance_pc, {{11, LineTable::ULEB}}); 1264 LT.addStandardOpcode(DW_LNS_advance_line, {{22, LineTable::SLEB}}); 1265 LT.addStandardOpcode(DW_LNS_set_file, {{33, LineTable::ULEB}}); 1266 LT.addStandardOpcode(DW_LNS_set_column, {{44, LineTable::ULEB}}); 1267 LT.addStandardOpcode(DW_LNS_negate_stmt, {}); 1268 LT.addStandardOpcode(DW_LNS_set_basic_block, {}); 1269 LT.addStandardOpcode(DW_LNS_const_add_pc, {}); 1270 LT.addStandardOpcode(DW_LNS_fixed_advance_pc, {{55, LineTable::Half}}); 1271 LT.addStandardOpcode(DW_LNS_set_prologue_end, {}); 1272 LT.addStandardOpcode(DW_LNS_set_epilogue_begin, {}); 1273 LT.addStandardOpcode(DW_LNS_set_isa, {{66, LineTable::ULEB}}); 1274 // Add unknown standard opcode with operands. 1275 LT.addStandardOpcode( 1276 0xd, {{1, LineTable::ULEB}, {0x123456789abcdef, LineTable::ULEB}}); 1277 // Add unknown standard opcode without operands. 1278 LT.addStandardOpcode(0xe, {}); 1279 LT.addByte(0xff); // Special opcode. 1280 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); 1281 1282 // Adjust the prologue to account for the extra standard opcode. 1283 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 1284 Prologue.TotalLength += 2; 1285 Prologue.PrologueLength += 2; 1286 Prologue.OpcodeBase += 2; 1287 Prologue.StandardOpcodeLengths.push_back(2); 1288 Prologue.StandardOpcodeLengths.push_back(0); 1289 LT.setPrologue(Prologue); 1290 1291 generate(); 1292 1293 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1294 std::string Output; 1295 raw_string_ostream OS(Output); 1296 Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS, 1297 /*Verbose=*/true); 1298 OS.flush(); 1299 StringRef OutputRef(Output); 1300 1301 size_t Pos = 0; 1302 auto NextLine = [&Pos, &OutputRef]() { 1303 size_t EOL = OutputRef.find_first_of('\n', Pos); 1304 StringRef Line = OutputRef.substr(Pos, EOL - Pos); 1305 Pos = EOL + 1; 1306 return Line; 1307 }; 1308 EXPECT_EQ(NextLine(), "Line table prologue:"); 1309 EXPECT_EQ(NextLine(), " total_length: 0x00000078"); 1310 EXPECT_EQ(NextLine(), " format: DWARF32"); 1311 EXPECT_EQ(NextLine(), " version: 5"); 1312 EXPECT_EQ(NextLine(), " address_size: 8"); 1313 EXPECT_EQ(NextLine(), " seg_select_size: 0"); 1314 EXPECT_EQ(NextLine(), " prologue_length: 0x0000002c"); 1315 EXPECT_EQ(NextLine(), " min_inst_length: 1"); 1316 EXPECT_EQ(NextLine(), "max_ops_per_inst: 1"); 1317 EXPECT_EQ(NextLine(), " default_is_stmt: 1"); 1318 EXPECT_EQ(NextLine(), " line_base: -5"); 1319 EXPECT_EQ(NextLine(), " line_range: 14"); 1320 EXPECT_EQ(NextLine(), " opcode_base: 15"); 1321 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_copy] = 0"); 1322 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_advance_pc] = 1"); 1323 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_advance_line] = 1"); 1324 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_file] = 1"); 1325 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_column] = 1"); 1326 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_negate_stmt] = 0"); 1327 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_basic_block] = 0"); 1328 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_const_add_pc] = 0"); 1329 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1"); 1330 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_prologue_end] = 0"); 1331 EXPECT_EQ(NextLine(), 1332 "standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0"); 1333 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_set_isa] = 1"); 1334 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_unknown_d] = 2"); 1335 EXPECT_EQ(NextLine(), "standard_opcode_lengths[DW_LNS_unknown_e] = 0"); 1336 EXPECT_EQ(NextLine(), "include_directories[ 0] = \"a dir\""); 1337 EXPECT_EQ(NextLine(), "file_names[ 0]:"); 1338 EXPECT_EQ(NextLine(), " name: \"a file\""); 1339 EXPECT_EQ(NextLine(), " dir_index: 0"); 1340 EXPECT_EQ(NextLine(), ""); 1341 EXPECT_EQ(NextLine(), " Address Line Column File ISA Discriminator Flags"); 1342 EXPECT_EQ(NextLine(), " ------------------ ------ ------ ------ --- ------------- -------------"); 1343 EXPECT_EQ(NextLine(), 1344 "0x00000038: 00 Badly formed extended line op (length 0)"); 1345 EXPECT_EQ(NextLine(), 1346 "0x0000003a: 00 Unrecognized extended op 0x00 length 2"); 1347 EXPECT_EQ(NextLine(), 1348 "0x0000003e: 00 Unrecognized extended op 0x42 length 2"); 1349 EXPECT_EQ(NextLine(), 1350 "0x00000042: 00 DW_LNE_set_address (0x0123456789abcdef)"); 1351 EXPECT_EQ(NextLine(), "0x0000004d: 00 DW_LNE_define_file (a, dir=2, " 1352 "mod_time=(0x0000000000000003), length=4)"); 1353 EXPECT_EQ(NextLine(), "0x00000055: 00 DW_LNE_set_discriminator (127)"); 1354 EXPECT_EQ(NextLine(), "0x00000059: 01 DW_LNS_copy"); 1355 EXPECT_EQ(NextLine(), " 0x0123456789abcdef 1 0 1 " 1356 "0 127 is_stmt"); 1357 EXPECT_EQ(NextLine(), "0x0000005a: 02 DW_LNS_advance_pc (11)"); 1358 EXPECT_EQ(NextLine(), "0x0000005c: 03 DW_LNS_advance_line (23)"); 1359 EXPECT_EQ(NextLine(), "0x0000005e: 04 DW_LNS_set_file (33)"); 1360 EXPECT_EQ(NextLine(), "0x00000060: 05 DW_LNS_set_column (44)"); 1361 EXPECT_EQ(NextLine(), "0x00000062: 06 DW_LNS_negate_stmt"); 1362 EXPECT_EQ(NextLine(), "0x00000063: 07 DW_LNS_set_basic_block"); 1363 EXPECT_EQ(NextLine(), 1364 "0x00000064: 08 DW_LNS_const_add_pc (0x0000000000000011)"); 1365 EXPECT_EQ(NextLine(), "0x00000065: 09 DW_LNS_fixed_advance_pc (0x0037)"); 1366 EXPECT_EQ(NextLine(), "0x00000068: 0a DW_LNS_set_prologue_end"); 1367 EXPECT_EQ(NextLine(), "0x00000069: 0b DW_LNS_set_epilogue_begin"); 1368 EXPECT_EQ(NextLine(), "0x0000006a: 0c DW_LNS_set_isa (66)"); 1369 EXPECT_EQ(NextLine(), "0x0000006c: 0d Unrecognized standard opcode " 1370 "(operands: 0x0000000000000001, 0x0123456789abcdef)"); 1371 EXPECT_EQ(NextLine(), "0x00000077: 0e Unrecognized standard opcode"); 1372 EXPECT_EQ(NextLine(), "0x00000078: ff address += 17, line += -3"); 1373 EXPECT_EQ(NextLine(), 1374 " 0x0123456789abce53 20 44 33 66 " 1375 " 0 basic_block prologue_end epilogue_begin"); 1376 EXPECT_EQ(NextLine(), "0x00000079: 00 DW_LNE_end_sequence"); 1377 EXPECT_EQ(NextLine(), " 0x0123456789abce53 20 44 33 " 1378 "66 0 end_sequence"); 1379 EXPECT_EQ(NextLine(), ""); 1380 EXPECT_EQ(Output.size(), Pos); 1381 } 1382 1383 using ValueAndLengths = std::vector<LineTable::ValueAndLength>; 1384 1385 struct TruncatedOpcodeFixtureBase : public CommonFixture { 1386 LineTable &setupTable() { 1387 LineTable < = Gen->addLineTable(); 1388 1389 // Creating the prologue before adding any opcodes ensures that the unit 1390 // length does not include the table body. 1391 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue(); 1392 1393 // Add an unrecognised standard opcode, and adjust prologue properties 1394 // accordingly. 1395 Prologue.TotalLength += BodyLength + 1; 1396 ++Prologue.PrologueLength; 1397 ++Prologue.OpcodeBase; 1398 Prologue.StandardOpcodeLengths.push_back(2); 1399 LT.setPrologue(Prologue); 1400 1401 return LT; 1402 } 1403 1404 void runTest(uint8_t OpcodeValue) { 1405 generate(); 1406 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); 1407 std::string Output; 1408 raw_string_ostream OS(Output); 1409 Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS, 1410 /*Verbose=*/true); 1411 OS.flush(); 1412 1413 std::string LinePrefix = 1414 ("0x0000002f: 0" + Twine::utohexstr(OpcodeValue) + " ").str(); 1415 StringRef OutputRef(Output); 1416 StringRef OutputToCheck = OutputRef.split(LinePrefix).second; 1417 // Each extended opcode ends with a new line and then the table ends with an 1418 // additional blank line. 1419 EXPECT_EQ((ExpectedOutput + "\n\n").str(), OutputToCheck); 1420 } 1421 1422 uint64_t BodyLength; 1423 uint8_t Opcode; 1424 ValueAndLengths Operands; 1425 StringRef ExpectedOutput; 1426 StringRef ExpectedErr; 1427 }; 1428 1429 struct TruncatedStandardOpcodeFixture 1430 : public TestWithParam< 1431 std::tuple<uint64_t, uint8_t, ValueAndLengths, StringRef, StringRef>>, 1432 public TruncatedOpcodeFixtureBase { 1433 void SetUp() { 1434 std::tie(BodyLength, Opcode, Operands, ExpectedOutput, ExpectedErr) = 1435 GetParam(); 1436 } 1437 }; 1438 1439 struct TruncatedExtendedOpcodeFixture 1440 : public TestWithParam<std::tuple<uint64_t, uint64_t, uint8_t, 1441 ValueAndLengths, StringRef, StringRef>>, 1442 public TruncatedOpcodeFixtureBase { 1443 void SetUp() { 1444 std::tie(BodyLength, OpcodeLength, Opcode, Operands, ExpectedOutput, 1445 ExpectedErr) = GetParam(); 1446 } 1447 1448 uint64_t OpcodeLength; 1449 }; 1450 1451 TEST_P(TruncatedExtendedOpcodeFixture, ErrorForTruncatedExtendedOpcode) { 1452 if (!setupGenerator()) 1453 return; 1454 LineTable < = setupTable(); 1455 LT.addExtendedOpcode(OpcodeLength, Opcode, Operands); 1456 runTest(0); 1457 EXPECT_THAT_ERROR(std::move(Recoverable), 1458 FailedWithMessage(ExpectedErr.str())); 1459 } 1460 1461 INSTANTIATE_TEST_CASE_P( 1462 TruncatedExtendedOpcodeParams, TruncatedExtendedOpcodeFixture, 1463 Values( 1464 std::make_tuple(1, 1, DW_LNE_end_sequence, ValueAndLengths(), 1465 "Badly formed extended line op (length 0)", 1466 "unable to decode LEB128 at offset 0x00000030: " 1467 "malformed uleb128, extends past end"), 1468 std::make_tuple( 1469 2, 9, DW_LNE_set_address, 1470 ValueAndLengths{{0x12345678, LineTable::Quad}}, 1471 "Unrecognized extended op 0x00 length 9", 1472 "unexpected end of data at offset 0x31 while reading [0x31, 0x32)"), 1473 std::make_tuple( 1474 3, 9, DW_LNE_set_address, 1475 ValueAndLengths{{0x12345678, LineTable::Quad}}, 1476 "DW_LNE_set_address (0x0000000000000000)", 1477 "unexpected end of data at offset 0x32 while reading [0x32, 0x3a)"), 1478 std::make_tuple(3, 5, DW_LNE_define_file, 1479 ValueAndLengths{{'a', LineTable::Byte}, 1480 {'\0', LineTable::Byte}, 1481 {1, LineTable::ULEB}, 1482 {1, LineTable::ULEB}, 1483 {1, LineTable::ULEB}}, 1484 "DW_LNE_define_file (, dir=0, " 1485 "mod_time=(0x0000000000000000), length=0)", 1486 "no null terminated string at offset 0x32"), 1487 std::make_tuple(5, 5, DW_LNE_define_file, 1488 ValueAndLengths{{'a', LineTable::Byte}, 1489 {'\0', LineTable::Byte}, 1490 {1, LineTable::ULEB}, 1491 {1, LineTable::ULEB}, 1492 {1, LineTable::ULEB}}, 1493 "DW_LNE_define_file (a, dir=0, " 1494 "mod_time=(0x0000000000000000), length=0)", 1495 "unable to decode LEB128 at offset 0x00000034: " 1496 "malformed uleb128, extends past end"), 1497 std::make_tuple(6, 5, DW_LNE_define_file, 1498 ValueAndLengths{{'a', LineTable::Byte}, 1499 {'\0', LineTable::Byte}, 1500 {1, LineTable::ULEB}, 1501 {1, LineTable::ULEB}, 1502 {1, LineTable::ULEB}}, 1503 "DW_LNE_define_file (a, dir=1, " 1504 "mod_time=(0x0000000000000000), length=0)", 1505 "unable to decode LEB128 at offset 0x00000035: " 1506 "malformed uleb128, extends past end"), 1507 std::make_tuple(7, 5, DW_LNE_define_file, 1508 ValueAndLengths{{'a', LineTable::Byte}, 1509 {'\0', LineTable::Byte}, 1510 {1, LineTable::ULEB}, 1511 {1, LineTable::ULEB}, 1512 {1, LineTable::ULEB}}, 1513 "DW_LNE_define_file (a, dir=1, " 1514 "mod_time=(0x0000000000000001), length=0)", 1515 "unable to decode LEB128 at offset 0x00000036: " 1516 "malformed uleb128, extends past end"), 1517 std::make_tuple(3, 2, DW_LNE_set_discriminator, 1518 ValueAndLengths{{1, LineTable::ULEB}}, 1519 "DW_LNE_set_discriminator (0)", 1520 "unable to decode LEB128 at offset 0x00000032: " 1521 "malformed uleb128, extends past end")), ); 1522 1523 TEST_P(TruncatedStandardOpcodeFixture, ErrorForTruncatedStandardOpcode) { 1524 if (!setupGenerator()) 1525 return; 1526 LineTable < = setupTable(); 1527 LT.addStandardOpcode(Opcode, Operands); 1528 runTest(Opcode); 1529 EXPECT_THAT_ERROR(std::move(Unrecoverable), 1530 FailedWithMessage(ExpectedErr.str())); 1531 } 1532 1533 INSTANTIATE_TEST_CASE_P( 1534 TruncatedStandardOpcodeParams, TruncatedStandardOpcodeFixture, 1535 Values( 1536 std::make_tuple(2, DW_LNS_advance_pc, 1537 ValueAndLengths{{0x100, LineTable::ULEB}}, 1538 "DW_LNS_advance_pc", 1539 "unable to decode LEB128 at offset 0x00000030: " 1540 "malformed uleb128, extends past end"), 1541 std::make_tuple(2, DW_LNS_advance_line, 1542 ValueAndLengths{{0x200, LineTable::SLEB}}, 1543 "DW_LNS_advance_line", 1544 "unable to decode LEB128 at offset 0x00000030: " 1545 "malformed sleb128, extends past end"), 1546 std::make_tuple(2, DW_LNS_set_file, 1547 ValueAndLengths{{0x300, LineTable::ULEB}}, 1548 "DW_LNS_set_file", 1549 "unable to decode LEB128 at offset 0x00000030: " 1550 "malformed uleb128, extends past end"), 1551 std::make_tuple(2, DW_LNS_set_column, 1552 ValueAndLengths{{0x400, LineTable::ULEB}}, 1553 "DW_LNS_set_column", 1554 "unable to decode LEB128 at offset 0x00000030: " 1555 "malformed uleb128, extends past end"), 1556 std::make_tuple( 1557 2, DW_LNS_fixed_advance_pc, 1558 ValueAndLengths{{0x500, LineTable::Half}}, 1559 "DW_LNS_fixed_advance_pc", 1560 "unexpected end of data at offset 0x31 while reading [0x30, 0x32)"), 1561 std::make_tuple(2, DW_LNS_set_isa, 1562 ValueAndLengths{{0x600, LineTable::ULEB}}, 1563 "DW_LNS_set_isa", 1564 "unable to decode LEB128 at offset 0x00000030: " 1565 "malformed uleb128, extends past end"), 1566 std::make_tuple(2, 0xd, 1567 ValueAndLengths{{0x700, LineTable::ULEB}, 1568 {0x800, LineTable::ULEB}}, 1569 "Unrecognized standard opcode", 1570 "unable to decode LEB128 at offset 0x00000030: " 1571 "malformed uleb128, extends past end"), 1572 std::make_tuple( 1573 4, 0xd, 1574 ValueAndLengths{{0x900, LineTable::ULEB}, {0xa00, LineTable::ULEB}}, 1575 "Unrecognized standard opcode (operands: 0x0000000000000900)", 1576 "unable to decode LEB128 at offset 0x00000032: " 1577 "malformed uleb128, extends past end")), ); 1578 1579 TEST_F(DebugLineBasicFixture, PrintPathsProperly) { 1580 if (!setupGenerator(5)) 1581 return; 1582 1583 LineTable < = Gen->addLineTable(); 1584 DWARFDebugLine::Prologue P = LT.createBasicPrologue(); 1585 P.IncludeDirectories.push_back( 1586 DWARFFormValue::createFromPValue(DW_FORM_string, "b dir")); 1587 P.FileNames.push_back(DWARFDebugLine::FileNameEntry()); 1588 P.FileNames.back().Name = 1589 DWARFFormValue::createFromPValue(DW_FORM_string, "b file"); 1590 P.FileNames.back().DirIdx = 1; 1591 P.TotalLength += 14; 1592 P.PrologueLength += 14; 1593 LT.setPrologue(P); 1594 generate(); 1595 1596 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, 1597 nullptr, RecordRecoverable); 1598 EXPECT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); 1599 std::string Result; 1600 // DWARF 5 stores the compilation directory in two places: the Compilation 1601 // Unit and the directory table entry 0, and implementations are free to use 1602 // one or the other. This copy serves as the one stored in the CU. 1603 StringRef CompDir = "a dir"; 1604 EXPECT_FALSE( 1605 (*ExpectedLineTable) 1606 ->Prologue.getFileNameByIndex( 1607 1, CompDir, DILineInfoSpecifier::FileLineInfoKind::None, Result)); 1608 EXPECT_TRUE((*ExpectedLineTable) 1609 ->Prologue.getFileNameByIndex( 1610 1, CompDir, 1611 DILineInfoSpecifier::FileLineInfoKind::RawValue, Result)); 1612 EXPECT_TRUE((*ExpectedLineTable) 1613 ->Prologue.getFileNameByIndex( 1614 1, CompDir, 1615 DILineInfoSpecifier::FileLineInfoKind::BaseNameOnly, 1616 Result)); 1617 EXPECT_STREQ(Result.c_str(), "b file"); 1618 EXPECT_TRUE((*ExpectedLineTable) 1619 ->Prologue.getFileNameByIndex( 1620 1, CompDir, 1621 DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath, 1622 Result)); 1623 EXPECT_THAT(Result.c_str(), MatchesRegex("b dir.b file")); 1624 EXPECT_TRUE((*ExpectedLineTable) 1625 ->Prologue.getFileNameByIndex( 1626 1, CompDir, 1627 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, 1628 Result)); 1629 EXPECT_THAT(Result.c_str(), MatchesRegex("a dir.b dir.b file")); 1630 } 1631 1632 } // end anonymous namespace 1633