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