1 //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// 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 "DWARFDebugInfoEntry.h" 10 11 #include <assert.h> 12 13 #include <algorithm> 14 15 #include "lldb/Core/Module.h" 16 #include "lldb/Expression/DWARFExpression.h" 17 #include "lldb/Symbol/ObjectFile.h" 18 #include "lldb/Utility/Stream.h" 19 20 #include "DWARFUnit.h" 21 #include "DWARFDebugAbbrev.h" 22 #include "DWARFDebugAranges.h" 23 #include "DWARFDebugInfo.h" 24 #include "DWARFDebugRanges.h" 25 #include "DWARFDeclContext.h" 26 #include "DWARFFormValue.h" 27 #include "SymbolFileDWARF.h" 28 #include "SymbolFileDWARFDwo.h" 29 30 using namespace lldb_private; 31 using namespace std; 32 extern int g_verbose; 33 34 bool DWARFDebugInfoEntry::FastExtract( 35 const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu, 36 lldb::offset_t *offset_ptr) { 37 m_offset = *offset_ptr; 38 m_parent_idx = 0; 39 m_sibling_idx = 0; 40 const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr); 41 lldbassert(abbr_idx <= UINT16_MAX); 42 m_abbr_idx = abbr_idx; 43 44 // assert (fixed_form_sizes); // For best performance this should be 45 // specified! 46 47 if (m_abbr_idx) { 48 lldb::offset_t offset = *offset_ptr; 49 50 const DWARFAbbreviationDeclaration *abbrevDecl = 51 cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx); 52 53 if (abbrevDecl == nullptr) { 54 cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( 55 "{0x%8.8x}: invalid abbreviation code %u, please file a bug and " 56 "attach the file at the start of this error message", 57 m_offset, (unsigned)abbr_idx); 58 // WE can't parse anymore if the DWARF is borked... 59 *offset_ptr = UINT32_MAX; 60 return false; 61 } 62 m_tag = abbrevDecl->Tag(); 63 m_has_children = abbrevDecl->HasChildren(); 64 // Skip all data in the .debug_info for the attributes 65 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 66 uint32_t i; 67 dw_form_t form; 68 for (i = 0; i < numAttributes; ++i) { 69 form = abbrevDecl->GetFormByIndexUnchecked(i); 70 71 llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); 72 if (fixed_skip_size) 73 offset += *fixed_skip_size; 74 else { 75 bool form_is_indirect = false; 76 do { 77 form_is_indirect = false; 78 uint32_t form_size = 0; 79 switch (form) { 80 // Blocks if inlined data that have a length field and the data bytes 81 // inlined in the .debug_info 82 case DW_FORM_exprloc: 83 case DW_FORM_block: 84 form_size = debug_info_data.GetULEB128(&offset); 85 break; 86 case DW_FORM_block1: 87 form_size = debug_info_data.GetU8_unchecked(&offset); 88 break; 89 case DW_FORM_block2: 90 form_size = debug_info_data.GetU16_unchecked(&offset); 91 break; 92 case DW_FORM_block4: 93 form_size = debug_info_data.GetU32_unchecked(&offset); 94 break; 95 96 // Inlined NULL terminated C-strings 97 case DW_FORM_string: 98 debug_info_data.GetCStr(&offset); 99 break; 100 101 // Compile unit address sized values 102 case DW_FORM_addr: 103 form_size = cu->GetAddressByteSize(); 104 break; 105 case DW_FORM_ref_addr: 106 if (cu->GetVersion() <= 2) 107 form_size = cu->GetAddressByteSize(); 108 else 109 form_size = 4; 110 break; 111 112 // 0 sized form 113 case DW_FORM_flag_present: 114 form_size = 0; 115 break; 116 117 // 1 byte values 118 case DW_FORM_addrx1: 119 case DW_FORM_data1: 120 case DW_FORM_flag: 121 case DW_FORM_ref1: 122 case DW_FORM_strx1: 123 form_size = 1; 124 break; 125 126 // 2 byte values 127 case DW_FORM_addrx2: 128 case DW_FORM_data2: 129 case DW_FORM_ref2: 130 case DW_FORM_strx2: 131 form_size = 2; 132 break; 133 134 // 3 byte values 135 case DW_FORM_addrx3: 136 case DW_FORM_strx3: 137 form_size = 3; 138 break; 139 140 // 4 byte values 141 case DW_FORM_addrx4: 142 case DW_FORM_data4: 143 case DW_FORM_ref4: 144 case DW_FORM_strx4: 145 form_size = 4; 146 break; 147 148 // 8 byte values 149 case DW_FORM_data8: 150 case DW_FORM_ref8: 151 case DW_FORM_ref_sig8: 152 form_size = 8; 153 break; 154 155 // signed or unsigned LEB 128 values 156 case DW_FORM_addrx: 157 case DW_FORM_rnglistx: 158 case DW_FORM_sdata: 159 case DW_FORM_udata: 160 case DW_FORM_ref_udata: 161 case DW_FORM_GNU_addr_index: 162 case DW_FORM_GNU_str_index: 163 case DW_FORM_strx: 164 debug_info_data.Skip_LEB128(&offset); 165 break; 166 167 case DW_FORM_indirect: 168 form_is_indirect = true; 169 form = debug_info_data.GetULEB128(&offset); 170 break; 171 172 case DW_FORM_strp: 173 case DW_FORM_sec_offset: 174 debug_info_data.GetU32(&offset); 175 break; 176 177 case DW_FORM_implicit_const: 178 form_size = 0; 179 break; 180 181 default: 182 *offset_ptr = m_offset; 183 return false; 184 } 185 offset += form_size; 186 187 } while (form_is_indirect); 188 } 189 } 190 *offset_ptr = offset; 191 return true; 192 } else { 193 m_tag = 0; 194 m_has_children = false; 195 return true; // NULL debug tag entry 196 } 197 198 return false; 199 } 200 201 // Extract 202 // 203 // Extract a debug info entry for a given compile unit from the .debug_info and 204 // .debug_abbrev data within the SymbolFileDWARF class starting at the given 205 // offset 206 bool DWARFDebugInfoEntry::Extract(const DWARFUnit *cu, 207 lldb::offset_t *offset_ptr) { 208 const DWARFDataExtractor &debug_info_data = cu->GetData(); 209 // const DWARFDataExtractor& debug_str_data = 210 // dwarf2Data->get_debug_str_data(); 211 const uint32_t cu_end_offset = cu->GetNextUnitOffset(); 212 lldb::offset_t offset = *offset_ptr; 213 // if (offset >= cu_end_offset) 214 // Log::Status("DIE at offset 0x%8.8x is beyond the end of the current 215 // compile unit (0x%8.8x)", m_offset, cu_end_offset); 216 if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) { 217 m_offset = offset; 218 219 const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); 220 lldbassert(abbr_idx <= UINT16_MAX); 221 m_abbr_idx = abbr_idx; 222 if (abbr_idx) { 223 const DWARFAbbreviationDeclaration *abbrevDecl = 224 cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx); 225 226 if (abbrevDecl) { 227 m_tag = abbrevDecl->Tag(); 228 m_has_children = abbrevDecl->HasChildren(); 229 230 bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit || 231 m_tag == DW_TAG_partial_unit); 232 if (cu && isCompileUnitTag) 233 const_cast<DWARFUnit *>(cu)->SetBaseAddress(0); 234 235 // Skip all data in the .debug_info for the attributes 236 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 237 for (uint32_t i = 0; i < numAttributes; ++i) { 238 DWARFFormValue form_value(cu); 239 dw_attr_t attr; 240 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); 241 dw_form_t form = form_value.Form(); 242 243 if (isCompileUnitTag && 244 ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { 245 if (form_value.ExtractValue(debug_info_data, &offset)) { 246 if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) 247 const_cast<DWARFUnit *>(cu)->SetBaseAddress( 248 form_value.Address()); 249 } 250 } else { 251 bool form_is_indirect = false; 252 do { 253 form_is_indirect = false; 254 uint32_t form_size = 0; 255 switch (form) { 256 // Blocks if inlined data that have a length field and the data 257 // bytes inlined in the .debug_info 258 case DW_FORM_exprloc: 259 case DW_FORM_block: 260 form_size = debug_info_data.GetULEB128(&offset); 261 break; 262 case DW_FORM_block1: 263 form_size = debug_info_data.GetU8(&offset); 264 break; 265 case DW_FORM_block2: 266 form_size = debug_info_data.GetU16(&offset); 267 break; 268 case DW_FORM_block4: 269 form_size = debug_info_data.GetU32(&offset); 270 break; 271 272 // Inlined NULL terminated C-strings 273 case DW_FORM_string: 274 debug_info_data.GetCStr(&offset); 275 break; 276 277 // Compile unit address sized values 278 case DW_FORM_addr: 279 form_size = cu->GetAddressByteSize(); 280 break; 281 case DW_FORM_ref_addr: 282 if (cu->GetVersion() <= 2) 283 form_size = cu->GetAddressByteSize(); 284 else 285 form_size = 4; 286 break; 287 288 // 0 sized form 289 case DW_FORM_flag_present: 290 case DW_FORM_implicit_const: 291 form_size = 0; 292 break; 293 294 // 1 byte values 295 case DW_FORM_data1: 296 case DW_FORM_flag: 297 case DW_FORM_ref1: 298 form_size = 1; 299 break; 300 301 // 2 byte values 302 case DW_FORM_data2: 303 case DW_FORM_ref2: 304 form_size = 2; 305 break; 306 307 // 4 byte values 308 case DW_FORM_data4: 309 case DW_FORM_ref4: 310 form_size = 4; 311 break; 312 313 // 8 byte values 314 case DW_FORM_data8: 315 case DW_FORM_ref8: 316 case DW_FORM_ref_sig8: 317 form_size = 8; 318 break; 319 320 // signed or unsigned LEB 128 values 321 case DW_FORM_addrx: 322 case DW_FORM_sdata: 323 case DW_FORM_udata: 324 case DW_FORM_ref_udata: 325 case DW_FORM_GNU_addr_index: 326 case DW_FORM_GNU_str_index: 327 debug_info_data.Skip_LEB128(&offset); 328 break; 329 330 case DW_FORM_indirect: 331 form = debug_info_data.GetULEB128(&offset); 332 form_is_indirect = true; 333 break; 334 335 case DW_FORM_strp: 336 case DW_FORM_sec_offset: 337 debug_info_data.GetU32(&offset); 338 break; 339 340 default: 341 *offset_ptr = offset; 342 return false; 343 } 344 345 offset += form_size; 346 } while (form_is_indirect); 347 } 348 } 349 *offset_ptr = offset; 350 return true; 351 } 352 } else { 353 m_tag = 0; 354 m_has_children = false; 355 *offset_ptr = offset; 356 return true; // NULL debug tag entry 357 } 358 } 359 360 return false; 361 } 362 363 static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges, 364 DWARFFormValue &form_value) { 365 if (form_value.Form() == DW_FORM_rnglistx) 366 return debug_ranges->GetOffset(form_value.Unsigned()); 367 return form_value.Unsigned(); 368 } 369 370 // GetDIENamesAndRanges 371 // 372 // Gets the valid address ranges for a given DIE by looking for a 373 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes. 374 bool DWARFDebugInfoEntry::GetDIENamesAndRanges( 375 const DWARFUnit *cu, const char *&name, const char *&mangled, 376 DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column, 377 int &call_file, int &call_line, int &call_column, 378 DWARFExpression *frame_base) const { 379 SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); 380 if (dwo_symbol_file) 381 return GetDIENamesAndRanges( 382 dwo_symbol_file->GetCompileUnit(), name, mangled, ranges, decl_file, 383 decl_line, decl_column, call_file, call_line, call_column, frame_base); 384 385 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 386 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 387 std::vector<DIERef> die_refs; 388 bool set_frame_base_loclist_addr = false; 389 390 lldb::offset_t offset; 391 const DWARFAbbreviationDeclaration *abbrevDecl = 392 GetAbbreviationDeclarationPtr(cu, offset); 393 394 SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF(); 395 lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); 396 397 if (abbrevDecl) { 398 const DWARFDataExtractor &debug_info_data = cu->GetData(); 399 400 if (!debug_info_data.ValidOffset(offset)) 401 return false; 402 403 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 404 bool do_offset = false; 405 406 for (uint32_t i = 0; i < numAttributes; ++i) { 407 DWARFFormValue form_value(cu); 408 dw_attr_t attr; 409 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); 410 411 if (form_value.ExtractValue(debug_info_data, &offset)) { 412 switch (attr) { 413 case DW_AT_low_pc: 414 lo_pc = form_value.Address(); 415 416 if (do_offset) 417 hi_pc += lo_pc; 418 do_offset = false; 419 break; 420 421 case DW_AT_entry_pc: 422 lo_pc = form_value.Address(); 423 break; 424 425 case DW_AT_high_pc: 426 if (form_value.Form() == DW_FORM_addr || 427 form_value.Form() == DW_FORM_addrx || 428 form_value.Form() == DW_FORM_GNU_addr_index) { 429 hi_pc = form_value.Address(); 430 } else { 431 hi_pc = form_value.Unsigned(); 432 if (lo_pc == LLDB_INVALID_ADDRESS) 433 do_offset = hi_pc != LLDB_INVALID_ADDRESS; 434 else 435 hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save 436 // on relocations 437 } 438 break; 439 440 case DW_AT_ranges: { 441 const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); 442 if (debug_ranges) 443 debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges); 444 else 445 cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( 446 "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 447 ") attribute yet DWARF has no .debug_ranges, please file a bug " 448 "and attach the file at the start of this error message", 449 m_offset, form_value.Unsigned()); 450 } break; 451 452 case DW_AT_name: 453 if (name == nullptr) 454 name = form_value.AsCString(); 455 break; 456 457 case DW_AT_MIPS_linkage_name: 458 case DW_AT_linkage_name: 459 if (mangled == nullptr) 460 mangled = form_value.AsCString(); 461 break; 462 463 case DW_AT_abstract_origin: 464 die_refs.emplace_back(form_value); 465 break; 466 467 case DW_AT_specification: 468 die_refs.emplace_back(form_value); 469 break; 470 471 case DW_AT_decl_file: 472 if (decl_file == 0) 473 decl_file = form_value.Unsigned(); 474 break; 475 476 case DW_AT_decl_line: 477 if (decl_line == 0) 478 decl_line = form_value.Unsigned(); 479 break; 480 481 case DW_AT_decl_column: 482 if (decl_column == 0) 483 decl_column = form_value.Unsigned(); 484 break; 485 486 case DW_AT_call_file: 487 if (call_file == 0) 488 call_file = form_value.Unsigned(); 489 break; 490 491 case DW_AT_call_line: 492 if (call_line == 0) 493 call_line = form_value.Unsigned(); 494 break; 495 496 case DW_AT_call_column: 497 if (call_column == 0) 498 call_column = form_value.Unsigned(); 499 break; 500 501 case DW_AT_frame_base: 502 if (frame_base) { 503 if (form_value.BlockData()) { 504 uint32_t block_offset = 505 form_value.BlockData() - debug_info_data.GetDataStart(); 506 uint32_t block_length = form_value.Unsigned(); 507 frame_base->SetOpcodeData(module, debug_info_data, block_offset, 508 block_length); 509 } else { 510 const DWARFDataExtractor &debug_loc_data = 511 dwarf2Data->DebugLocData(); 512 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 513 514 size_t loc_list_length = DWARFExpression::LocationListSize( 515 cu, debug_loc_data, debug_loc_offset); 516 if (loc_list_length > 0) { 517 frame_base->SetOpcodeData(module, debug_loc_data, 518 debug_loc_offset, loc_list_length); 519 if (lo_pc != LLDB_INVALID_ADDRESS) { 520 assert(lo_pc >= cu->GetBaseAddress()); 521 frame_base->SetLocationListSlide(lo_pc - 522 cu->GetBaseAddress()); 523 } else { 524 set_frame_base_loclist_addr = true; 525 } 526 } 527 } 528 } 529 break; 530 531 default: 532 break; 533 } 534 } 535 } 536 } 537 538 if (ranges.IsEmpty()) { 539 if (lo_pc != LLDB_INVALID_ADDRESS) { 540 if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc) 541 ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); 542 else 543 ranges.Append(DWARFRangeList::Entry(lo_pc, 0)); 544 } 545 } 546 547 if (set_frame_base_loclist_addr) { 548 dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0); 549 assert(lowest_range_pc >= cu->GetBaseAddress()); 550 frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress()); 551 } 552 553 if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) { 554 for (const DIERef &die_ref : die_refs) { 555 if (die_ref.die_offset != DW_INVALID_OFFSET) { 556 DWARFDIE die = dwarf2Data->GetDIE(die_ref); 557 if (die) 558 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges, 559 decl_file, decl_line, decl_column, 560 call_file, call_line, call_column); 561 } 562 } 563 } 564 return !ranges.IsEmpty(); 565 } 566 567 // Dump 568 // 569 // Dumps a debug information entry and all of it's attributes to the specified 570 // stream. 571 void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s, 572 uint32_t recurse_depth) const { 573 const DWARFDataExtractor &debug_info_data = cu->GetData(); 574 lldb::offset_t offset = m_offset; 575 576 if (debug_info_data.ValidOffset(offset)) { 577 dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset); 578 579 s.Printf("\n0x%8.8x: ", m_offset); 580 s.Indent(); 581 if (abbrCode != m_abbr_idx) { 582 s.Printf("error: DWARF has been modified\n"); 583 } else if (abbrCode) { 584 const DWARFAbbreviationDeclaration *abbrevDecl = 585 cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode); 586 587 if (abbrevDecl) { 588 s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); 589 s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' '); 590 591 // Dump all data in the .debug_info for the attributes 592 const uint32_t numAttributes = abbrevDecl->NumAttributes(); 593 for (uint32_t i = 0; i < numAttributes; ++i) { 594 DWARFFormValue form_value(cu); 595 dw_attr_t attr; 596 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); 597 598 DumpAttribute(cu, debug_info_data, &offset, s, attr, form_value); 599 } 600 601 const DWARFDebugInfoEntry *child = GetFirstChild(); 602 if (recurse_depth > 0 && child) { 603 s.IndentMore(); 604 605 while (child) { 606 child->Dump(cu, s, recurse_depth - 1); 607 child = child->GetSibling(); 608 } 609 s.IndentLess(); 610 } 611 } else 612 s.Printf("Abbreviation code note found in 'debug_abbrev' class for " 613 "code: %u\n", 614 abbrCode); 615 } else { 616 s.Printf("NULL\n"); 617 } 618 } 619 } 620 621 // DumpAttribute 622 // 623 // Dumps a debug information entry attribute along with it's form. Any special 624 // display of attributes is done (disassemble location lists, show enumeration 625 // values for attributes, etc). 626 void DWARFDebugInfoEntry::DumpAttribute( 627 const DWARFUnit *cu, const DWARFDataExtractor &debug_info_data, 628 lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr, 629 DWARFFormValue &form_value) { 630 bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); 631 632 s.Printf(" "); 633 s.Indent(DW_AT_value_to_name(attr)); 634 635 if (show_form) { 636 s.Printf("[%s", DW_FORM_value_to_name(form_value.Form())); 637 } 638 639 if (!form_value.ExtractValue(debug_info_data, offset_ptr)) 640 return; 641 642 if (show_form) { 643 if (form_value.Form() == DW_FORM_indirect) { 644 s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); 645 } 646 647 s.PutCString("] "); 648 } 649 650 s.PutCString("( "); 651 652 SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF(); 653 654 // Check to see if we have any special attribute formatters 655 switch (attr) { 656 case DW_AT_stmt_list: 657 s.Printf("0x%8.8" PRIx64, form_value.Unsigned()); 658 break; 659 660 case DW_AT_language: 661 s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); 662 break; 663 664 case DW_AT_encoding: 665 s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); 666 break; 667 668 case DW_AT_frame_base: 669 case DW_AT_location: 670 case DW_AT_data_member_location: { 671 const uint8_t *blockData = form_value.BlockData(); 672 if (blockData) { 673 // Location description is inlined in data in the form value 674 DWARFDataExtractor locationData(debug_info_data, 675 (*offset_ptr) - form_value.Unsigned(), 676 form_value.Unsigned()); 677 DWARFExpression::PrintDWARFExpression( 678 s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false); 679 } else { 680 // We have a location list offset as the value that is the offset into 681 // the .debug_loc section that describes the value over it's lifetime 682 uint64_t debug_loc_offset = form_value.Unsigned(); 683 if (dwarf2Data) { 684 DWARFExpression::PrintDWARFLocationList( 685 s, cu, dwarf2Data->DebugLocData(), debug_loc_offset); 686 } 687 } 688 } break; 689 690 case DW_AT_abstract_origin: 691 case DW_AT_specification: { 692 DWARFDIE abstract_die = form_value.Reference(); 693 form_value.Dump(s); 694 // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( "; 695 abstract_die.GetName(s); 696 } break; 697 698 case DW_AT_type: { 699 DWARFDIE type_die = form_value.Reference(); 700 s.PutCString(" ( "); 701 type_die.AppendTypeName(s); 702 s.PutCString(" )"); 703 } break; 704 705 case DW_AT_ranges: { 706 lldb::offset_t ranges_offset = 707 GetRangesOffset(dwarf2Data->DebugRanges(), form_value); 708 dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; 709 DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), 710 &ranges_offset, base_addr); 711 } break; 712 713 default: 714 break; 715 } 716 717 s.PutCString(" )\n"); 718 } 719 720 // Get all attribute values for a given DIE, including following any 721 // specification or abstract origin attributes and including those in the 722 // results. Any duplicate attributes will have the first instance take 723 // precedence (this can happen for declaration attributes). 724 size_t DWARFDebugInfoEntry::GetAttributes( 725 const DWARFUnit *cu, DWARFAttributes &attributes, 726 uint32_t curr_depth) const { 727 const DWARFAbbreviationDeclaration *abbrevDecl = nullptr; 728 lldb::offset_t offset = 0; 729 if (cu) 730 abbrevDecl = GetAbbreviationDeclarationPtr(cu, offset); 731 732 if (abbrevDecl) { 733 const DWARFDataExtractor &debug_info_data = cu->GetData(); 734 735 const uint32_t num_attributes = abbrevDecl->NumAttributes(); 736 for (uint32_t i = 0; i < num_attributes; ++i) { 737 DWARFFormValue form_value(cu); 738 dw_attr_t attr; 739 abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); 740 const dw_form_t form = form_value.Form(); 741 742 // If we are tracking down DW_AT_specification or DW_AT_abstract_origin 743 // attributes, the depth will be non-zero. We need to omit certain 744 // attributes that don't make sense. 745 switch (attr) { 746 case DW_AT_sibling: 747 case DW_AT_declaration: 748 if (curr_depth > 0) { 749 // This attribute doesn't make sense when combined with the DIE that 750 // references this DIE. We know a DIE is referencing this DIE because 751 // curr_depth is not zero 752 break; 753 } 754 LLVM_FALLTHROUGH; 755 default: 756 attributes.Append(cu, offset, attr, form); 757 break; 758 } 759 760 if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { 761 if (form_value.ExtractValue(debug_info_data, &offset)) { 762 DWARFDIE spec_die = form_value.Reference(); 763 if (spec_die) 764 spec_die.GetAttributes(attributes, curr_depth + 1); 765 } 766 } else { 767 llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); 768 if (fixed_skip_size) 769 offset += *fixed_skip_size; 770 else 771 DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); 772 } 773 } 774 } else { 775 attributes.Clear(); 776 } 777 return attributes.Size(); 778 } 779 780 // GetAttributeValue 781 // 782 // Get the value of an attribute and return the .debug_info offset of the 783 // attribute if it was properly extracted into form_value, or zero if we fail 784 // since an offset of zero is invalid for an attribute (it would be a compile 785 // unit header). 786 dw_offset_t DWARFDebugInfoEntry::GetAttributeValue( 787 const DWARFUnit *cu, const dw_attr_t attr, DWARFFormValue &form_value, 788 dw_offset_t *end_attr_offset_ptr, 789 bool check_specification_or_abstract_origin) const { 790 SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile(); 791 if (dwo_symbol_file && m_tag != DW_TAG_compile_unit && 792 m_tag != DW_TAG_partial_unit) 793 return GetAttributeValue(dwo_symbol_file->GetCompileUnit(), attr, 794 form_value, end_attr_offset_ptr, 795 check_specification_or_abstract_origin); 796 797 lldb::offset_t offset; 798 const DWARFAbbreviationDeclaration *abbrevDecl = 799 GetAbbreviationDeclarationPtr(cu, offset); 800 801 if (abbrevDecl) { 802 uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); 803 804 if (attr_idx != DW_INVALID_INDEX) { 805 const DWARFDataExtractor &debug_info_data = cu->GetData(); 806 807 uint32_t idx = 0; 808 while (idx < attr_idx) 809 DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), 810 debug_info_data, &offset, cu); 811 812 const dw_offset_t attr_offset = offset; 813 form_value.SetUnit(cu); 814 form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); 815 if (form_value.ExtractValue(debug_info_data, &offset)) { 816 if (end_attr_offset_ptr) 817 *end_attr_offset_ptr = offset; 818 return attr_offset; 819 } 820 } 821 } 822 823 if (check_specification_or_abstract_origin) { 824 if (GetAttributeValue(cu, DW_AT_specification, form_value)) { 825 DWARFDIE die = form_value.Reference(); 826 if (die) { 827 dw_offset_t die_offset = die.GetDIE()->GetAttributeValue( 828 die.GetCU(), attr, form_value, end_attr_offset_ptr, false); 829 if (die_offset) 830 return die_offset; 831 } 832 } 833 834 if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) { 835 DWARFDIE die = form_value.Reference(); 836 if (die) { 837 dw_offset_t die_offset = die.GetDIE()->GetAttributeValue( 838 die.GetCU(), attr, form_value, end_attr_offset_ptr, false); 839 if (die_offset) 840 return die_offset; 841 } 842 } 843 } 844 845 if (!dwo_symbol_file) 846 return 0; 847 848 DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); 849 if (!dwo_cu) 850 return 0; 851 852 DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); 853 if (!dwo_cu_die.IsValid()) 854 return 0; 855 856 return dwo_cu_die.GetDIE()->GetAttributeValue( 857 dwo_cu, attr, form_value, end_attr_offset_ptr, 858 check_specification_or_abstract_origin); 859 } 860 861 // GetAttributeValueAsString 862 // 863 // Get the value of an attribute as a string return it. The resulting pointer 864 // to the string data exists within the supplied SymbolFileDWARF and will only 865 // be available as long as the SymbolFileDWARF is still around and it's content 866 // doesn't change. 867 const char *DWARFDebugInfoEntry::GetAttributeValueAsString( 868 const DWARFUnit *cu, const dw_attr_t attr, const char *fail_value, 869 bool check_specification_or_abstract_origin) const { 870 DWARFFormValue form_value; 871 if (GetAttributeValue(cu, attr, form_value, nullptr, 872 check_specification_or_abstract_origin)) 873 return form_value.AsCString(); 874 return fail_value; 875 } 876 877 // GetAttributeValueAsUnsigned 878 // 879 // Get the value of an attribute as unsigned and return it. 880 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned( 881 const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, 882 bool check_specification_or_abstract_origin) const { 883 DWARFFormValue form_value; 884 if (GetAttributeValue(cu, attr, form_value, nullptr, 885 check_specification_or_abstract_origin)) 886 return form_value.Unsigned(); 887 return fail_value; 888 } 889 890 // GetAttributeValueAsReference 891 // 892 // Get the value of an attribute as reference and fix up and compile unit 893 // relative offsets as needed. 894 DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference( 895 const DWARFUnit *cu, const dw_attr_t attr, 896 bool check_specification_or_abstract_origin) const { 897 DWARFFormValue form_value; 898 if (GetAttributeValue(cu, attr, form_value, nullptr, 899 check_specification_or_abstract_origin)) 900 return form_value.Reference(); 901 return {}; 902 } 903 904 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress( 905 const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value, 906 bool check_specification_or_abstract_origin) const { 907 DWARFFormValue form_value; 908 if (GetAttributeValue(cu, attr, form_value, nullptr, 909 check_specification_or_abstract_origin)) 910 return form_value.Address(); 911 return fail_value; 912 } 913 914 // GetAttributeHighPC 915 // 916 // Get the hi_pc, adding hi_pc to lo_pc when specified as an <offset-from-low- 917 // pc>. 918 // 919 // Returns the hi_pc or fail_value. 920 dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC( 921 const DWARFUnit *cu, dw_addr_t lo_pc, uint64_t fail_value, 922 bool check_specification_or_abstract_origin) const { 923 DWARFFormValue form_value; 924 if (GetAttributeValue(cu, DW_AT_high_pc, form_value, nullptr, 925 check_specification_or_abstract_origin)) { 926 dw_form_t form = form_value.Form(); 927 if (form == DW_FORM_addr || form == DW_FORM_addrx || 928 form == DW_FORM_GNU_addr_index) 929 return form_value.Address(); 930 931 // DWARF4 can specify the hi_pc as an <offset-from-lowpc> 932 return lo_pc + form_value.Unsigned(); 933 } 934 return fail_value; 935 } 936 937 // GetAttributeAddressRange 938 // 939 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified as an <offset- 940 // from-low-pc>. 941 // 942 // Returns true or sets lo_pc and hi_pc to fail_value. 943 bool DWARFDebugInfoEntry::GetAttributeAddressRange( 944 const DWARFUnit *cu, dw_addr_t &lo_pc, dw_addr_t &hi_pc, 945 uint64_t fail_value, bool check_specification_or_abstract_origin) const { 946 lo_pc = GetAttributeValueAsAddress(cu, DW_AT_low_pc, fail_value, 947 check_specification_or_abstract_origin); 948 if (lo_pc != fail_value) { 949 hi_pc = GetAttributeHighPC(cu, lo_pc, fail_value, 950 check_specification_or_abstract_origin); 951 if (hi_pc != fail_value) 952 return true; 953 } 954 lo_pc = fail_value; 955 hi_pc = fail_value; 956 return false; 957 } 958 959 size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( 960 const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, 961 bool check_specification_or_abstract_origin) const { 962 ranges.Clear(); 963 964 SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF(); 965 966 DWARFFormValue form_value; 967 if (GetAttributeValue(cu, DW_AT_ranges, form_value)) { 968 if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges()) 969 debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), 970 ranges); 971 } else if (check_hi_lo_pc) { 972 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 973 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 974 if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS, 975 check_specification_or_abstract_origin)) { 976 if (lo_pc < hi_pc) 977 ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); 978 } 979 } 980 return ranges.GetSize(); 981 } 982 983 // GetName 984 // 985 // Get value of the DW_AT_name attribute and return it if one exists, else 986 // return NULL. 987 const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const { 988 return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true); 989 } 990 991 // GetMangledName 992 // 993 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one 994 // exists, else return the value of the DW_AT_name attribute 995 const char * 996 DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu, 997 bool substitute_name_allowed) const { 998 const char *name = nullptr; 999 1000 name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true); 1001 if (name) 1002 return name; 1003 1004 name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true); 1005 if (name) 1006 return name; 1007 1008 if (!substitute_name_allowed) 1009 return nullptr; 1010 1011 name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true); 1012 return name; 1013 } 1014 1015 // GetPubname 1016 // 1017 // Get value the name for a DIE as it should appear for a .debug_pubnames or 1018 // .debug_pubtypes section. 1019 const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const { 1020 const char *name = nullptr; 1021 if (!cu) 1022 return name; 1023 1024 name = GetAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, nullptr, true); 1025 if (name) 1026 return name; 1027 1028 name = GetAttributeValueAsString(cu, DW_AT_linkage_name, nullptr, true); 1029 if (name) 1030 return name; 1031 1032 name = GetAttributeValueAsString(cu, DW_AT_name, nullptr, true); 1033 return name; 1034 } 1035 1036 // BuildAddressRangeTable 1037 void DWARFDebugInfoEntry::BuildAddressRangeTable( 1038 const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { 1039 if (m_tag) { 1040 if (m_tag == DW_TAG_subprogram) { 1041 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 1042 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 1043 if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { 1044 /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 1045 /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); 1046 debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc); 1047 } 1048 } 1049 1050 const DWARFDebugInfoEntry *child = GetFirstChild(); 1051 while (child) { 1052 child->BuildAddressRangeTable(cu, debug_aranges); 1053 child = child->GetSibling(); 1054 } 1055 } 1056 } 1057 1058 // BuildFunctionAddressRangeTable 1059 // 1060 // This function is very similar to the BuildAddressRangeTable function except 1061 // that the actual DIE offset for the function is placed in the table instead 1062 // of the compile unit offset (which is the way the standard .debug_aranges 1063 // section does it). 1064 void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( 1065 const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { 1066 if (m_tag) { 1067 if (m_tag == DW_TAG_subprogram) { 1068 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; 1069 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; 1070 if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { 1071 // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 1072 // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY 1073 debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc); 1074 } 1075 } 1076 1077 const DWARFDebugInfoEntry *child = GetFirstChild(); 1078 while (child) { 1079 child->BuildFunctionAddressRangeTable(cu, debug_aranges); 1080 child = child->GetSibling(); 1081 } 1082 } 1083 } 1084 1085 std::vector<DWARFDIE> 1086 DWARFDebugInfoEntry::GetDeclContextDIEs(DWARFUnit *cu) const { 1087 1088 DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); 1089 return die.GetDeclContextDIEs(); 1090 } 1091 1092 void DWARFDebugInfoEntry::GetDWARFDeclContext( 1093 DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const { 1094 const dw_tag_t tag = Tag(); 1095 if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) { 1096 dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu)); 1097 DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); 1098 if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) { 1099 if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit && 1100 parent_decl_ctx_die.Tag() != DW_TAG_partial_unit) 1101 parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext( 1102 parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); 1103 } 1104 } 1105 } 1106 1107 bool DWARFDebugInfoEntry::MatchesDWARFDeclContext( 1108 DWARFUnit *cu, const DWARFDeclContext &dwarf_decl_ctx) const { 1109 1110 DWARFDeclContext this_dwarf_decl_ctx; 1111 GetDWARFDeclContext(cu, this_dwarf_decl_ctx); 1112 return this_dwarf_decl_ctx == dwarf_decl_ctx; 1113 } 1114 1115 DWARFDIE 1116 DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const { 1117 DWARFAttributes attributes; 1118 GetAttributes(cu, attributes); 1119 return GetParentDeclContextDIE(cu, attributes); 1120 } 1121 1122 DWARFDIE 1123 DWARFDebugInfoEntry::GetParentDeclContextDIE( 1124 DWARFUnit *cu, const DWARFAttributes &attributes) const { 1125 DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this)); 1126 1127 while (die) { 1128 // If this is the original DIE that we are searching for a declaration for, 1129 // then don't look in the cache as we don't want our own decl context to be 1130 // our decl context... 1131 if (die.GetDIE() != this) { 1132 switch (die.Tag()) { 1133 case DW_TAG_compile_unit: 1134 case DW_TAG_partial_unit: 1135 case DW_TAG_namespace: 1136 case DW_TAG_structure_type: 1137 case DW_TAG_union_type: 1138 case DW_TAG_class_type: 1139 return die; 1140 1141 default: 1142 break; 1143 } 1144 } 1145 1146 DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification); 1147 if (spec_die) { 1148 DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE(); 1149 if (decl_ctx_die) 1150 return decl_ctx_die; 1151 } 1152 1153 DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin); 1154 if (abs_die) { 1155 DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE(); 1156 if (decl_ctx_die) 1157 return decl_ctx_die; 1158 } 1159 1160 die = die.GetParent(); 1161 } 1162 return DWARFDIE(); 1163 } 1164 1165 const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, 1166 std::string &storage) const { 1167 DWARFAttributes attributes; 1168 GetAttributes(cu, attributes); 1169 return GetQualifiedName(cu, attributes, storage); 1170 } 1171 1172 const char * 1173 DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, 1174 const DWARFAttributes &attributes, 1175 std::string &storage) const { 1176 1177 const char *name = GetName(cu); 1178 1179 if (name) { 1180 DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); 1181 storage.clear(); 1182 // TODO: change this to get the correct decl context parent.... 1183 while (parent_decl_ctx_die) { 1184 const dw_tag_t parent_tag = parent_decl_ctx_die.Tag(); 1185 switch (parent_tag) { 1186 case DW_TAG_namespace: { 1187 const char *namespace_name = parent_decl_ctx_die.GetName(); 1188 if (namespace_name) { 1189 storage.insert(0, "::"); 1190 storage.insert(0, namespace_name); 1191 } else { 1192 storage.insert(0, "(anonymous namespace)::"); 1193 } 1194 parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); 1195 } break; 1196 1197 case DW_TAG_class_type: 1198 case DW_TAG_structure_type: 1199 case DW_TAG_union_type: { 1200 const char *class_union_struct_name = parent_decl_ctx_die.GetName(); 1201 1202 if (class_union_struct_name) { 1203 storage.insert(0, "::"); 1204 storage.insert(0, class_union_struct_name); 1205 } 1206 parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE(); 1207 } break; 1208 1209 default: 1210 parent_decl_ctx_die.Clear(); 1211 break; 1212 } 1213 } 1214 1215 if (storage.empty()) 1216 storage.append("::"); 1217 1218 storage.append(name); 1219 } 1220 if (storage.empty()) 1221 return nullptr; 1222 return storage.c_str(); 1223 } 1224 1225 // LookupAddress 1226 bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, 1227 const DWARFUnit *cu, 1228 DWARFDebugInfoEntry **function_die, 1229 DWARFDebugInfoEntry **block_die) { 1230 bool found_address = false; 1231 if (m_tag) { 1232 bool check_children = false; 1233 bool match_addr_range = false; 1234 // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, 1235 // DW_TAG_value_to_name(tag), address); 1236 switch (m_tag) { 1237 case DW_TAG_array_type: 1238 break; 1239 case DW_TAG_class_type: 1240 check_children = true; 1241 break; 1242 case DW_TAG_entry_point: 1243 break; 1244 case DW_TAG_enumeration_type: 1245 break; 1246 case DW_TAG_formal_parameter: 1247 break; 1248 case DW_TAG_imported_declaration: 1249 break; 1250 case DW_TAG_label: 1251 break; 1252 case DW_TAG_lexical_block: 1253 check_children = true; 1254 match_addr_range = true; 1255 break; 1256 case DW_TAG_member: 1257 break; 1258 case DW_TAG_pointer_type: 1259 break; 1260 case DW_TAG_reference_type: 1261 break; 1262 case DW_TAG_compile_unit: 1263 match_addr_range = true; 1264 break; 1265 case DW_TAG_string_type: 1266 break; 1267 case DW_TAG_structure_type: 1268 check_children = true; 1269 break; 1270 case DW_TAG_subroutine_type: 1271 break; 1272 case DW_TAG_typedef: 1273 break; 1274 case DW_TAG_union_type: 1275 break; 1276 case DW_TAG_unspecified_parameters: 1277 break; 1278 case DW_TAG_variant: 1279 break; 1280 case DW_TAG_common_block: 1281 check_children = true; 1282 break; 1283 case DW_TAG_common_inclusion: 1284 break; 1285 case DW_TAG_inheritance: 1286 break; 1287 case DW_TAG_inlined_subroutine: 1288 check_children = true; 1289 match_addr_range = true; 1290 break; 1291 case DW_TAG_module: 1292 match_addr_range = true; 1293 break; 1294 case DW_TAG_ptr_to_member_type: 1295 break; 1296 case DW_TAG_set_type: 1297 break; 1298 case DW_TAG_subrange_type: 1299 break; 1300 case DW_TAG_with_stmt: 1301 break; 1302 case DW_TAG_access_declaration: 1303 break; 1304 case DW_TAG_base_type: 1305 break; 1306 case DW_TAG_catch_block: 1307 match_addr_range = true; 1308 break; 1309 case DW_TAG_const_type: 1310 break; 1311 case DW_TAG_constant: 1312 break; 1313 case DW_TAG_enumerator: 1314 break; 1315 case DW_TAG_file_type: 1316 break; 1317 case DW_TAG_friend: 1318 break; 1319 case DW_TAG_namelist: 1320 break; 1321 case DW_TAG_namelist_item: 1322 break; 1323 case DW_TAG_packed_type: 1324 break; 1325 case DW_TAG_subprogram: 1326 match_addr_range = true; 1327 break; 1328 case DW_TAG_template_type_parameter: 1329 break; 1330 case DW_TAG_template_value_parameter: 1331 break; 1332 case DW_TAG_GNU_template_parameter_pack: 1333 break; 1334 case DW_TAG_thrown_type: 1335 break; 1336 case DW_TAG_try_block: 1337 match_addr_range = true; 1338 break; 1339 case DW_TAG_variant_part: 1340 break; 1341 case DW_TAG_variable: 1342 break; 1343 case DW_TAG_volatile_type: 1344 break; 1345 case DW_TAG_dwarf_procedure: 1346 break; 1347 case DW_TAG_restrict_type: 1348 break; 1349 case DW_TAG_interface_type: 1350 break; 1351 case DW_TAG_namespace: 1352 check_children = true; 1353 break; 1354 case DW_TAG_imported_module: 1355 break; 1356 case DW_TAG_unspecified_type: 1357 break; 1358 case DW_TAG_partial_unit: 1359 match_addr_range = true; 1360 break; 1361 case DW_TAG_imported_unit: 1362 break; 1363 case DW_TAG_shared_type: 1364 break; 1365 default: 1366 break; 1367 } 1368 1369 if (match_addr_range) { 1370 dw_addr_t lo_pc = 1371 GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); 1372 if (lo_pc != LLDB_INVALID_ADDRESS) { 1373 dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS); 1374 if (hi_pc != LLDB_INVALID_ADDRESS) { 1375 // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", 1376 // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); 1377 if ((lo_pc <= address) && (address < hi_pc)) { 1378 found_address = true; 1379 // puts("***MATCH***"); 1380 switch (m_tag) { 1381 case DW_TAG_compile_unit: // File 1382 case DW_TAG_partial_unit: // File 1383 check_children = 1384 ((function_die != nullptr) || (block_die != nullptr)); 1385 break; 1386 1387 case DW_TAG_subprogram: // Function 1388 if (function_die) 1389 *function_die = this; 1390 check_children = (block_die != nullptr); 1391 break; 1392 1393 case DW_TAG_inlined_subroutine: // Inlined Function 1394 case DW_TAG_lexical_block: // Block { } in code 1395 if (block_die) { 1396 *block_die = this; 1397 check_children = true; 1398 } 1399 break; 1400 1401 default: 1402 check_children = true; 1403 break; 1404 } 1405 } 1406 } else { 1407 // Compile units may not have a valid high/low pc when there 1408 // are address gaps in subroutines so we must always search 1409 // if there is no valid high and low PC. 1410 check_children = 1411 (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) && 1412 ((function_die != nullptr) || (block_die != nullptr)); 1413 } 1414 } else { 1415 DWARFFormValue form_value; 1416 if (GetAttributeValue(cu, DW_AT_ranges, form_value)) { 1417 DWARFRangeList ranges; 1418 SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF(); 1419 DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); 1420 debug_ranges->FindRanges( 1421 cu, GetRangesOffset(debug_ranges, form_value), ranges); 1422 1423 if (ranges.FindEntryThatContains(address)) { 1424 found_address = true; 1425 // puts("***MATCH***"); 1426 switch (m_tag) { 1427 case DW_TAG_compile_unit: // File 1428 case DW_TAG_partial_unit: // File 1429 check_children = 1430 ((function_die != nullptr) || (block_die != nullptr)); 1431 break; 1432 1433 case DW_TAG_subprogram: // Function 1434 if (function_die) 1435 *function_die = this; 1436 check_children = (block_die != nullptr); 1437 break; 1438 1439 case DW_TAG_inlined_subroutine: // Inlined Function 1440 case DW_TAG_lexical_block: // Block { } in code 1441 if (block_die) { 1442 *block_die = this; 1443 check_children = true; 1444 } 1445 break; 1446 1447 default: 1448 check_children = true; 1449 break; 1450 } 1451 } else { 1452 check_children = false; 1453 } 1454 } 1455 } 1456 } 1457 1458 if (check_children) { 1459 // printf("checking children\n"); 1460 DWARFDebugInfoEntry *child = GetFirstChild(); 1461 while (child) { 1462 if (child->LookupAddress(address, cu, function_die, block_die)) 1463 return true; 1464 child = child->GetSibling(); 1465 } 1466 } 1467 } 1468 return found_address; 1469 } 1470 1471 const DWARFAbbreviationDeclaration * 1472 DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr( 1473 const DWARFUnit *cu, lldb::offset_t &offset) const { 1474 if (cu) { 1475 offset = GetOffset(); 1476 1477 const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations(); 1478 if (abbrev_set) { 1479 const DWARFAbbreviationDeclaration *abbrev_decl = 1480 abbrev_set->GetAbbreviationDeclaration(m_abbr_idx); 1481 if (abbrev_decl) { 1482 // Make sure the abbreviation code still matches. If it doesn't and the 1483 // DWARF data was mmap'ed, the backing file might have been modified 1484 // which is bad news. 1485 const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset); 1486 1487 if (abbrev_decl->Code() == abbrev_code) 1488 return abbrev_decl; 1489 1490 SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF(); 1491 1492 dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( 1493 "0x%8.8x: the DWARF debug information has been modified (abbrev " 1494 "code was %u, and is now %u)", 1495 GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code); 1496 } 1497 } 1498 } 1499 offset = DW_INVALID_OFFSET; 1500 return nullptr; 1501 } 1502 1503 bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a, 1504 const DWARFDebugInfoEntry &b) { 1505 return a.GetOffset() < b.GetOffset(); 1506 } 1507 1508 bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const { 1509 return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx && 1510 m_sibling_idx == rhs.m_sibling_idx && 1511 m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children && 1512 m_tag == rhs.m_tag; 1513 } 1514 1515 bool DWARFDebugInfoEntry::operator!=(const DWARFDebugInfoEntry &rhs) const { 1516 return !(*this == rhs); 1517 } 1518