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