xref: /llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp (revision 290e482342826ee4c65bd6d2aece25736d3f0c7b)
1dcff3961SIgor Kudrin //===- llvm/unittest/DebugInfo/DWARFDebugArangeSetTest.cpp-----------------===//
2dcff3961SIgor Kudrin //
3dcff3961SIgor Kudrin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4dcff3961SIgor Kudrin // See https://llvm.org/LICENSE.txt for license information.
5dcff3961SIgor Kudrin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6dcff3961SIgor Kudrin //
7dcff3961SIgor Kudrin //===----------------------------------------------------------------------===//
8dcff3961SIgor Kudrin 
9dcff3961SIgor Kudrin #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
10*290e4823Sserge-sans-paille #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
11ca05601cSJames Henderson #include "llvm/Testing/Support/Error.h"
12dcff3961SIgor Kudrin #include "gtest/gtest.h"
13dcff3961SIgor Kudrin 
14dcff3961SIgor Kudrin using namespace llvm;
15dcff3961SIgor Kudrin 
16dcff3961SIgor Kudrin namespace {
17dcff3961SIgor Kudrin 
18ca05601cSJames Henderson struct WarningHandler {
~WarningHandler__anon4c7241790111::WarningHandler19ca05601cSJames Henderson   ~WarningHandler() { EXPECT_THAT_ERROR(std::move(Err), Succeeded()); }
20ca05601cSJames Henderson 
operator ()__anon4c7241790111::WarningHandler21ca05601cSJames Henderson   void operator()(Error E) { Err = joinErrors(std::move(Err), std::move(E)); }
22ca05601cSJames Henderson 
getWarning__anon4c7241790111::WarningHandler23ca05601cSJames Henderson   Error getWarning() { return std::move(Err); }
24ca05601cSJames Henderson 
25ca05601cSJames Henderson   Error Err = Error::success();
26ca05601cSJames Henderson };
27ca05601cSJames Henderson 
28dcff3961SIgor Kudrin template <size_t SecSize>
ExpectExtractError(const char (& SecDataRaw)[SecSize],const char * ErrorMessage)29dcff3961SIgor Kudrin void ExpectExtractError(const char (&SecDataRaw)[SecSize],
30dcff3961SIgor Kudrin                         const char *ErrorMessage) {
31eb2b17eeSPavel Labath   DWARFDataExtractor Extractor(StringRef(SecDataRaw, SecSize - 1),
32dcff3961SIgor Kudrin                                /* IsLittleEndian = */ true,
33dcff3961SIgor Kudrin                                /* AddressSize = */ 4);
34dcff3961SIgor Kudrin   DWARFDebugArangeSet Set;
35dcff3961SIgor Kudrin   uint64_t Offset = 0;
36ca05601cSJames Henderson   WarningHandler Warnings;
37ca05601cSJames Henderson   Error E = Set.extract(Extractor, &Offset, Warnings);
38dcff3961SIgor Kudrin   ASSERT_TRUE(E.operator bool());
39dcff3961SIgor Kudrin   EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str());
40dcff3961SIgor Kudrin }
41dcff3961SIgor Kudrin 
TEST(DWARFDebugArangeSet,LengthExceedsSectionSize)42dcff3961SIgor Kudrin TEST(DWARFDebugArangeSet, LengthExceedsSectionSize) {
43dcff3961SIgor Kudrin   static const char DebugArangesSecRaw[] =
44dcff3961SIgor Kudrin       "\x15\x00\x00\x00" // The length exceeds the section boundaries
45dcff3961SIgor Kudrin       "\x02\x00"         // Version
46dcff3961SIgor Kudrin       "\x00\x00\x00\x00" // Debug Info Offset
47dcff3961SIgor Kudrin       "\x04"             // Address Size
48dcff3961SIgor Kudrin       "\x00"             // Segment Selector Size
49dcff3961SIgor Kudrin       "\x00\x00\x00\x00" // Padding
50dcff3961SIgor Kudrin       "\x00\x00\x00\x00" // Termination tuple
51dcff3961SIgor Kudrin       "\x00\x00\x00\x00";
52dcff3961SIgor Kudrin   ExpectExtractError(
53dcff3961SIgor Kudrin       DebugArangesSecRaw,
54dcff3961SIgor Kudrin       "the length of address range table at offset 0x0 exceeds section size");
55dcff3961SIgor Kudrin }
56dcff3961SIgor Kudrin 
TEST(DWARFDebugArangeSet,LengthExceedsSectionSizeDWARF64)5763329907SIgor Kudrin TEST(DWARFDebugArangeSet, LengthExceedsSectionSizeDWARF64) {
5863329907SIgor Kudrin   static const char DebugArangesSecRaw[] =
5963329907SIgor Kudrin       "\xff\xff\xff\xff"                 // DWARF64 mark
6063329907SIgor Kudrin       "\x15\x00\x00\x00\x00\x00\x00\x00" // The length exceeds the section
6163329907SIgor Kudrin                                          // boundaries
6263329907SIgor Kudrin       "\x02\x00"                         // Version
6363329907SIgor Kudrin       "\x00\x00\x00\x00\x00\x00\x00\x00" // Debug Info Offset
6463329907SIgor Kudrin       "\x04"                             // Address Size
6563329907SIgor Kudrin       "\x00"                             // Segment Selector Size
6663329907SIgor Kudrin                                          // No padding
6763329907SIgor Kudrin       "\x00\x00\x00\x00"                 // Termination tuple
6863329907SIgor Kudrin       "\x00\x00\x00\x00";
6963329907SIgor Kudrin   ExpectExtractError(
7063329907SIgor Kudrin       DebugArangesSecRaw,
7163329907SIgor Kudrin       "the length of address range table at offset 0x0 exceeds section size");
7263329907SIgor Kudrin }
7363329907SIgor Kudrin 
TEST(DWARFDebugArangeSet,UnsupportedAddressSize)74dcff3961SIgor Kudrin TEST(DWARFDebugArangeSet, UnsupportedAddressSize) {
75dcff3961SIgor Kudrin   static const char DebugArangesSecRaw[] =
76dcff3961SIgor Kudrin       "\x0c\x00\x00\x00"  // Length
77dcff3961SIgor Kudrin       "\x02\x00"          // Version
78dcff3961SIgor Kudrin       "\x00\x00\x00\x00"  // Debug Info Offset
79d7733f84SJack Anderson       "\x03"              // Address Size (not supported)
80dcff3961SIgor Kudrin       "\x00"              // Segment Selector Size
81dcff3961SIgor Kudrin                           // No padding
82dcff3961SIgor Kudrin       "\x00\x00\x00\x00"; // Termination tuple
83dcff3961SIgor Kudrin   ExpectExtractError(
84dcff3961SIgor Kudrin       DebugArangesSecRaw,
85d7733f84SJack Anderson       "address range table at offset 0x0 has unsupported address size: 3 "
86d7733f84SJack Anderson       "(supported are 2, 4, 8)");
87dcff3961SIgor Kudrin }
88dcff3961SIgor Kudrin 
TEST(DWARFDebugArangeSet,UnsupportedSegmentSelectorSize)89ed9851a0SIgor Kudrin TEST(DWARFDebugArangeSet, UnsupportedSegmentSelectorSize) {
90ed9851a0SIgor Kudrin   static const char DebugArangesSecRaw[] =
91ed9851a0SIgor Kudrin       "\x14\x00\x00\x00" // Length
92ed9851a0SIgor Kudrin       "\x02\x00"         // Version
93ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Debug Info Offset
94ed9851a0SIgor Kudrin       "\x04"             // Address Size
95ed9851a0SIgor Kudrin       "\x04"             // Segment Selector Size (not supported)
96ed9851a0SIgor Kudrin                          // No padding
97ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Termination tuple
98ed9851a0SIgor Kudrin       "\x00\x00\x00\x00"
99ed9851a0SIgor Kudrin       "\x00\x00\x00\x00";
100ed9851a0SIgor Kudrin   ExpectExtractError(
101ed9851a0SIgor Kudrin       DebugArangesSecRaw,
102ed9851a0SIgor Kudrin       "non-zero segment selector size in address range table at offset 0x0 "
103ed9851a0SIgor Kudrin       "is not supported");
104ed9851a0SIgor Kudrin }
105ed9851a0SIgor Kudrin 
TEST(DWARFDebugArangeSet,NoTerminationEntry)106dcff3961SIgor Kudrin TEST(DWARFDebugArangeSet, NoTerminationEntry) {
107dcff3961SIgor Kudrin   static const char DebugArangesSecRaw[] =
108dcff3961SIgor Kudrin       "\x14\x00\x00\x00" // Length
109dcff3961SIgor Kudrin       "\x02\x00"         // Version
110dcff3961SIgor Kudrin       "\x00\x00\x00\x00" // Debug Info Offset
111dcff3961SIgor Kudrin       "\x04"             // Address Size
112dcff3961SIgor Kudrin       "\x00"             // Segment Selector Size
113dcff3961SIgor Kudrin       "\x00\x00\x00\x00" // Padding
114dcff3961SIgor Kudrin       "\x00\x00\x00\x00" // Entry: Address
115dcff3961SIgor Kudrin       "\x01\x00\x00\x00" //        Length
116dcff3961SIgor Kudrin       ;                  // No termination tuple
117dcff3961SIgor Kudrin   ExpectExtractError(
118dcff3961SIgor Kudrin       DebugArangesSecRaw,
119dcff3961SIgor Kudrin       "address range table at offset 0x0 is not terminated by null entry");
120dcff3961SIgor Kudrin }
121dcff3961SIgor Kudrin 
TEST(DWARFDebugArangeSet,ReservedUnitLength)12263329907SIgor Kudrin TEST(DWARFDebugArangeSet, ReservedUnitLength) {
123ed9851a0SIgor Kudrin   // Note: 12 is the minimum length to pass the basic check for the size of
124ed9851a0SIgor Kudrin   // the section. 1 will be automatically subtracted in ExpectExtractError().
125ed9851a0SIgor Kudrin   static const char DebugArangesSecRaw[12 + 1] =
12663329907SIgor Kudrin       "\xf0\xff\xff\xff"; // Reserved unit length value
127eb2b17eeSPavel Labath   ExpectExtractError(DebugArangesSecRaw,
128eb2b17eeSPavel Labath                      "parsing address ranges table at offset 0x0: unsupported "
129eb2b17eeSPavel Labath                      "reserved unit length of value 0xfffffff0");
13063329907SIgor Kudrin }
13163329907SIgor Kudrin 
TEST(DWARFDebugArangeSet,SectionTooShort)132ed9851a0SIgor Kudrin TEST(DWARFDebugArangeSet, SectionTooShort) {
133ed9851a0SIgor Kudrin   // Note: 1 will be automatically subtracted in ExpectExtractError().
134ed9851a0SIgor Kudrin   static const char DebugArangesSecRaw[11 + 1] = {0};
135eb2b17eeSPavel Labath   ExpectExtractError(DebugArangesSecRaw,
136eb2b17eeSPavel Labath                      "parsing address ranges table at offset 0x0: unexpected "
13704aea769SPavel Labath                      "end of data at offset 0xb while reading [0xb, 0xc)");
138ed9851a0SIgor Kudrin }
139ed9851a0SIgor Kudrin 
TEST(DWARFDebugArangeSet,SectionTooShortDWARF64)140ed9851a0SIgor Kudrin TEST(DWARFDebugArangeSet, SectionTooShortDWARF64) {
141ed9851a0SIgor Kudrin   // Note: 1 will be automatically subtracted in ExpectExtractError().
142ed9851a0SIgor Kudrin   static const char DebugArangesSecRaw[23 + 1] =
143ed9851a0SIgor Kudrin       "\xff\xff\xff\xff"; // DWARF64 mark
144eb2b17eeSPavel Labath   ExpectExtractError(DebugArangesSecRaw,
145eb2b17eeSPavel Labath                      "parsing address ranges table at offset 0x0: unexpected "
14604aea769SPavel Labath                      "end of data at offset 0x17 while reading [0x17, 0x18)");
147ed9851a0SIgor Kudrin }
148ed9851a0SIgor Kudrin 
TEST(DWARFDebugArangeSet,NoSpaceForEntries)149ed9851a0SIgor Kudrin TEST(DWARFDebugArangeSet, NoSpaceForEntries) {
150ed9851a0SIgor Kudrin   static const char DebugArangesSecRaw[] =
151ed9851a0SIgor Kudrin       "\x0c\x00\x00\x00" // Length
152ed9851a0SIgor Kudrin       "\x02\x00"         // Version
153ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Debug Info Offset
154ed9851a0SIgor Kudrin       "\x04"             // Address Size
155ed9851a0SIgor Kudrin       "\x00"             // Segment Selector Size
156ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Padding
157ed9851a0SIgor Kudrin       ;                  // No entries
158ed9851a0SIgor Kudrin   ExpectExtractError(
159ed9851a0SIgor Kudrin       DebugArangesSecRaw,
160ed9851a0SIgor Kudrin       "address range table at offset 0x0 has an insufficient length "
161ed9851a0SIgor Kudrin       "to contain any entries");
162ed9851a0SIgor Kudrin }
163ed9851a0SIgor Kudrin 
TEST(DWARFDebugArangeSet,UnevenLength)164ed9851a0SIgor Kudrin TEST(DWARFDebugArangeSet, UnevenLength) {
165ed9851a0SIgor Kudrin   static const char DebugArangesSecRaw[] =
166ed9851a0SIgor Kudrin       "\x1b\x00\x00\x00" // Length (not a multiple of tuple size)
167ed9851a0SIgor Kudrin       "\x02\x00"         // Version
168ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Debug Info Offset
169ed9851a0SIgor Kudrin       "\x04"             // Address Size
170ed9851a0SIgor Kudrin       "\x00"             // Segment Selector Size
171ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Padding
172ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Entry: Address
173ed9851a0SIgor Kudrin       "\x01\x00\x00\x00" //        Length
174ed9851a0SIgor Kudrin       "\x00\x00\x00\x00" // Termination tuple
175ed9851a0SIgor Kudrin       "\x00\x00\x00\x00";
176ed9851a0SIgor Kudrin   ExpectExtractError(
177ed9851a0SIgor Kudrin       DebugArangesSecRaw,
178ed9851a0SIgor Kudrin       "address range table at offset 0x0 has length that is not a multiple "
179ed9851a0SIgor Kudrin       "of the tuple size");
180ed9851a0SIgor Kudrin }
181ed9851a0SIgor Kudrin 
TEST(DWARFDebugArangeSet,ZeroAddressEntry)182ca05601cSJames Henderson TEST(DWARFDebugArangeSet, ZeroAddressEntry) {
183cb3a598cSJames Henderson   static const char DebugArangesSecRaw[] =
184ca05601cSJames Henderson       "\x1c\x00\x00\x00" // Length
185cb3a598cSJames Henderson       "\x02\x00"         // Version
186cb3a598cSJames Henderson       "\x00\x00\x00\x00" // Debug Info Offset
187cb3a598cSJames Henderson       "\x04"             // Address Size
188cb3a598cSJames Henderson       "\x00"             // Segment Selector Size
189cb3a598cSJames Henderson       "\x00\x00\x00\x00" // Padding
190bc5d68ddSNico Weber       "\x00\x00\x00\x00" // Entry1: Address
191cb3a598cSJames Henderson       "\x01\x00\x00\x00" //         Length
192cb3a598cSJames Henderson       "\x00\x00\x00\x00" // Termination tuple
193cb3a598cSJames Henderson       "\x00\x00\x00\x00";
194ca05601cSJames Henderson   DWARFDataExtractor Extractor(
195ca05601cSJames Henderson       StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
196ca05601cSJames Henderson       /*IsLittleEndian=*/true,
197ca05601cSJames Henderson       /*AddressSize=*/4);
198ca05601cSJames Henderson   DWARFDebugArangeSet Set;
199ca05601cSJames Henderson   uint64_t Offset = 0;
200ca05601cSJames Henderson   ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),
201ca05601cSJames Henderson                     Succeeded());
202ca05601cSJames Henderson   auto Range = Set.descriptors();
203ca05601cSJames Henderson   auto Iter = Range.begin();
204f4d8e86dSHubert Tong   ASSERT_EQ(std::distance(Iter, Range.end()), 1);
205ca05601cSJames Henderson   EXPECT_EQ(Iter->Address, 0u);
206ca05601cSJames Henderson   EXPECT_EQ(Iter->Length, 1u);
207ca05601cSJames Henderson }
208ca05601cSJames Henderson 
TEST(DWARFDebugArangeSet,ZeroLengthEntry)209ca05601cSJames Henderson TEST(DWARFDebugArangeSet, ZeroLengthEntry) {
210ca05601cSJames Henderson   static const char DebugArangesSecRaw[] =
211ca05601cSJames Henderson       "\x1c\x00\x00\x00" // Length
212ca05601cSJames Henderson       "\x02\x00"         // Version
213ca05601cSJames Henderson       "\x00\x00\x00\x00" // Debug Info Offset
214ca05601cSJames Henderson       "\x04"             // Address Size
215ca05601cSJames Henderson       "\x00"             // Segment Selector Size
216ca05601cSJames Henderson       "\x00\x00\x00\x00" // Padding
217ca05601cSJames Henderson       "\x01\x00\x00\x00" // Entry1: Address
218ca05601cSJames Henderson       "\x00\x00\x00\x00" //         Length
219ca05601cSJames Henderson       "\x00\x00\x00\x00" // Termination tuple
220ca05601cSJames Henderson       "\x00\x00\x00\x00";
221ca05601cSJames Henderson   DWARFDataExtractor Extractor(
222ca05601cSJames Henderson       StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
223ca05601cSJames Henderson       /*IsLittleEndian=*/true,
224ca05601cSJames Henderson       /*AddressSize=*/4);
225ca05601cSJames Henderson   DWARFDebugArangeSet Set;
226ca05601cSJames Henderson   uint64_t Offset = 0;
227ca05601cSJames Henderson   ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, WarningHandler()),
228ca05601cSJames Henderson                     Succeeded());
229ca05601cSJames Henderson   auto Range = Set.descriptors();
230ca05601cSJames Henderson   auto Iter = Range.begin();
231f4d8e86dSHubert Tong   ASSERT_EQ(std::distance(Iter, Range.end()), 1);
232ca05601cSJames Henderson   EXPECT_EQ(Iter->Address, 1u);
233ca05601cSJames Henderson   EXPECT_EQ(Iter->Length, 0u);
234ca05601cSJames Henderson }
235ca05601cSJames Henderson 
TEST(DWARFDebugArangesSet,PrematureTerminator)236ca05601cSJames Henderson TEST(DWARFDebugArangesSet, PrematureTerminator) {
237ca05601cSJames Henderson   static const char DebugArangesSecRaw[] =
238ca05601cSJames Henderson       "\x24\x00\x00\x00" // Length
239ca05601cSJames Henderson       "\x02\x00"         // Version
240ca05601cSJames Henderson       "\x00\x00\x00\x00" // Debug Info Offset
241ca05601cSJames Henderson       "\x04"             // Address Size
242ca05601cSJames Henderson       "\x00"             // Segment Selector Size
243ca05601cSJames Henderson       "\x00\x00\x00\x00" // Padding
244ca05601cSJames Henderson       "\x00\x00\x00\x00" // Entry1: Premature
245ca05601cSJames Henderson       "\x00\x00\x00\x00" //         terminator
246ca05601cSJames Henderson       "\x01\x00\x00\x00" // Entry2: Address
247ca05601cSJames Henderson       "\x01\x00\x00\x00" //         Length
248ca05601cSJames Henderson       "\x00\x00\x00\x00" // Termination tuple
249ca05601cSJames Henderson       "\x00\x00\x00\x00";
250ca05601cSJames Henderson   DWARFDataExtractor Extractor(
251ca05601cSJames Henderson       StringRef(DebugArangesSecRaw, sizeof(DebugArangesSecRaw) - 1),
252ca05601cSJames Henderson       /*IsLittleEndian=*/true,
253ca05601cSJames Henderson       /*AddressSize=*/4);
254ca05601cSJames Henderson   DWARFDebugArangeSet Set;
255ca05601cSJames Henderson   uint64_t Offset = 0;
256ca05601cSJames Henderson   WarningHandler Warnings;
257ca05601cSJames Henderson   ASSERT_THAT_ERROR(Set.extract(Extractor, &Offset, Warnings), Succeeded());
258ca05601cSJames Henderson   auto Range = Set.descriptors();
259ca05601cSJames Henderson   auto Iter = Range.begin();
260f4d8e86dSHubert Tong   ASSERT_EQ(std::distance(Iter, Range.end()), 2);
261ca05601cSJames Henderson   EXPECT_EQ(Iter->Address, 0u);
262ca05601cSJames Henderson   EXPECT_EQ(Iter->Length, 0u);
263ca05601cSJames Henderson   ++Iter;
264ca05601cSJames Henderson   EXPECT_EQ(Iter->Address, 1u);
265ca05601cSJames Henderson   EXPECT_EQ(Iter->Length, 1u);
266ca05601cSJames Henderson   EXPECT_THAT_ERROR(
267ca05601cSJames Henderson       Warnings.getWarning(),
268ca05601cSJames Henderson       FailedWithMessage("address range table at offset 0x0 has a premature "
269ca05601cSJames Henderson                         "terminator entry at offset 0x10"));
270ed9851a0SIgor Kudrin }
271ed9851a0SIgor Kudrin 
272dcff3961SIgor Kudrin } // end anonymous namespace
273