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