1dd6faf13SIgor Kudrin //===- DWARFListTableTest.cpp ---------------------------------------------===//
2dd6faf13SIgor Kudrin //
3dd6faf13SIgor Kudrin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4dd6faf13SIgor Kudrin // See https://llvm.org/LICENSE.txt for license information.
5dd6faf13SIgor Kudrin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6dd6faf13SIgor Kudrin //
7dd6faf13SIgor Kudrin //===----------------------------------------------------------------------===//
8dd6faf13SIgor Kudrin
9dd6faf13SIgor Kudrin #include "llvm/DebugInfo/DWARF/DWARFListTable.h"
10dd6faf13SIgor Kudrin #include "llvm/Testing/Support/Error.h"
11dd6faf13SIgor Kudrin #include "gtest/gtest.h"
12dd6faf13SIgor Kudrin
13dd6faf13SIgor Kudrin using namespace llvm;
14dd6faf13SIgor Kudrin
15dd6faf13SIgor Kudrin namespace {
16dd6faf13SIgor Kudrin
TEST(DWARFListTableHeader,TruncatedLength)17dd6faf13SIgor Kudrin TEST(DWARFListTableHeader, TruncatedLength) {
18dd6faf13SIgor Kudrin static const char SecData[] = "\x33\x22\x11"; // Truncated DWARF32 length
19dd6faf13SIgor Kudrin DWARFDataExtractor Extractor(StringRef(SecData, sizeof(SecData) - 1),
20dd6faf13SIgor Kudrin /*isLittleEndian=*/true,
21dd6faf13SIgor Kudrin /*AddrSize=*/4);
22dd6faf13SIgor Kudrin DWARFListTableHeader Header(/*SectionName=*/".debug_rnglists",
23dd6faf13SIgor Kudrin /*ListTypeString=*/"range");
24dd6faf13SIgor Kudrin uint64_t Offset = 0;
25dd6faf13SIgor Kudrin EXPECT_THAT_ERROR(
26dd6faf13SIgor Kudrin Header.extract(Extractor, &Offset),
27dd6faf13SIgor Kudrin FailedWithMessage(
28dd6faf13SIgor Kudrin "parsing .debug_rnglists table at offset 0x0: unexpected end of data "
29dd6faf13SIgor Kudrin "at offset 0x3 while reading [0x0, 0x4)"));
30dd6faf13SIgor Kudrin // length() is expected to return 0 to indicate that the unit length field
31dd6faf13SIgor Kudrin // can not be parsed and so we can not, for example, skip the current set
32dd6faf13SIgor Kudrin // to continue parsing from the next one.
33dd6faf13SIgor Kudrin EXPECT_EQ(Header.length(), 0u);
34dd6faf13SIgor Kudrin }
35dd6faf13SIgor Kudrin
TEST(DWARFListTableHeader,TruncatedLengthDWARF64)36dd6faf13SIgor Kudrin TEST(DWARFListTableHeader, TruncatedLengthDWARF64) {
37dd6faf13SIgor Kudrin static const char SecData[] =
38dd6faf13SIgor Kudrin "\xff\xff\xff\xff" // DWARF64 mark
39dd6faf13SIgor Kudrin "\x55\x44\x33\x22\x11"; // Truncated DWARF64 length
40dd6faf13SIgor Kudrin DWARFDataExtractor Extractor(StringRef(SecData, sizeof(SecData) - 1),
41dd6faf13SIgor Kudrin /*isLittleEndian=*/true,
42dd6faf13SIgor Kudrin /*AddrSize=*/4);
43dd6faf13SIgor Kudrin DWARFListTableHeader Header(/*SectionName=*/".debug_rnglists",
44dd6faf13SIgor Kudrin /*ListTypeString=*/"range");
45dd6faf13SIgor Kudrin uint64_t Offset = 0;
46dd6faf13SIgor Kudrin EXPECT_THAT_ERROR(
47dd6faf13SIgor Kudrin Header.extract(Extractor, &Offset),
48dd6faf13SIgor Kudrin FailedWithMessage(
49dd6faf13SIgor Kudrin "parsing .debug_rnglists table at offset 0x0: unexpected end of data "
50dd6faf13SIgor Kudrin "at offset 0x9 while reading [0x4, 0xc)"));
51dd6faf13SIgor Kudrin // length() is expected to return 0 to indicate that the unit length field
52dd6faf13SIgor Kudrin // can not be parsed and so we can not, for example, skip the current set
53dd6faf13SIgor Kudrin // to continue parsing from the next one.
54dd6faf13SIgor Kudrin EXPECT_EQ(Header.length(), 0u);
55dd6faf13SIgor Kudrin }
56dd6faf13SIgor Kudrin
TEST(DWARFListTableHeader,TruncatedHeader)57dd6faf13SIgor Kudrin TEST(DWARFListTableHeader, TruncatedHeader) {
58dd6faf13SIgor Kudrin static const char SecData[] = "\x02\x00\x00\x00" // Length
59dd6faf13SIgor Kudrin "\x05\x00"; // Version
60dd6faf13SIgor Kudrin DWARFDataExtractor Extractor(StringRef(SecData, sizeof(SecData) - 1),
61dd6faf13SIgor Kudrin /*isLittleEndian=*/true,
62dd6faf13SIgor Kudrin /*AddrSize=*/4);
63dd6faf13SIgor Kudrin DWARFListTableHeader Header(/*SectionName=*/".debug_rnglists",
64dd6faf13SIgor Kudrin /*ListTypeString=*/"range");
65dd6faf13SIgor Kudrin uint64_t Offset = 0;
66dd6faf13SIgor Kudrin EXPECT_THAT_ERROR(
67dd6faf13SIgor Kudrin Header.extract(Extractor, &Offset),
68dd6faf13SIgor Kudrin FailedWithMessage(".debug_rnglists table at offset 0x0 has too small "
69dd6faf13SIgor Kudrin "length (0x6) to contain a complete header"));
70dd6faf13SIgor Kudrin // length() is expected to return the full length of the set if the unit
71dd6faf13SIgor Kudrin // length field is read, even if an error occurred during the parsing,
72dd6faf13SIgor Kudrin // to allow skipping the current set and continue parsing from the next one.
73dd6faf13SIgor Kudrin EXPECT_EQ(Header.length(), 6u);
74dd6faf13SIgor Kudrin }
75dd6faf13SIgor Kudrin
TEST(DWARFListTableHeader,OffsetEntryCount)76a28facbaSJan Kratochvil TEST(DWARFListTableHeader, OffsetEntryCount) {
77a28facbaSJan Kratochvil static const char SecData[] = "\x10\x00\x00\x00" // Length
78a28facbaSJan Kratochvil "\x05\x00" // Version
79a28facbaSJan Kratochvil "\x08" // Address size
80a28facbaSJan Kratochvil "\x00" // Segment selector size
81a28facbaSJan Kratochvil "\x01\x00\x00\x00" // Offset entry count
82a28facbaSJan Kratochvil "\x04\x00\x00\x00" // offset[0]
83a28facbaSJan Kratochvil "\x04" // DW_RLE_offset_pair
84a28facbaSJan Kratochvil "\x01" // ULEB128 starting offset
85a28facbaSJan Kratochvil "\x02" // ULEB128 ending offset
86a28facbaSJan Kratochvil "\x00"; // DW_RLE_end_of_list
87a28facbaSJan Kratochvil DWARFDataExtractor Extractor(StringRef(SecData, sizeof(SecData) - 1),
88a28facbaSJan Kratochvil /*isLittleEndian=*/true,
89a28facbaSJan Kratochvil /*AddrSize=*/4);
90a28facbaSJan Kratochvil DWARFListTableHeader Header(/*SectionName=*/".debug_rnglists",
91a28facbaSJan Kratochvil /*ListTypeString=*/"range");
92a28facbaSJan Kratochvil uint64_t Offset = 0;
93a28facbaSJan Kratochvil EXPECT_FALSE(!!Header.extract(Extractor, &Offset));
94*89fab98eSFangrui Song std::optional<uint64_t> Offset0 = Header.getOffsetEntry(Extractor, 0);
95a28facbaSJan Kratochvil EXPECT_TRUE(!!Offset0);
96a28facbaSJan Kratochvil EXPECT_EQ(Offset0, uint64_t(4));
97*89fab98eSFangrui Song std::optional<uint64_t> Offset1 = Header.getOffsetEntry(Extractor, 1);
98a28facbaSJan Kratochvil EXPECT_FALSE(!!Offset1);
99a28facbaSJan Kratochvil EXPECT_EQ(Header.length(), sizeof(SecData) - 1);
100a28facbaSJan Kratochvil }
101a28facbaSJan Kratochvil
102dd6faf13SIgor Kudrin } // end anonymous namespace
103