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