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