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