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