[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / lldb / unittests / SymbolFile / DWARF / SymbolFileDWARFTests.cpp
blob92fb798d5d4813989f86f5414d2620b3ee024724
1 //===-- SymbolFileDWARFTests.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 //===----------------------------------------------------------------------===//
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"
40 using namespace lldb;
41 using namespace lldb_private;
43 class SymbolFileDWARFTests : public testing::Test {
44 SubsystemRAII<FileSystem, HostInfo, ObjectFilePECOFF, SymbolFileDWARF,
45 TypeSystemClang, SymbolFilePDB>
46 subsystems;
48 public:
49 void SetUp() override {
50 m_dwarf_test_exe = GetInputFilePath("test-dwarf.exe");
53 protected:
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
292 // abbreviation
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
323 // of this test
324 4, // address size
325 1, // segment size
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
328 // example.
329 0, 0, 0, 0, 0, 0,
330 // BEGIN TUPLES
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
335 // END TUPLES
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;
342 offset_t off = 0;
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)
365 4, // address size
366 0, // segment size
367 0, 0, 0, 0, // alignment for the first tuple
368 // BEGIN TUPLES
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)
373 // END TUPLES
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;
383 offset_t off = 0;
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)
404 4, // address size
405 0, // segment size
406 0, 0, 0, 0, // alignment for the first tuple
407 // BEGIN TUPLES
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)
412 // END TUPLES
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;
422 offset_t off = 0;
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
447 8, // address size
448 0, // segment size
449 0, 0, 0, 0, // pad bytes
450 // BEGIN TUPLES
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
457 // Terminating tuple
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
484 // is set correctly.
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
491 4, // address size
492 0, // segment size
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
501 4, // address size
502 0, // segment size
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
510 4, // address size
511 0, // segment size
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);