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