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