1 //===-- SymbolFileDWARF.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 "SymbolFileDWARF.h" 11 12 // Other libraries and framework includes 13 #include "clang/AST/ASTConsumer.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/Decl.h" 16 #include "clang/AST/DeclGroup.h" 17 #include "clang/Basic/Builtins.h" 18 #include "clang/Basic/IdentifierTable.h" 19 #include "clang/Basic/LangOptions.h" 20 #include "clang/Basic/SourceManager.h" 21 #include "clang/Basic/TargetInfo.h" 22 #include "clang/Basic/Specifiers.h" 23 24 #include "lldb/Core/Module.h" 25 #include "lldb/Core/PluginManager.h" 26 #include "lldb/Core/RegularExpression.h" 27 #include "lldb/Core/Scalar.h" 28 #include "lldb/Core/Section.h" 29 #include "lldb/Core/Timer.h" 30 #include "lldb/Core/Value.h" 31 32 #include "lldb/Symbol/Block.h" 33 #include "lldb/Symbol/CompileUnit.h" 34 #include "lldb/Symbol/LineTable.h" 35 #include "lldb/Symbol/ObjectFile.h" 36 #include "lldb/Symbol/SymbolVendor.h" 37 #include "lldb/Symbol/VariableList.h" 38 39 #include "DWARFCompileUnit.h" 40 #include "DWARFDebugAbbrev.h" 41 #include "DWARFDebugAranges.h" 42 #include "DWARFDebugInfo.h" 43 #include "DWARFDebugInfoEntry.h" 44 #include "DWARFDebugLine.h" 45 #include "DWARFDebugPubnames.h" 46 #include "DWARFDebugRanges.h" 47 #include "DWARFDIECollection.h" 48 #include "DWARFFormValue.h" 49 #include "DWARFLocationList.h" 50 #include "LogChannelDWARF.h" 51 52 #include <map> 53 54 #define DIE_IS_BEING_PARSED ((void*)1) 55 56 using namespace lldb; 57 using namespace lldb_private; 58 59 60 static const ConstString& 61 GetSectionNameDebugInfo() 62 { 63 static const ConstString g_sect_name("__debug_info"); 64 return g_sect_name; 65 } 66 67 static const ConstString& 68 GetSectionNameDebugAbbrev() 69 { 70 static const ConstString g_sect_name ("__debug_abbrev"); 71 return g_sect_name; 72 } 73 74 static const ConstString& 75 GetSectionNameDebugAranges() 76 { 77 static const ConstString g_sect_name ("__debug_aranges"); 78 return g_sect_name; 79 } 80 81 static const ConstString& 82 GetSectionNameDebugFrame() 83 { 84 static const ConstString g_sect_name ("__debug_frame"); 85 return g_sect_name; 86 } 87 88 static const ConstString& 89 GetSectionNameDebugLine() 90 { 91 static const ConstString g_sect_name ("__debug_line"); 92 return g_sect_name; 93 } 94 95 static const ConstString& 96 GetSectionNameDebugLoc() 97 { 98 static const ConstString g_sect_name ("__debug_loc"); 99 return g_sect_name; 100 } 101 102 static const ConstString& 103 GetSectionNameDebugMacInfo() 104 { 105 static const ConstString g_sect_name ("__debug_macinfo"); 106 return g_sect_name; 107 } 108 109 static const ConstString& 110 GetSectionNameDebugPubNames() 111 { 112 static const ConstString g_sect_name ("__debug_pubnames"); 113 return g_sect_name; 114 } 115 116 static const ConstString& 117 GetSectionNameDebugPubTypes() 118 { 119 static const ConstString g_sect_name ("__debug_pubtypes"); 120 return g_sect_name; 121 } 122 123 static const ConstString& 124 GetSectionNameDebugRanges() 125 { 126 static const ConstString g_sect_name ("__debug_ranges"); 127 return g_sect_name; 128 } 129 130 static const ConstString& 131 GetSectionNameDebugStr() 132 { 133 static const ConstString g_sect_name ("__debug_str"); 134 return g_sect_name; 135 } 136 137 static uint32_t 138 DwarfToClangAccessibility (uint32_t dwarf_accessibility) 139 { 140 switch (dwarf_accessibility) 141 { 142 case DW_ACCESS_public: 143 return clang::AS_public; 144 case DW_ACCESS_private: 145 return clang::AS_private; 146 case DW_ACCESS_protected: 147 return clang::AS_protected; 148 default: 149 return clang::AS_none; 150 } 151 } 152 153 void 154 SymbolFileDWARF::Initialize() 155 { 156 LogChannelDWARF::Initialize(); 157 PluginManager::RegisterPlugin (GetPluginNameStatic(), 158 GetPluginDescriptionStatic(), 159 CreateInstance); 160 } 161 162 void 163 SymbolFileDWARF::Terminate() 164 { 165 PluginManager::UnregisterPlugin (CreateInstance); 166 LogChannelDWARF::Initialize(); 167 } 168 169 170 const char * 171 SymbolFileDWARF::GetPluginNameStatic() 172 { 173 return "symbol-file.dwarf2"; 174 } 175 176 const char * 177 SymbolFileDWARF::GetPluginDescriptionStatic() 178 { 179 return "DWARF and DWARF3 debug symbol file reader."; 180 } 181 182 183 SymbolFile* 184 SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) 185 { 186 return new SymbolFileDWARF(obj_file); 187 } 188 189 //---------------------------------------------------------------------- 190 // Gets the first parent that is a lexical block, function or inlined 191 // subroutine, or compile unit. 192 //---------------------------------------------------------------------- 193 static const DWARFDebugInfoEntry * 194 GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die) 195 { 196 const DWARFDebugInfoEntry *die; 197 for (die = child_die->GetParent(); die != NULL; die = die->GetParent()) 198 { 199 dw_tag_t tag = die->Tag(); 200 201 switch (tag) 202 { 203 case DW_TAG_compile_unit: 204 case DW_TAG_subprogram: 205 case DW_TAG_inlined_subroutine: 206 case DW_TAG_lexical_block: 207 return die; 208 } 209 } 210 return NULL; 211 } 212 213 214 SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) : 215 SymbolFile(ofile), 216 m_flags(), 217 m_data_debug_abbrev(), 218 m_data_debug_aranges(), 219 m_data_debug_frame(), 220 m_data_debug_info(), 221 m_data_debug_line(), 222 m_data_debug_loc(), 223 m_data_debug_macinfo(), 224 m_data_debug_pubnames(), 225 m_data_debug_pubtypes(), 226 m_data_debug_ranges(), 227 m_data_debug_str(), 228 m_abbr(), 229 m_aranges(), 230 m_info(), 231 m_line(), 232 m_name_to_function_die(), 233 m_name_to_inlined_die(), 234 m_name_to_global_die(), 235 m_name_to_type_die(), 236 m_indexed(false), 237 // m_pubnames(), 238 // m_pubtypes(), 239 // m_pubbasetypes(), 240 m_ranges()//, 241 // m_type_fixups(), 242 // m_indirect_fixups() 243 { 244 } 245 246 SymbolFileDWARF::~SymbolFileDWARF() 247 { 248 } 249 250 bool 251 SymbolFileDWARF::SupportedVersion(uint16_t version) 252 { 253 return version == 2 || version == 3; 254 } 255 256 uint32_t 257 SymbolFileDWARF::GetAbilities () 258 { 259 uint32_t abilities = 0; 260 if (m_obj_file != NULL) 261 { 262 const Section* section = NULL; 263 const SectionList *section_list = m_obj_file->GetSectionList(); 264 if (section_list == NULL) 265 return 0; 266 267 uint64_t debug_abbrev_file_size = 0; 268 uint64_t debug_aranges_file_size = 0; 269 uint64_t debug_frame_file_size = 0; 270 uint64_t debug_info_file_size = 0; 271 uint64_t debug_line_file_size = 0; 272 uint64_t debug_loc_file_size = 0; 273 uint64_t debug_macinfo_file_size = 0; 274 uint64_t debug_pubnames_file_size = 0; 275 uint64_t debug_pubtypes_file_size = 0; 276 uint64_t debug_ranges_file_size = 0; 277 uint64_t debug_str_file_size = 0; 278 279 static ConstString g_dwarf_section_name ("__DWARF"); 280 281 section = section_list->FindSectionByName(g_dwarf_section_name).get(); 282 283 if (section) 284 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data); 285 286 section = section_list->FindSectionByName (GetSectionNameDebugInfo()).get(); 287 if (section != NULL) 288 { 289 debug_info_file_size = section->GetByteSize(); 290 291 section = section_list->FindSectionByName (GetSectionNameDebugAbbrev()).get(); 292 if (section) 293 debug_abbrev_file_size = section->GetByteSize(); 294 else 295 m_flags.Set (flagsGotDebugAbbrevData); 296 297 section = section_list->FindSectionByName (GetSectionNameDebugAranges()).get(); 298 if (section) 299 debug_aranges_file_size = section->GetByteSize(); 300 else 301 m_flags.Set (flagsGotDebugArangesData); 302 303 section = section_list->FindSectionByName (GetSectionNameDebugFrame()).get(); 304 if (section) 305 debug_frame_file_size = section->GetByteSize(); 306 else 307 m_flags.Set (flagsGotDebugFrameData); 308 309 section = section_list->FindSectionByName (GetSectionNameDebugLine()).get(); 310 if (section) 311 debug_line_file_size = section->GetByteSize(); 312 else 313 m_flags.Set (flagsGotDebugLineData); 314 315 section = section_list->FindSectionByName (GetSectionNameDebugLoc()).get(); 316 if (section) 317 debug_loc_file_size = section->GetByteSize(); 318 else 319 m_flags.Set (flagsGotDebugLocData); 320 321 section = section_list->FindSectionByName (GetSectionNameDebugMacInfo()).get(); 322 if (section) 323 debug_macinfo_file_size = section->GetByteSize(); 324 else 325 m_flags.Set (flagsGotDebugMacInfoData); 326 327 section = section_list->FindSectionByName (GetSectionNameDebugPubNames()).get(); 328 if (section) 329 debug_pubnames_file_size = section->GetByteSize(); 330 else 331 m_flags.Set (flagsGotDebugPubNamesData); 332 333 section = section_list->FindSectionByName (GetSectionNameDebugPubTypes()).get(); 334 if (section) 335 debug_pubtypes_file_size = section->GetByteSize(); 336 else 337 m_flags.Set (flagsGotDebugPubTypesData); 338 339 section = section_list->FindSectionByName (GetSectionNameDebugRanges()).get(); 340 if (section) 341 debug_ranges_file_size = section->GetByteSize(); 342 else 343 m_flags.Set (flagsGotDebugRangesData); 344 345 section = section_list->FindSectionByName (GetSectionNameDebugStr()).get(); 346 if (section) 347 debug_str_file_size = section->GetByteSize(); 348 else 349 m_flags.Set (flagsGotDebugStrData); 350 } 351 352 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) 353 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; 354 355 if (debug_line_file_size > 0) 356 abilities |= LineTables; 357 358 if (debug_aranges_file_size > 0) 359 abilities |= AddressAcceleratorTable; 360 361 if (debug_pubnames_file_size > 0) 362 abilities |= FunctionAcceleratorTable; 363 364 if (debug_pubtypes_file_size > 0) 365 abilities |= TypeAcceleratorTable; 366 367 if (debug_macinfo_file_size > 0) 368 abilities |= MacroInformation; 369 370 if (debug_frame_file_size > 0) 371 abilities |= CallFrameInformation; 372 } 373 return abilities; 374 } 375 376 const DataExtractor& 377 SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, const ConstString §ion_name, DataExtractor &data) 378 { 379 if (m_flags.IsClear (got_flag)) 380 { 381 m_flags.Set (got_flag); 382 const SectionList *section_list = m_obj_file->GetSectionList(); 383 if (section_list) 384 { 385 Section *section = section_list->FindSectionByName (section_name).get(); 386 if (section ) 387 { 388 // See if we memory mapped the DWARF segment? 389 if (m_dwarf_data.GetByteSize()) 390 { 391 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize()); 392 } 393 else 394 { 395 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0) 396 data.Clear(); 397 } 398 } 399 } 400 } 401 return data; 402 } 403 404 const DataExtractor& 405 SymbolFileDWARF::get_debug_abbrev_data() 406 { 407 return GetCachedSectionData (flagsGotDebugAbbrevData, GetSectionNameDebugAbbrev(), m_data_debug_abbrev); 408 } 409 410 const DataExtractor& 411 SymbolFileDWARF::get_debug_aranges_data() 412 { 413 return GetCachedSectionData (flagsGotDebugArangesData, GetSectionNameDebugAranges(), m_data_debug_aranges); 414 } 415 416 const DataExtractor& 417 SymbolFileDWARF::get_debug_frame_data() 418 { 419 return GetCachedSectionData (flagsGotDebugFrameData, GetSectionNameDebugFrame(), m_data_debug_frame); 420 } 421 422 const DataExtractor& 423 SymbolFileDWARF::get_debug_info_data() 424 { 425 return GetCachedSectionData (flagsGotDebugInfoData, GetSectionNameDebugInfo(), m_data_debug_info); 426 } 427 428 const DataExtractor& 429 SymbolFileDWARF::get_debug_line_data() 430 { 431 return GetCachedSectionData (flagsGotDebugLineData, GetSectionNameDebugLine(), m_data_debug_line); 432 } 433 434 const DataExtractor& 435 SymbolFileDWARF::get_debug_loc_data() 436 { 437 return GetCachedSectionData (flagsGotDebugLocData, GetSectionNameDebugLoc(), m_data_debug_loc); 438 } 439 440 const DataExtractor& 441 SymbolFileDWARF::get_debug_macinfo_data() 442 { 443 return GetCachedSectionData (flagsGotDebugMacInfoData, GetSectionNameDebugMacInfo(), m_data_debug_macinfo); 444 } 445 446 const DataExtractor& 447 SymbolFileDWARF::get_debug_pubnames_data() 448 { 449 return GetCachedSectionData (flagsGotDebugPubNamesData, GetSectionNameDebugPubNames(), m_data_debug_pubnames); 450 } 451 452 const DataExtractor& 453 SymbolFileDWARF::get_debug_pubtypes_data() 454 { 455 return GetCachedSectionData (flagsGotDebugPubTypesData, GetSectionNameDebugPubTypes(), m_data_debug_pubtypes); 456 } 457 458 const DataExtractor& 459 SymbolFileDWARF::get_debug_ranges_data() 460 { 461 return GetCachedSectionData (flagsGotDebugRangesData, GetSectionNameDebugRanges(), m_data_debug_ranges); 462 } 463 464 const DataExtractor& 465 SymbolFileDWARF::get_debug_str_data() 466 { 467 return GetCachedSectionData (flagsGotDebugStrData, GetSectionNameDebugStr(), m_data_debug_str); 468 } 469 470 471 DWARFDebugAbbrev* 472 SymbolFileDWARF::DebugAbbrev() 473 { 474 if (m_abbr.get() == NULL) 475 { 476 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data(); 477 if (debug_abbrev_data.GetByteSize() > 0) 478 { 479 m_abbr.reset(new DWARFDebugAbbrev()); 480 if (m_abbr.get()) 481 m_abbr->Parse(debug_abbrev_data); 482 } 483 } 484 return m_abbr.get(); 485 } 486 487 const DWARFDebugAbbrev* 488 SymbolFileDWARF::DebugAbbrev() const 489 { 490 return m_abbr.get(); 491 } 492 493 DWARFDebugAranges* 494 SymbolFileDWARF::DebugAranges() 495 { 496 if (m_aranges.get() == NULL) 497 { 498 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 499 m_aranges.reset(new DWARFDebugAranges()); 500 if (m_aranges.get()) 501 { 502 const DataExtractor &debug_aranges_data = get_debug_aranges_data(); 503 if (debug_aranges_data.GetByteSize() > 0) 504 m_aranges->Extract(debug_aranges_data); 505 else 506 m_aranges->Generate(this); 507 } 508 } 509 return m_aranges.get(); 510 } 511 512 const DWARFDebugAranges* 513 SymbolFileDWARF::DebugAranges() const 514 { 515 return m_aranges.get(); 516 } 517 518 519 DWARFDebugInfo* 520 SymbolFileDWARF::DebugInfo() 521 { 522 if (m_info.get() == NULL) 523 { 524 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 525 if (get_debug_info_data().GetByteSize() > 0) 526 { 527 m_info.reset(new DWARFDebugInfo()); 528 if (m_info.get()) 529 { 530 m_info->SetDwarfData(this); 531 } 532 } 533 } 534 return m_info.get(); 535 } 536 537 const DWARFDebugInfo* 538 SymbolFileDWARF::DebugInfo() const 539 { 540 return m_info.get(); 541 } 542 543 //DWARFDebugLine* 544 //SymbolFileDWARF::DebugLine() 545 //{ 546 // if (m_line.get() == NULL) 547 // { 548 // Timer scoped_timer(__PRETTY_FUNCTION__); 549 // const DataExtractor &debug_line_data = debug_line(); 550 // if (debug_line_data.GetByteSize() > 0) 551 // { 552 // m_line.reset(new DWARFDebugLine()); 553 // if (m_line.get()) 554 // m_line->Parse(debug_line_data); 555 // } 556 // } 557 // return m_line.get(); 558 //} 559 // 560 //const DWARFDebugLine* 561 //SymbolFileDWARF::DebugLine() const 562 //{ 563 // return m_line.get(); 564 //} 565 566 567 DWARFCompileUnit* 568 SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid) 569 { 570 DWARFDebugInfo* info = DebugInfo(); 571 if (info) 572 return info->GetCompileUnit(cu_uid).get(); 573 return NULL; 574 } 575 576 //DWARFCompileUnit* 577 //SymbolFileDWARF::GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu) 578 //{ 579 // DWARFCompileUnit* cu = NULL; 580 // DWARFDebugInfo* info = DebugInfo(); 581 // if (info) 582 // { 583 // uint32_t cu_idx = 0; 584 // if (prev_cu != NULL) 585 // { 586 // // Find the index of the previus DWARF compile unit if one was provided 587 // while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL) 588 // { 589 // ++cu_idx; 590 // if (cu == prev_cu) 591 // break; 592 // } 593 // } 594 // 595 // // Now find the next unparsed DWARF compile unit. We do this by checking the 596 // // user data in the DWARFCompileUnit class that starts as NULL, and eventually 597 // // holds a pointer to the CompileUnit that was created for it after it has 598 // // been parsed. 599 // while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL) 600 // { 601 // if (cu->GetUserData() == NULL) 602 // break; 603 // } 604 // } 605 // return cu; 606 //} 607 608 DWARFDebugRanges* 609 SymbolFileDWARF::DebugRanges() 610 { 611 if (m_ranges.get() == NULL) 612 { 613 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 614 if (get_debug_ranges_data().GetByteSize() > 0) 615 { 616 m_ranges.reset(new DWARFDebugRanges()); 617 if (m_ranges.get()) 618 m_ranges->Extract(this); 619 } 620 } 621 return m_ranges.get(); 622 } 623 624 const DWARFDebugRanges* 625 SymbolFileDWARF::DebugRanges() const 626 { 627 return m_ranges.get(); 628 } 629 // 630 //DWARFDebugPubnames* 631 //SymbolFileDWARF::DebugPubnames() 632 //{ 633 // if (m_pubnames.get() == NULL) 634 // { 635 // Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 636 // const DataExtractor &debug_pubnames_data = get_debug_pubnames_data(); 637 // if (debug_pubnames_data.GetByteSize() > 0) 638 // { 639 // // Pass false to indicate this is a pubnames section 640 // m_pubnames.reset(new DWARFDebugPubnames()); 641 // if (m_pubnames.get()) 642 // { 643 // // "m_pubnames->GeneratePubnames" is costly, but needed for global variables 644 // m_pubnames->GeneratePubnames(this); 645 // 646 //#if 0 647 // StreamFile s(stdout); 648 // s.Printf (".debug_pubnames for %s/%s:\n", 649 // m_obj_file->GetModule()->GetFileSpec().GetDirectory().AsCString(), 650 // m_obj_file->GetModule()->GetFileSpec().GetFilename().AsCString()); 651 // m_pubnames->Dump (&s); 652 //#endif 653 // // "m_pubnames->Extract" is quicker, but the pubnames don't always contain what we need. 654 // //m_pubnames->Extract(debug_pubnames_data); 655 // } 656 // } 657 // } 658 // return m_pubnames.get(); 659 //} 660 // 661 //const DWARFDebugPubnames* 662 //SymbolFileDWARF::DebugPubnames() const 663 //{ 664 // return m_pubnames.get(); 665 //} 666 667 //DWARFDebugPubnames* 668 //SymbolFileDWARF::DebugPubBaseTypes() 669 //{ 670 // if (m_pubbasetypes.get() == NULL) 671 // { 672 // Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 673 // // Pass false to indicate this is a pubnames section 674 // m_pubbasetypes.reset(new DWARFDebugPubnames()); 675 // if (m_pubbasetypes.get()) 676 // m_pubbasetypes->GeneratePubBaseTypes(this); 677 // } 678 // return m_pubbasetypes.get(); 679 //} 680 // 681 //const DWARFDebugPubnames* 682 //SymbolFileDWARF::DebugPubBaseTypes() const 683 //{ 684 // return m_pubbasetypes.get(); 685 //} 686 // 687 //const DWARFDebugPubnames* 688 //SymbolFileDWARF::DebugPubtypes() const 689 //{ 690 // return m_pubtypes.get(); 691 //} 692 // 693 //DWARFDebugPubnames* 694 //SymbolFileDWARF::DebugPubtypes() 695 //{ 696 // if (m_pubtypes.get() == NULL) 697 // { 698 // Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 699 // const DataExtractor &debug_pubtypes_data = get_debug_pubtypes_data(); 700 // if (debug_pubtypes_data.GetByteSize() > 0) 701 // { 702 // // Pass false to indicate this is a pubnames section 703 // m_pubtypes.reset(new DWARFDebugPubnames()); 704 // if (m_pubtypes.get()) 705 // m_pubtypes->Extract(debug_pubtypes_data); 706 // } 707 // } 708 // return m_pubtypes.get(); 709 //} 710 // 711 712 bool 713 SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp) 714 { 715 if (cu != NULL) 716 { 717 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly (); 718 if (cu_die) 719 { 720 const char * cu_die_name = cu_die->GetName(this, cu); 721 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL); 722 Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0); 723 if (cu_die_name) 724 { 725 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0]) 726 { 727 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language)); 728 } 729 else 730 { 731 std::string fullpath(cu_comp_dir); 732 if (*fullpath.rbegin() != '/') 733 fullpath += '/'; 734 fullpath += cu_die_name; 735 736 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language)); 737 } 738 739 if (compile_unit_sp.get()) 740 { 741 cu->SetUserData(compile_unit_sp.get()); 742 return true; 743 } 744 } 745 } 746 } 747 return false; 748 } 749 750 #if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST 751 752 void 753 SymbolFileDWARF::ShrinkDSYM(CompileUnit *dc_cu, DWARFCompileUnit *dw_cu, const FileSpec& cu_fspec, const FileSpec& base_types_fspec, FSToDIES& fs_to_dies, const DWARFDebugInfoEntry *die) 754 { 755 while (die != NULL) 756 { 757 dw_tag_t tag = die->Tag(); 758 759 switch (tag) 760 { 761 case DW_TAG_base_type: 762 // Put all base types into the base type compile unit 763 fs_to_dies[base_types_fspec].Insert(die); 764 break; 765 766 default: 767 { 768 uint32_t decl_file = die->GetAttributeValueAsUnsigned(this, dw_cu, DW_AT_decl_file, 0); 769 if (decl_file) 770 { 771 fs_to_dies[dc_cu->GetSupportFiles().GetFileSpecAtIndex(decl_file)].Insert(die); 772 } 773 else 774 { 775 // add this to the current compile unit 776 fs_to_dies[cu_fspec].Insert(die); 777 } 778 } 779 break; 780 } 781 782 die = die->GetSibling(); 783 } 784 } 785 786 787 788 #endif 789 790 uint32_t 791 SymbolFileDWARF::GetNumCompileUnits() 792 { 793 DWARFDebugInfo* info = DebugInfo(); 794 if (info) 795 { 796 #if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST 797 uint32_t cu_idx; 798 FSToDIES fs_to_dies; 799 800 FileSpec base_type_fspec("DW_TAG_base_type"); 801 const uint32_t num_comp_units = info->GetNumCompileUnits(); 802 803 for (cu_idx=0; cu_idx < num_comp_units; ++cu_idx) 804 { 805 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx); 806 if (cu != NULL) 807 { 808 const DWARFDebugInfoEntry *cu_die = cu->DIE(); 809 if (cu_die) 810 { 811 CompUnitSP dc_cu_sp; 812 ParseCompileUnit(cu, dc_cu_sp); 813 if (dc_cu_sp.get()) 814 { 815 FileSpec cu_fspec(*dc_cu_sp.get()); 816 817 ShrinkDSYM(dc_cu_sp.get(), cu, cu_fspec, base_type_fspec, fs_to_dies, cu->DIE()->GetFirstChild()); 818 } 819 } 820 } 821 } 822 823 Stream strm(stdout); 824 FSToDIES::const_iterator pos, end = fs_to_dies.end(); 825 for (pos = fs_to_dies.begin(); pos != end; ++pos) 826 { 827 strm << "\n\nMinimal Compile Unit: " << pos->first << ":\n"; 828 const DWARFDIECollection& dies = pos->second; 829 dies.Dump(strm, NULL); 830 } 831 return num_comp_units; 832 #else 833 return info->GetNumCompileUnits(); 834 #endif 835 } 836 return 0; 837 } 838 839 CompUnitSP 840 SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) 841 { 842 CompUnitSP comp_unit; 843 DWARFDebugInfo* info = DebugInfo(); 844 if (info) 845 { 846 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx); 847 if (cu != NULL) 848 { 849 // Our symbol vendor shouldn't be asking us to add a compile unit that 850 // has already been added to it, which this DWARF plug-in knows as it 851 // stores the lldb compile unit (CompileUnit) pointer in each 852 // DWARFCompileUnit object when it gets added. 853 assert(cu->GetUserData() == NULL); 854 ParseCompileUnit(cu, comp_unit); 855 } 856 } 857 return comp_unit; 858 } 859 860 static void 861 AddRangesToBlock 862 ( 863 BlockList& blocks, 864 lldb::user_id_t blockID, 865 DWARFDebugRanges::RangeList& ranges, 866 addr_t block_base_addr 867 ) 868 { 869 ranges.SubtractOffset (block_base_addr); 870 size_t range_idx = 0; 871 const DWARFDebugRanges::Range *debug_range; 872 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++) 873 { 874 blocks.AddRange(blockID, debug_range->begin_offset, debug_range->end_offset); 875 } 876 } 877 878 879 Function * 880 SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die) 881 { 882 DWARFDebugRanges::RangeList func_ranges; 883 const char *name = NULL; 884 const char *mangled = NULL; 885 int decl_file = 0; 886 int decl_line = 0; 887 int decl_column = 0; 888 int call_file = 0; 889 int call_line = 0; 890 int call_column = 0; 891 DWARFExpression frame_base; 892 893 // Parse the function prototype as a type that can then be added to concrete function instance 894 ParseTypes (sc, dwarf_cu, die, false, false); 895 //FixupTypes(); 896 897 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base)) 898 { 899 // Union of all ranges in the function DIE (if the function is discontiguous) 900 AddressRange func_range; 901 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0); 902 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0); 903 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr) 904 { 905 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList()); 906 if (func_range.GetBaseAddress().IsValid()) 907 func_range.SetByteSize(highest_func_addr - lowest_func_addr); 908 } 909 910 if (func_range.GetBaseAddress().IsValid()) 911 { 912 Mangled func_name; 913 if (mangled) 914 func_name.SetValue(mangled, true); 915 else if (name) 916 func_name.SetValue(name, false); 917 918 FunctionSP func_sp; 919 std::auto_ptr<Declaration> decl_ap; 920 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 921 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); 922 923 Type *func_type = NULL; 924 925 if (die->GetUserData() != DIE_IS_BEING_PARSED) 926 func_type = (Type*)die->GetUserData(); 927 928 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); 929 930 func_range.GetBaseAddress().ResolveLinkedAddress(); 931 932 func_sp.reset(new Function (sc.comp_unit, 933 die->GetOffset(), // UserID is the DIE offset 934 die->GetOffset(), 935 func_name, 936 func_type, 937 func_range)); // first address range 938 939 if (func_sp.get() != NULL) 940 { 941 func_sp->GetFrameBaseExpression() = frame_base; 942 sc.comp_unit->AddFunction(func_sp); 943 return func_sp.get(); 944 } 945 } 946 } 947 return NULL; 948 } 949 950 size_t 951 SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) 952 { 953 assert (sc.comp_unit); 954 size_t functions_added = 0; 955 const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 956 if (dwarf_cu) 957 { 958 DWARFDIECollection function_dies; 959 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); 960 size_t func_idx; 961 for (func_idx = 0; func_idx < num_funtions; ++func_idx) 962 { 963 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx); 964 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL) 965 { 966 if (ParseCompileUnitFunction(sc, dwarf_cu, die)) 967 ++functions_added; 968 } 969 } 970 //FixupTypes(); 971 } 972 return functions_added; 973 } 974 975 bool 976 SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) 977 { 978 assert (sc.comp_unit); 979 DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 980 assert (cu); 981 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly(); 982 983 if (cu_die) 984 { 985 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL); 986 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 987 988 // All file indexes in DWARF are one based and a file of index zero is 989 // supposed to be the compile unit itself. 990 support_files.Append (*sc.comp_unit); 991 992 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files); 993 } 994 return false; 995 } 996 997 struct ParseDWARFLineTableCallbackInfo 998 { 999 LineTable* line_table; 1000 const SectionList *section_list; 1001 lldb::addr_t prev_sect_file_base_addr; 1002 lldb::addr_t curr_sect_file_base_addr; 1003 bool is_oso_for_debug_map; 1004 bool prev_in_final_executable; 1005 DWARFDebugLine::Row prev_row; 1006 SectionSP prev_section_sp; 1007 SectionSP curr_section_sp; 1008 }; 1009 1010 //---------------------------------------------------------------------- 1011 // ParseStatementTableCallback 1012 //---------------------------------------------------------------------- 1013 static void 1014 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 1015 { 1016 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table; 1017 if (state.row == DWARFDebugLine::State::StartParsingLineTable) 1018 { 1019 // Just started parsing the line table 1020 } 1021 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 1022 { 1023 // Done parsing line table, nothing to do for the cleanup 1024 } 1025 else 1026 { 1027 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData; 1028 // We have a new row, lets append it 1029 1030 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false) 1031 { 1032 info->prev_section_sp = info->curr_section_sp; 1033 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr; 1034 // If this is an end sequence entry, then we subtract one from the 1035 // address to make sure we get an address that is not the end of 1036 // a section. 1037 if (state.end_sequence && state.address != 0) 1038 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1); 1039 else 1040 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address); 1041 1042 if (info->curr_section_sp.get()) 1043 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress (); 1044 else 1045 info->curr_sect_file_base_addr = 0; 1046 } 1047 if (info->curr_section_sp.get()) 1048 { 1049 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr; 1050 // Check for the fancy section magic to determine if we 1051 1052 if (info->is_oso_for_debug_map) 1053 { 1054 // When this is a debug map object file that contains DWARF 1055 // (referenced from an N_OSO debug map nlist entry) we will have 1056 // a file address in the file range for our section from the 1057 // original .o file, and a load address in the executable that 1058 // contains the debug map. 1059 // 1060 // If the sections for the file range and load range are 1061 // different, we have a remapped section for the function and 1062 // this address is resolved. If they are the same, then the 1063 // function for this address didn't make it into the final 1064 // executable. 1065 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL; 1066 1067 // If we are doing DWARF with debug map, then we need to carefully 1068 // add each line table entry as there may be gaps as functions 1069 // get moved around or removed. 1070 if (!info->prev_row.end_sequence && info->prev_section_sp.get()) 1071 { 1072 if (info->prev_in_final_executable) 1073 { 1074 bool terminate_previous_entry = false; 1075 if (!curr_in_final_executable) 1076 { 1077 // Check for the case where the previous line entry 1078 // in a function made it into the final executable, 1079 // yet the current line entry falls in a function 1080 // that didn't. The line table used to be contiguous 1081 // through this address range but now it isn't. We 1082 // need to terminate the previous line entry so 1083 // that we can reconstruct the line range correctly 1084 // for it and to keep the line table correct. 1085 terminate_previous_entry = true; 1086 } 1087 else if (info->curr_section_sp.get() != info->prev_section_sp.get()) 1088 { 1089 // Check for cases where the line entries used to be 1090 // contiguous address ranges, but now they aren't. 1091 // This can happen when order files specify the 1092 // ordering of the functions. 1093 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr; 1094 Section *curr_sect = info->curr_section_sp.get(); 1095 Section *prev_sect = info->prev_section_sp.get(); 1096 assert (curr_sect->GetLinkedSection()); 1097 assert (prev_sect->GetLinkedSection()); 1098 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address; 1099 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset; 1100 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset; 1101 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr; 1102 if (object_file_addr_delta != linked_file_addr_delta) 1103 terminate_previous_entry = true; 1104 } 1105 1106 if (terminate_previous_entry) 1107 { 1108 line_table->InsertLineEntry (info->prev_section_sp, 1109 state.address - info->prev_sect_file_base_addr, 1110 info->prev_row.line, 1111 info->prev_row.column, 1112 info->prev_row.file, 1113 false, // is_stmt 1114 false, // basic_block 1115 false, // state.prologue_end 1116 false, // state.epilogue_begin 1117 true); // end_sequence); 1118 } 1119 } 1120 } 1121 1122 if (curr_in_final_executable) 1123 { 1124 line_table->InsertLineEntry (info->curr_section_sp, 1125 curr_line_section_offset, 1126 state.line, 1127 state.column, 1128 state.file, 1129 state.is_stmt, 1130 state.basic_block, 1131 state.prologue_end, 1132 state.epilogue_begin, 1133 state.end_sequence); 1134 info->prev_section_sp = info->curr_section_sp; 1135 } 1136 else 1137 { 1138 // If the current address didn't make it into the final 1139 // executable, the current section will be the __text 1140 // segment in the .o file, so we need to clear this so 1141 // we can catch the next function that did make it into 1142 // the final executable. 1143 info->prev_section_sp.reset(); 1144 info->curr_section_sp.reset(); 1145 } 1146 1147 info->prev_in_final_executable = curr_in_final_executable; 1148 } 1149 else 1150 { 1151 // We are not in an object file that contains DWARF for an 1152 // N_OSO, this is just a normal DWARF file. The DWARF spec 1153 // guarantees that the addresses will be in increasing order 1154 // so, since we store line tables in file address order, we 1155 // can always just append the line entry without needing to 1156 // search for the correct insertion point (we don't need to 1157 // use LineEntry::InsertLineEntry()). 1158 line_table->AppendLineEntry (info->curr_section_sp, 1159 curr_line_section_offset, 1160 state.line, 1161 state.column, 1162 state.file, 1163 state.is_stmt, 1164 state.basic_block, 1165 state.prologue_end, 1166 state.epilogue_begin, 1167 state.end_sequence); 1168 } 1169 } 1170 1171 info->prev_row = state; 1172 } 1173 } 1174 1175 bool 1176 SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) 1177 { 1178 assert (sc.comp_unit); 1179 if (sc.comp_unit->GetLineTable() != NULL) 1180 return true; 1181 1182 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 1183 if (dwarf_cu) 1184 { 1185 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); 1186 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 1187 if (cu_line_offset != DW_INVALID_OFFSET) 1188 { 1189 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit)); 1190 if (line_table_ap.get()) 1191 { 1192 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false}; 1193 uint32_t offset = cu_line_offset; 1194 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); 1195 sc.comp_unit->SetLineTable(line_table_ap.release()); 1196 return true; 1197 } 1198 } 1199 } 1200 return false; 1201 } 1202 1203 size_t 1204 SymbolFileDWARF::ParseFunctionBlocks 1205 ( 1206 const SymbolContext& sc, 1207 lldb::user_id_t parentBlockID, 1208 const DWARFCompileUnit* dwarf_cu, 1209 const DWARFDebugInfoEntry *die, 1210 addr_t subprogram_low_pc, 1211 bool parse_siblings, 1212 bool parse_children 1213 ) 1214 { 1215 size_t blocks_added = 0; 1216 while (die != NULL) 1217 { 1218 dw_tag_t tag = die->Tag(); 1219 1220 switch (tag) 1221 { 1222 case DW_TAG_subprogram: 1223 case DW_TAG_inlined_subroutine: 1224 case DW_TAG_lexical_block: 1225 { 1226 DWARFDebugRanges::RangeList ranges; 1227 const char *name = NULL; 1228 const char *mangled_name = NULL; 1229 BlockList& blocks = sc.function->GetBlocks(false); 1230 1231 lldb::user_id_t blockID = blocks.AddChild(parentBlockID, die->GetOffset()); 1232 int decl_file = 0; 1233 int decl_line = 0; 1234 int decl_column = 0; 1235 int call_file = 0; 1236 int call_line = 0; 1237 int call_column = 0; 1238 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column)) 1239 { 1240 if (tag == DW_TAG_subprogram) 1241 { 1242 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); 1243 subprogram_low_pc = ranges.LowestAddress(0); 1244 } 1245 1246 AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc); 1247 1248 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) 1249 { 1250 std::auto_ptr<Declaration> decl_ap; 1251 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 1252 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); 1253 1254 std::auto_ptr<Declaration> call_ap; 1255 if (call_file != 0 || call_line != 0 || call_column != 0) 1256 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); 1257 1258 blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get()); 1259 } 1260 1261 ++blocks_added; 1262 1263 if (parse_children && die->HasChildren()) 1264 { 1265 blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true); 1266 } 1267 } 1268 } 1269 break; 1270 default: 1271 break; 1272 } 1273 1274 if (parse_siblings) 1275 die = die->GetSibling(); 1276 else 1277 die = NULL; 1278 } 1279 return blocks_added; 1280 } 1281 1282 size_t 1283 SymbolFileDWARF::ParseChildMembers 1284 ( 1285 const SymbolContext& sc, 1286 TypeSP& type_sp, 1287 const DWARFCompileUnit* dwarf_cu, 1288 const DWARFDebugInfoEntry *parent_die, 1289 std::vector<clang::CXXBaseSpecifier *>& base_classes, 1290 std::vector<int>& member_accessibilities, 1291 int& default_accessibility, 1292 bool &is_a_class 1293 ) 1294 { 1295 if (parent_die == NULL) 1296 return 0; 1297 1298 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 1299 1300 size_t count = 0; 1301 const DWARFDebugInfoEntry *die; 1302 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 1303 { 1304 dw_tag_t tag = die->Tag(); 1305 1306 switch (tag) 1307 { 1308 case DW_TAG_member: 1309 { 1310 DWARFDebugInfoEntry::Attributes attributes; 1311 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 1312 if (num_attributes > 0) 1313 { 1314 Declaration decl; 1315 DWARFExpression location; 1316 const char *name = NULL; 1317 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1318 uint32_t accessibility = clang::AS_none; 1319 off_t member_offset = 0; 1320 size_t byte_size = 0; 1321 size_t bit_offset = 0; 1322 size_t bit_size = 0; 1323 uint32_t i; 1324 for (i=0; i<num_attributes; ++i) 1325 { 1326 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1327 DWARFFormValue form_value; 1328 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1329 { 1330 switch (attr) 1331 { 1332 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1333 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1334 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1335 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 1336 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1337 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break; 1338 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; 1339 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 1340 case DW_AT_data_member_location: 1341 if (form_value.BlockData()) 1342 { 1343 Value initialValue(0); 1344 Value memberOffset(0); 1345 const DataExtractor& debug_info_data = get_debug_info_data(); 1346 uint32_t block_length = form_value.Unsigned(); 1347 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1348 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1349 { 1350 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1351 } 1352 } 1353 break; 1354 1355 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility (form_value.Unsigned()); break; 1356 case DW_AT_declaration: 1357 case DW_AT_description: 1358 case DW_AT_mutable: 1359 case DW_AT_visibility: 1360 default: 1361 case DW_AT_sibling: 1362 break; 1363 } 1364 } 1365 } 1366 1367 Type *member_type = ResolveTypeUID(encoding_uid); 1368 assert(member_type); 1369 if (accessibility == clang::AS_none) 1370 accessibility = default_accessibility; 1371 member_accessibilities.push_back(accessibility); 1372 1373 type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size); 1374 } 1375 } 1376 break; 1377 1378 case DW_TAG_subprogram: 1379 { 1380 is_a_class = true; 1381 if (default_accessibility == clang::AS_none) 1382 default_accessibility = clang::AS_private; 1383 // TODO: implement DW_TAG_subprogram type parsing 1384 // UserDefTypeChildInfo method_info(die->GetOffset()); 1385 // 1386 // FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset())); 1387 // if (func_sp.get() == NULL) 1388 // ParseCompileUnitFunction(sc, dwarf_cu, die); 1389 // 1390 // method_info.SetEncodingTypeUID(die->GetOffset()); 1391 // struct_udt->AddMethod(method_info); 1392 } 1393 break; 1394 1395 case DW_TAG_inheritance: 1396 { 1397 is_a_class = true; 1398 if (default_accessibility == clang::AS_none) 1399 default_accessibility = clang::AS_private; 1400 // TODO: implement DW_TAG_inheritance type parsing 1401 DWARFDebugInfoEntry::Attributes attributes; 1402 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 1403 if (num_attributes > 0) 1404 { 1405 Declaration decl; 1406 DWARFExpression location; 1407 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1408 uint32_t accessibility = default_accessibility; 1409 bool is_virtual = false; 1410 bool is_base_of_class = true; 1411 off_t member_offset = 0; 1412 uint32_t i; 1413 for (i=0; i<num_attributes; ++i) 1414 { 1415 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1416 DWARFFormValue form_value; 1417 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1418 { 1419 switch (attr) 1420 { 1421 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1422 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1423 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1424 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1425 case DW_AT_data_member_location: 1426 if (form_value.BlockData()) 1427 { 1428 Value initialValue(0); 1429 Value memberOffset(0); 1430 const DataExtractor& debug_info_data = get_debug_info_data(); 1431 uint32_t block_length = form_value.Unsigned(); 1432 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1433 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1434 { 1435 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1436 } 1437 } 1438 break; 1439 1440 case DW_AT_accessibility: 1441 accessibility = DwarfToClangAccessibility(form_value.Unsigned()); 1442 break; 1443 1444 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 1445 default: 1446 case DW_AT_sibling: 1447 break; 1448 } 1449 } 1450 } 1451 1452 Type *base_class_dctype = ResolveTypeUID(encoding_uid); 1453 assert(base_class_dctype); 1454 base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class)); 1455 assert(base_classes.back()); 1456 } 1457 } 1458 break; 1459 1460 default: 1461 break; 1462 } 1463 } 1464 return count; 1465 } 1466 1467 1468 clang::DeclContext* 1469 SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid) 1470 { 1471 DWARFDebugInfo* debug_info = DebugInfo(); 1472 if (debug_info) 1473 { 1474 DWARFCompileUnitSP cu_sp; 1475 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1476 if (die) 1477 return GetClangDeclContextForDIE (cu_sp.get(), die); 1478 } 1479 return NULL; 1480 } 1481 1482 Type* 1483 SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) 1484 { 1485 DWARFDebugInfo* debug_info = DebugInfo(); 1486 if (debug_info) 1487 { 1488 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL); 1489 if (type_die != NULL) 1490 { 1491 void *type = type_die->GetUserData(); 1492 if (type == NULL) 1493 { 1494 DWARFCompileUnitSP cu_sp; 1495 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1496 if (die != NULL) 1497 { 1498 TypeSP owning_type_sp; 1499 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0)); 1500 } 1501 type = type_die->GetUserData(); 1502 } 1503 if (type != DIE_IS_BEING_PARSED) 1504 return (Type *)type; 1505 } 1506 } 1507 return NULL; 1508 } 1509 1510 CompileUnit* 1511 SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx) 1512 { 1513 // Check if the symbol vendor already knows about this compile unit? 1514 if (cu->GetUserData() == NULL) 1515 { 1516 // The symbol vendor doesn't know about this compile unit, we 1517 // need to parse and add it to the symbol vendor object. 1518 CompUnitSP dc_cu; 1519 ParseCompileUnit(cu, dc_cu); 1520 if (dc_cu.get()) 1521 { 1522 // Figure out the compile unit index if we weren't given one 1523 if (cu_idx == UINT_MAX) 1524 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx); 1525 1526 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); 1527 } 1528 } 1529 return (CompileUnit*)cu->GetUserData(); 1530 } 1531 1532 bool 1533 SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc) 1534 { 1535 sc.Clear(); 1536 // Check if the symbol vendor already knows about this compile unit? 1537 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1538 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1539 1540 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get(); 1541 if (sc.function == NULL) 1542 sc.function = ParseCompileUnitFunction(sc, cu, func_die); 1543 1544 return sc.function != NULL; 1545 } 1546 1547 uint32_t 1548 SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 1549 { 1550 Timer scoped_timer(__PRETTY_FUNCTION__, 1551 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)", 1552 so_addr.GetSection(), 1553 so_addr.GetOffset(), 1554 resolve_scope); 1555 uint32_t resolved = 0; 1556 if (resolve_scope & ( eSymbolContextCompUnit | 1557 eSymbolContextFunction | 1558 eSymbolContextBlock | 1559 eSymbolContextLineEntry)) 1560 { 1561 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1562 1563 DWARFDebugAranges* debug_aranges = DebugAranges(); 1564 DWARFDebugInfo* debug_info = DebugInfo(); 1565 if (debug_aranges) 1566 { 1567 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr); 1568 if (cu_offset != DW_INVALID_OFFSET) 1569 { 1570 uint32_t cu_idx; 1571 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get(); 1572 if (cu) 1573 { 1574 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1575 assert(sc.comp_unit != NULL); 1576 resolved |= eSymbolContextCompUnit; 1577 1578 if (resolve_scope & eSymbolContextLineEntry) 1579 { 1580 LineTable *line_table = sc.comp_unit->GetLineTable(); 1581 if (line_table == NULL) 1582 { 1583 if (ParseCompileUnitLineTable(sc)) 1584 line_table = sc.comp_unit->GetLineTable(); 1585 } 1586 if (line_table != NULL) 1587 { 1588 if (so_addr.IsLinkedAddress()) 1589 { 1590 Address linked_addr (so_addr); 1591 linked_addr.ResolveLinkedAddress(); 1592 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry)) 1593 { 1594 resolved |= eSymbolContextLineEntry; 1595 } 1596 } 1597 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry)) 1598 { 1599 resolved |= eSymbolContextLineEntry; 1600 } 1601 } 1602 } 1603 1604 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1605 { 1606 DWARFDebugInfoEntry *function_die = NULL; 1607 DWARFDebugInfoEntry *block_die = NULL; 1608 if (resolve_scope & eSymbolContextBlock) 1609 { 1610 cu->LookupAddress(file_vm_addr, &function_die, &block_die); 1611 } 1612 else 1613 { 1614 cu->LookupAddress(file_vm_addr, &function_die, NULL); 1615 } 1616 1617 if (function_die != NULL) 1618 { 1619 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1620 if (sc.function == NULL) 1621 sc.function = ParseCompileUnitFunction(sc, cu, function_die); 1622 } 1623 1624 if (sc.function != NULL) 1625 { 1626 resolved |= eSymbolContextFunction; 1627 1628 if (resolve_scope & eSymbolContextBlock) 1629 { 1630 BlockList& blocks = sc.function->GetBlocks(true); 1631 1632 if (block_die != NULL) 1633 sc.block = blocks.GetBlockByID(block_die->GetOffset()); 1634 else 1635 sc.block = blocks.GetBlockByID(function_die->GetOffset()); 1636 if (sc.block) 1637 resolved |= eSymbolContextBlock; 1638 } 1639 } 1640 } 1641 } 1642 } 1643 } 1644 } 1645 return resolved; 1646 } 1647 1648 1649 1650 uint32_t 1651 SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 1652 { 1653 const uint32_t prev_size = sc_list.GetSize(); 1654 if (resolve_scope & eSymbolContextCompUnit) 1655 { 1656 DWARFDebugInfo* debug_info = DebugInfo(); 1657 if (debug_info) 1658 { 1659 uint32_t cu_idx; 1660 DWARFCompileUnit* cu = NULL; 1661 1662 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 1663 { 1664 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1665 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0; 1666 if (check_inlines || file_spec_matches_cu_file_spec) 1667 { 1668 SymbolContext sc (m_obj_file->GetModule()); 1669 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1670 assert(sc.comp_unit != NULL); 1671 1672 uint32_t file_idx = UINT32_MAX; 1673 1674 // If we are looking for inline functions only and we don't 1675 // find it in the support files, we are done. 1676 if (check_inlines) 1677 { 1678 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1679 if (file_idx == UINT32_MAX) 1680 continue; 1681 } 1682 1683 if (line != 0) 1684 { 1685 LineTable *line_table = sc.comp_unit->GetLineTable(); 1686 1687 if (line_table != NULL && line != 0) 1688 { 1689 // We will have already looked up the file index if 1690 // we are searching for inline entries. 1691 if (!check_inlines) 1692 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1693 1694 if (file_idx != UINT32_MAX) 1695 { 1696 uint32_t found_line; 1697 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 1698 found_line = sc.line_entry.line; 1699 1700 while (line_idx != UINT_MAX) 1701 { 1702 sc.function = NULL; 1703 sc.block = NULL; 1704 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1705 { 1706 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 1707 if (file_vm_addr != LLDB_INVALID_ADDRESS) 1708 { 1709 DWARFDebugInfoEntry *function_die = NULL; 1710 DWARFDebugInfoEntry *block_die = NULL; 1711 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL); 1712 1713 if (function_die != NULL) 1714 { 1715 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1716 if (sc.function == NULL) 1717 sc.function = ParseCompileUnitFunction(sc, cu, function_die); 1718 } 1719 1720 if (sc.function != NULL) 1721 { 1722 BlockList& blocks = sc.function->GetBlocks(true); 1723 1724 if (block_die != NULL) 1725 sc.block = blocks.GetBlockByID(block_die->GetOffset()); 1726 else 1727 sc.block = blocks.GetBlockByID(function_die->GetOffset()); 1728 } 1729 } 1730 } 1731 1732 sc_list.Append(sc); 1733 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 1734 } 1735 } 1736 } 1737 else if (file_spec_matches_cu_file_spec && !check_inlines) 1738 { 1739 // only append the context if we aren't looking for inline call sites 1740 // by file and line and if the file spec matches that of the compile unit 1741 sc_list.Append(sc); 1742 } 1743 } 1744 else if (file_spec_matches_cu_file_spec && !check_inlines) 1745 { 1746 // only append the context if we aren't looking for inline call sites 1747 // by file and line and if the file spec matches that of the compile unit 1748 sc_list.Append(sc); 1749 } 1750 1751 if (!check_inlines) 1752 break; 1753 } 1754 } 1755 } 1756 } 1757 return sc_list.GetSize() - prev_size; 1758 } 1759 1760 void 1761 SymbolFileDWARF::Index () 1762 { 1763 if (m_indexed) 1764 return; 1765 m_indexed = true; 1766 Timer scoped_timer (__PRETTY_FUNCTION__, 1767 "SymbolFileDWARF::Index (%s)", 1768 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1769 1770 DWARFDebugInfo* debug_info = DebugInfo(); 1771 if (debug_info) 1772 { 1773 uint32_t cu_idx = 0; 1774 const uint32_t num_compile_units = GetNumCompileUnits(); 1775 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 1776 { 1777 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); 1778 1779 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1; 1780 1781 cu->Index (m_name_to_function_die, 1782 m_name_to_inlined_die, 1783 m_name_to_global_die, 1784 m_name_to_type_die); 1785 1786 // Keep memory down by clearing DIEs if this generate function 1787 // caused them to be parsed 1788 if (clear_dies) 1789 cu->ClearDIEs (true); 1790 } 1791 1792 m_name_to_function_die.Sort(); 1793 m_name_to_inlined_die.Sort(); 1794 m_name_to_global_die.Sort(); 1795 m_name_to_type_die.Sort(); 1796 } 1797 } 1798 1799 uint32_t 1800 SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 1801 { 1802 std::vector<dw_offset_t> die_offsets; 1803 1804 // If we aren't appending the results to this list, then clear the list 1805 if (!append) 1806 variables.Clear(); 1807 1808 // Remember how many variables are in the list before we search in case 1809 // we are appending the results to a variable list. 1810 const uint32_t original_size = variables.GetSize(); 1811 1812 // Index the DWARF if we haven't already 1813 if (!m_indexed) 1814 Index (); 1815 1816 const UniqueCStringMap<dw_offset_t>::Entry *entry; 1817 1818 for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString()); 1819 entry != NULL; 1820 entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry)) 1821 { 1822 DWARFCompileUnitSP cu_sp; 1823 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp); 1824 DWARFCompileUnit* cu = cu_sp.get(); 1825 if (die) 1826 { 1827 SymbolContext sc; 1828 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1829 assert (sc.module_sp); 1830 1831 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1832 assert(sc.comp_unit != NULL); 1833 1834 ParseVariables(sc, cu_sp.get(), die, false, false, &variables); 1835 1836 if (variables.GetSize() - original_size >= max_matches) 1837 break; 1838 } 1839 } 1840 1841 // Return the number of variable that were appended to the list 1842 return variables.GetSize() - original_size; 1843 } 1844 1845 uint32_t 1846 SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 1847 { 1848 std::vector<dw_offset_t> die_offsets; 1849 1850 // If we aren't appending the results to this list, then clear the list 1851 if (!append) 1852 variables.Clear(); 1853 1854 // Remember how many variables are in the list before we search in case 1855 // we are appending the results to a variable list. 1856 const uint32_t original_size = variables.GetSize(); 1857 1858 // Index the DWARF if we haven't already 1859 if (!m_indexed) 1860 Index (); 1861 1862 // Create the pubnames information so we can quickly lookup external symbols by name 1863 const size_t num_entries = m_name_to_global_die.GetSize(); 1864 for (size_t i=0; i<num_entries; i++) 1865 { 1866 if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i))) 1867 continue; 1868 1869 const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i); 1870 1871 DWARFCompileUnitSP cu_sp; 1872 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp); 1873 DWARFCompileUnit* cu = cu_sp.get(); 1874 if (die) 1875 { 1876 SymbolContext sc; 1877 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1878 assert (sc.module_sp); 1879 1880 1881 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1882 assert(sc.comp_unit != NULL); 1883 1884 ParseVariables(sc, cu_sp.get(), die, false, false, &variables); 1885 1886 if (variables.GetSize() - original_size >= max_matches) 1887 break; 1888 } 1889 } 1890 1891 // Return the number of variable that were appended to the list 1892 return variables.GetSize() - original_size; 1893 } 1894 1895 1896 uint32_t 1897 SymbolFileDWARF::FindFunctions(const ConstString &name, bool append, SymbolContextList& sc_list) 1898 { 1899 Timer scoped_timer (__PRETTY_FUNCTION__, 1900 "SymbolFileDWARF::FindFunctions (name = '%s')", 1901 name.AsCString()); 1902 1903 std::vector<dw_offset_t> die_offsets; 1904 1905 // If we aren't appending the results to this list, then clear the list 1906 if (!append) 1907 sc_list.Clear(); 1908 1909 // Remember how many sc_list are in the list before we search in case 1910 // we are appending the results to a variable list. 1911 uint32_t original_size = sc_list.GetSize(); 1912 1913 // Index the DWARF if we haven't already 1914 if (!m_indexed) 1915 Index (); 1916 1917 const UniqueCStringMap<dw_offset_t>::Entry *entry; 1918 1919 SymbolContext sc; 1920 for (entry = m_name_to_function_die.FindFirstValueForName (name.AsCString()); 1921 entry != NULL; 1922 entry = m_name_to_function_die.FindNextValueForName (name.AsCString(), entry)) 1923 { 1924 DWARFCompileUnitSP cu_sp; 1925 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp); 1926 if (die) 1927 { 1928 if (GetFunction (cu_sp.get(), die, sc)) 1929 { 1930 // We found the function, so we should find the line table 1931 // and line table entry as well 1932 LineTable *line_table = sc.comp_unit->GetLineTable(); 1933 if (line_table == NULL) 1934 { 1935 if (ParseCompileUnitLineTable(sc)) 1936 line_table = sc.comp_unit->GetLineTable(); 1937 } 1938 if (line_table != NULL) 1939 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry); 1940 1941 sc_list.Append(sc); 1942 } 1943 } 1944 } 1945 1946 // Return the number of variable that were appended to the list 1947 return sc_list.GetSize() - original_size; 1948 } 1949 1950 1951 uint32_t 1952 SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) 1953 { 1954 Timer scoped_timer (__PRETTY_FUNCTION__, 1955 "SymbolFileDWARF::FindFunctions (regex = '%s')", 1956 regex.GetText()); 1957 1958 std::vector<dw_offset_t> die_offsets; 1959 1960 // If we aren't appending the results to this list, then clear the list 1961 if (!append) 1962 sc_list.Clear(); 1963 1964 // Remember how many sc_list are in the list before we search in case 1965 // we are appending the results to a variable list. 1966 uint32_t original_size = sc_list.GetSize(); 1967 1968 // Index the DWARF if we haven't already 1969 if (!m_indexed) 1970 Index (); 1971 1972 // Create the pubnames information so we can quickly lookup external symbols by name 1973 // Create the pubnames information so we can quickly lookup external symbols by name 1974 const size_t num_entries = m_name_to_function_die.GetSize(); 1975 SymbolContext sc; 1976 for (size_t i=0; i<num_entries; i++) 1977 { 1978 if (!regex.Execute(m_name_to_function_die.GetCStringAtIndex (i))) 1979 continue; 1980 1981 const dw_offset_t die_offset = *m_name_to_function_die.GetValueAtIndex (i); 1982 1983 DWARFCompileUnitSP cu_sp; 1984 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp); 1985 if (die) 1986 { 1987 if (GetFunction (cu_sp.get(), die, sc)) 1988 { 1989 // We found the function, so we should find the line table 1990 // and line table entry as well 1991 LineTable *line_table = sc.comp_unit->GetLineTable(); 1992 if (line_table == NULL) 1993 { 1994 if (ParseCompileUnitLineTable(sc)) 1995 line_table = sc.comp_unit->GetLineTable(); 1996 } 1997 if (line_table != NULL) 1998 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry); 1999 2000 2001 sc_list.Append(sc); 2002 } 2003 } 2004 } 2005 2006 // Return the number of variable that were appended to the list 2007 return sc_list.GetSize() - original_size; 2008 } 2009 2010 #if 0 2011 uint32_t 2012 SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 2013 { 2014 // If we aren't appending the results to this list, then clear the list 2015 if (!append) 2016 types.Clear(); 2017 2018 // Create the pubnames information so we can quickly lookup external symbols by name 2019 DWARFDebugPubnames* pubtypes = DebugPubtypes(); 2020 if (pubtypes) 2021 { 2022 std::vector<dw_offset_t> die_offsets; 2023 if (!pubtypes->Find(name.AsCString(), false, die_offsets)) 2024 { 2025 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); 2026 if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets)) 2027 return 0; 2028 } 2029 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); 2030 } 2031 return 0; 2032 } 2033 2034 2035 uint32_t 2036 SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 2037 { 2038 // If we aren't appending the results to this list, then clear the list 2039 if (!append) 2040 types.Clear(); 2041 2042 // Create the pubnames information so we can quickly lookup external symbols by name 2043 DWARFDebugPubnames* pubtypes = DebugPubtypes(); 2044 if (pubtypes) 2045 { 2046 std::vector<dw_offset_t> die_offsets; 2047 if (!pubtypes->Find(regex, die_offsets)) 2048 { 2049 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); 2050 if (pub_base_types && !pub_base_types->Find(regex, die_offsets)) 2051 return 0; 2052 } 2053 2054 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); 2055 } 2056 2057 return 0; 2058 } 2059 2060 2061 2062 uint32_t 2063 SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 2064 { 2065 // Remember how many sc_list are in the list before we search in case 2066 // we are appending the results to a variable list. 2067 uint32_t original_size = types.Size(); 2068 2069 const uint32_t num_die_offsets = die_offsets.size(); 2070 // Parse all of the types we found from the pubtypes matches 2071 uint32_t i; 2072 uint32_t num_matches = 0; 2073 for (i = 0; i < num_die_offsets; ++i) 2074 { 2075 dw_offset_t die_offset = die_offsets[i]; 2076 DWARFCompileUnitSP cu_sp; 2077 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2078 2079 assert(die != NULL); 2080 2081 bool get_type_for_die = true; 2082 if (encoding) 2083 { 2084 // Check if this type has already been uniqued and registers with the module? 2085 Type* type = (Type*)die->GetUserData(); 2086 if (type != NULL && type != DIE_IS_BEING_PARSED) 2087 { 2088 get_type_for_die = type->GetEncoding() == encoding; 2089 } 2090 else 2091 { 2092 dw_tag_t tag = die->Tag(); 2093 switch (encoding) 2094 { 2095 case Type::address: 2096 case Type::boolean: 2097 case Type::complex_float: 2098 case Type::float_type: 2099 case Type::signed_int: 2100 case Type::signed_char: 2101 case Type::unsigned_int: 2102 case Type::unsigned_char: 2103 case Type::imaginary_float: 2104 case Type::packed_decimal: 2105 case Type::numeric_string: 2106 case Type::edited_string: 2107 case Type::signed_fixed: 2108 case Type::unsigned_fixed: 2109 case Type::decimal_float: 2110 if (tag != DW_TAG_base_type) 2111 get_type_for_die = false; 2112 else 2113 { 2114 if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding) 2115 get_type_for_die = false; 2116 } 2117 break; 2118 2119 case Type::indirect_const: get_type_for_die = tag == DW_TAG_const_type; break; 2120 case Type::indirect_restrict: get_type_for_die = tag == DW_TAG_restrict_type; break; 2121 case Type::indirect_volatile: get_type_for_die = tag == DW_TAG_volatile_type; break; 2122 case Type::indirect_typedef: get_type_for_die = tag == DW_TAG_typedef; break; 2123 case Type::indirect_pointer: get_type_for_die = tag == DW_TAG_pointer_type; break; 2124 case Type::indirect_reference: get_type_for_die = tag == DW_TAG_reference_type; break; 2125 2126 case Type::user_defined_type: 2127 switch (tag) 2128 { 2129 case DW_TAG_array_type: 2130 get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid); 2131 break; 2132 2133 case DW_TAG_structure_type: 2134 case DW_TAG_union_type: 2135 case DW_TAG_class_type: 2136 get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid); 2137 break; 2138 2139 case DW_TAG_enumeration_type: 2140 get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid); 2141 break; 2142 2143 case DW_TAG_subprogram: 2144 case DW_TAG_subroutine_type: 2145 get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid); 2146 break; 2147 } 2148 } 2149 } 2150 } 2151 2152 if (get_type_for_die) 2153 { 2154 TypeSP owning_type_sp; 2155 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0)); 2156 2157 if (type_sp.get()) 2158 { 2159 // See if we are filtering results based on encoding? 2160 bool add_type = (encoding == Type::invalid); 2161 if (!add_type) 2162 { 2163 // We are filtering base on encoding, so lets check the resulting type encoding 2164 add_type = (encoding == type_sp->GetEncoding()); 2165 if (add_type) 2166 { 2167 // The type encoding matches, if this is a user defined type, lets 2168 // make sure the exact user define type uid matches if one was provided 2169 if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID) 2170 { 2171 UserDefType* udt = type_sp->GetUserDefinedType().get(); 2172 if (udt) 2173 add_type = udt->UserDefinedTypeUID() == udt_uid; 2174 } 2175 } 2176 } 2177 // Add the type to our list as long as everything matched 2178 if (add_type) 2179 { 2180 types.InsertUnique(type_sp); 2181 if (++num_matches >= max_matches) 2182 break; 2183 } 2184 } 2185 } 2186 } 2187 2188 // Return the number of variable that were appended to the list 2189 return types.Size() - original_size; 2190 } 2191 2192 #endif 2193 2194 2195 size_t 2196 SymbolFileDWARF::ParseChildParameters 2197 ( 2198 const SymbolContext& sc, 2199 TypeSP& type_sp, 2200 const DWARFCompileUnit* dwarf_cu, 2201 const DWARFDebugInfoEntry *parent_die, 2202 TypeList* type_list, 2203 std::vector<void *>& function_param_types, 2204 std::vector<clang::ParmVarDecl*>& function_param_decls 2205 ) 2206 { 2207 if (parent_die == NULL) 2208 return 0; 2209 2210 size_t count = 0; 2211 const DWARFDebugInfoEntry *die; 2212 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2213 { 2214 dw_tag_t tag = die->Tag(); 2215 switch (tag) 2216 { 2217 case DW_TAG_formal_parameter: 2218 { 2219 DWARFDebugInfoEntry::Attributes attributes; 2220 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2221 if (num_attributes > 0) 2222 { 2223 const char *name = NULL; 2224 Declaration decl; 2225 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; 2226 // one of None, Auto, Register, Extern, Static, PrivateExtern 2227 2228 clang::VarDecl::StorageClass storage = clang::VarDecl::None; 2229 uint32_t i; 2230 for (i=0; i<num_attributes; ++i) 2231 { 2232 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2233 DWARFFormValue form_value; 2234 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2235 { 2236 switch (attr) 2237 { 2238 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2239 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2240 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2241 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 2242 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; 2243 case DW_AT_location: 2244 // if (form_value.BlockData()) 2245 // { 2246 // const DataExtractor& debug_info_data = debug_info(); 2247 // uint32_t block_length = form_value.Unsigned(); 2248 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); 2249 // } 2250 // else 2251 // { 2252 // } 2253 // break; 2254 case DW_AT_artificial: 2255 case DW_AT_const_value: 2256 case DW_AT_default_value: 2257 case DW_AT_description: 2258 case DW_AT_endianity: 2259 case DW_AT_is_optional: 2260 case DW_AT_segment: 2261 case DW_AT_variable_parameter: 2262 default: 2263 case DW_AT_abstract_origin: 2264 case DW_AT_sibling: 2265 break; 2266 } 2267 } 2268 } 2269 Type *dc_type = ResolveTypeUID(param_type_die_offset); 2270 if (dc_type) 2271 { 2272 function_param_types.push_back (dc_type->GetOpaqueClangQualType()); 2273 2274 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage); 2275 assert(param_var_decl); 2276 function_param_decls.push_back(param_var_decl); 2277 } 2278 } 2279 } 2280 break; 2281 2282 default: 2283 break; 2284 } 2285 } 2286 return count; 2287 } 2288 2289 size_t 2290 SymbolFileDWARF::ParseChildEnumerators 2291 ( 2292 const SymbolContext& sc, 2293 TypeSP& type_sp, 2294 void * enumerator_qual_type, 2295 uint32_t enumerator_byte_size, 2296 const DWARFCompileUnit* dwarf_cu, 2297 const DWARFDebugInfoEntry *parent_die 2298 ) 2299 { 2300 if (parent_die == NULL) 2301 return 0; 2302 2303 size_t enumerators_added = 0; 2304 const DWARFDebugInfoEntry *die; 2305 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2306 { 2307 const dw_tag_t tag = die->Tag(); 2308 if (tag == DW_TAG_enumerator) 2309 { 2310 DWARFDebugInfoEntry::Attributes attributes; 2311 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2312 if (num_child_attributes > 0) 2313 { 2314 const char *name = NULL; 2315 bool got_value = false; 2316 int64_t enum_value = 0; 2317 Declaration decl; 2318 2319 uint32_t i; 2320 for (i=0; i<num_child_attributes; ++i) 2321 { 2322 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2323 DWARFFormValue form_value; 2324 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2325 { 2326 switch (attr) 2327 { 2328 case DW_AT_const_value: 2329 got_value = true; 2330 enum_value = form_value.Unsigned(); 2331 break; 2332 2333 case DW_AT_name: 2334 name = form_value.AsCString(&get_debug_str_data()); 2335 break; 2336 2337 case DW_AT_description: 2338 default: 2339 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2340 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2341 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2342 case DW_AT_sibling: 2343 break; 2344 } 2345 } 2346 } 2347 2348 if (name && name[0] && got_value) 2349 { 2350 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2351 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8); 2352 ++enumerators_added; 2353 } 2354 } 2355 } 2356 } 2357 return enumerators_added; 2358 } 2359 2360 void 2361 SymbolFileDWARF::ParseChildArrayInfo 2362 ( 2363 const SymbolContext& sc, 2364 const DWARFCompileUnit* dwarf_cu, 2365 const DWARFDebugInfoEntry *parent_die, 2366 int64_t& first_index, 2367 std::vector<uint64_t>& element_orders, 2368 uint32_t& byte_stride, 2369 uint32_t& bit_stride 2370 ) 2371 { 2372 if (parent_die == NULL) 2373 return; 2374 2375 const DWARFDebugInfoEntry *die; 2376 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2377 { 2378 const dw_tag_t tag = die->Tag(); 2379 switch (tag) 2380 { 2381 case DW_TAG_enumerator: 2382 { 2383 DWARFDebugInfoEntry::Attributes attributes; 2384 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2385 if (num_child_attributes > 0) 2386 { 2387 const char *name = NULL; 2388 bool got_value = false; 2389 int64_t enum_value = 0; 2390 2391 uint32_t i; 2392 for (i=0; i<num_child_attributes; ++i) 2393 { 2394 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2395 DWARFFormValue form_value; 2396 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2397 { 2398 switch (attr) 2399 { 2400 case DW_AT_const_value: 2401 got_value = true; 2402 enum_value = form_value.Unsigned(); 2403 break; 2404 2405 case DW_AT_name: 2406 name = form_value.AsCString(&get_debug_str_data()); 2407 break; 2408 2409 case DW_AT_description: 2410 default: 2411 case DW_AT_decl_file: 2412 case DW_AT_decl_line: 2413 case DW_AT_decl_column: 2414 case DW_AT_sibling: 2415 break; 2416 } 2417 } 2418 } 2419 } 2420 } 2421 break; 2422 2423 case DW_TAG_subrange_type: 2424 { 2425 DWARFDebugInfoEntry::Attributes attributes; 2426 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2427 if (num_child_attributes > 0) 2428 { 2429 const char *name = NULL; 2430 bool got_value = false; 2431 uint64_t byte_size = 0; 2432 int64_t enum_value = 0; 2433 uint64_t num_elements = 0; 2434 uint64_t lower_bound = 0; 2435 uint64_t upper_bound = 0; 2436 uint32_t i; 2437 for (i=0; i<num_child_attributes; ++i) 2438 { 2439 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2440 DWARFFormValue form_value; 2441 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2442 { 2443 switch (attr) 2444 { 2445 case DW_AT_const_value: 2446 got_value = true; 2447 enum_value = form_value.Unsigned(); 2448 break; 2449 2450 case DW_AT_name: 2451 name = form_value.AsCString(&get_debug_str_data()); 2452 break; 2453 2454 case DW_AT_count: 2455 num_elements = form_value.Unsigned(); 2456 break; 2457 2458 case DW_AT_bit_stride: 2459 bit_stride = form_value.Unsigned(); 2460 break; 2461 2462 case DW_AT_byte_stride: 2463 byte_stride = form_value.Unsigned(); 2464 break; 2465 2466 case DW_AT_byte_size: 2467 byte_size = form_value.Unsigned(); 2468 break; 2469 2470 case DW_AT_lower_bound: 2471 lower_bound = form_value.Unsigned(); 2472 break; 2473 2474 case DW_AT_upper_bound: 2475 upper_bound = form_value.Unsigned(); 2476 break; 2477 2478 default: 2479 //printf("0x%8.8x: %-30s skipping attribute at 0x%8.8x: %s\n", die->GetOffset(), DW_TAG_value_to_name(tag), attributes.die_offsets[i], DW_AT_value_to_name(attr)); // remove this, debug only 2480 2481 case DW_AT_abstract_origin: 2482 case DW_AT_accessibility: 2483 case DW_AT_allocated: 2484 case DW_AT_associated: 2485 case DW_AT_data_location: 2486 case DW_AT_declaration: 2487 case DW_AT_description: 2488 case DW_AT_sibling: 2489 case DW_AT_threads_scaled: 2490 case DW_AT_type: 2491 case DW_AT_visibility: 2492 break; 2493 } 2494 } 2495 } 2496 2497 if (upper_bound > lower_bound) 2498 num_elements = upper_bound - lower_bound + 1; 2499 2500 if (num_elements > 0) 2501 element_orders.push_back (num_elements); 2502 } 2503 } 2504 break; 2505 } 2506 } 2507 } 2508 2509 Type* 2510 SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe) 2511 { 2512 if (type_die_offset != DW_INVALID_OFFSET) 2513 { 2514 DWARFCompileUnitSP cu_sp; 2515 const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp); 2516 assert(type_die != NULL); 2517 GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx); 2518 // Return the uniqued type if there is one 2519 Type* type = (Type*)type_die->GetUserData(); 2520 if (type == DIE_IS_BEING_PARSED && safe) 2521 return NULL; 2522 return type; 2523 } 2524 return NULL; 2525 } 2526 2527 TypeSP 2528 SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx) 2529 { 2530 TypeSP type_sp; 2531 if (die != NULL) 2532 { 2533 assert(cu != NULL); 2534 Type *type_ptr = (Type *)die->GetUserData(); 2535 if (type_ptr == NULL) 2536 { 2537 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu)); 2538 bool type_is_new = false; 2539 type_sp = ParseType(sc, cu, die, type_is_new); 2540 type_ptr = (Type *)die->GetUserData(); 2541 if (owning_type_sp.get() == NULL) 2542 owning_type_sp = type_sp; 2543 } 2544 else if (type_ptr != DIE_IS_BEING_PARSED) 2545 { 2546 // Grab the existing type from the master types lists 2547 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID()); 2548 } 2549 2550 } 2551 return type_sp; 2552 } 2553 2554 clang::DeclContext * 2555 SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset) 2556 { 2557 if (die_offset != DW_INVALID_OFFSET) 2558 { 2559 DWARFCompileUnitSP cu_sp; 2560 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2561 return GetClangDeclContextForDIE (cu_sp.get(), die); 2562 } 2563 return NULL; 2564 } 2565 2566 2567 2568 clang::DeclContext * 2569 SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 2570 { 2571 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); 2572 if (pos != m_die_to_decl_ctx.end()) 2573 return pos->second; 2574 2575 while (die != NULL) 2576 { 2577 switch (die->Tag()) 2578 { 2579 case DW_TAG_namespace: 2580 { 2581 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL); 2582 if (namespace_name) 2583 { 2584 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2585 assert(type_list); 2586 Declaration decl; // TODO: fill in the decl object 2587 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent())); 2588 if (namespace_decl) 2589 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl; 2590 return namespace_decl; 2591 } 2592 } 2593 break; 2594 2595 default: 2596 break; 2597 } 2598 clang::DeclContext *decl_ctx; 2599 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET)); 2600 if (decl_ctx) 2601 return decl_ctx; 2602 2603 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET)); 2604 if (decl_ctx) 2605 return decl_ctx; 2606 2607 die = die->GetParent(); 2608 } 2609 return NULL; 2610 } 2611 2612 TypeSP 2613 SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new) 2614 { 2615 TypeSP type_sp; 2616 2617 uint32_t accessibility = clang::AS_none; 2618 if (die != NULL) 2619 { 2620 dw_tag_t tag = die->Tag(); 2621 if (die->GetUserData() == NULL) 2622 { 2623 type_is_new = true; 2624 2625 bool is_forward_declaration = false; 2626 DWARFDebugInfoEntry::Attributes attributes; 2627 const char *type_name_cstr = NULL; 2628 ConstString type_name_dbstr; 2629 Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID; 2630 void *clang_type = NULL; 2631 2632 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2633 dw_attr_t attr; 2634 2635 switch (tag) 2636 { 2637 case DW_TAG_base_type: 2638 case DW_TAG_pointer_type: 2639 case DW_TAG_reference_type: 2640 case DW_TAG_typedef: 2641 case DW_TAG_const_type: 2642 case DW_TAG_restrict_type: 2643 case DW_TAG_volatile_type: 2644 { 2645 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2646 // Set a bit that lets us know that we are currently parsing this 2647 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2648 2649 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2650 Declaration decl; 2651 uint32_t encoding = 0; 2652 size_t byte_size = 0; 2653 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 2654 2655 if (num_attributes > 0) 2656 { 2657 uint32_t i; 2658 for (i=0; i<num_attributes; ++i) 2659 { 2660 attr = attributes.AttributeAtIndex(i); 2661 DWARFFormValue form_value; 2662 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2663 { 2664 switch (attr) 2665 { 2666 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2667 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2668 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2669 case DW_AT_name: 2670 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2671 type_name_dbstr.SetCString(type_name_cstr); 2672 break; 2673 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2674 case DW_AT_encoding: encoding = form_value.Unsigned(); break; 2675 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 2676 default: 2677 case DW_AT_sibling: 2678 break; 2679 } 2680 } 2681 } 2682 } 2683 2684 switch (tag) 2685 { 2686 default: 2687 case DW_TAG_base_type: 2688 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8); 2689 break; 2690 2691 case DW_TAG_pointer_type: 2692 // The encoding_uid will be embedded into the 2693 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2694 encoding_uid_type = Type::ePointerToTypeWithUID; 2695 break; 2696 2697 case DW_TAG_reference_type: 2698 // The encoding_uid will be embedded into the 2699 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2700 encoding_uid_type = Type::eLValueReferenceToTypeWithUID; 2701 break; 2702 2703 case DW_TAG_typedef: 2704 // The encoding_uid will be embedded into the 2705 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2706 encoding_uid_type = Type::eTypedefToTypeWithUID; 2707 break; 2708 2709 case DW_TAG_const_type: 2710 // The encoding_uid will be embedded into the 2711 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2712 encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type); 2713 break; 2714 2715 case DW_TAG_restrict_type: 2716 // The encoding_uid will be embedded into the 2717 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2718 encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type); 2719 break; 2720 2721 case DW_TAG_volatile_type: 2722 // The encoding_uid will be embedded into the 2723 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2724 encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type); 2725 break; 2726 } 2727 2728 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type)); 2729 2730 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2731 2732 2733 // Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); 2734 // if (encoding_type != NULL) 2735 // { 2736 // if (encoding_type != DIE_IS_BEING_PARSED) 2737 // type_sp->SetEncodingType(encoding_type); 2738 // else 2739 // m_indirect_fixups.push_back(type_sp.get()); 2740 // } 2741 } 2742 break; 2743 2744 case DW_TAG_structure_type: 2745 case DW_TAG_union_type: 2746 case DW_TAG_class_type: 2747 { 2748 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2749 // Set a bit that lets us know that we are currently parsing this 2750 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2751 2752 size_t byte_size = 0; 2753 //bool struct_is_class = false; 2754 Declaration decl; 2755 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2756 if (num_attributes > 0) 2757 { 2758 uint32_t i; 2759 for (i=0; i<num_attributes; ++i) 2760 { 2761 attr = attributes.AttributeAtIndex(i); 2762 DWARFFormValue form_value; 2763 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2764 { 2765 switch (attr) 2766 { 2767 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2768 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2769 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2770 case DW_AT_name: 2771 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2772 type_name_dbstr.SetCString(type_name_cstr); 2773 break; 2774 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2775 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; break; 2776 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2777 case DW_AT_allocated: 2778 case DW_AT_associated: 2779 case DW_AT_data_location: 2780 case DW_AT_description: 2781 case DW_AT_start_scope: 2782 case DW_AT_visibility: 2783 default: 2784 case DW_AT_sibling: 2785 break; 2786 } 2787 } 2788 } 2789 } 2790 2791 int tag_decl_kind = -1; 2792 int default_accessibility = clang::AS_none; 2793 if (tag == DW_TAG_structure_type) 2794 { 2795 tag_decl_kind = clang::TTK_Struct; 2796 default_accessibility = clang::AS_public; 2797 } 2798 else if (tag == DW_TAG_union_type) 2799 { 2800 tag_decl_kind = clang::TTK_Union; 2801 default_accessibility = clang::AS_public; 2802 } 2803 else if (tag == DW_TAG_class_type) 2804 { 2805 tag_decl_kind = clang::TTK_Class; 2806 default_accessibility = clang::AS_private; 2807 } 2808 2809 assert (tag_decl_kind != -1); 2810 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die)); 2811 2812 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); 2813 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 2814 2815 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2816 2817 // assert(type_sp.get()); 2818 // if (accessibility) 2819 // type_sp->SetAccess(accessibility); 2820 // 2821 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type); 2822 if (die->HasChildren()) 2823 { 2824 std::vector<clang::CXXBaseSpecifier *> base_classes; 2825 std::vector<int> member_accessibilities; 2826 bool is_a_class = false; 2827 ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class); 2828 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we 2829 // need to tell the clang type it is actually a class. 2830 if (is_a_class && tag_decl_kind != clang::TTK_Class) 2831 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class); 2832 2833 // Since DW_TAG_structure_type gets used for both classes 2834 // and structures, we may need to set any DW_TAG_member 2835 // fields to have a "private" access if none was specified. 2836 // When we parsed the child members we tracked that actual 2837 // accessibility value for each DW_TAG_member in the 2838 // "member_accessibilities" array. If the value for the 2839 // member is zero, then it was set to the "default_accessibility" 2840 // which for structs was "public". Below we correct this 2841 // by setting any fields to "private" that weren't correctly 2842 // set. 2843 if (is_a_class && !member_accessibilities.empty()) 2844 { 2845 // This is a class and all members that didn't have 2846 // their access specified are private. 2847 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, clang::AS_private, member_accessibilities.data(), member_accessibilities.size()); 2848 } 2849 2850 if (!base_classes.empty()) 2851 { 2852 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, base_classes.data(), base_classes.size()); 2853 } 2854 } 2855 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type); 2856 } 2857 break; 2858 2859 case DW_TAG_enumeration_type: 2860 { 2861 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2862 // Set a bit that lets us know that we are currently parsing this 2863 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2864 2865 size_t byte_size = 0; 2866 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; 2867 Declaration decl; 2868 2869 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2870 if (num_attributes > 0) 2871 { 2872 uint32_t i; 2873 2874 for (i=0; i<num_attributes; ++i) 2875 { 2876 attr = attributes.AttributeAtIndex(i); 2877 DWARFFormValue form_value; 2878 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2879 { 2880 switch (attr) 2881 { 2882 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2883 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2884 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2885 case DW_AT_name: 2886 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2887 type_name_dbstr.SetCString(type_name_cstr); 2888 break; 2889 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 2890 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2891 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 2892 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2893 case DW_AT_allocated: 2894 case DW_AT_associated: 2895 case DW_AT_bit_stride: 2896 case DW_AT_byte_stride: 2897 case DW_AT_data_location: 2898 case DW_AT_description: 2899 case DW_AT_start_scope: 2900 case DW_AT_visibility: 2901 case DW_AT_specification: 2902 case DW_AT_abstract_origin: 2903 case DW_AT_sibling: 2904 break; 2905 } 2906 } 2907 } 2908 2909 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr); 2910 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); 2911 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type)); 2912 2913 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2914 2915 if (die->HasChildren()) 2916 { 2917 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type); 2918 void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8); 2919 ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die); 2920 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type); 2921 } 2922 } 2923 } 2924 break; 2925 2926 case DW_TAG_subprogram: 2927 case DW_TAG_subroutine_type: 2928 { 2929 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2930 // Set a bit that lets us know that we are currently parsing this 2931 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2932 2933 const char *mangled = NULL; 2934 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 2935 Declaration decl; 2936 bool isVariadic = false; 2937 bool is_inline = false; 2938 unsigned type_quals = 0; 2939 clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern 2940 2941 2942 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2943 if (num_attributes > 0) 2944 { 2945 uint32_t i; 2946 for (i=0; i<num_attributes; ++i) 2947 { 2948 attr = attributes.AttributeAtIndex(i); 2949 DWARFFormValue form_value; 2950 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2951 { 2952 switch (attr) 2953 { 2954 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2955 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2956 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2957 case DW_AT_name: 2958 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2959 type_name_dbstr.SetCString(type_name_cstr); 2960 break; 2961 2962 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 2963 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 2964 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 2965 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2966 case DW_AT_external: 2967 if (form_value.Unsigned()) 2968 { 2969 if (storage == clang::FunctionDecl::None) 2970 storage = clang::FunctionDecl::Extern; 2971 else 2972 storage = clang::FunctionDecl::PrivateExtern; 2973 } 2974 break; 2975 case DW_AT_inline: 2976 is_inline = form_value.Unsigned() != 0; 2977 break; 2978 2979 case DW_AT_allocated: 2980 case DW_AT_associated: 2981 case DW_AT_address_class: 2982 case DW_AT_artificial: 2983 case DW_AT_calling_convention: 2984 case DW_AT_data_location: 2985 case DW_AT_elemental: 2986 case DW_AT_entry_pc: 2987 case DW_AT_explicit: 2988 case DW_AT_frame_base: 2989 case DW_AT_high_pc: 2990 case DW_AT_low_pc: 2991 case DW_AT_object_pointer: 2992 case DW_AT_prototyped: 2993 case DW_AT_pure: 2994 case DW_AT_ranges: 2995 case DW_AT_recursive: 2996 case DW_AT_return_addr: 2997 case DW_AT_segment: 2998 case DW_AT_specification: 2999 case DW_AT_start_scope: 3000 case DW_AT_static_link: 3001 case DW_AT_trampoline: 3002 case DW_AT_visibility: 3003 case DW_AT_virtuality: 3004 case DW_AT_vtable_elem_location: 3005 case DW_AT_abstract_origin: 3006 case DW_AT_description: 3007 case DW_AT_sibling: 3008 break; 3009 } 3010 } 3011 } 3012 3013 void *return_clang_type = NULL; 3014 Type *func_type = ResolveTypeUID(type_die_offset); 3015 if (func_type) 3016 return_clang_type = func_type->GetOpaqueClangQualType(); 3017 else 3018 return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType(); 3019 3020 std::vector<void *> function_param_types; 3021 std::vector<clang::ParmVarDecl*> function_param_decls; 3022 3023 // Parse the function children for the parameters 3024 ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls); 3025 3026 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals); 3027 if (type_name_cstr) 3028 { 3029 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline); 3030 // Add the decl to our DIE to decl context map 3031 assert (function_decl); 3032 m_die_to_decl_ctx[die] = function_decl; 3033 if (!function_param_decls.empty()) 3034 type_list->GetClangASTContext().SetFunctionParameters (function_decl, function_param_decls.data(), function_param_decls.size()); 3035 } 3036 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 3037 3038 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3039 assert(type_sp.get()); 3040 } 3041 } 3042 break; 3043 3044 case DW_TAG_array_type: 3045 { 3046 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 3047 // Set a bit that lets us know that we are currently parsing this 3048 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 3049 3050 size_t byte_size = 0; 3051 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; 3052 Declaration decl; 3053 int64_t first_index = 0; 3054 uint32_t byte_stride = 0; 3055 uint32_t bit_stride = 0; 3056 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3057 3058 if (num_attributes > 0) 3059 { 3060 uint32_t i; 3061 for (i=0; i<num_attributes; ++i) 3062 { 3063 attr = attributes.AttributeAtIndex(i); 3064 DWARFFormValue form_value; 3065 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3066 { 3067 switch (attr) 3068 { 3069 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3070 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3071 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3072 case DW_AT_name: 3073 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3074 type_name_dbstr.SetCString(type_name_cstr); 3075 break; 3076 3077 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3078 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 3079 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; 3080 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; 3081 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 3082 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3083 case DW_AT_allocated: 3084 case DW_AT_associated: 3085 case DW_AT_data_location: 3086 case DW_AT_description: 3087 case DW_AT_ordering: 3088 case DW_AT_start_scope: 3089 case DW_AT_visibility: 3090 case DW_AT_specification: 3091 case DW_AT_abstract_origin: 3092 case DW_AT_sibling: 3093 break; 3094 } 3095 } 3096 } 3097 3098 Type *element_type = ResolveTypeUID(type_die_offset); 3099 3100 if (element_type) 3101 { 3102 std::vector<uint64_t> element_orders; 3103 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); 3104 if (byte_stride == 0 && bit_stride == 0) 3105 byte_stride = element_type->GetByteSize(); 3106 void *array_element_type = element_type->GetOpaqueClangQualType(); 3107 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; 3108 uint64_t num_elements = 0; 3109 std::vector<uint64_t>::const_reverse_iterator pos; 3110 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); 3111 for (pos = element_orders.rbegin(); pos != end; ++pos) 3112 { 3113 num_elements = *pos; 3114 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride); 3115 array_element_type = clang_type; 3116 array_element_bit_stride = array_element_bit_stride * num_elements; 3117 } 3118 ConstString empty_name; 3119 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 3120 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3121 } 3122 } 3123 } 3124 break; 3125 3126 default: 3127 break; 3128 } 3129 3130 if (type_sp.get()) 3131 { 3132 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3133 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3134 3135 SymbolContextScope * symbol_context_scope = NULL; 3136 if (sc_parent_tag == DW_TAG_compile_unit) 3137 { 3138 symbol_context_scope = sc.comp_unit; 3139 } 3140 else if (sc.function != NULL) 3141 { 3142 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); 3143 if (symbol_context_scope == NULL) 3144 symbol_context_scope = sc.function; 3145 } 3146 3147 if (symbol_context_scope != NULL) 3148 { 3149 type_sp->SetSymbolContextScope(symbol_context_scope); 3150 } 3151 3152 // if (udt_sp.get()) 3153 // { 3154 // if (is_forward_declaration) 3155 // udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition); 3156 // type_sp->SetUserDefinedType(udt_sp); 3157 // } 3158 3159 if (type_sp.unique()) 3160 { 3161 // We are ready to put this type into the uniqued list up at the module level 3162 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp)); 3163 3164 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get()); 3165 3166 type_sp = uniqued_type_sp; 3167 } 3168 } 3169 } 3170 else 3171 { 3172 switch (tag) 3173 { 3174 case DW_TAG_base_type: 3175 case DW_TAG_pointer_type: 3176 case DW_TAG_reference_type: 3177 case DW_TAG_typedef: 3178 case DW_TAG_const_type: 3179 case DW_TAG_restrict_type: 3180 case DW_TAG_volatile_type: 3181 case DW_TAG_structure_type: 3182 case DW_TAG_union_type: 3183 case DW_TAG_class_type: 3184 case DW_TAG_enumeration_type: 3185 case DW_TAG_subprogram: 3186 case DW_TAG_subroutine_type: 3187 case DW_TAG_array_type: 3188 { 3189 Type *existing_type = (Type*)die->GetUserData(); 3190 if (existing_type != DIE_IS_BEING_PARSED) 3191 { 3192 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID()); 3193 } 3194 } 3195 break; 3196 default: 3197 //assert(!"invalid type tag..."); 3198 break; 3199 } 3200 } 3201 } 3202 return type_sp; 3203 } 3204 3205 size_t 3206 SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children) 3207 { 3208 size_t types_added = 0; 3209 while (die != NULL) 3210 { 3211 bool type_is_new = false; 3212 if (ParseType(sc, dwarf_cu, die, type_is_new).get()) 3213 { 3214 if (type_is_new) 3215 ++types_added; 3216 } 3217 3218 if (parse_children && die->HasChildren()) 3219 { 3220 if (die->Tag() == DW_TAG_subprogram) 3221 { 3222 SymbolContext child_sc(sc); 3223 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get(); 3224 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true); 3225 } 3226 else 3227 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true); 3228 } 3229 3230 if (parse_siblings) 3231 die = die->GetSibling(); 3232 else 3233 die = NULL; 3234 } 3235 return types_added; 3236 } 3237 3238 3239 size_t 3240 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 3241 { 3242 assert(sc.comp_unit && sc.function); 3243 size_t functions_added = 0; 3244 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3245 if (dwarf_cu) 3246 { 3247 dw_offset_t function_die_offset = sc.function->GetID(); 3248 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); 3249 if (function_die) 3250 { 3251 ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true); 3252 } 3253 } 3254 3255 return functions_added; 3256 } 3257 3258 3259 size_t 3260 SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 3261 { 3262 // At least a compile unit must be valid 3263 assert(sc.comp_unit); 3264 size_t types_added = 0; 3265 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3266 if (dwarf_cu) 3267 { 3268 if (sc.function) 3269 { 3270 dw_offset_t function_die_offset = sc.function->GetID(); 3271 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset); 3272 if (func_die && func_die->HasChildren()) 3273 { 3274 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true); 3275 } 3276 } 3277 else 3278 { 3279 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE(); 3280 if (dwarf_cu_die && dwarf_cu_die->HasChildren()) 3281 { 3282 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true); 3283 } 3284 } 3285 } 3286 3287 return types_added; 3288 } 3289 3290 size_t 3291 SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 3292 { 3293 if (sc.comp_unit != NULL) 3294 { 3295 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3296 3297 if (dwarf_cu == NULL) 3298 return 0; 3299 3300 if (sc.function) 3301 { 3302 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); 3303 return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true); 3304 } 3305 else if (sc.comp_unit) 3306 { 3307 uint32_t vars_added = 0; 3308 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 3309 3310 if (variables.get() == NULL) 3311 { 3312 variables.reset(new VariableList()); 3313 sc.comp_unit->SetVariableList(variables); 3314 3315 // Index if we already haven't to make sure the compile units 3316 // get indexed and make their global DIE index list 3317 if (!m_indexed) 3318 Index (); 3319 3320 const size_t num_globals = dwarf_cu->GetNumGlobals(); 3321 for (size_t idx=0; idx<num_globals; ++idx) 3322 { 3323 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx))); 3324 if (var_sp) 3325 { 3326 variables->AddVariable(var_sp); 3327 ++vars_added; 3328 } 3329 } 3330 } 3331 return vars_added; 3332 } 3333 } 3334 return 0; 3335 } 3336 3337 3338 VariableSP 3339 SymbolFileDWARF::ParseVariableDIE 3340 ( 3341 const SymbolContext& sc, 3342 const DWARFCompileUnit* dwarf_cu, 3343 const DWARFDebugInfoEntry *die 3344 ) 3345 { 3346 3347 VariableSP var_sp; 3348 3349 const dw_tag_t tag = die->Tag(); 3350 DWARFDebugInfoEntry::Attributes attributes; 3351 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3352 if (num_attributes > 0) 3353 { 3354 const char *name = NULL; 3355 Declaration decl; 3356 uint32_t i; 3357 TypeSP type_sp; 3358 Type *var_type = NULL; 3359 DWARFExpression location; 3360 bool is_external = false; 3361 bool is_artificial = false; 3362 uint32_t accessibility = clang::AS_none; 3363 3364 for (i=0; i<num_attributes; ++i) 3365 { 3366 dw_attr_t attr = attributes.AttributeAtIndex(i); 3367 DWARFFormValue form_value; 3368 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3369 { 3370 switch (attr) 3371 { 3372 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3373 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3374 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3375 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 3376 case DW_AT_type: var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break; 3377 case DW_AT_external: is_external = form_value.Unsigned() != 0; break; 3378 case DW_AT_location: 3379 { 3380 if (form_value.BlockData()) 3381 { 3382 const DataExtractor& debug_info_data = get_debug_info_data(); 3383 3384 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 3385 uint32_t block_length = form_value.Unsigned(); 3386 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL); 3387 } 3388 else 3389 { 3390 const DataExtractor& debug_loc_data = get_debug_loc_data(); 3391 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 3392 3393 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 3394 if (loc_list_length > 0) 3395 { 3396 Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList()); 3397 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address); 3398 } 3399 } 3400 } 3401 break; 3402 3403 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 3404 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; 3405 case DW_AT_const_value: 3406 case DW_AT_declaration: 3407 case DW_AT_description: 3408 case DW_AT_endianity: 3409 case DW_AT_segment: 3410 case DW_AT_start_scope: 3411 case DW_AT_visibility: 3412 default: 3413 case DW_AT_abstract_origin: 3414 case DW_AT_sibling: 3415 case DW_AT_specification: 3416 break; 3417 } 3418 } 3419 } 3420 3421 if (location.IsValid()) 3422 { 3423 assert(var_type != DIE_IS_BEING_PARSED); 3424 3425 ConstString var_name(name); 3426 3427 ValueType scope = eValueTypeInvalid; 3428 3429 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3430 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3431 3432 if (tag == DW_TAG_formal_parameter) 3433 scope = eValueTypeVariableArgument; 3434 else if (is_external || parent_tag == DW_TAG_compile_unit) 3435 scope = eValueTypeVariableGlobal; 3436 else 3437 scope = eValueTypeVariableLocal; 3438 3439 SymbolContextScope * symbol_context_scope = NULL; 3440 if (parent_tag == DW_TAG_compile_unit) 3441 { 3442 symbol_context_scope = sc.comp_unit; 3443 } 3444 else if (sc.function != NULL) 3445 { 3446 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); 3447 if (symbol_context_scope == NULL) 3448 symbol_context_scope = sc.function; 3449 } 3450 3451 assert(symbol_context_scope != NULL); 3452 var_sp.reset (new Variable(die->GetOffset(), 3453 var_name, 3454 var_type, 3455 scope, 3456 symbol_context_scope, 3457 &decl, 3458 location, 3459 is_external, 3460 is_artificial)); 3461 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get()); 3462 } 3463 } 3464 return var_sp; 3465 } 3466 3467 size_t 3468 SymbolFileDWARF::ParseVariables 3469 ( 3470 const SymbolContext& sc, 3471 const DWARFCompileUnit* dwarf_cu, 3472 const DWARFDebugInfoEntry *orig_die, 3473 bool parse_siblings, 3474 bool parse_children, 3475 VariableList* cc_variable_list 3476 ) 3477 { 3478 if (orig_die == NULL) 3479 return 0; 3480 3481 size_t vars_added = 0; 3482 const DWARFDebugInfoEntry *die = orig_die; 3483 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); 3484 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3485 VariableListSP variables; 3486 switch (parent_tag) 3487 { 3488 case DW_TAG_compile_unit: 3489 if (sc.comp_unit != NULL) 3490 { 3491 variables = sc.comp_unit->GetVariableList(false); 3492 if (variables.get() == NULL) 3493 { 3494 variables.reset(new VariableList()); 3495 sc.comp_unit->SetVariableList(variables); 3496 } 3497 } 3498 else 3499 { 3500 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context..."); 3501 vars_added = 0; 3502 } 3503 break; 3504 3505 case DW_TAG_subprogram: 3506 case DW_TAG_inlined_subroutine: 3507 case DW_TAG_lexical_block: 3508 if (sc.function != NULL) 3509 { 3510 // Check to see if we already have parsed the variables for the given scope 3511 variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false); 3512 if (variables.get() == NULL) 3513 { 3514 variables.reset(new VariableList()); 3515 sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables); 3516 } 3517 } 3518 else 3519 { 3520 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context..."); 3521 vars_added = 0; 3522 } 3523 break; 3524 3525 default: 3526 assert(!"Didn't find appropriate parent DIE for variable list..."); 3527 break; 3528 } 3529 3530 // We need to have a variable list at this point that we can add variables to 3531 assert(variables.get()); 3532 3533 while (die != NULL) 3534 { 3535 dw_tag_t tag = die->Tag(); 3536 3537 // Check to see if we have already parsed this variable or constant? 3538 if (die->GetUserData() == NULL) 3539 { 3540 // We haven't already parsed it, lets do that now. 3541 if ((tag == DW_TAG_variable) || 3542 (tag == DW_TAG_constant) || 3543 (tag == DW_TAG_formal_parameter && sc.function)) 3544 { 3545 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die)); 3546 if (var_sp) 3547 { 3548 variables->AddVariable(var_sp); 3549 ++vars_added; 3550 } 3551 } 3552 } 3553 3554 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 3555 3556 if (!skip_children && parse_children && die->HasChildren()) 3557 { 3558 vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true); 3559 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children); 3560 } 3561 3562 if (parse_siblings) 3563 die = die->GetSibling(); 3564 else 3565 die = NULL; 3566 } 3567 3568 if (cc_variable_list) 3569 { 3570 cc_variable_list->AddVariables(variables.get()); 3571 } 3572 3573 return vars_added; 3574 } 3575 3576 //------------------------------------------------------------------ 3577 // PluginInterface protocol 3578 //------------------------------------------------------------------ 3579 const char * 3580 SymbolFileDWARF::GetPluginName() 3581 { 3582 return "SymbolFileDWARF"; 3583 } 3584 3585 const char * 3586 SymbolFileDWARF::GetShortPluginName() 3587 { 3588 return GetPluginNameStatic(); 3589 } 3590 3591 uint32_t 3592 SymbolFileDWARF::GetPluginVersion() 3593 { 3594 return 1; 3595 } 3596 3597 void 3598 SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm) 3599 { 3600 } 3601 3602 Error 3603 SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm) 3604 { 3605 Error error; 3606 error.SetErrorString("No plug-in command are currently supported."); 3607 return error; 3608 } 3609 3610 Log * 3611 SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command) 3612 { 3613 return NULL; 3614 } 3615 3616