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