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