1 //===-- SymbolFileDWARFTests.cpp ------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
13 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
14 #include "llvm/Support/FileSystem.h"
15 #include "llvm/Support/Path.h"
17 #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
18 #include "Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h"
19 #include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h"
20 #include "Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h"
21 #include "Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h"
22 #include "Plugins/SymbolFile/DWARF/DWARFDebugAranges.h"
23 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
24 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
25 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
26 #include "TestingSupport/SubsystemRAII.h"
27 #include "TestingSupport/TestUtilities.h"
28 #include "lldb/Core/Address.h"
29 #include "lldb/Core/Module.h"
30 #include "lldb/Core/ModuleSpec.h"
31 #include "lldb/Host/FileSystem.h"
32 #include "lldb/Host/HostInfo.h"
33 #include "lldb/Symbol/CompileUnit.h"
34 #include "lldb/Symbol/LineTable.h"
35 #include "lldb/Utility/ArchSpec.h"
36 #include "lldb/Utility/DataEncoder.h"
37 #include "lldb/Utility/FileSpec.h"
38 #include "lldb/Utility/StreamString.h"
41 using namespace lldb_private
;
43 class SymbolFileDWARFTests
: public testing::Test
{
44 SubsystemRAII
<FileSystem
, HostInfo
, ObjectFilePECOFF
, SymbolFileDWARF
,
45 TypeSystemClang
, SymbolFilePDB
>
49 void SetUp() override
{
50 m_dwarf_test_exe
= GetInputFilePath("test-dwarf.exe");
54 std::string m_dwarf_test_exe
;
57 TEST_F(SymbolFileDWARFTests
, TestAbilitiesForDWARF
) {
58 // Test that when we have Dwarf debug info, SymbolFileDWARF is used.
59 FileSpec
fspec(m_dwarf_test_exe
);
60 ArchSpec
aspec("i686-pc-windows");
61 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
63 SymbolFile
*symfile
= module
->GetSymbolFile();
64 ASSERT_NE(nullptr, symfile
);
65 EXPECT_EQ(symfile
->GetPluginName(), SymbolFileDWARF::GetPluginNameStatic());
67 uint32_t expected_abilities
= SymbolFile::kAllAbilities
;
68 EXPECT_EQ(expected_abilities
, symfile
->CalculateAbilities());
71 TEST_F(SymbolFileDWARFTests
, TestAbbrevOrder1Start1
) {
72 // Test that if we have a .debug_abbrev that contains ordered abbreviation
73 // codes that start at 1, that we get O(1) access.
75 const auto byte_order
= eByteOrderLittle
;
76 const uint8_t addr_size
= 4;
77 StreamString
encoder(Stream::eBinary
, addr_size
, byte_order
);
78 encoder
.PutULEB128(1); // Abbrev code 1
79 encoder
.PutULEB128(DW_TAG_compile_unit
);
80 encoder
.PutHex8(DW_CHILDREN_yes
);
81 encoder
.PutULEB128(DW_AT_name
);
82 encoder
.PutULEB128(DW_FORM_strp
);
83 encoder
.PutULEB128(0);
84 encoder
.PutULEB128(0);
86 encoder
.PutULEB128(2); // Abbrev code 2
87 encoder
.PutULEB128(DW_TAG_subprogram
);
88 encoder
.PutHex8(DW_CHILDREN_no
);
89 encoder
.PutULEB128(DW_AT_name
);
90 encoder
.PutULEB128(DW_FORM_strp
);
91 encoder
.PutULEB128(0);
92 encoder
.PutULEB128(0);
94 encoder
.PutULEB128(0); // Abbrev code 0 (termination)
96 DWARFDataExtractor data
;
97 data
.SetData(encoder
.GetData(), encoder
.GetSize(), byte_order
);
98 DWARFAbbreviationDeclarationSet abbrev_set
;
99 lldb::offset_t data_offset
= 0;
100 llvm::Error error
= abbrev_set
.extract(data
, &data_offset
);
101 EXPECT_FALSE(bool(error
));
102 // Make sure we have O(1) access to each abbreviation by making sure the
103 // index offset is 1 and not UINT32_MAX
104 EXPECT_EQ(abbrev_set
.GetIndexOffset(), 1u);
106 auto abbrev1
= abbrev_set
.GetAbbreviationDeclaration(1);
107 EXPECT_EQ(abbrev1
->Tag(), DW_TAG_compile_unit
);
108 EXPECT_TRUE(abbrev1
->HasChildren());
109 EXPECT_EQ(abbrev1
->NumAttributes(), 1u);
110 auto abbrev2
= abbrev_set
.GetAbbreviationDeclaration(2);
111 EXPECT_EQ(abbrev2
->Tag(), DW_TAG_subprogram
);
112 EXPECT_FALSE(abbrev2
->HasChildren());
113 EXPECT_EQ(abbrev2
->NumAttributes(), 1u);
116 TEST_F(SymbolFileDWARFTests
, TestAbbrevOrder1Start5
) {
117 // Test that if we have a .debug_abbrev that contains ordered abbreviation
118 // codes that start at 5, that we get O(1) access.
120 const auto byte_order
= eByteOrderLittle
;
121 const uint8_t addr_size
= 4;
122 StreamString
encoder(Stream::eBinary
, addr_size
, byte_order
);
123 encoder
.PutULEB128(5); // Abbrev code 5
124 encoder
.PutULEB128(DW_TAG_compile_unit
);
125 encoder
.PutHex8(DW_CHILDREN_yes
);
126 encoder
.PutULEB128(DW_AT_name
);
127 encoder
.PutULEB128(DW_FORM_strp
);
128 encoder
.PutULEB128(0);
129 encoder
.PutULEB128(0);
131 encoder
.PutULEB128(6); // Abbrev code 6
132 encoder
.PutULEB128(DW_TAG_subprogram
);
133 encoder
.PutHex8(DW_CHILDREN_no
);
134 encoder
.PutULEB128(DW_AT_name
);
135 encoder
.PutULEB128(DW_FORM_strp
);
136 encoder
.PutULEB128(0);
137 encoder
.PutULEB128(0);
139 encoder
.PutULEB128(0); // Abbrev code 0 (termination)
141 DWARFDataExtractor data
;
142 data
.SetData(encoder
.GetData(), encoder
.GetSize(), byte_order
);
143 DWARFAbbreviationDeclarationSet abbrev_set
;
144 lldb::offset_t data_offset
= 0;
145 llvm::Error error
= abbrev_set
.extract(data
, &data_offset
);
146 EXPECT_FALSE(bool(error
));
147 // Make sure we have O(1) access to each abbreviation by making sure the
148 // index offset is 5 and not UINT32_MAX
149 EXPECT_EQ(abbrev_set
.GetIndexOffset(), 5u);
151 auto abbrev1
= abbrev_set
.GetAbbreviationDeclaration(5);
152 EXPECT_EQ(abbrev1
->Tag(), DW_TAG_compile_unit
);
153 EXPECT_TRUE(abbrev1
->HasChildren());
154 EXPECT_EQ(abbrev1
->NumAttributes(), 1u);
155 auto abbrev2
= abbrev_set
.GetAbbreviationDeclaration(6);
156 EXPECT_EQ(abbrev2
->Tag(), DW_TAG_subprogram
);
157 EXPECT_FALSE(abbrev2
->HasChildren());
158 EXPECT_EQ(abbrev2
->NumAttributes(), 1u);
161 TEST_F(SymbolFileDWARFTests
, TestAbbrevOutOfOrder
) {
162 // Test that if we have a .debug_abbrev that contains unordered abbreviation
163 // codes, that we can access the information correctly.
165 const auto byte_order
= eByteOrderLittle
;
166 const uint8_t addr_size
= 4;
167 StreamString
encoder(Stream::eBinary
, addr_size
, byte_order
);
168 encoder
.PutULEB128(2); // Abbrev code 2
169 encoder
.PutULEB128(DW_TAG_compile_unit
);
170 encoder
.PutHex8(DW_CHILDREN_yes
);
171 encoder
.PutULEB128(DW_AT_name
);
172 encoder
.PutULEB128(DW_FORM_strp
);
173 encoder
.PutULEB128(0);
174 encoder
.PutULEB128(0);
176 encoder
.PutULEB128(1); // Abbrev code 1
177 encoder
.PutULEB128(DW_TAG_subprogram
);
178 encoder
.PutHex8(DW_CHILDREN_no
);
179 encoder
.PutULEB128(DW_AT_name
);
180 encoder
.PutULEB128(DW_FORM_strp
);
181 encoder
.PutULEB128(0);
182 encoder
.PutULEB128(0);
184 encoder
.PutULEB128(0); // Abbrev code 0 (termination)
186 DWARFDataExtractor data
;
187 data
.SetData(encoder
.GetData(), encoder
.GetSize(), byte_order
);
188 DWARFAbbreviationDeclarationSet abbrev_set
;
189 lldb::offset_t data_offset
= 0;
190 llvm::Error error
= abbrev_set
.extract(data
, &data_offset
);
191 EXPECT_FALSE(bool(error
));
192 // Make sure we don't have O(1) access to each abbreviation by making sure
193 // the index offset is UINT32_MAX
194 EXPECT_EQ(abbrev_set
.GetIndexOffset(), UINT32_MAX
);
196 auto abbrev1
= abbrev_set
.GetAbbreviationDeclaration(2);
197 EXPECT_EQ(abbrev1
->Tag(), DW_TAG_compile_unit
);
198 EXPECT_TRUE(abbrev1
->HasChildren());
199 EXPECT_EQ(abbrev1
->NumAttributes(), 1u);
200 auto abbrev2
= abbrev_set
.GetAbbreviationDeclaration(1);
201 EXPECT_EQ(abbrev2
->Tag(), DW_TAG_subprogram
);
202 EXPECT_FALSE(abbrev2
->HasChildren());
203 EXPECT_EQ(abbrev2
->NumAttributes(), 1u);
206 TEST_F(SymbolFileDWARFTests
, TestAbbrevInvalidNULLTag
) {
207 // Test that we detect when an abbreviation has a NULL tag and that we get
208 // an error when decoding.
210 const auto byte_order
= eByteOrderLittle
;
211 const uint8_t addr_size
= 4;
212 StreamString
encoder(Stream::eBinary
, addr_size
, byte_order
);
213 encoder
.PutULEB128(1); // Abbrev code 1
214 encoder
.PutULEB128(0); // Invalid NULL tag here!
215 encoder
.PutHex8(DW_CHILDREN_no
);
216 encoder
.PutULEB128(0);
217 encoder
.PutULEB128(0);
219 encoder
.PutULEB128(0); // Abbrev code 0 (termination)
221 DWARFDataExtractor data
;
222 data
.SetData(encoder
.GetData(), encoder
.GetSize(), byte_order
);
223 DWARFAbbreviationDeclarationSet abbrev_set
;
224 lldb::offset_t data_offset
= 0;
225 llvm::Error error
= abbrev_set
.extract(data
, &data_offset
);
226 // Verify we get an error
227 EXPECT_TRUE(bool(error
));
228 EXPECT_EQ("abbrev decl requires non-null tag.",
229 llvm::toString(std::move(error
)));
233 TEST_F(SymbolFileDWARFTests
, TestAbbrevNullAttrValidForm
) {
234 // Test that we detect when an abbreviation has a NULL attribute and a non
235 // NULL form and that we get an error when decoding.
237 const auto byte_order
= eByteOrderLittle
;
238 const uint8_t addr_size
= 4;
239 StreamString
encoder(Stream::eBinary
, addr_size
, byte_order
);
240 encoder
.PutULEB128(1); // Abbrev code 1
241 encoder
.PutULEB128(DW_TAG_compile_unit
);
242 encoder
.PutHex8(DW_CHILDREN_no
);
243 encoder
.PutULEB128(0); // Invalid NULL DW_AT
244 encoder
.PutULEB128(DW_FORM_strp
); // With a valid form
245 encoder
.PutULEB128(0);
246 encoder
.PutULEB128(0);
248 encoder
.PutULEB128(0); // Abbrev code 0 (termination)
250 DWARFDataExtractor data
;
251 data
.SetData(encoder
.GetData(), encoder
.GetSize(), byte_order
);
252 DWARFAbbreviationDeclarationSet abbrev_set
;
253 lldb::offset_t data_offset
= 0;
254 llvm::Error error
= abbrev_set
.extract(data
, &data_offset
);
255 // Verify we get an error
256 EXPECT_TRUE(bool(error
));
257 EXPECT_EQ("malformed abbreviation declaration attribute",
258 llvm::toString(std::move(error
)));
261 TEST_F(SymbolFileDWARFTests
, TestAbbrevValidAttrNullForm
) {
262 // Test that we detect when an abbreviation has a valid attribute and a
263 // NULL form and that we get an error when decoding.
265 const auto byte_order
= eByteOrderLittle
;
266 const uint8_t addr_size
= 4;
267 StreamString
encoder(Stream::eBinary
, addr_size
, byte_order
);
268 encoder
.PutULEB128(1); // Abbrev code 1
269 encoder
.PutULEB128(DW_TAG_compile_unit
);
270 encoder
.PutHex8(DW_CHILDREN_no
);
271 encoder
.PutULEB128(DW_AT_name
); // Valid attribute
272 encoder
.PutULEB128(0); // NULL form
273 encoder
.PutULEB128(0);
274 encoder
.PutULEB128(0);
276 encoder
.PutULEB128(0); // Abbrev code 0 (termination)
278 DWARFDataExtractor data
;
279 data
.SetData(encoder
.GetData(), encoder
.GetSize(), byte_order
);
280 DWARFAbbreviationDeclarationSet abbrev_set
;
281 lldb::offset_t data_offset
= 0;
282 llvm::Error error
= abbrev_set
.extract(data
, &data_offset
);
283 // Verify we get an error
284 EXPECT_TRUE(bool(error
));
285 EXPECT_EQ("malformed abbreviation declaration attribute",
286 llvm::toString(std::move(error
)));
289 TEST_F(SymbolFileDWARFTests
, TestAbbrevMissingTerminator
) {
290 // Test that we detect when an abbreviation has a valid attribute and a
291 // form, but is missing the NULL attribute and form that terminates an
294 const auto byte_order
= eByteOrderLittle
;
295 const uint8_t addr_size
= 4;
296 StreamString
encoder(Stream::eBinary
, addr_size
, byte_order
);
297 encoder
.PutULEB128(1); // Abbrev code 1
298 encoder
.PutULEB128(DW_TAG_compile_unit
);
299 encoder
.PutHex8(DW_CHILDREN_no
);
300 encoder
.PutULEB128(DW_AT_name
);
301 encoder
.PutULEB128(DW_FORM_strp
);
302 // Don't add the NULL DW_AT and NULL DW_FORM terminator
304 DWARFDataExtractor data
;
305 data
.SetData(encoder
.GetData(), encoder
.GetSize(), byte_order
);
306 DWARFAbbreviationDeclarationSet abbrev_set
;
307 lldb::offset_t data_offset
= 0;
308 llvm::Error error
= abbrev_set
.extract(data
, &data_offset
);
309 // Verify we get an error
310 EXPECT_TRUE(bool(error
));
311 EXPECT_EQ("abbreviation declaration attribute list not terminated with a "
312 "null entry", llvm::toString(std::move(error
)));
315 TEST_F(SymbolFileDWARFTests
, ParseArangesNonzeroSegmentSize
) {
316 // This `.debug_aranges` table header is a valid 32bit big-endian section
317 // according to the DWARFv5 spec:6.2.1, but contains segment selectors which
318 // are not supported by lldb, and should be gracefully rejected
319 const unsigned char binary_data
[] = {
320 0, 0, 0, 41, // unit_length (length field not including this field itself)
321 0, 2, // DWARF version number (half)
322 0, 0, 0, 0, // offset into the .debug_info_table (ignored for the purposes
326 // alignment for the first tuple which "begins at an offset that is a
327 // multiple of the size of a single tuple". Tuples are nine bytes in this
331 1, 0, 0, 0, 4, 0, 0, 0,
332 1, // a 1byte object starting at address 4 in segment 1
333 0, 0, 0, 0, 4, 0, 0, 0,
334 1, // a 1byte object starting at address 4 in segment 0
336 0, 0, 0, 0, 0, 0, 0, 0, 0 // terminator
338 DWARFDataExtractor data
;
339 data
.SetData(static_cast<const void *>(binary_data
), sizeof binary_data
,
340 lldb::ByteOrder::eByteOrderBig
);
341 DWARFDebugArangeSet debug_aranges
;
343 llvm::Error error
= debug_aranges
.extract(data
, &off
);
344 EXPECT_TRUE(bool(error
));
345 EXPECT_EQ("segmented arange entries are not supported",
346 llvm::toString(std::move(error
)));
347 EXPECT_EQ(off
, 12U); // Parser should read no further than the segment size
350 TEST_F(SymbolFileDWARFTests
, ParseArangesWithMultipleTerminators
) {
351 // This .debug_aranges set has multiple terminator entries which appear in
352 // binaries produced by popular linux compilers and linker combinations. We
353 // must be able to parse all the way through the data for each
354 // DWARFDebugArangeSet. Previously the DWARFDebugArangeSet::extract()
355 // function would stop parsing as soon as we ran into a terminator even
356 // though the length field stated that there was more data that follows. This
357 // would cause the next DWARFDebugArangeSet to be parsed immediately
358 // following the first terminator and it would attempt to decode the
359 // DWARFDebugArangeSet header using the remaining segment + address pairs
360 // from the remaining bytes.
361 unsigned char binary_data
[] = {
362 0, 0, 0, 0, // unit_length that will be set correctly after this
363 0, 2, // DWARF version number (uint16_t)
364 0, 0, 0, 0, // CU offset (ignored for the purposes of this test)
367 0, 0, 0, 0, // alignment for the first tuple
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // premature terminator
370 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100)
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // premature terminator
372 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, // [0x2000-0x2010)
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
376 // Set the big endian length correctly.
377 const offset_t binary_data_size
= sizeof(binary_data
);
378 binary_data
[3] = (uint8_t)binary_data_size
- 4;
379 DWARFDataExtractor data
;
380 data
.SetData(static_cast<const void *>(binary_data
), sizeof binary_data
,
381 lldb::ByteOrder::eByteOrderBig
);
382 DWARFDebugArangeSet set
;
384 llvm::Error error
= set
.extract(data
, &off
);
385 // Multiple terminators are not fatal as they do appear in binaries.
386 EXPECT_FALSE(bool(error
));
387 // Parser should read all terminators to the end of the length specified.
388 EXPECT_EQ(off
, binary_data_size
);
389 ASSERT_EQ(set
.NumDescriptors(), 2U);
390 ASSERT_EQ(set
.GetDescriptorRef(0).address
, (dw_addr_t
)0x1000);
391 ASSERT_EQ(set
.GetDescriptorRef(0).length
, (dw_addr_t
)0x100);
392 ASSERT_EQ(set
.GetDescriptorRef(1).address
, (dw_addr_t
)0x2000);
393 ASSERT_EQ(set
.GetDescriptorRef(1).length
, (dw_addr_t
)0x10);
396 TEST_F(SymbolFileDWARFTests
, ParseArangesIgnoreEmpty
) {
397 // This .debug_aranges set has some address ranges which have zero length
398 // and we ensure that these are ignored by our DWARFDebugArangeSet parser
399 // and not included in the descriptors that are returned.
400 unsigned char binary_data
[] = {
401 0, 0, 0, 0, // unit_length that will be set correctly after this
402 0, 2, // DWARF version number (uint16_t)
403 0, 0, 0, 0, // CU offset (ignored for the purposes of this test)
406 0, 0, 0, 0, // alignment for the first tuple
408 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100)
409 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, // [0x1100-0x1100)
410 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, // [0x2000-0x2010)
411 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // [0x2010-0x2010)
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
415 // Set the big endian length correctly.
416 const offset_t binary_data_size
= sizeof(binary_data
);
417 binary_data
[3] = (uint8_t)binary_data_size
- 4;
418 DWARFDataExtractor data
;
419 data
.SetData(static_cast<const void *>(binary_data
), sizeof binary_data
,
420 lldb::ByteOrder::eByteOrderBig
);
421 DWARFDebugArangeSet set
;
423 llvm::Error error
= set
.extract(data
, &off
);
424 // Multiple terminators are not fatal as they do appear in binaries.
425 EXPECT_FALSE(bool(error
));
426 // Parser should read all terminators to the end of the length specified.
427 // Previously the DWARFDebugArangeSet would stop at the first terminator
428 // entry and leave the offset in the middle of the current
429 // DWARFDebugArangeSet data, and that would cause the next extracted
430 // DWARFDebugArangeSet to fail.
431 EXPECT_EQ(off
, binary_data_size
);
432 ASSERT_EQ(set
.NumDescriptors(), 2U);
433 ASSERT_EQ(set
.GetDescriptorRef(0).address
, (dw_addr_t
)0x1000);
434 ASSERT_EQ(set
.GetDescriptorRef(0).length
, (dw_addr_t
)0x100);
435 ASSERT_EQ(set
.GetDescriptorRef(1).address
, (dw_addr_t
)0x2000);
436 ASSERT_EQ(set
.GetDescriptorRef(1).length
, (dw_addr_t
)0x10);
439 TEST_F(SymbolFileDWARFTests
, ParseAranges
) {
440 // Test we can successfully parse a DWARFDebugAranges. The initial error
441 // checking code had a bug where it would always return an empty address
442 // ranges for everything in .debug_aranges and no error.
443 unsigned char binary_data
[] = {
444 0, 0, 0, 0, // unit_length that will be set correctly after this
445 2, 0, // DWARF version number
446 255, 0, 0, 0, // offset into the .debug_info_table
449 0, 0, 0, 0, // pad bytes
451 // First tuple: [0x1000-0x1100)
452 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Address 0x1000
453 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Size 0x0100
454 // Second tuple: [0x2000-0x2100)
455 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Address 0x2000
456 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Size 0x0100
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Terminator
460 // Set the little endian length correctly.
461 binary_data
[0] = sizeof(binary_data
) - 4;
462 DWARFDataExtractor data
;
463 data
.SetData(static_cast<const void *>(binary_data
), sizeof binary_data
,
464 lldb::ByteOrder::eByteOrderLittle
);
465 DWARFDebugAranges debug_aranges
;
466 debug_aranges
.extract(data
);
467 EXPECT_EQ(debug_aranges
.GetNumRanges(), 2u);
468 EXPECT_EQ(debug_aranges
.FindAddress(0x0fff), DW_INVALID_OFFSET
);
469 EXPECT_EQ(debug_aranges
.FindAddress(0x1000), 255u);
470 EXPECT_EQ(debug_aranges
.FindAddress(0x1100 - 1), 255u);
471 EXPECT_EQ(debug_aranges
.FindAddress(0x1100), DW_INVALID_OFFSET
);
472 EXPECT_EQ(debug_aranges
.FindAddress(0x1fff), DW_INVALID_OFFSET
);
473 EXPECT_EQ(debug_aranges
.FindAddress(0x2000), 255u);
474 EXPECT_EQ(debug_aranges
.FindAddress(0x2100 - 1), 255u);
475 EXPECT_EQ(debug_aranges
.FindAddress(0x2100), DW_INVALID_OFFSET
);
478 TEST_F(SymbolFileDWARFTests
, ParseArangesSkipErrors
) {
479 // Test we can successfully parse a DWARFDebugAranges that contains some
480 // valid DWARFDebugArangeSet objects and some with errors as long as their
481 // length is set correctly. This helps LLDB ensure that it can parse newer
482 // .debug_aranges version that LLDB currently doesn't support, or ignore
483 // errors in individual DWARFDebugArangeSet objects as long as the length
485 const unsigned char binary_data
[] = {
486 // This DWARFDebugArangeSet is well formed and has a single address range
487 // for [0x1000-0x1100) with a CU offset of 0x00000000.
488 0, 0, 0, 28, // unit_length that will be set correctly after this
489 0, 2, // DWARF version number (uint16_t)
490 0, 0, 0, 0, // CU offset = 0x00000000
493 0, 0, 0, 0, // alignment for the first tuple
494 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x1000-0x1100)
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
496 // This DWARFDebugArangeSet has the correct length, but an invalid
497 // version. We need to be able to skip this correctly and ignore it.
498 0, 0, 0, 20, // unit_length that will be set correctly after this
499 0, 44, // invalid DWARF version number (uint16_t)
500 0, 0, 1, 0, // CU offset = 0x00000100
503 0, 0, 0, 0, // alignment for the first tuple
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
505 // This DWARFDebugArangeSet is well formed and has a single address range
506 // for [0x2000-0x2100) with a CU offset of 0x00000000.
507 0, 0, 0, 28, // unit_length that will be set correctly after this
508 0, 2, // DWARF version number (uint16_t)
509 0, 0, 2, 0, // CU offset = 0x00000200
512 0, 0, 0, 0, // alignment for the first tuple
513 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, // [0x2000-0x2100)
514 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // terminator
517 DWARFDataExtractor data
;
518 data
.SetData(static_cast<const void *>(binary_data
), sizeof binary_data
,
519 lldb::ByteOrder::eByteOrderBig
);
520 DWARFDebugAranges debug_aranges
;
521 debug_aranges
.extract(data
);
522 EXPECT_EQ(debug_aranges
.GetNumRanges(), 2u);
523 EXPECT_EQ(debug_aranges
.FindAddress(0x0fff), DW_INVALID_OFFSET
);
524 EXPECT_EQ(debug_aranges
.FindAddress(0x1000), 0u);
525 EXPECT_EQ(debug_aranges
.FindAddress(0x1100 - 1), 0u);
526 EXPECT_EQ(debug_aranges
.FindAddress(0x1100), DW_INVALID_OFFSET
);
527 EXPECT_EQ(debug_aranges
.FindAddress(0x1fff), DW_INVALID_OFFSET
);
528 EXPECT_EQ(debug_aranges
.FindAddress(0x2000), 0x200u
);
529 EXPECT_EQ(debug_aranges
.FindAddress(0x2100 - 1), 0x200u
);
530 EXPECT_EQ(debug_aranges
.FindAddress(0x2100), DW_INVALID_OFFSET
);