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