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