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