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