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