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), Recoverable(Error::success()),
29 RecordRecoverable(std::bind(&CommonFixture::recordRecoverable
, this,
30 std::placeholders::_1
)),
31 Unrecoverable(Error::success()),
32 RecordUnrecoverable(std::bind(&CommonFixture::recordUnrecoverable
, this,
33 std::placeholders::_1
)){};
36 EXPECT_FALSE(Recoverable
);
37 EXPECT_FALSE(Unrecoverable
);
40 bool setupGenerator(uint16_t Version
= 4) {
41 Triple T
= getHostTripleForAddrSize(8);
42 if (!isConfigurationSupported(T
))
44 auto ExpectedGenerator
= Generator::create(T
, Version
);
45 if (ExpectedGenerator
)
46 Gen
.reset(ExpectedGenerator
->release());
51 Context
= createContext();
52 assert(Context
!= nullptr && "test state is not valid");
53 const DWARFObject
&Obj
= Context
->getDWARFObj();
54 LineData
= DWARFDataExtractor(Obj
, Obj
.getLineSection(),
55 sys::IsLittleEndianHost
, 8);
58 std::unique_ptr
<DWARFContext
> createContext() {
61 StringRef FileBytes
= Gen
->generate();
62 MemoryBufferRef
FileBuffer(FileBytes
, "dwarf");
63 auto Obj
= object::ObjectFile::createObjectFile(FileBuffer
);
65 return DWARFContext::create(**Obj
);
69 DWARFDebugLine::SectionParser
setupParser() {
70 LineTable
<
= Gen
->addLineTable(DWARF32
);
71 LT
.addExtendedOpcode(9, DW_LNE_set_address
, {{0xadd4e55, LineTable::Quad
}});
72 LT
.addStandardOpcode(DW_LNS_copy
, {});
74 LT
.addExtendedOpcode(1, DW_LNE_end_sequence
, {});
76 LineTable
<2
= Gen
->addLineTable(DWARF64
);
77 LT2
.addExtendedOpcode(9, DW_LNE_set_address
,
78 {{0x11223344, LineTable::Quad
}});
79 LT2
.addStandardOpcode(DW_LNS_copy
, {});
81 LT2
.addExtendedOpcode(1, DW_LNE_end_sequence
, {});
85 return DWARFDebugLine::SectionParser(LineData
, *Context
, CUs
, TUs
);
88 void recordRecoverable(Error Err
) {
89 Recoverable
= joinErrors(std::move(Recoverable
), std::move(Err
));
91 void recordUnrecoverable(Error Err
) {
92 Unrecoverable
= joinErrors(std::move(Unrecoverable
), std::move(Err
));
95 void checkError(ArrayRef
<StringRef
> ExpectedMsgs
, Error Err
) {
96 ASSERT_TRUE(Err
.operator bool());
99 handleErrors(std::move(Err
), [&](const ErrorInfoBase
&Actual
) {
100 ASSERT_LT(WhichMsg
, ExpectedMsgs
.size());
101 // Use .str(), because googletest doesn't visualise a StringRef
103 EXPECT_EQ(Actual
.message(), ExpectedMsgs
[WhichMsg
++].str());
105 EXPECT_EQ(WhichMsg
, ExpectedMsgs
.size());
106 EXPECT_FALSE(Remaining
);
109 void checkError(StringRef ExpectedMsg
, Error Err
) {
110 checkError(ArrayRef
<StringRef
>{ExpectedMsg
}, std::move(Err
));
113 void checkGetOrParseLineTableEmitsError(StringRef ExpectedMsg
,
114 uint64_t Offset
= 0) {
115 auto ExpectedLineTable
= Line
.getOrParseLineTable(
116 LineData
, Offset
, *Context
, nullptr, RecordRecoverable
);
117 EXPECT_FALSE(ExpectedLineTable
);
118 EXPECT_FALSE(Recoverable
);
120 checkError(ExpectedMsg
, ExpectedLineTable
.takeError());
123 std::unique_ptr
<Generator
> Gen
;
124 std::unique_ptr
<DWARFContext
> Context
;
125 DWARFDataExtractor LineData
;
128 std::function
<void(Error
)> RecordRecoverable
;
130 std::function
<void(Error
)> RecordUnrecoverable
;
132 SmallVector
<std::unique_ptr
<DWARFUnit
>, 2> CUs
;
133 SmallVector
<std::unique_ptr
<DWARFUnit
>, 2> TUs
;
136 // Fixtures must derive from "Test", but parameterised fixtures from
137 // "TestWithParam". It does not seem possible to inherit from both, so we share
138 // the common state in a separate class, inherited by the two fixture classes.
139 struct DebugLineBasicFixture
: public Test
, public CommonFixture
{};
141 struct DebugLineParameterisedFixture
142 : public TestWithParam
<std::pair
<uint16_t, DwarfFormat
>>,
143 public CommonFixture
{
144 void SetUp() { std::tie(Version
, Format
) = GetParam(); }
150 void checkDefaultPrologue(uint16_t Version
, DwarfFormat Format
,
151 DWARFDebugLine::Prologue Prologue
,
152 uint64_t BodyLength
) {
153 // Check version specific fields and values.
155 uint64_t PrologueLength
;
159 UnitLength
= PrologueLength
+ 2;
160 EXPECT_EQ(Prologue
.MaxOpsPerInst
, 1u);
165 UnitLength
= PrologueLength
+ 2;
169 UnitLength
= PrologueLength
+ 4;
170 EXPECT_EQ(Prologue
.getAddressSize(), 8u);
171 EXPECT_EQ(Prologue
.SegSelectorSize
, 0u);
174 llvm_unreachable("unsupported DWARF version");
176 UnitLength
+= BodyLength
+ (Format
== DWARF32
? 4 : 8);
178 EXPECT_EQ(Prologue
.TotalLength
, UnitLength
);
179 EXPECT_EQ(Prologue
.PrologueLength
, PrologueLength
);
180 EXPECT_EQ(Prologue
.MinInstLength
, 1u);
181 EXPECT_EQ(Prologue
.DefaultIsStmt
, 1u);
182 EXPECT_EQ(Prologue
.LineBase
, -5);
183 EXPECT_EQ(Prologue
.LineRange
, 14u);
184 EXPECT_EQ(Prologue
.OpcodeBase
, 13u);
185 std::vector
<uint8_t> ExpectedLengths
= {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1};
186 EXPECT_EQ(Prologue
.StandardOpcodeLengths
, ExpectedLengths
);
187 ASSERT_EQ(Prologue
.IncludeDirectories
.size(), 1u);
188 ASSERT_EQ(Prologue
.IncludeDirectories
[0].getForm(), DW_FORM_string
);
189 EXPECT_STREQ(*Prologue
.IncludeDirectories
[0].getAsCString(), "a dir");
190 ASSERT_EQ(Prologue
.FileNames
.size(), 1u);
191 ASSERT_EQ(Prologue
.FileNames
[0].Name
.getForm(), DW_FORM_string
);
192 EXPECT_STREQ(*Prologue
.FileNames
[0].Name
.getAsCString(), "a file");
195 TEST_F(DebugLineBasicFixture
, GetOrParseLineTableAtInvalidOffset
) {
196 if (!setupGenerator())
200 checkGetOrParseLineTableEmitsError(
201 "offset 0x00000000 is not a valid debug line section offset", 0);
202 // Repeat to show that an error is reported each time.
203 checkGetOrParseLineTableEmitsError(
204 "offset 0x00000000 is not a valid debug line section offset", 0);
205 // Show that an error is reported for later offsets too.
206 checkGetOrParseLineTableEmitsError(
207 "offset 0x00000001 is not a valid debug line section offset", 1);
210 TEST_F(DebugLineBasicFixture
, GetOrParseLineTableAtInvalidOffsetAfterData
) {
211 if (!setupGenerator())
214 LineTable
<
= Gen
->addLineTable();
215 LT
.setCustomPrologue({{0, LineTable::Byte
}});
219 checkGetOrParseLineTableEmitsError(
220 "offset 0x00000001 is not a valid debug line section offset", 1);
223 TEST_P(DebugLineParameterisedFixture
, GetOrParseLineTableValidTable
) {
224 if (!setupGenerator(Version
))
227 SCOPED_TRACE("Checking Version " + std::to_string(Version
) + ", Format " +
228 (Format
== DWARF64
? "DWARF64" : "DWARF32"));
230 LineTable
<
= Gen
->addLineTable(Format
);
231 LT
.addExtendedOpcode(9, DW_LNE_set_address
, {{0xadd4e55, LineTable::Quad
}});
232 LT
.addStandardOpcode(DW_LNS_copy
, {});
234 LT
.addExtendedOpcode(1, DW_LNE_end_sequence
, {});
236 LineTable
<2
= Gen
->addLineTable(Format
);
237 LT2
.addExtendedOpcode(9, DW_LNE_set_address
, {{0x11223344, LineTable::Quad
}});
238 LT2
.addStandardOpcode(DW_LNS_copy
, {});
240 LT2
.addExtendedOpcode(1, DW_LNE_end_sequence
, {});
241 LT2
.addExtendedOpcode(9, DW_LNE_set_address
, {{0x55667788, LineTable::Quad
}});
242 LT2
.addStandardOpcode(DW_LNS_copy
, {});
244 LT2
.addExtendedOpcode(1, DW_LNE_end_sequence
, {});
248 auto ExpectedLineTable
= Line
.getOrParseLineTable(LineData
, 0, *Context
,
249 nullptr, RecordRecoverable
);
250 ASSERT_TRUE(ExpectedLineTable
.operator bool());
251 EXPECT_FALSE(Recoverable
);
252 const DWARFDebugLine::LineTable
*Expected
= *ExpectedLineTable
;
253 checkDefaultPrologue(Version
, Format
, Expected
->Prologue
, 16);
254 EXPECT_EQ(Expected
->Sequences
.size(), 1u);
256 uint64_t SecondOffset
=
257 Expected
->Prologue
.sizeofTotalLength() + Expected
->Prologue
.TotalLength
;
258 Recoverable
= Error::success();
259 auto ExpectedLineTable2
= Line
.getOrParseLineTable(
260 LineData
, SecondOffset
, *Context
, nullptr, RecordRecoverable
);
261 ASSERT_TRUE(ExpectedLineTable2
.operator bool());
262 EXPECT_FALSE(Recoverable
);
263 const DWARFDebugLine::LineTable
*Expected2
= *ExpectedLineTable2
;
264 checkDefaultPrologue(Version
, Format
, Expected2
->Prologue
, 32);
265 EXPECT_EQ(Expected2
->Sequences
.size(), 2u);
267 EXPECT_NE(Expected
, Expected2
);
269 // Check that if the same offset is requested, the exact same pointer is
271 Recoverable
= Error::success();
272 auto ExpectedLineTable3
= Line
.getOrParseLineTable(
273 LineData
, 0, *Context
, nullptr, RecordRecoverable
);
274 ASSERT_TRUE(ExpectedLineTable3
.operator bool());
275 EXPECT_FALSE(Recoverable
);
276 EXPECT_EQ(Expected
, *ExpectedLineTable3
);
278 Recoverable
= Error::success();
279 auto ExpectedLineTable4
= Line
.getOrParseLineTable(
280 LineData
, SecondOffset
, *Context
, nullptr, RecordRecoverable
);
281 ASSERT_TRUE(ExpectedLineTable4
.operator bool());
282 EXPECT_FALSE(Recoverable
);
283 EXPECT_EQ(Expected2
, *ExpectedLineTable4
);
285 // TODO: Add tests that show that the body of the programs have been read
289 TEST_F(DebugLineBasicFixture
, ErrorForReservedLength
) {
290 if (!setupGenerator())
293 LineTable
<
= Gen
->addLineTable();
294 LT
.setCustomPrologue({{0xffffff00, LineTable::Long
}});
298 checkGetOrParseLineTableEmitsError(
299 "parsing line table prologue at offset 0x00000000 unsupported reserved "
300 "unit length found of value 0xffffff00");
303 TEST_F(DebugLineBasicFixture
, ErrorForLowVersion
) {
304 if (!setupGenerator())
307 LineTable
<
= Gen
->addLineTable();
308 LT
.setCustomPrologue(
309 {{LineTable::Half
, LineTable::Long
}, {1, LineTable::Half
}});
313 checkGetOrParseLineTableEmitsError("parsing line table prologue at offset "
314 "0x00000000 found unsupported version "
318 TEST_F(DebugLineBasicFixture
, ErrorForInvalidV5IncludeDirTable
) {
319 if (!setupGenerator(5))
322 LineTable
<
= Gen
->addLineTable();
323 LT
.setCustomPrologue({
324 {19, LineTable::Long
}, // unit length
325 {5, LineTable::Half
}, // version
326 {8, LineTable::Byte
}, // addr size
327 {0, LineTable::Byte
}, // segment selector size
328 {11, LineTable::Long
}, // prologue length
329 {1, LineTable::Byte
}, // min instruction length
330 {1, LineTable::Byte
}, // max ops per instruction
331 {1, LineTable::Byte
}, // default is_stmt
332 {0, LineTable::Byte
}, // line base
333 {14, LineTable::Byte
}, // line range
334 {2, LineTable::Byte
}, // opcode base (small to reduce the amount of
336 {0, LineTable::Byte
}, // standard opcode lengths
337 {0, LineTable::Byte
}, // directory entry format count (should not be
339 {0, LineTable::ULEB
}, // directories count
340 {0, LineTable::Byte
}, // file name entry format count
341 {0, LineTable::ULEB
} // file name entry count
346 checkGetOrParseLineTableEmitsError(
347 "parsing line table prologue at 0x00000000 found an invalid directory or "
348 "file table description at 0x00000014");
351 TEST_P(DebugLineParameterisedFixture
, ErrorForTooLargePrologueLength
) {
352 if (!setupGenerator(Version
))
355 SCOPED_TRACE("Checking Version " + std::to_string(Version
) + ", Format " +
356 (Format
== DWARF64
? "DWARF64" : "DWARF32"));
358 LineTable
<
= Gen
->addLineTable(Format
);
359 DWARFDebugLine::Prologue Prologue
= LT
.createBasicPrologue();
360 ++Prologue
.PrologueLength
;
361 LT
.setPrologue(Prologue
);
365 uint64_t ExpectedEnd
=
366 Prologue
.TotalLength
+ 1 + Prologue
.sizeofTotalLength();
367 checkGetOrParseLineTableEmitsError(
368 (Twine("parsing line table prologue at 0x00000000 should have ended at "
370 Twine::utohexstr(ExpectedEnd
) + " but it ended at 0x000000" +
371 Twine::utohexstr(ExpectedEnd
- 1))
375 TEST_P(DebugLineParameterisedFixture
, ErrorForTooShortPrologueLength
) {
376 if (!setupGenerator(Version
))
379 SCOPED_TRACE("Checking Version " + std::to_string(Version
) + ", Format " +
380 (Format
== DWARF64
? "DWARF64" : "DWARF32"));
382 LineTable
<
= Gen
->addLineTable(Format
);
383 DWARFDebugLine::Prologue Prologue
= LT
.createBasicPrologue();
384 // FIXME: Ideally, we'd test for 1 less than expected, but the code does not
385 // currently fail if missing only the terminator of a v2-4 file table.
387 Prologue
.PrologueLength
-= 2;
389 Prologue
.PrologueLength
-= 1;
390 LT
.setPrologue(Prologue
);
394 uint64_t ExpectedEnd
=
395 Prologue
.TotalLength
- 1 + Prologue
.sizeofTotalLength();
398 checkGetOrParseLineTableEmitsError(
399 (Twine("parsing line table prologue at 0x00000000 should have ended at "
401 Twine::utohexstr(ExpectedEnd
) + " but it ended at 0x000000" +
402 Twine::utohexstr(ExpectedEnd
+ 1))
406 INSTANTIATE_TEST_CASE_P(
407 LineTableTestParams
, DebugLineParameterisedFixture
,
408 Values(std::make_pair(
409 2, DWARF32
), // Test lower-bound of v2-3 fields and DWARF32.
410 std::make_pair(3, DWARF32
), // Test upper-bound of v2-3 fields.
411 std::make_pair(4, DWARF64
), // Test v4 fields and DWARF64.
412 std::make_pair(5, DWARF32
), std::make_pair(5, DWARF64
)), );
414 TEST_F(DebugLineBasicFixture
, ErrorForInvalidExtendedOpcodeLength
) {
415 if (!setupGenerator())
418 LineTable
<
= Gen
->addLineTable();
419 // The Length should be 1 for an end sequence opcode.
420 LT
.addExtendedOpcode(2, DW_LNE_end_sequence
, {});
424 checkGetOrParseLineTableEmitsError("unexpected line op length at offset "
425 "0x00000030 expected 0x02 found 0x01");
428 TEST_F(DebugLineBasicFixture
, ErrorForMismatchedAddressSize
) {
429 if (!setupGenerator())
432 LineTable
<
= Gen
->addLineTable();
433 // The line data extractor expects size 8 (Quad) addresses.
434 LT
.addExtendedOpcode(5, DW_LNE_set_address
, {{0x11223344, LineTable::Long
}});
435 LT
.addStandardOpcode(DW_LNS_copy
, {});
437 LT
.addExtendedOpcode(1, DW_LNE_end_sequence
, {});
441 checkGetOrParseLineTableEmitsError(
442 "mismatching address size at offset 0x00000030 expected 0x08 found 0x04");
445 TEST_F(DebugLineBasicFixture
, CallbackUsedForUnterminatedSequence
) {
446 if (!setupGenerator())
449 LineTable
<
= Gen
->addLineTable();
450 LT
.addExtendedOpcode(9, DW_LNE_set_address
,
451 {{0x1122334455667788, LineTable::Quad
}});
452 LT
.addStandardOpcode(DW_LNS_copy
, {});
454 LT
.addExtendedOpcode(1, DW_LNE_end_sequence
, {});
455 LT
.addExtendedOpcode(9, DW_LNE_set_address
,
456 {{0x99aabbccddeeff00, LineTable::Quad
}});
457 LT
.addStandardOpcode(DW_LNS_copy
, {});
463 auto ExpectedLineTable
= Line
.getOrParseLineTable(LineData
, 0, *Context
,
464 nullptr, RecordRecoverable
);
465 checkError("last sequence in debug line table is not terminated!",
466 std::move(Recoverable
));
467 ASSERT_TRUE(ExpectedLineTable
.operator bool());
468 EXPECT_EQ((*ExpectedLineTable
)->Rows
.size(), 6u);
469 // The unterminated sequence is not added to the sequence list.
470 EXPECT_EQ((*ExpectedLineTable
)->Sequences
.size(), 1u);
473 TEST_F(DebugLineBasicFixture
, ParserParsesCorrectly
) {
474 if (!setupGenerator())
477 DWARFDebugLine::SectionParser Parser
= setupParser();
479 EXPECT_EQ(Parser
.getOffset(), 0u);
480 ASSERT_FALSE(Parser
.done());
482 DWARFDebugLine::LineTable Parsed
=
483 Parser
.parseNext(RecordRecoverable
, RecordUnrecoverable
);
484 checkDefaultPrologue(4, DWARF32
, Parsed
.Prologue
, 16);
485 EXPECT_EQ(Parsed
.Sequences
.size(), 1u);
486 EXPECT_EQ(Parser
.getOffset(), 62u);
487 ASSERT_FALSE(Parser
.done());
489 DWARFDebugLine::LineTable Parsed2
=
490 Parser
.parseNext(RecordRecoverable
, RecordUnrecoverable
);
491 checkDefaultPrologue(4, DWARF64
, Parsed2
.Prologue
, 16);
492 EXPECT_EQ(Parsed2
.Sequences
.size(), 1u);
493 EXPECT_EQ(Parser
.getOffset(), 136u);
494 EXPECT_TRUE(Parser
.done());
496 EXPECT_FALSE(Recoverable
);
497 EXPECT_FALSE(Unrecoverable
);
500 TEST_F(DebugLineBasicFixture
, ParserSkipsCorrectly
) {
501 if (!setupGenerator())
504 DWARFDebugLine::SectionParser Parser
= setupParser();
506 EXPECT_EQ(Parser
.getOffset(), 0u);
507 ASSERT_FALSE(Parser
.done());
509 Parser
.skip(RecordUnrecoverable
);
510 EXPECT_EQ(Parser
.getOffset(), 62u);
511 ASSERT_FALSE(Parser
.done());
513 Parser
.skip(RecordUnrecoverable
);
514 EXPECT_EQ(Parser
.getOffset(), 136u);
515 EXPECT_TRUE(Parser
.done());
517 EXPECT_FALSE(Unrecoverable
);
520 TEST_F(DebugLineBasicFixture
, ParserAlwaysDoneForEmptySection
) {
521 if (!setupGenerator())
525 DWARFDebugLine::SectionParser
Parser(LineData
, *Context
, CUs
, TUs
);
527 EXPECT_TRUE(Parser
.done());
530 TEST_F(DebugLineBasicFixture
, ParserMovesToEndForBadLengthWhenParsing
) {
531 if (!setupGenerator())
534 LineTable
<
= Gen
->addLineTable();
535 LT
.setCustomPrologue({{0xffffff00, LineTable::Long
}});
539 DWARFDebugLine::SectionParser
Parser(LineData
, *Context
, CUs
, TUs
);
540 Parser
.parseNext(RecordRecoverable
, RecordUnrecoverable
);
542 EXPECT_EQ(Parser
.getOffset(), 4u);
543 EXPECT_TRUE(Parser
.done());
544 EXPECT_FALSE(Recoverable
);
546 checkError("parsing line table prologue at offset 0x00000000 unsupported "
547 "reserved unit length found of value 0xffffff00",
548 std::move(Unrecoverable
));
551 TEST_F(DebugLineBasicFixture
, ParserMovesToEndForBadLengthWhenSkipping
) {
552 if (!setupGenerator())
555 LineTable
<
= Gen
->addLineTable();
556 LT
.setCustomPrologue({{0xffffff00, LineTable::Long
}});
560 DWARFDebugLine::SectionParser
Parser(LineData
, *Context
, CUs
, TUs
);
561 Parser
.skip(RecordUnrecoverable
);
563 EXPECT_EQ(Parser
.getOffset(), 4u);
564 EXPECT_TRUE(Parser
.done());
566 checkError("parsing line table prologue at offset 0x00000000 unsupported "
567 "reserved unit length found of value 0xffffff00",
568 std::move(Unrecoverable
));
571 TEST_F(DebugLineBasicFixture
, ParserReportsFirstErrorInEachTableWhenParsing
) {
572 if (!setupGenerator())
575 LineTable
<
= Gen
->addLineTable(DWARF32
);
576 LT
.setCustomPrologue({{2, LineTable::Long
}, {0, LineTable::Half
}});
577 LineTable
<2
= Gen
->addLineTable(DWARF32
);
578 LT2
.setCustomPrologue({{2, LineTable::Long
}, {1, LineTable::Half
}});
581 DWARFDebugLine::SectionParser
Parser(LineData
, *Context
, CUs
, TUs
);
582 Parser
.parseNext(RecordRecoverable
, RecordUnrecoverable
);
583 ASSERT_FALSE(Parser
.done());
584 Parser
.parseNext(RecordRecoverable
, RecordUnrecoverable
);
586 EXPECT_TRUE(Parser
.done());
587 EXPECT_FALSE(Recoverable
);
589 checkError({"parsing line table prologue at offset 0x00000000 found "
590 "unsupported version 0x00",
591 "parsing line table prologue at offset 0x00000006 found "
592 "unsupported version 0x01"},
593 std::move(Unrecoverable
));
596 TEST_F(DebugLineBasicFixture
, ParserReportsNonPrologueProblemsWhenParsing
) {
597 if (!setupGenerator())
600 LineTable
<
= Gen
->addLineTable(DWARF32
);
601 LT
.addExtendedOpcode(0x42, DW_LNE_end_sequence
, {});
602 LineTable
<2
= Gen
->addLineTable(DWARF32
);
603 LT2
.addExtendedOpcode(9, DW_LNE_set_address
,
604 {{0x1234567890abcdef, LineTable::Quad
}});
605 LT2
.addStandardOpcode(DW_LNS_copy
, {});
609 DWARFDebugLine::SectionParser
Parser(LineData
, *Context
, CUs
, TUs
);
610 Parser
.parseNext(RecordRecoverable
, RecordUnrecoverable
);
611 EXPECT_FALSE(Recoverable
);
612 ASSERT_FALSE(Parser
.done());
614 "unexpected line op length at offset 0x00000030 expected 0x42 found 0x01",
615 std::move(Unrecoverable
));
617 // Reset the error state so that it does not confuse the next set of checks.
618 Unrecoverable
= Error::success();
619 Parser
.parseNext(RecordRecoverable
, RecordUnrecoverable
);
621 EXPECT_TRUE(Parser
.done());
622 checkError("last sequence in debug line table is not terminated!",
623 std::move(Recoverable
));
624 EXPECT_FALSE(Unrecoverable
);
627 TEST_F(DebugLineBasicFixture
,
628 ParserReportsPrologueErrorsInEachTableWhenSkipping
) {
629 if (!setupGenerator())
632 LineTable
<
= Gen
->addLineTable(DWARF32
);
633 LT
.setCustomPrologue({{2, LineTable::Long
}, {0, LineTable::Half
}});
634 LineTable
<2
= Gen
->addLineTable(DWARF32
);
635 LT2
.setCustomPrologue({{2, LineTable::Long
}, {1, LineTable::Half
}});
638 DWARFDebugLine::SectionParser
Parser(LineData
, *Context
, CUs
, TUs
);
639 Parser
.skip(RecordUnrecoverable
);
640 ASSERT_FALSE(Parser
.done());
641 Parser
.skip(RecordUnrecoverable
);
643 EXPECT_TRUE(Parser
.done());
645 checkError({"parsing line table prologue at offset 0x00000000 found "
646 "unsupported version 0x00",
647 "parsing line table prologue at offset 0x00000006 found "
648 "unsupported version 0x01"},
649 std::move(Unrecoverable
));
652 TEST_F(DebugLineBasicFixture
, ParserIgnoresNonPrologueErrorsWhenSkipping
) {
653 if (!setupGenerator())
656 LineTable
<
= Gen
->addLineTable(DWARF32
);
657 LT
.addExtendedOpcode(42, DW_LNE_end_sequence
, {});
660 DWARFDebugLine::SectionParser
Parser(LineData
, *Context
, CUs
, TUs
);
661 Parser
.skip(RecordUnrecoverable
);
663 EXPECT_TRUE(Parser
.done());
664 EXPECT_FALSE(Unrecoverable
);
667 } // end anonymous namespace