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