1 //===- DWARFDebugLineTest.cpp ---------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DwarfGenerator.h"
11 #include "DwarfUtils.h"
12 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
13 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
14 #include "llvm/Object/ObjectFile.h"
15 #include "llvm/Testing/Support/Error.h"
16 #include "gtest/gtest.h"
19 using namespace dwarf;
20 using namespace dwarfgen;
21 using namespace object;
22 using namespace utils;
23 using namespace testing;
26 struct CommonFixture {
28 : LineData("", true, 0),
29 RecordIssue(std::bind(&CommonFixture::recordIssue, this,
30 std::placeholders::_1)),
31 FoundError(Error::success()),
32 RecordError(std::bind(&CommonFixture::recordError, this,
33 std::placeholders::_1)){};
35 ~CommonFixture() { EXPECT_FALSE(FoundError); }
37 bool setupGenerator(uint16_t Version = 4) {
38 Triple T = getHostTripleForAddrSize(8);
39 if (!isConfigurationSupported(T))
41 auto ExpectedGenerator = Generator::create(T, Version);
42 if (ExpectedGenerator)
43 Gen.reset(ExpectedGenerator->release());
48 Context = createContext();
49 assert(Context != nullptr && "test state is not valid");
50 const DWARFObject &Obj = Context->getDWARFObj();
51 LineData = DWARFDataExtractor(Obj, Obj.getLineSection(), true, 8);
54 std::unique_ptr<DWARFContext> createContext() {
57 StringRef FileBytes = Gen->generate();
58 MemoryBufferRef FileBuffer(FileBytes, "dwarf");
59 auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
61 return DWARFContext::create(**Obj);
65 DWARFDebugLine::SectionParser setupParser() {
66 LineTable < = Gen->addLineTable(DWARF32);
67 LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});
68 LT.addStandardOpcode(DW_LNS_copy, {});
70 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
72 LineTable <2 = Gen->addLineTable(DWARF64);
73 LT2.addExtendedOpcode(9, DW_LNE_set_address,
74 {{0x11223344, LineTable::Quad}});
75 LT2.addStandardOpcode(DW_LNS_copy, {});
77 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
81 return DWARFDebugLine::SectionParser(LineData, *Context, CUs, TUs);
84 void recordIssue(StringRef Message) { IssueMessage = Message; }
85 void recordError(Error Err) {
86 FoundError = joinErrors(std::move(FoundError), std::move(Err));
89 void checkError(ArrayRef<StringRef> ExpectedMsgs, Error Err) {
90 ASSERT_TRUE(Err.operator bool());
93 handleErrors(std::move(Err), [&](const ErrorInfoBase &Actual) {
94 ASSERT_LT(WhichMsg, ExpectedMsgs.size());
95 // Use .str(), because googletest doesn't visualise a StringRef
97 EXPECT_EQ(Actual.message(), ExpectedMsgs[WhichMsg++].str());
99 EXPECT_EQ(WhichMsg, ExpectedMsgs.size());
100 EXPECT_FALSE(Remaining);
103 void checkError(StringRef ExpectedMsg, Error Err) {
104 checkError(ArrayRef<StringRef>{ExpectedMsg}, std::move(Err));
107 void checkGetOrParseLineTableEmitsError(StringRef ExpectedMsg,
108 uint64_t Offset = 0) {
109 auto ExpectedLineTable = Line.getOrParseLineTable(
110 LineData, Offset, *Context, nullptr, RecordIssue);
111 EXPECT_FALSE(ExpectedLineTable);
112 EXPECT_TRUE(IssueMessage.empty());
114 checkError(ExpectedMsg, ExpectedLineTable.takeError());
117 std::unique_ptr<Generator> Gen;
118 std::unique_ptr<DWARFContext> Context;
119 DWARFDataExtractor LineData;
121 std::string IssueMessage;
122 std::function<void(StringRef)> RecordIssue;
124 std::function<void(Error)> RecordError;
126 SmallVector<std::unique_ptr<DWARFCompileUnit>, 2> CUs;
127 std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
130 // Fixtures must derive from "Test", but parameterised fixtures from
131 // "TestWithParam". It does not seem possible to inherit from both, so we share
132 // the common state in a separate class, inherited by the two fixture classes.
133 struct DebugLineBasicFixture : public Test, public CommonFixture {};
135 struct DebugLineParameterisedFixture
136 : public TestWithParam<std::pair<uint16_t, DwarfFormat>>,
137 public CommonFixture {
138 void SetUp() { std::tie(Version, Format) = GetParam(); }
144 void checkDefaultPrologue(uint16_t Version, DwarfFormat Format,
145 DWARFDebugLine::Prologue Prologue,
146 uint64_t BodyLength) {
147 // Check version specific fields and values.
149 uint64_t PrologueLength;
153 UnitLength = PrologueLength + 2;
154 EXPECT_EQ(Prologue.MaxOpsPerInst, 1u);
159 UnitLength = PrologueLength + 2;
163 UnitLength = PrologueLength + 4;
164 EXPECT_EQ(Prologue.getAddressSize(), 8u);
165 EXPECT_EQ(Prologue.SegSelectorSize, 0u);
168 llvm_unreachable("unsupported DWARF version");
170 UnitLength += BodyLength + (Format == DWARF32 ? 4 : 8);
172 EXPECT_EQ(Prologue.TotalLength, UnitLength);
173 EXPECT_EQ(Prologue.PrologueLength, PrologueLength);
174 EXPECT_EQ(Prologue.MinInstLength, 1u);
175 EXPECT_EQ(Prologue.DefaultIsStmt, 1u);
176 EXPECT_EQ(Prologue.LineBase, -5);
177 EXPECT_EQ(Prologue.LineRange, 14u);
178 EXPECT_EQ(Prologue.OpcodeBase, 13u);
179 std::vector<uint8_t> ExpectedLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1};
180 EXPECT_EQ(Prologue.StandardOpcodeLengths, ExpectedLengths);
181 ASSERT_EQ(Prologue.IncludeDirectories.size(), 1u);
182 ASSERT_EQ(Prologue.IncludeDirectories[0].getForm(), DW_FORM_string);
183 EXPECT_STREQ(*Prologue.IncludeDirectories[0].getAsCString(), "a dir");
184 ASSERT_EQ(Prologue.FileNames.size(), 1u);
185 ASSERT_EQ(Prologue.FileNames[0].Name.getForm(), DW_FORM_string);
186 EXPECT_STREQ(*Prologue.FileNames[0].Name.getAsCString(), "a file");
189 TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffset) {
190 if (!setupGenerator())
194 checkGetOrParseLineTableEmitsError(
195 "offset 0x00000000 is not a valid debug line section offset", 0);
196 // Repeat to show that an error is reported each time.
197 checkGetOrParseLineTableEmitsError(
198 "offset 0x00000000 is not a valid debug line section offset", 0);
199 // Show that an error is reported for later offsets too.
200 checkGetOrParseLineTableEmitsError(
201 "offset 0x00000001 is not a valid debug line section offset", 1);
204 TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) {
205 if (!setupGenerator())
208 LineTable < = Gen->addLineTable();
209 LT.setCustomPrologue({{0, LineTable::Byte}});
213 checkGetOrParseLineTableEmitsError(
214 "offset 0x00000001 is not a valid debug line section offset", 1);
217 TEST_P(DebugLineParameterisedFixture, GetOrParseLineTableValidTable) {
218 if (!setupGenerator(Version))
221 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +
222 (Format == DWARF64 ? "DWARF64" : "DWARF32"));
224 LineTable < = Gen->addLineTable(Format);
225 LT.addExtendedOpcode(9, DW_LNE_set_address, {{0xadd4e55, LineTable::Quad}});
226 LT.addStandardOpcode(DW_LNS_copy, {});
228 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
230 LineTable <2 = Gen->addLineTable(Format);
231 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x11223344, LineTable::Quad}});
232 LT2.addStandardOpcode(DW_LNS_copy, {});
234 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
235 LT2.addExtendedOpcode(9, DW_LNE_set_address, {{0x55667788, LineTable::Quad}});
236 LT2.addStandardOpcode(DW_LNS_copy, {});
238 LT2.addExtendedOpcode(1, DW_LNE_end_sequence, {});
242 auto ExpectedLineTable =
243 Line.getOrParseLineTable(LineData, 0, *Context, nullptr, RecordIssue);
244 ASSERT_TRUE(ExpectedLineTable.operator bool());
245 EXPECT_TRUE(IssueMessage.empty());
246 const DWARFDebugLine::LineTable *Expected = *ExpectedLineTable;
247 checkDefaultPrologue(Version, Format, Expected->Prologue, 16);
248 EXPECT_EQ(Expected->Sequences.size(), 1);
250 uint64_t SecondOffset =
251 Expected->Prologue.sizeofTotalLength() + Expected->Prologue.TotalLength;
252 IssueMessage.clear();
253 auto ExpectedLineTable2 = Line.getOrParseLineTable(
254 LineData, SecondOffset, *Context, nullptr, RecordIssue);
255 ASSERT_TRUE(ExpectedLineTable2.operator bool());
256 EXPECT_TRUE(IssueMessage.empty());
257 const DWARFDebugLine::LineTable *Expected2 = *ExpectedLineTable2;
258 checkDefaultPrologue(Version, Format, Expected2->Prologue, 32);
259 EXPECT_EQ(Expected2->Sequences.size(), 2u);
261 EXPECT_NE(Expected, Expected2);
263 // Check that if the same offset is requested, the exact same pointer is
265 IssueMessage.clear();
266 auto ExpectedLineTable3 =
267 Line.getOrParseLineTable(LineData, 0, *Context, nullptr, RecordIssue);
268 ASSERT_TRUE(ExpectedLineTable3.operator bool());
269 EXPECT_TRUE(IssueMessage.empty());
270 EXPECT_EQ(Expected, *ExpectedLineTable3);
272 IssueMessage.clear();
273 auto ExpectedLineTable4 = Line.getOrParseLineTable(
274 LineData, SecondOffset, *Context, nullptr, RecordIssue);
275 ASSERT_TRUE(ExpectedLineTable4.operator bool());
276 EXPECT_TRUE(IssueMessage.empty());
277 EXPECT_EQ(Expected2, *ExpectedLineTable4);
279 // TODO: Add tests that show that the body of the programs have been read
283 TEST_F(DebugLineBasicFixture, ErrorForReservedLength) {
284 if (!setupGenerator())
287 LineTable < = Gen->addLineTable();
288 LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
292 checkGetOrParseLineTableEmitsError(
293 "parsing line table prologue at offset 0x00000000 unsupported reserved "
294 "unit length found of value 0xffffff00");
297 TEST_F(DebugLineBasicFixture, ErrorForLowVersion) {
298 if (!setupGenerator())
301 LineTable < = Gen->addLineTable();
302 LT.setCustomPrologue(
303 {{LineTable::Half, LineTable::Long}, {1, LineTable::Half}});
307 checkGetOrParseLineTableEmitsError("parsing line table prologue at offset "
308 "0x00000000 found unsupported version "
312 TEST_F(DebugLineBasicFixture, ErrorForInvalidV5IncludeDirTable) {
313 if (!setupGenerator(5))
316 LineTable < = Gen->addLineTable();
317 LT.setCustomPrologue({
318 {19, LineTable::Long}, // unit length
319 {5, LineTable::Half}, // version
320 {8, LineTable::Byte}, // addr size
321 {0, LineTable::Byte}, // segment selector size
322 {11, LineTable::Long}, // prologue length
323 {1, LineTable::Byte}, // min instruction length
324 {1, LineTable::Byte}, // max ops per instruction
325 {1, LineTable::Byte}, // default is_stmt
326 {0, LineTable::Byte}, // line base
327 {14, LineTable::Byte}, // line range
328 {2, LineTable::Byte}, // opcode base (small to reduce the amount of
330 {0, LineTable::Byte}, // standard opcode lengths
331 {0, LineTable::Byte}, // directory entry format count (should not be
333 {0, LineTable::ULEB}, // directories count
334 {0, LineTable::Byte}, // file name entry format count
335 {0, LineTable::ULEB} // file name entry count
340 checkGetOrParseLineTableEmitsError(
341 "parsing line table prologue at 0x00000000 found an invalid directory or "
342 "file table description at 0x00000014");
345 TEST_P(DebugLineParameterisedFixture, ErrorForTooLargePrologueLength) {
346 if (!setupGenerator(Version))
349 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +
350 (Format == DWARF64 ? "DWARF64" : "DWARF32"));
352 LineTable < = Gen->addLineTable(Format);
353 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
354 ++Prologue.PrologueLength;
355 LT.setPrologue(Prologue);
359 uint64_t ExpectedEnd =
360 Prologue.TotalLength + 1 + Prologue.sizeofTotalLength();
361 checkGetOrParseLineTableEmitsError(
362 (Twine("parsing line table prologue at 0x00000000 should have ended at "
364 Twine::utohexstr(ExpectedEnd) + " but it ended at 0x000000" +
365 Twine::utohexstr(ExpectedEnd - 1))
369 TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) {
370 if (!setupGenerator(Version))
373 SCOPED_TRACE("Checking Version " + std::to_string(Version) + ", Format " +
374 (Format == DWARF64 ? "DWARF64" : "DWARF32"));
376 LineTable < = Gen->addLineTable(Format);
377 DWARFDebugLine::Prologue Prologue = LT.createBasicPrologue();
378 // FIXME: Ideally, we'd test for 1 less than expected, but the code does not
379 // currently fail if missing only the terminator of a v2-4 file table.
381 Prologue.PrologueLength -= 2;
383 Prologue.PrologueLength -= 1;
384 LT.setPrologue(Prologue);
388 uint64_t ExpectedEnd =
389 Prologue.TotalLength - 1 + Prologue.sizeofTotalLength();
392 checkGetOrParseLineTableEmitsError(
393 (Twine("parsing line table prologue at 0x00000000 should have ended at "
395 Twine::utohexstr(ExpectedEnd) + " but it ended at 0x000000" +
396 Twine::utohexstr(ExpectedEnd + 1))
400 INSTANTIATE_TEST_CASE_P(
401 LineTableTestParams, DebugLineParameterisedFixture,
402 Values(std::make_pair(
403 2, DWARF32), // Test lower-bound of v2-3 fields and DWARF32.
404 std::make_pair(3, DWARF32), // Test upper-bound of v2-3 fields.
405 std::make_pair(4, DWARF64), // Test v4 fields and DWARF64.
406 std::make_pair(5, DWARF32), std::make_pair(5, DWARF64)),);
408 TEST_F(DebugLineBasicFixture, ErrorForInvalidExtendedOpcodeLength) {
409 if (!setupGenerator())
412 LineTable < = Gen->addLineTable();
413 // The Length should be 1 for an end sequence opcode.
414 LT.addExtendedOpcode(2, DW_LNE_end_sequence, {});
418 checkGetOrParseLineTableEmitsError("unexpected line op length at offset "
419 "0x00000030 expected 0x02 found 0x01");
422 TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) {
423 if (!setupGenerator())
426 LineTable < = Gen->addLineTable();
427 // The line data extractor expects size 8 (Quad) addresses.
428 LT.addExtendedOpcode(5, DW_LNE_set_address, {{0x11223344, LineTable::Long}});
429 LT.addStandardOpcode(DW_LNS_copy, {});
431 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
435 checkGetOrParseLineTableEmitsError(
436 "mismatching address size at offset 0x00000030 expected 0x08 found 0x04");
439 TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) {
440 if (!setupGenerator())
443 LineTable < = Gen->addLineTable();
444 LT.addExtendedOpcode(9, DW_LNE_set_address,
445 {{0x1122334455667788, LineTable::Quad}});
446 LT.addStandardOpcode(DW_LNS_copy, {});
448 LT.addExtendedOpcode(1, DW_LNE_end_sequence, {});
449 LT.addExtendedOpcode(9, DW_LNE_set_address,
450 {{0x99aabbccddeeff00, LineTable::Quad}});
451 LT.addStandardOpcode(DW_LNS_copy, {});
457 auto ExpectedLineTable =
458 Line.getOrParseLineTable(LineData, 0, *Context, nullptr, RecordIssue);
459 EXPECT_EQ(IssueMessage,
460 "last sequence in debug line table is not terminated!");
461 ASSERT_TRUE(ExpectedLineTable.operator bool());
462 EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 6);
463 // The unterminated sequence is not added to the sequence list.
464 EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1);
467 TEST_F(DebugLineBasicFixture, ParserParsesCorrectly) {
468 if (!setupGenerator())
471 DWARFDebugLine::SectionParser Parser = setupParser();
473 EXPECT_EQ(Parser.getOffset(), 0u);
474 ASSERT_FALSE(Parser.done());
476 DWARFDebugLine::LineTable Parsed = Parser.parseNext(RecordIssue, RecordError);
477 checkDefaultPrologue(4, DWARF32, Parsed.Prologue, 16);
478 EXPECT_EQ(Parsed.Sequences.size(), 1u);
479 EXPECT_EQ(Parser.getOffset(), 62u);
480 ASSERT_FALSE(Parser.done());
482 DWARFDebugLine::LineTable Parsed2 =
483 Parser.parseNext(RecordIssue, RecordError);
484 checkDefaultPrologue(4, DWARF64, Parsed2.Prologue, 16);
485 EXPECT_EQ(Parsed2.Sequences.size(), 1u);
486 EXPECT_EQ(Parser.getOffset(), 136u);
487 EXPECT_TRUE(Parser.done());
489 EXPECT_TRUE(IssueMessage.empty());
490 EXPECT_FALSE(FoundError);
493 TEST_F(DebugLineBasicFixture, ParserSkipsCorrectly) {
494 if (!setupGenerator())
497 DWARFDebugLine::SectionParser Parser = setupParser();
499 EXPECT_EQ(Parser.getOffset(), 0u);
500 ASSERT_FALSE(Parser.done());
502 Parser.skip(RecordError);
503 EXPECT_EQ(Parser.getOffset(), 62u);
504 ASSERT_FALSE(Parser.done());
506 Parser.skip(RecordError);
507 EXPECT_EQ(Parser.getOffset(), 136u);
508 EXPECT_TRUE(Parser.done());
510 EXPECT_FALSE(FoundError);
513 TEST_F(DebugLineBasicFixture, ParserAlwaysDoneForEmptySection) {
514 if (!setupGenerator())
518 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
520 EXPECT_TRUE(Parser.done());
523 TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenParsing) {
524 if (!setupGenerator())
527 LineTable < = Gen->addLineTable();
528 LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
532 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
533 Parser.parseNext(RecordIssue, RecordError);
535 EXPECT_EQ(Parser.getOffset(), 4u);
536 EXPECT_TRUE(Parser.done());
537 EXPECT_TRUE(IssueMessage.empty());
539 checkError("parsing line table prologue at offset 0x00000000 unsupported "
540 "reserved unit length found of value 0xffffff00",
541 std::move(FoundError));
544 TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) {
545 if (!setupGenerator())
548 LineTable < = Gen->addLineTable();
549 LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
553 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
554 Parser.skip(RecordError);
556 EXPECT_EQ(Parser.getOffset(), 4u);
557 EXPECT_TRUE(Parser.done());
559 checkError("parsing line table prologue at offset 0x00000000 unsupported "
560 "reserved unit length found of value 0xffffff00",
561 std::move(FoundError));
564 TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {
565 if (!setupGenerator())
568 LineTable < = Gen->addLineTable(DWARF32);
569 LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}});
570 LineTable <2 = Gen->addLineTable(DWARF32);
571 LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}});
574 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
575 Parser.parseNext(RecordIssue, RecordError);
576 ASSERT_FALSE(Parser.done());
577 Parser.parseNext(RecordIssue, RecordError);
579 EXPECT_TRUE(Parser.done());
580 EXPECT_TRUE(IssueMessage.empty());
582 checkError({"parsing line table prologue at offset 0x00000000 found "
583 "unsupported version 0x00",
584 "parsing line table prologue at offset 0x00000006 found "
585 "unsupported version 0x01"},
586 std::move(FoundError));
589 TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) {
590 if (!setupGenerator())
593 LineTable < = Gen->addLineTable(DWARF32);
594 LT.addExtendedOpcode(0x42, DW_LNE_end_sequence, {});
595 LineTable <2 = Gen->addLineTable(DWARF32);
596 LT2.addExtendedOpcode(9, DW_LNE_set_address,
597 {{0x1234567890abcdef, LineTable::Quad}});
598 LT2.addStandardOpcode(DW_LNS_copy, {});
602 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
603 Parser.parseNext(RecordIssue, RecordError);
604 EXPECT_TRUE(IssueMessage.empty());
605 ASSERT_FALSE(Parser.done());
607 "unexpected line op length at offset 0x00000030 expected 0x42 found 0x01",
608 std::move(FoundError));
610 // Reset the error state so that it does not confuse the next set of checks.
611 FoundError = Error::success();
612 Parser.parseNext(RecordIssue, RecordError);
614 EXPECT_TRUE(Parser.done());
615 EXPECT_EQ(IssueMessage,
616 "last sequence in debug line table is not terminated!");
617 EXPECT_TRUE(!FoundError);
620 TEST_F(DebugLineBasicFixture,
621 ParserReportsPrologueErrorsInEachTableWhenSkipping) {
622 if (!setupGenerator())
625 LineTable < = Gen->addLineTable(DWARF32);
626 LT.setCustomPrologue({{2, LineTable::Long}, {0, LineTable::Half}});
627 LineTable <2 = Gen->addLineTable(DWARF32);
628 LT2.setCustomPrologue({{2, LineTable::Long}, {1, LineTable::Half}});
631 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
632 Parser.skip(RecordError);
633 ASSERT_FALSE(Parser.done());
634 Parser.skip(RecordError);
636 EXPECT_TRUE(Parser.done());
638 checkError({"parsing line table prologue at offset 0x00000000 found "
639 "unsupported version 0x00",
640 "parsing line table prologue at offset 0x00000006 found "
641 "unsupported version 0x01"},
642 std::move(FoundError));
645 TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) {
646 if (!setupGenerator())
649 LineTable < = Gen->addLineTable(DWARF32);
650 LT.addExtendedOpcode(42, DW_LNE_end_sequence, {});
653 DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs);
654 Parser.skip(RecordError);
656 EXPECT_TRUE(Parser.done());
657 EXPECT_TRUE(!FoundError);
660 } // end anonymous namespace