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