[clangd] Re-land "support outgoing calls in call hierarchy" (#117673)
[llvm-project.git] / llvm / unittests / DebugInfo / DWARF / DWARFDebugLineTest.cpp
blobe549128031744e695a4b74017239afd130ac4425
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 //===----------------------------------------------------------------------===//
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"
17 // AIX doesn't support the debug_addr section
18 #ifdef _AIX
19 #define NO_SUPPORT_DEBUG_ADDR
20 #endif
22 using namespace llvm;
23 using namespace dwarf;
24 using namespace dwarfgen;
25 using namespace object;
26 using namespace utils;
27 using namespace testing;
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)){};
39 ~CommonFixture() {
40 EXPECT_FALSE(Recoverable);
41 EXPECT_FALSE(Unrecoverable);
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);
56 bool setupGenerator(uint16_t Version = 4, uint8_t AddrSize = 8) {
57 setupGeneratorImpl(Version, AddrSize);
58 return Gen != nullptr;
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);
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;
82 DWARFDebugLine::SectionParser setupParser() {
83 LineTable &LT = Gen->addLineTable(DWARF32);
84 LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});
85 LT.addStandardOpcode(DW_LNS_copy, {});
86 LT.addByte(0xaa);
87 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
89 LineTable &LT2 = Gen->addLineTable(DWARF64);
90 LT2.addExtendedOpcode(9, DW_LNE_set_address,
91 {{0x11223344, LineTable::Quad}});
92 LT2.addStandardOpcode(DW_LNS_copy, {});
93 LT2.addByte(0xbb);
94 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
96 generate();
98 return DWARFDebugLine::SectionParser(LineData, *Context, Units);
101 void recordRecoverable(Error Err) {
102 Recoverable = joinErrors(std::move(Recoverable), std::move(Err));
104 void recordUnrecoverable(Error Err) {
105 Unrecoverable = joinErrors(std::move(Unrecoverable), std::move(Err));
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;
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;
126 SmallVector<std::unique_ptr<DWARFUnit>, 2> Units;
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 {};
134 struct DebugLineParameterisedFixture
135 : public TestWithParam<std::pair<uint16_t, DwarfFormat>>,
136 public CommonFixture {
137 void SetUp() override { std::tie(Version, Format) = GetParam(); }
139 uint16_t Version;
140 DwarfFormat Format;
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");
169 UnitLength += BodyLength + (Format == DWARF32 ? 4 : 8);
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");
189 TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffset) {
190 if (!setupGenerator())
191 GTEST_SKIP();
192 generate();
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"));
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"));
211 TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) {
212 if (!setupGenerator())
213 GTEST_SKIP();
215 LineTable &LT = Gen->addLineTable();
216 LT.setCustomPrologue({{0, LineTable::Byte}});
218 generate();
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)"));
226 EXPECT_THAT_EXPECTED(
227 getOrParseLineTableFatalErrors(1),
228 FailedWithMessage(
229 "offset 0x00000001 is not a valid debug line section offset"));
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 &LT = Gen->addLineTable(Format);
240 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
241 LT.setPrologue(Prologue);
242 generate();
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;
253 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
254 nullptr, RecordRecoverable);
255 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
256 EXPECT_EQ((*ExpectedLineTable)->Prologue.getLength(), ExpectedLength);
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();
267 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +
268 (Format == DWARF64 ? "DWARF64" : "DWARF32"));
270 LineTable &LT = Gen->addLineTable(Format);
271 LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});
272 LT.addStandardOpcode(DW_LNS_copy, {});
273 LT.addByte(0xaa);
274 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
276 LineTable &LT2 = Gen->addLineTable(Format);
277 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x11223344, LineTable::Quad}});
278 LT2.addStandardOpcode(DW_LNS_copy, {});
279 LT2.addByte(0xbb);
280 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
281 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x55667788, LineTable::Quad}});
282 LT2.addStandardOpcode(DW_LNS_copy, {});
283 LT2.addByte(0xcc);
284 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
286 generate();
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);
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);
307 EXPECT_NE(Expected, Expected2);
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);
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);
325 // TODO: Add tests that show that the body of the programs have been read
326 // correctly.
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();
337 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +
338 (Format == DWARF64 ? "DWARF64" : "DWARF32"));
340 LineTable &LT = Gen->addLineTable(Format);
341 LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});
342 LT.addStandardOpcode(DW_LNS_copy, {});
343 LT.addByte(0xaa);
344 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
346 LineTable &LT2 = Gen->addLineTable(Format);
347 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x11223344, LineTable::Quad}});
348 LT2.addStandardOpcode(DW_LNS_copy, {});
349 LT2.addByte(0xbb);
350 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
351 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x55667788, LineTable::Quad}});
352 LT2.addStandardOpcode(DW_LNS_copy, {});
353 LT2.addByte(0xcc);
354 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
356 generate();
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);
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);
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);
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);
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);
405 TEST_F(DebugLineBasicFixture, ErrorForReservedLength) {
406 if (!setupGenerator())
407 GTEST_SKIP();
409 LineTable &LT = Gen->addLineTable();
410 LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
412 generate();
414 EXPECT_THAT_EXPECTED(
415 getOrParseLineTableFatalErrors(),
416 FailedWithMessage(
417 "parsing line table prologue at offset 0x00000000: unsupported "
418 "reserved unit length of value 0xfffffff0"));
421 struct DebugLineUnsupportedVersionFixture : public TestWithParam<uint16_t>,
422 public CommonFixture {
423 void SetUp() override { Version = GetParam(); }
425 uint16_t Version;
428 TEST_P(DebugLineUnsupportedVersionFixture, ErrorForUnsupportedVersion) {
429 if (!setupGenerator())
430 GTEST_SKIP();
432 LineTable &LT = Gen->addLineTable();
433 LT.setCustomPrologue(
434 {{LineTable::Half, LineTable::Long}, {Version, LineTable::Half}});
436 generate();
438 EXPECT_THAT_EXPECTED(
439 getOrParseLineTableFatalErrors(),
440 FailedWithMessage("parsing line table prologue at offset 0x00000000: "
441 "unsupported version " +
442 std::to_string(Version)));
445 INSTANTIATE_TEST_SUITE_P(UnsupportedVersionTestParams,
446 DebugLineUnsupportedVersionFixture,
447 Values(/*1 below min */ 1, /* 1 above max */ 6,
448 /* Maximum possible */ 0xffff));
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();
458 LineTable &LT = 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
480 generate();
482 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
483 nullptr, RecordRecoverable);
484 EXPECT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
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"));
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();
503 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +
504 (Format == DWARF64 ? "DWARF64" : "DWARF32"));
506 LineTable &LT = Gen->addLineTable(Format);
507 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
508 ++Prologue.PrologueLength;
509 LT.setPrologue(Prologue);
511 generate();
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);
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()));
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();
543 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +
544 (Format == DWARF64 ? "DWARF64" : "DWARF32"));
546 LineTable &LT = Gen->addLineTable(Format);
547 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
548 Prologue.PrologueLength -= 2;
549 LT.setPrologue(Prologue);
551 generate();
553 auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
554 nullptr, RecordRecoverable);
555 ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
556 DWARFDebugLine::LineTable Result(**ExpectedLineTable);
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);
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");
581 EXPECT_THAT_ERROR(std::move(Recoverable),
582 FailedWithMessageArray(testing::ElementsAreArray(Errs)));
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)));
593 TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthSmallerThanExpected) {
594 if (!setupGenerator())
595 GTEST_SKIP();
597 LineTable &LT = Gen->addLineTable();
598 LT.addByte(0xaa);
599 // The Length should be 1 + sizeof(ULEB) for a set discriminator opcode.
600 // The operand will be read for both the discriminator opcode and then 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, {});
608 generate();
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);
622 TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthLargerThanExpected) {
623 if (!setupGenerator())
624 GTEST_SKIP();
626 LineTable &LT = Gen->addLineTable();
627 LT.addByte(0xaa);
628 LT.addStandardOpcode(DW_LNS_const_add_pc, {});
629 // The Length should be 1 for an end sequence opcode.
630 LT.addExtendedOpcode(2, DW_LNE_end_sequence, {});
631 // The negate statement opcode will be skipped.
632 LT.addStandardOpcode(DW_LNS_negate_stmt, {});
633 LT.addByte(0xbb);
634 LT.addStandardOpcode(DW_LNS_const_add_pc, {});
635 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
637 generate();
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);
651 TEST_F(DebugLineBasicFixture, ErrorForUnitLengthTooLarge) {
652 if (!setupGenerator())
653 GTEST_SKIP();
655 LineTable &Padding = Gen->addLineTable();
656 // Add some padding to show that a non-zero offset is handled correctly.
657 Padding.setCustomPrologue({{0, LineTable::Byte}});
658 LineTable &LT = Gen->addLineTable();
659 LT.addStandardOpcode(DW_LNS_copy, {});
660 LT.addStandardOpcode(DW_LNS_const_add_pc, {});
661 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
662 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
663 // Set the total length to 1 higher than the actual length.
664 ++Prologue.TotalLength;
665 LT.setPrologue(Prologue);
667 generate();
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);
680 TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) {
681 if (!setupGenerator(4, 8))
682 GTEST_SKIP();
684 LineTable &LT = Gen->addLineTable();
685 // The line data extractor expects size 8 (Quad) addresses.
686 uint64_t Addr1 = 0x11223344;
687 LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});
688 LT.addStandardOpcode(DW_LNS_copy, {});
689 // Show that the expected address size is unchanged, so later valid 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, {});
695 generate();
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);
709 TEST_F(DebugLineBasicFixture,
710 ErrorForMismatchedAddressSizeUnsetInitialAddress) {
711 if (!setupGenerator(4, 0))
712 GTEST_SKIP();
714 LineTable &LT = Gen->addLineTable();
715 uint64_t Addr1 = 0x11223344;
716 LT.addExtendedOpcode(5, DW_LNE_set_address, {{Addr1, LineTable::Long}});
717 LT.addStandardOpcode(DW_LNS_copy, {});
718 uint64_t Addr2 = 0x1122334455667788;
719 LT.addExtendedOpcode(9, DW_LNE_set_address, {{Addr2, LineTable::Quad}});
720 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
722 generate();
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);
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();
743 LineTable &LT = 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, {});
754 generate();
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);
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();
775 LineTable &LT = 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, {});
782 generate();
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());
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();
804 LineTable &LT = 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);
820 generate();
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);
837 TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) {
838 if (!setupGenerator())
839 GTEST_SKIP();
841 LineTable &LT = Gen->addLineTable();
842 LT.addExtendedOpcode(9, DW_LNE_set_address,
843 {{0x1122334455667788, LineTable::Quad}});
844 LT.addStandardOpcode(DW_LNS_copy, {});
845 LT.addByte(0xaa);
846 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
847 LT.addExtendedOpcode(9, DW_LNE_set_address,
848 {{0x99aabbccddeeff00, LineTable::Quad}});
849 LT.addStandardOpcode(DW_LNS_copy, {});
850 LT.addByte(0xbb);
851 LT.addByte(0xcc);
853 generate();
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);
866 struct AdjustAddressFixtureBase : public CommonFixture {
867 virtual ~AdjustAddressFixtureBase() {}
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 &LT) = 0;
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;
879 virtual uint64_t getAdjustedLine(uint64_t Base, uint64_t Incr) {
880 return Base + Incr;
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);
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);
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);
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);
931 void setupTables(bool AddAdvancePCFirstTable) {
932 LineTable &Padding = Gen->addLineTable();
933 Padding.setCustomPrologue({{0, LineTable::Byte}});
934 NoProblemOffset = 1;
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;
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;
944 // Show that the warning is emitted for the first special opcode and then
945 // not again.
946 AdvancePCOffset = setupSpecialFirstTable() + SpecialOffset;
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();
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()));
979 return ExpectedTable;
982 void runTest(bool CheckAdvancePC, Twine MsgSuffix) {
983 if (!setupGenerator(Version))
984 GTEST_SKIP();
986 setupTables(/*AddAdvancePCFirstTable=*/CheckAdvancePC);
988 generate();
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());
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());
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());
1016 if (!CheckAdvancePC)
1017 return;
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));
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;
1037 uint16_t Version = 4;
1038 bool IsErrorExpected;
1041 struct OpIndexFixture : Test, CommonFixture {
1042 void createPrologue(LineTable &LT, uint8_t MaxOpsPerInst,
1043 uint8_t MinInstLength) {
1044 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
1045 Prologue.MaxOpsPerInst = MaxOpsPerInst;
1046 Prologue.MinInstLength = MinInstLength;
1047 LT.setPrologue(Prologue);
1051 TEST_F(OpIndexFixture, OpIndexAdvance) {
1052 if (!setupGenerator(4, 4))
1053 GTEST_SKIP();
1055 uint8_t MaxOpsPerInst = 13;
1056 uint8_t MinInstLength = 4;
1058 LineTable &LT = Gen->addLineTable();
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.
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.
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.
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.
1082 // Row 6: End sequence to have the input well-formed.
1083 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
1085 createPrologue(LT, MaxOpsPerInst, MinInstLength);
1087 generate();
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);
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());
1108 ASSERT_EQ((*Table)->Rows.size(), 7u);
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);
1118 TEST_F(OpIndexFixture, OpIndexReset) {
1119 if (!setupGenerator(4, 4))
1120 GTEST_SKIP();
1122 uint8_t MaxOpsPerInst = 13;
1123 uint8_t MinInstLength = 4;
1125 LineTable &LT = Gen->addLineTable();
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
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.
1135 // Row 2: Just set op-index to some value > 0.
1136 LT.addByte(0x66); // Special opcode, +6 op-index
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.
1142 // Row 4: Just set op-index to some value > 0.
1143 LT.addByte(0xba); // Special opcode, +12 op-index
1145 // Row 5: End sequence (op-index unchanged for this row)...
1146 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
1148 // Row 6: ... but shall be reset after the DW_LNE_end_sequence row.
1149 LT.addStandardOpcode(DW_LNS_copy, {}); // Create new row.
1151 // Row 7: End sequence to have the input well-formed.
1152 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
1154 createPrologue(LT, MaxOpsPerInst, MinInstLength);
1156 generate();
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());
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);
1181 TEST_F(OpIndexFixture, MaxOpsZeroDwarf3) {
1182 if (!setupGenerator(3, 4))
1183 GTEST_SKIP();
1185 LineTable &LT = Gen->addLineTable();
1186 LT.addStandardOpcode(DW_LNS_const_add_pc, {}); // Just some opcode to advance.
1187 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); //
1188 createPrologue(LT, /*MaxOpsPerInst=*/0, /*MinInstLength=*/1);
1189 generate();
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());
1198 TEST_F(OpIndexFixture, MaxOpsZeroDwarf4) {
1199 if (!setupGenerator(4, 4))
1200 GTEST_SKIP();
1202 LineTable &LT = Gen->addLineTable();
1203 LT.addStandardOpcode(DW_LNS_const_add_pc, {}); // Just some opcode to advance.
1204 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {}); //
1205 createPrologue(LT, /*MaxOpsPerInst=*/0, /*MinInstLength=*/1);
1206 generate();
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());
1221 struct LineRangeFixture : TestWithParam<std::tuple<uint8_t, bool>>,
1222 AdjustAddressFixtureBase {
1223 void SetUp() override { std::tie(LineRange, IsErrorExpected) = GetParam(); }
1225 uint64_t editPrologue(LineTable &LT) override {
1226 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
1227 Prologue.LineRange = LineRange;
1228 LT.setPrologue(Prologue);
1229 return Prologue.TotalLength + Prologue.sizeofTotalLength();
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);
1241 uint64_t getAdjustedLine(uint64_t Base, uint64_t Incr) override {
1242 return LineRange != 0
1243 ? AdjustAddressFixtureBase::getAdjustedLine(Base, Incr)
1244 : Base;
1247 uint8_t LineRange;
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");
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).
1261 struct BadMinInstLenFixture : TestWithParam<std::tuple<uint8_t, bool>>,
1262 AdjustAddressFixtureBase {
1263 void SetUp() override {
1264 std::tie(MinInstLength, IsErrorExpected) = GetParam();
1267 uint64_t editPrologue(LineTable &LT) override {
1268 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
1269 Prologue.MinInstLength = MinInstLength;
1270 LT.setPrologue(Prologue);
1271 return Prologue.TotalLength + Prologue.sizeofTotalLength();
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;
1282 uint8_t MinInstLength;
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");
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).
1296 TEST_F(DebugLineBasicFixture, ParserParsesCorrectly) {
1297 if (!setupGenerator())
1298 GTEST_SKIP();
1300 DWARFDebugLine::SectionParser Parser = setupParser();
1302 EXPECT_EQ(Parser.getOffset(), 0u);
1303 ASSERT_FALSE(Parser.done());
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());
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());
1319 EXPECT_FALSE(Recoverable);
1320 EXPECT_FALSE(Unrecoverable);
1323 TEST_F(DebugLineBasicFixture, ParserSkipsCorrectly) {
1324 if (!setupGenerator())
1325 GTEST_SKIP();
1327 DWARFDebugLine::SectionParser Parser = setupParser();
1329 EXPECT_EQ(Parser.getOffset(), 0u);
1330 ASSERT_FALSE(Parser.done());
1332 Parser.skip(RecordRecoverable, RecordUnrecoverable);
1333 EXPECT_EQ(Parser.getOffset(), 62u);
1334 ASSERT_FALSE(Parser.done());
1336 Parser.skip(RecordRecoverable, RecordUnrecoverable);
1337 EXPECT_EQ(Parser.getOffset(), 136u);
1338 EXPECT_TRUE(Parser.done());
1340 EXPECT_FALSE(Recoverable);
1341 EXPECT_FALSE(Unrecoverable);
1344 TEST_F(DebugLineBasicFixture, ParserAlwaysDoneForEmptySection) {
1345 if (!setupGenerator())
1346 GTEST_SKIP();
1348 generate();
1349 DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);
1351 EXPECT_TRUE(Parser.done());
1354 TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenParsing) {
1355 if (!setupGenerator())
1356 GTEST_SKIP();
1358 LineTable &LT = Gen->addLineTable();
1359 LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
1360 Gen->addLineTable();
1361 generate();
1363 DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);
1364 Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
1366 EXPECT_EQ(Parser.getOffset(), 0u);
1367 EXPECT_TRUE(Parser.done());
1368 EXPECT_FALSE(Recoverable);
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"));
1377 TEST_F(DebugLineBasicFixture, ParserMarkedAsDoneForBadLengthWhenSkipping) {
1378 if (!setupGenerator())
1379 GTEST_SKIP();
1381 LineTable &LT = Gen->addLineTable();
1382 LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
1383 Gen->addLineTable();
1384 generate();
1386 DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);
1387 Parser.skip(RecordRecoverable, RecordUnrecoverable);
1389 EXPECT_EQ(Parser.getOffset(), 0u);
1390 EXPECT_TRUE(Parser.done());
1391 EXPECT_FALSE(Recoverable);
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"));
1400 TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {
1401 if (!setupGenerator())
1402 GTEST_SKIP();
1404 LineTable &LT = Gen->addLineTable(DWARF32);
1405 LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}});
1406 LineTable &LT2 = Gen->addLineTable(DWARF32);
1407 LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}});
1408 generate();
1410 DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);
1411 Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
1412 ASSERT_FALSE(Parser.done());
1413 Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
1415 EXPECT_TRUE(Parser.done());
1416 EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());
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"));
1426 TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) {
1427 if (!setupGenerator())
1428 GTEST_SKIP();
1430 LineTable &LT = Gen->addLineTable(DWARF32);
1431 LT.addExtendedOpcode(0x42, DW_LNE_end_sequence, {});
1432 LineTable &LT2 = Gen->addLineTable(DWARF32);
1433 LT2.addExtendedOpcode(9, DW_LNE_set_address,
1434 {{0x1234567890abcdef, LineTable::Quad}});
1435 LT2.addStandardOpcode(DW_LNS_copy, {});
1436 LT2.addByte(0xbb);
1437 generate();
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"));
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);
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);
1458 TEST_F(DebugLineBasicFixture,
1459 ParserReportsPrologueErrorsInEachTableWhenSkipping) {
1460 if (!setupGenerator())
1461 GTEST_SKIP();
1463 LineTable &LT = Gen->addLineTable(DWARF32);
1464 LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}});
1465 LineTable &LT2 = Gen->addLineTable(DWARF32);
1466 LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}});
1467 generate();
1469 DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);
1470 Parser.skip(RecordRecoverable, RecordUnrecoverable);
1471 ASSERT_FALSE(Parser.done());
1472 Parser.skip(RecordRecoverable, RecordUnrecoverable);
1474 EXPECT_TRUE(Parser.done());
1475 EXPECT_FALSE(Recoverable);
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"));
1485 TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) {
1486 if (!setupGenerator())
1487 GTEST_SKIP();
1489 LineTable &LT = Gen->addLineTable(DWARF32);
1490 LT.addExtendedOpcode(42, DW_LNE_end_sequence, {});
1491 generate();
1493 DWARFDebugLine::SectionParser Parser(LineData, *Context, Units);
1494 Parser.skip(RecordRecoverable, RecordUnrecoverable);
1496 EXPECT_TRUE(Parser.done());
1497 EXPECT_FALSE(Recoverable);
1498 EXPECT_FALSE(Unrecoverable);
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();
1509 LineTable &LT = Gen->addLineTable();
1510 LT.addByte(0); // Extended opcode with zero length.
1511 LT.addByte(0);
1512 // Zero-value extended opcode.
1513 LT.addExtendedOpcode(2, 0, {{1, LineTable::Byte}});
1514 // Unknown extended opcode.
1515 LT.addExtendedOpcode(2, 0x42, {{1, LineTable::Byte}});
1516 LT.addExtendedOpcode(9, DW_LNE_set_address,
1517 {{0x123456789abcdef, LineTable::Quad}});
1518 LT.addExtendedOpcode(6, DW_LNE_define_file,
1519 {{'a', LineTable::Byte},
1520 {'\0', LineTable::Byte},
1521 {2, LineTable::ULEB},
1522 {3, LineTable::ULEB},
1523 {4, LineTable::ULEB}});
1524 LT.addExtendedOpcode(2, DW_LNE_set_discriminator, {{0x7f, LineTable::ULEB}});
1525 LT.addStandardOpcode(DW_LNS_copy, {});
1526 LT.addStandardOpcode(DW_LNS_advance_pc, {{11, LineTable::ULEB}});
1527 LT.addStandardOpcode(DW_LNS_advance_line, {{22, LineTable::SLEB}});
1528 LT.addStandardOpcode(DW_LNS_set_file, {{33, LineTable::ULEB}});
1529 LT.addStandardOpcode(DW_LNS_set_column, {{44, LineTable::ULEB}});
1530 LT.addStandardOpcode(DW_LNS_negate_stmt, {});
1531 LT.addStandardOpcode(DW_LNS_set_basic_block, {});
1532 LT.addStandardOpcode(DW_LNS_const_add_pc, {});
1533 LT.addStandardOpcode(DW_LNS_fixed_advance_pc, {{55, LineTable::Half}});
1534 LT.addStandardOpcode(DW_LNS_set_prologue_end, {});
1535 LT.addStandardOpcode(DW_LNS_set_epilogue_begin, {});
1536 LT.addStandardOpcode(DW_LNS_set_isa, {{66, LineTable::ULEB}});
1537 // Add unknown standard opcode with operands.
1538 LT.addStandardOpcode(
1539 0xd, {{1, LineTable::ULEB}, {0x123456789abcdef, LineTable::ULEB}});
1540 // Add unknown standard opcode without operands.
1541 LT.addStandardOpcode(0xe, {});
1542 LT.addByte(0xff); // Special opcode.
1543 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
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);
1554 generate();
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);
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;
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);
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();
1659 uint64_t Length;
1660 uint64_t ExpectedOffset;
1661 uint16_t Version;
1662 DwarfFormat Format;
1663 StringRef ExpectedErr;
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();
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}});
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);
1686 generate();
1687 // Truncate the data extractor to the specified length.
1688 LineData = DWARFDataExtractor(LineData, Length);
1690 DWARFDebugLine::Prologue Prologue;
1691 uint64_t Offset = 1;
1692 Error Err = Prologue.parse(LineData, &Offset, RecordRecoverable, *Context);
1694 EXPECT_THAT_ERROR(std::move(Err), FailedWithMessage(ExpectedErr.str()));
1695 EXPECT_EQ(Offset, ExpectedOffset);
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)")));
1779 using ValueAndLengths = std::vector<LineTable::ValueAndLength>;
1781 struct TruncatedOpcodeFixtureBase : public CommonFixture {
1782 LineTable &setupTable() {
1783 LineTable &LT = Gen->addLineTable();
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();
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);
1797 return LT;
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);
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);
1817 uint64_t BodyLength;
1818 uint8_t Opcode;
1819 ValueAndLengths Operands;
1820 StringRef ExpectedOutput;
1821 StringRef ExpectedErr;
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();
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();
1843 uint64_t OpcodeLength;
1846 TEST_P(TruncatedExtendedOpcodeFixture, ErrorForTruncatedExtendedOpcode) {
1847 if (!setupGenerator())
1848 GTEST_SKIP();
1849 LineTable &LT = setupTable();
1850 LT.addExtendedOpcode(OpcodeLength, Opcode, Operands);
1851 runTest(0);
1852 EXPECT_THAT_ERROR(std::move(Recoverable),
1853 FailedWithMessage(ExpectedErr.str()));
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)")));
1925 TEST_P(TruncatedStandardOpcodeFixture, ErrorForTruncatedStandardOpcode) {
1926 if (!setupGenerator())
1927 GTEST_SKIP();
1928 LineTable &LT = setupTable();
1929 LT.addStandardOpcode(Opcode, Operands);
1930 runTest(Opcode);
1931 EXPECT_THAT_ERROR(std::move(Unrecoverable),
1932 FailedWithMessage(ExpectedErr.str()));
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")));
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();
1989 LineTable &LT = Gen->addLineTable();
1990 DWARFDebugLine::Prologue P = LT.createBasicPrologue();
1991 P.IncludeDirectories.push_back(
1992 DWARFFormValue::createFromPValue(DW_FORM_string, "b dir"));
1993 P.FileNames.push_back(DWARFDebugLine::FileNameEntry());
1994 P.FileNames.back().Name =
1995 DWARFFormValue::createFromPValue(DW_FORM_string, "b file");
1996 P.FileNames.back().DirIdx = 1;
1997 P.TotalLength += 14;
1998 P.PrologueLength += 14;
1999 LT.setPrologue(P);
2000 generate();
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"));
2038 } // end anonymous namespace