1ca1b9943SAlex Langford //===- llvm/unittest/DebugInfo/DWARFDebugAbbrevTest.cpp -------------------===//
2ca1b9943SAlex Langford //
3ca1b9943SAlex Langford // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ca1b9943SAlex Langford // See https://llvm.org/LICENSE.txt for license information.
5ca1b9943SAlex Langford // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ca1b9943SAlex Langford //
7ca1b9943SAlex Langford //===----------------------------------------------------------------------===//
8ca1b9943SAlex Langford
9ca1b9943SAlex Langford #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
10ca1b9943SAlex Langford #include "llvm/BinaryFormat/Dwarf.h"
11ca1b9943SAlex Langford #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
12ca1b9943SAlex Langford #include "llvm/Support/DataExtractor.h"
13ca1b9943SAlex Langford #include "llvm/Support/LEB128.h"
14ca1b9943SAlex Langford #include "llvm/Support/MemoryBuffer.h"
15ca1b9943SAlex Langford #include "llvm/Testing/Support/Error.h"
16ca1b9943SAlex Langford #include "gtest/gtest.h"
17ca1b9943SAlex Langford
18ca1b9943SAlex Langford using namespace llvm;
19ca1b9943SAlex Langford using namespace dwarf;
20ca1b9943SAlex Langford
21ad66e9beSAlex Langford enum OrderKind : bool { InOrder, OutOfOrder };
22ca1b9943SAlex Langford
writeValidAbbreviationDeclarations(raw_ostream & OS,uint32_t FirstCode,OrderKind Order)2371572642SAlex Langford void writeValidAbbreviationDeclarations(raw_ostream &OS, uint32_t FirstCode,
24ad66e9beSAlex Langford OrderKind Order) {
25ca1b9943SAlex Langford encodeULEB128(FirstCode, OS);
26ca1b9943SAlex Langford encodeULEB128(DW_TAG_compile_unit, OS);
27ca1b9943SAlex Langford OS << static_cast<uint8_t>(DW_CHILDREN_yes);
28ca1b9943SAlex Langford encodeULEB128(DW_AT_name, OS);
29ca1b9943SAlex Langford encodeULEB128(DW_FORM_strp, OS);
30ca1b9943SAlex Langford encodeULEB128(0, OS);
31ca1b9943SAlex Langford encodeULEB128(0, OS);
32ca1b9943SAlex Langford
33ad66e9beSAlex Langford uint32_t SecondCode =
34ad66e9beSAlex Langford Order == OrderKind::InOrder ? FirstCode + 1 : FirstCode - 1;
35ca1b9943SAlex Langford
36ca1b9943SAlex Langford encodeULEB128(SecondCode, OS);
37ca1b9943SAlex Langford encodeULEB128(DW_TAG_subprogram, OS);
38ca1b9943SAlex Langford OS << static_cast<uint8_t>(DW_CHILDREN_no);
39ca1b9943SAlex Langford encodeULEB128(DW_AT_name, OS);
40ca1b9943SAlex Langford encodeULEB128(DW_FORM_strp, OS);
41ca1b9943SAlex Langford encodeULEB128(0, OS);
42ca1b9943SAlex Langford encodeULEB128(0, OS);
43ca1b9943SAlex Langford }
44ca1b9943SAlex Langford
writeMalformedULEB128Value(raw_ostream & OS)4594935c0dSAlex Langford void writeMalformedULEB128Value(raw_ostream &OS) {
4694935c0dSAlex Langford OS << static_cast<uint8_t>(0x80);
4794935c0dSAlex Langford }
4894935c0dSAlex Langford
writeULEB128LargerThan64Bits(raw_ostream & OS)4994935c0dSAlex Langford void writeULEB128LargerThan64Bits(raw_ostream &OS) {
5094935c0dSAlex Langford static constexpr llvm::StringRef LargeULEB128 =
5194935c0dSAlex Langford "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01";
5294935c0dSAlex Langford OS << LargeULEB128;
5394935c0dSAlex Langford }
5494935c0dSAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbrevDeclSetExtractSuccess)55ca1b9943SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetExtractSuccess) {
56ca1b9943SAlex Langford SmallString<64> RawData;
57ca1b9943SAlex Langford raw_svector_ostream OS(RawData);
58ca1b9943SAlex Langford uint32_t FirstCode = 5;
59ca1b9943SAlex Langford
6071572642SAlex Langford writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
61ca1b9943SAlex Langford encodeULEB128(0, OS);
62ca1b9943SAlex Langford
63ca1b9943SAlex Langford uint64_t Offset = 0;
64ca1b9943SAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
65ca1b9943SAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
6671572642SAlex Langford ASSERT_THAT_ERROR(AbbrevSet.extract(Data, &Offset), Succeeded());
67ca1b9943SAlex Langford // The Abbreviation Declarations are in order and contiguous, so we want to
68ad66e9beSAlex Langford // make sure that FirstAbbrCode was correctly set.
69ca1b9943SAlex Langford EXPECT_EQ(AbbrevSet.getFirstAbbrCode(), FirstCode);
70ca1b9943SAlex Langford
71ca1b9943SAlex Langford const DWARFAbbreviationDeclaration *Abbrev5 =
72ca1b9943SAlex Langford AbbrevSet.getAbbreviationDeclaration(FirstCode);
73ad66e9beSAlex Langford ASSERT_TRUE(Abbrev5);
74ca1b9943SAlex Langford EXPECT_EQ(Abbrev5->getTag(), DW_TAG_compile_unit);
75ca1b9943SAlex Langford EXPECT_TRUE(Abbrev5->hasChildren());
76ca1b9943SAlex Langford EXPECT_EQ(Abbrev5->getNumAttributes(), 1u);
77ca1b9943SAlex Langford
78ca1b9943SAlex Langford const DWARFAbbreviationDeclaration *Abbrev6 =
79ca1b9943SAlex Langford AbbrevSet.getAbbreviationDeclaration(FirstCode + 1);
80ad66e9beSAlex Langford ASSERT_TRUE(Abbrev6);
81ca1b9943SAlex Langford EXPECT_EQ(Abbrev6->getTag(), DW_TAG_subprogram);
82ca1b9943SAlex Langford EXPECT_FALSE(Abbrev6->hasChildren());
83ca1b9943SAlex Langford EXPECT_EQ(Abbrev6->getNumAttributes(), 1u);
84ca1b9943SAlex Langford }
85ca1b9943SAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbrevDeclSetExtractSuccessOutOfOrder)86ca1b9943SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetExtractSuccessOutOfOrder) {
87ca1b9943SAlex Langford SmallString<64> RawData;
88ca1b9943SAlex Langford raw_svector_ostream OS(RawData);
89ca1b9943SAlex Langford uint32_t FirstCode = 2;
90ca1b9943SAlex Langford
9171572642SAlex Langford writeValidAbbreviationDeclarations(OS, FirstCode, OutOfOrder);
92ca1b9943SAlex Langford encodeULEB128(0, OS);
93ca1b9943SAlex Langford
94ca1b9943SAlex Langford uint64_t Offset = 0;
95ca1b9943SAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
96ca1b9943SAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
9771572642SAlex Langford ASSERT_THAT_ERROR(AbbrevSet.extract(Data, &Offset), Succeeded());
98ad66e9beSAlex Langford // The declarations are out of order, ensure that FirstAbbrCode is UINT32_MAX.
99ca1b9943SAlex Langford EXPECT_EQ(AbbrevSet.getFirstAbbrCode(), UINT32_MAX);
100ca1b9943SAlex Langford
101ca1b9943SAlex Langford const DWARFAbbreviationDeclaration *Abbrev2 =
102ca1b9943SAlex Langford AbbrevSet.getAbbreviationDeclaration(FirstCode);
103ad66e9beSAlex Langford ASSERT_TRUE(Abbrev2);
104ca1b9943SAlex Langford EXPECT_EQ(Abbrev2->getTag(), DW_TAG_compile_unit);
105ca1b9943SAlex Langford EXPECT_TRUE(Abbrev2->hasChildren());
106ca1b9943SAlex Langford EXPECT_EQ(Abbrev2->getNumAttributes(), 1u);
107ca1b9943SAlex Langford
108ca1b9943SAlex Langford const DWARFAbbreviationDeclaration *Abbrev1 =
109ca1b9943SAlex Langford AbbrevSet.getAbbreviationDeclaration(FirstCode - 1);
110ad66e9beSAlex Langford ASSERT_TRUE(Abbrev1);
111ca1b9943SAlex Langford EXPECT_EQ(Abbrev1->getTag(), DW_TAG_subprogram);
112ca1b9943SAlex Langford EXPECT_FALSE(Abbrev1->hasChildren());
113ca1b9943SAlex Langford EXPECT_EQ(Abbrev1->getNumAttributes(), 1u);
114ca1b9943SAlex Langford }
11594935c0dSAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbreviationDeclSetCodeExtractionError)11694935c0dSAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetCodeExtractionError) {
11794935c0dSAlex Langford SmallString<64> RawData;
11894935c0dSAlex Langford
11994935c0dSAlex Langford // Check for malformed ULEB128.
12094935c0dSAlex Langford {
12194935c0dSAlex Langford raw_svector_ostream OS(RawData);
12294935c0dSAlex Langford writeMalformedULEB128Value(OS);
12394935c0dSAlex Langford
12494935c0dSAlex Langford uint64_t Offset = 0;
12594935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
12694935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
12771572642SAlex Langford ASSERT_THAT_ERROR(
12871572642SAlex Langford AbbrevSet.extract(Data, &Offset),
12971572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000000: "
13071572642SAlex Langford "malformed uleb128, extends past end"));
13194935c0dSAlex Langford EXPECT_EQ(Offset, 0u);
13294935c0dSAlex Langford }
13394935c0dSAlex Langford
13494935c0dSAlex Langford RawData.clear();
13594935c0dSAlex Langford // Check for ULEB128 too large to fit into a uin64_t.
13694935c0dSAlex Langford {
13794935c0dSAlex Langford raw_svector_ostream OS(RawData);
13894935c0dSAlex Langford writeULEB128LargerThan64Bits(OS);
13994935c0dSAlex Langford
14094935c0dSAlex Langford uint64_t Offset = 0;
14194935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
14294935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
14371572642SAlex Langford ASSERT_THAT_ERROR(
14471572642SAlex Langford AbbrevSet.extract(Data, &Offset),
14571572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000000: "
14671572642SAlex Langford "uleb128 too big for uint64"));
14794935c0dSAlex Langford EXPECT_EQ(Offset, 0u);
14894935c0dSAlex Langford }
14994935c0dSAlex Langford }
15094935c0dSAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbreviationDeclSetTagExtractionError)15194935c0dSAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetTagExtractionError) {
15294935c0dSAlex Langford SmallString<64> RawData;
15394935c0dSAlex Langford const uint32_t Code = 1;
15494935c0dSAlex Langford
15594935c0dSAlex Langford // Check for malformed ULEB128.
15694935c0dSAlex Langford {
15794935c0dSAlex Langford raw_svector_ostream OS(RawData);
15894935c0dSAlex Langford encodeULEB128(Code, OS);
15994935c0dSAlex Langford writeMalformedULEB128Value(OS);
16094935c0dSAlex Langford
16194935c0dSAlex Langford uint64_t Offset = 0;
16294935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
16394935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
16471572642SAlex Langford ASSERT_THAT_ERROR(
16571572642SAlex Langford AbbrevSet.extract(Data, &Offset),
16671572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
16771572642SAlex Langford "malformed uleb128, extends past end"));
16894935c0dSAlex Langford // Only the code was extracted correctly.
16994935c0dSAlex Langford EXPECT_EQ(Offset, 1u);
17094935c0dSAlex Langford }
17194935c0dSAlex Langford
17294935c0dSAlex Langford RawData.clear();
17394935c0dSAlex Langford // Check for ULEB128 too large to fit into a uint64_t.
17494935c0dSAlex Langford {
17594935c0dSAlex Langford raw_svector_ostream OS(RawData);
17694935c0dSAlex Langford encodeULEB128(Code, OS);
17794935c0dSAlex Langford writeULEB128LargerThan64Bits(OS);
17894935c0dSAlex Langford
17994935c0dSAlex Langford uint64_t Offset = 0;
18094935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
18194935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
18271572642SAlex Langford ASSERT_THAT_ERROR(
18371572642SAlex Langford AbbrevSet.extract(Data, &Offset),
18471572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
18571572642SAlex Langford "uleb128 too big for uint64"));
18694935c0dSAlex Langford // Only the code was extracted correctly.
18794935c0dSAlex Langford EXPECT_EQ(Offset, 1u);
18894935c0dSAlex Langford }
18994935c0dSAlex Langford }
19094935c0dSAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbreviationDeclSetChildExtractionError)19171572642SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetChildExtractionError) {
19294935c0dSAlex Langford SmallString<64> RawData;
19394935c0dSAlex Langford const uint32_t Code = 1;
19494935c0dSAlex Langford const dwarf::Tag Tag = DW_TAG_compile_unit;
19594935c0dSAlex Langford
19694935c0dSAlex Langford // We want to make sure that we fail if we reach the end of the stream before
19794935c0dSAlex Langford // reading the 'children' byte.
19894935c0dSAlex Langford raw_svector_ostream OS(RawData);
19994935c0dSAlex Langford encodeULEB128(Code, OS);
20094935c0dSAlex Langford encodeULEB128(Tag, OS);
20194935c0dSAlex Langford uint64_t Offset = 0;
20294935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
20394935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
20471572642SAlex Langford ASSERT_THAT_ERROR(
20571572642SAlex Langford AbbrevSet.extract(Data, &Offset),
20671572642SAlex Langford FailedWithMessage(
20771572642SAlex Langford "unexpected end of data at offset 0x2 while reading [0x2, 0x3)"));
20894935c0dSAlex Langford // The code and the tag were extracted correctly.
20994935c0dSAlex Langford EXPECT_EQ(Offset, 2u);
21094935c0dSAlex Langford }
21194935c0dSAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbreviationDeclSetAttributeExtractionError)21294935c0dSAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetAttributeExtractionError) {
21394935c0dSAlex Langford SmallString<64> RawData;
21494935c0dSAlex Langford const uint32_t Code = 1;
21594935c0dSAlex Langford const dwarf::Tag Tag = DW_TAG_compile_unit;
21694935c0dSAlex Langford const uint8_t Children = DW_CHILDREN_yes;
21794935c0dSAlex Langford
21894935c0dSAlex Langford // Check for malformed ULEB128.
21994935c0dSAlex Langford {
22094935c0dSAlex Langford raw_svector_ostream OS(RawData);
22194935c0dSAlex Langford encodeULEB128(Code, OS);
22294935c0dSAlex Langford encodeULEB128(Tag, OS);
22394935c0dSAlex Langford OS << Children;
22494935c0dSAlex Langford writeMalformedULEB128Value(OS);
22594935c0dSAlex Langford
22694935c0dSAlex Langford uint64_t Offset = 0;
22794935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
22894935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
22971572642SAlex Langford ASSERT_THAT_ERROR(
23071572642SAlex Langford AbbrevSet.extract(Data, &Offset),
23171572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000003: "
23271572642SAlex Langford "malformed uleb128, extends past end"));
23394935c0dSAlex Langford // The code, tag, and child byte were extracted correctly.
23494935c0dSAlex Langford EXPECT_EQ(Offset, 3u);
23594935c0dSAlex Langford }
23694935c0dSAlex Langford
23794935c0dSAlex Langford RawData.clear();
23894935c0dSAlex Langford // Check for ULEB128 too large to fit into a uint64_t.
23994935c0dSAlex Langford {
24094935c0dSAlex Langford raw_svector_ostream OS(RawData);
24194935c0dSAlex Langford encodeULEB128(Code, OS);
24294935c0dSAlex Langford encodeULEB128(Tag, OS);
24394935c0dSAlex Langford OS << Children;
24494935c0dSAlex Langford writeULEB128LargerThan64Bits(OS);
24594935c0dSAlex Langford
24694935c0dSAlex Langford uint64_t Offset = 0;
24794935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
24894935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
24971572642SAlex Langford ASSERT_THAT_ERROR(
25071572642SAlex Langford AbbrevSet.extract(Data, &Offset),
25171572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000003: "
25271572642SAlex Langford "uleb128 too big for uint64"));
25394935c0dSAlex Langford // The code, tag, and child byte were extracted correctly.
25494935c0dSAlex Langford EXPECT_EQ(Offset, 3u);
25594935c0dSAlex Langford }
25694935c0dSAlex Langford }
25794935c0dSAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbreviationDeclSetFormExtractionError)25894935c0dSAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetFormExtractionError) {
25994935c0dSAlex Langford SmallString<64> RawData;
26094935c0dSAlex Langford const uint32_t Code = 1;
26194935c0dSAlex Langford const dwarf::Tag Tag = DW_TAG_compile_unit;
26294935c0dSAlex Langford const uint8_t Children = DW_CHILDREN_yes;
26394935c0dSAlex Langford const dwarf::Attribute Attr = DW_AT_name;
26494935c0dSAlex Langford
26594935c0dSAlex Langford // Check for malformed ULEB128.
26694935c0dSAlex Langford {
26794935c0dSAlex Langford raw_svector_ostream OS(RawData);
26894935c0dSAlex Langford encodeULEB128(Code, OS);
26994935c0dSAlex Langford encodeULEB128(Tag, OS);
27094935c0dSAlex Langford OS << Children;
27194935c0dSAlex Langford encodeULEB128(Attr, OS);
27294935c0dSAlex Langford writeMalformedULEB128Value(OS);
27394935c0dSAlex Langford
27494935c0dSAlex Langford uint64_t Offset = 0;
27594935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
27694935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
27771572642SAlex Langford ASSERT_THAT_ERROR(
27871572642SAlex Langford AbbrevSet.extract(Data, &Offset),
27971572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000004: "
28071572642SAlex Langford "malformed uleb128, extends past end"));
28194935c0dSAlex Langford // The code, tag, child byte, and first attribute were extracted correctly.
28294935c0dSAlex Langford EXPECT_EQ(Offset, 4u);
28394935c0dSAlex Langford }
28494935c0dSAlex Langford
28594935c0dSAlex Langford RawData.clear();
28694935c0dSAlex Langford // Check for ULEB128 too large to fit into a uint64_t.
28794935c0dSAlex Langford {
28894935c0dSAlex Langford raw_svector_ostream OS(RawData);
28994935c0dSAlex Langford encodeULEB128(Code, OS);
29094935c0dSAlex Langford encodeULEB128(Tag, OS);
29194935c0dSAlex Langford OS << Children;
29294935c0dSAlex Langford encodeULEB128(Attr, OS);
29394935c0dSAlex Langford writeULEB128LargerThan64Bits(OS);
29494935c0dSAlex Langford
29594935c0dSAlex Langford uint64_t Offset = 0;
29694935c0dSAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
29794935c0dSAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
29871572642SAlex Langford ASSERT_THAT_ERROR(
29971572642SAlex Langford AbbrevSet.extract(Data, &Offset),
30071572642SAlex Langford FailedWithMessage("unable to decode LEB128 at offset 0x00000004: "
30171572642SAlex Langford "uleb128 too big for uint64"));
30294935c0dSAlex Langford // The code, tag, child byte, and first attribute were extracted correctly.
30394935c0dSAlex Langford EXPECT_EQ(Offset, 4u);
30494935c0dSAlex Langford }
30594935c0dSAlex Langford }
30671572642SAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbrevDeclSetInvalidTag)30771572642SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetInvalidTag) {
30871572642SAlex Langford SmallString<64> RawData;
30971572642SAlex Langford raw_svector_ostream OS(RawData);
31071572642SAlex Langford uint32_t FirstCode = 1;
31171572642SAlex Langford // First, we're going to manually add good data.
31271572642SAlex Langford writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
31371572642SAlex Langford
31471572642SAlex Langford // Afterwards, we're going to write an Abbreviation Decl manually with an
31571572642SAlex Langford // invalid tag.
31671572642SAlex Langford encodeULEB128(FirstCode + 2, OS);
31771572642SAlex Langford encodeULEB128(0, OS); // Invalid Tag
31871572642SAlex Langford OS << static_cast<uint8_t>(DW_CHILDREN_no);
31971572642SAlex Langford encodeULEB128(DW_AT_name, OS);
32071572642SAlex Langford encodeULEB128(DW_FORM_strp, OS);
32171572642SAlex Langford encodeULEB128(0, OS);
32271572642SAlex Langford encodeULEB128(0, OS);
32371572642SAlex Langford
32471572642SAlex Langford encodeULEB128(0, OS);
32571572642SAlex Langford uint64_t Offset = 0;
32671572642SAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
32771572642SAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
32871572642SAlex Langford EXPECT_THAT_ERROR(
32971572642SAlex Langford AbbrevSet.extract(Data, &Offset),
33071572642SAlex Langford FailedWithMessage("abbreviation declaration requires a non-null tag"));
33171572642SAlex Langford }
33271572642SAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbrevDeclSetInvalidAttrValidForm)33371572642SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetInvalidAttrValidForm) {
33471572642SAlex Langford SmallString<64> RawData;
33571572642SAlex Langford raw_svector_ostream OS(RawData);
33671572642SAlex Langford uint32_t FirstCode = 120;
33771572642SAlex Langford // First, we're going to manually add good data.
33871572642SAlex Langford writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
33971572642SAlex Langford
34071572642SAlex Langford // Afterwards, we're going to write an Abbreviation Decl manually with an
34171572642SAlex Langford // invalid attribute but valid form.
34271572642SAlex Langford encodeULEB128(FirstCode - 5, OS);
34371572642SAlex Langford encodeULEB128(DW_TAG_compile_unit, OS);
34471572642SAlex Langford OS << static_cast<uint8_t>(DW_CHILDREN_no);
34571572642SAlex Langford encodeULEB128(0, OS); // Invalid attribute followed by an invalid form.
34671572642SAlex Langford encodeULEB128(DW_FORM_strp, OS);
34771572642SAlex Langford encodeULEB128(0, OS);
34871572642SAlex Langford encodeULEB128(0, OS);
34971572642SAlex Langford
35071572642SAlex Langford encodeULEB128(0, OS);
35171572642SAlex Langford
35271572642SAlex Langford uint64_t Offset = 0;
35371572642SAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
35471572642SAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
35571572642SAlex Langford EXPECT_THAT_ERROR(
35671572642SAlex Langford AbbrevSet.extract(Data, &Offset),
35771572642SAlex Langford FailedWithMessage(
35871572642SAlex Langford "malformed abbreviation declaration attribute. Either the "
35971572642SAlex Langford "attribute or the form is zero while the other is not"));
36071572642SAlex Langford }
36171572642SAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbrevDeclSetValidAttrInvalidForm)36271572642SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetValidAttrInvalidForm) {
36371572642SAlex Langford SmallString<64> RawData;
36471572642SAlex Langford raw_svector_ostream OS(RawData);
36571572642SAlex Langford uint32_t FirstCode = 120;
36671572642SAlex Langford // First, we're going to manually add good data.
36771572642SAlex Langford writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
36871572642SAlex Langford
36971572642SAlex Langford // Afterwards, we're going to write an Abbreviation Decl manually with a
37071572642SAlex Langford // valid attribute but invalid form.
37171572642SAlex Langford encodeULEB128(FirstCode - 5, OS);
37271572642SAlex Langford encodeULEB128(DW_TAG_compile_unit, OS);
37371572642SAlex Langford OS << static_cast<uint8_t>(DW_CHILDREN_no);
37471572642SAlex Langford encodeULEB128(DW_AT_name, OS);
37571572642SAlex Langford encodeULEB128(0, OS); // Invalid form after a valid attribute.
37671572642SAlex Langford encodeULEB128(0, OS);
37771572642SAlex Langford encodeULEB128(0, OS);
37871572642SAlex Langford
37971572642SAlex Langford encodeULEB128(0, OS);
38071572642SAlex Langford
38171572642SAlex Langford uint64_t Offset = 0;
38271572642SAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
38371572642SAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
38471572642SAlex Langford EXPECT_THAT_ERROR(
38571572642SAlex Langford AbbrevSet.extract(Data, &Offset),
38671572642SAlex Langford FailedWithMessage(
38771572642SAlex Langford "malformed abbreviation declaration attribute. Either the "
38871572642SAlex Langford "attribute or the form is zero while the other is not"));
38971572642SAlex Langford }
39071572642SAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFAbbrevDeclSetMissingTerminator)39171572642SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetMissingTerminator) {
39271572642SAlex Langford SmallString<64> RawData;
39371572642SAlex Langford raw_svector_ostream OS(RawData);
39471572642SAlex Langford uint32_t FirstCode = 120;
39571572642SAlex Langford // First, we're going to manually add good data.
39671572642SAlex Langford writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
39771572642SAlex Langford
39871572642SAlex Langford // Afterwards, we're going to write an Abbreviation Decl manually without a
39971572642SAlex Langford // termintating sequence.
40071572642SAlex Langford encodeULEB128(FirstCode + 7, OS);
40171572642SAlex Langford encodeULEB128(DW_TAG_compile_unit, OS);
40271572642SAlex Langford OS << static_cast<uint8_t>(DW_CHILDREN_no);
40371572642SAlex Langford encodeULEB128(DW_AT_name, OS);
40471572642SAlex Langford encodeULEB128(DW_FORM_strp, OS);
40571572642SAlex Langford
40671572642SAlex Langford uint64_t Offset = 0;
40771572642SAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
40871572642SAlex Langford DWARFAbbreviationDeclarationSet AbbrevSet;
40971572642SAlex Langford EXPECT_THAT_ERROR(
41071572642SAlex Langford AbbrevSet.extract(Data, &Offset),
41171572642SAlex Langford FailedWithMessage(
41271572642SAlex Langford "abbreviation declaration attribute list was not terminated with a "
41371572642SAlex Langford "null entry"));
41471572642SAlex Langford }
415*32e10aa6SAlex Langford
TEST(DWARFDebugAbbrevTest,DWARFDebugAbbrevParseError)416*32e10aa6SAlex Langford TEST(DWARFDebugAbbrevTest, DWARFDebugAbbrevParseError) {
417*32e10aa6SAlex Langford SmallString<64> RawData;
418*32e10aa6SAlex Langford raw_svector_ostream OS(RawData);
419*32e10aa6SAlex Langford const uint32_t FirstCode = 70;
420*32e10aa6SAlex Langford // First, we're going to manually add good data.
421*32e10aa6SAlex Langford writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
422*32e10aa6SAlex Langford
423*32e10aa6SAlex Langford // Afterwards, we're going to write an Abbreviation Decl manually without a
424*32e10aa6SAlex Langford // termintating sequence.
425*32e10aa6SAlex Langford encodeULEB128(FirstCode - 1, OS);
426*32e10aa6SAlex Langford encodeULEB128(DW_TAG_compile_unit, OS);
427*32e10aa6SAlex Langford OS << static_cast<uint8_t>(DW_CHILDREN_no);
428*32e10aa6SAlex Langford encodeULEB128(DW_AT_name, OS);
429*32e10aa6SAlex Langford encodeULEB128(DW_FORM_strp, OS);
430*32e10aa6SAlex Langford
431*32e10aa6SAlex Langford // The specific error should percolate up to the DWARFDebugAbbrev::parse().
432*32e10aa6SAlex Langford DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
433*32e10aa6SAlex Langford DWARFDebugAbbrev DebugAbbrev(Data);
434*32e10aa6SAlex Langford EXPECT_THAT_ERROR(
435*32e10aa6SAlex Langford DebugAbbrev.parse(),
436*32e10aa6SAlex Langford FailedWithMessage(
437*32e10aa6SAlex Langford "abbreviation declaration attribute list was not terminated with a "
438*32e10aa6SAlex Langford "null entry"));
439*32e10aa6SAlex Langford }
440