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