SymbolFileDWARF.cpp revision 84f8075072eef306234f8109573067647735c111
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 Language::Type language = (Language::Type)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(), 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(), 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 std::vector<clang::CXXBaseSpecifier *>& base_classes, 1215 std::vector<int>& member_accessibilities, 1216 ClangASTContext::AccessType& default_accessibility, 1217 bool &is_a_class 1218) 1219{ 1220 if (parent_die == NULL) 1221 return 0; 1222 1223 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 1224 1225 size_t count = 0; 1226 const DWARFDebugInfoEntry *die; 1227 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 1228 { 1229 dw_tag_t tag = die->Tag(); 1230 1231 switch (tag) 1232 { 1233 case DW_TAG_member: 1234 { 1235 DWARFDebugInfoEntry::Attributes attributes; 1236 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 1237 if (num_attributes > 0) 1238 { 1239 Declaration decl; 1240 DWARFExpression location; 1241 const char *name = NULL; 1242 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1243 ClangASTContext::AccessType accessibility = ClangASTContext::eAccessNone; 1244 off_t member_offset = 0; 1245 size_t byte_size = 0; 1246 size_t bit_offset = 0; 1247 size_t bit_size = 0; 1248 uint32_t i; 1249 for (i=0; i<num_attributes; ++i) 1250 { 1251 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1252 DWARFFormValue form_value; 1253 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1254 { 1255 switch (attr) 1256 { 1257 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1258 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1259 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1260 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 1261 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1262 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break; 1263 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; 1264 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 1265 case DW_AT_data_member_location: 1266 if (form_value.BlockData()) 1267 { 1268 Value initialValue(0); 1269 Value memberOffset(0); 1270 const DataExtractor& debug_info_data = get_debug_info_data(); 1271 uint32_t block_length = form_value.Unsigned(); 1272 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1273 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1274 { 1275 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1276 } 1277 } 1278 break; 1279 1280 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break; 1281 case DW_AT_declaration: 1282 case DW_AT_description: 1283 case DW_AT_mutable: 1284 case DW_AT_visibility: 1285 default: 1286 case DW_AT_sibling: 1287 break; 1288 } 1289 } 1290 } 1291 1292 Type *member_type = ResolveTypeUID(encoding_uid); 1293 assert(member_type); 1294 if (accessibility == ClangASTContext::eAccessNone) 1295 accessibility = default_accessibility; 1296 member_accessibilities.push_back(accessibility); 1297 1298 type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size); 1299 } 1300 } 1301 break; 1302 1303 case DW_TAG_subprogram: 1304 { 1305 is_a_class = true; 1306 if (default_accessibility == ClangASTContext::eAccessNone) 1307 default_accessibility = ClangASTContext::eAccessPrivate; 1308 // TODO: implement DW_TAG_subprogram type parsing 1309// UserDefTypeChildInfo method_info(die->GetOffset()); 1310// 1311// FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset())); 1312// if (func_sp.get() == NULL) 1313// ParseCompileUnitFunction(sc, dwarf_cu, die); 1314// 1315// method_info.SetEncodingTypeUID(die->GetOffset()); 1316// struct_udt->AddMethod(method_info); 1317 } 1318 break; 1319 1320 case DW_TAG_inheritance: 1321 { 1322 is_a_class = true; 1323 if (default_accessibility == ClangASTContext::eAccessNone) 1324 default_accessibility = ClangASTContext::eAccessPrivate; 1325 // TODO: implement DW_TAG_inheritance type parsing 1326 DWARFDebugInfoEntry::Attributes attributes; 1327 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 1328 if (num_attributes > 0) 1329 { 1330 Declaration decl; 1331 DWARFExpression location; 1332 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1333 ClangASTContext::AccessType accessibility = default_accessibility; 1334 bool is_virtual = false; 1335 bool is_base_of_class = true; 1336 off_t member_offset = 0; 1337 uint32_t i; 1338 for (i=0; i<num_attributes; ++i) 1339 { 1340 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1341 DWARFFormValue form_value; 1342 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1343 { 1344 switch (attr) 1345 { 1346 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1347 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1348 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1349 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1350 case DW_AT_data_member_location: 1351 if (form_value.BlockData()) 1352 { 1353 Value initialValue(0); 1354 Value memberOffset(0); 1355 const DataExtractor& debug_info_data = get_debug_info_data(); 1356 uint32_t block_length = form_value.Unsigned(); 1357 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1358 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1359 { 1360 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1361 } 1362 } 1363 break; 1364 1365 case DW_AT_accessibility: 1366 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 1367 break; 1368 1369 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 1370 default: 1371 case DW_AT_sibling: 1372 break; 1373 } 1374 } 1375 } 1376 1377 Type *base_class_dctype = ResolveTypeUID(encoding_uid); 1378 assert(base_class_dctype); 1379 base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class)); 1380 assert(base_classes.back()); 1381 } 1382 } 1383 break; 1384 1385 default: 1386 break; 1387 } 1388 } 1389 return count; 1390} 1391 1392 1393clang::DeclContext* 1394SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid) 1395{ 1396 DWARFDebugInfo* debug_info = DebugInfo(); 1397 if (debug_info) 1398 { 1399 DWARFCompileUnitSP cu_sp; 1400 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1401 if (die) 1402 return GetClangDeclContextForDIE (cu_sp.get(), die); 1403 } 1404 return NULL; 1405} 1406 1407Type* 1408SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) 1409{ 1410 DWARFDebugInfo* debug_info = DebugInfo(); 1411 if (debug_info) 1412 { 1413 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL); 1414 if (type_die != NULL) 1415 { 1416 void *type = type_die->GetUserData(); 1417 if (type == NULL) 1418 { 1419 DWARFCompileUnitSP cu_sp; 1420 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1421 if (die != NULL) 1422 { 1423 TypeSP owning_type_sp; 1424 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0)); 1425 } 1426 type = type_die->GetUserData(); 1427 } 1428 if (type != DIE_IS_BEING_PARSED) 1429 return (Type *)type; 1430 } 1431 } 1432 return NULL; 1433} 1434 1435CompileUnit* 1436SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx) 1437{ 1438 // Check if the symbol vendor already knows about this compile unit? 1439 if (cu->GetUserData() == NULL) 1440 { 1441 // The symbol vendor doesn't know about this compile unit, we 1442 // need to parse and add it to the symbol vendor object. 1443 CompUnitSP dc_cu; 1444 ParseCompileUnit(cu, dc_cu); 1445 if (dc_cu.get()) 1446 { 1447 // Figure out the compile unit index if we weren't given one 1448 if (cu_idx == UINT_MAX) 1449 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx); 1450 1451 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); 1452 } 1453 } 1454 return (CompileUnit*)cu->GetUserData(); 1455} 1456 1457bool 1458SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc) 1459{ 1460 sc.Clear(); 1461 // Check if the symbol vendor already knows about this compile unit? 1462 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1463 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1464 1465 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get(); 1466 if (sc.function == NULL) 1467 sc.function = ParseCompileUnitFunction(sc, cu, func_die); 1468 1469 return sc.function != NULL; 1470} 1471 1472uint32_t 1473SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 1474{ 1475 Timer scoped_timer(__PRETTY_FUNCTION__, 1476 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)", 1477 so_addr.GetSection(), 1478 so_addr.GetOffset(), 1479 resolve_scope); 1480 uint32_t resolved = 0; 1481 if (resolve_scope & ( eSymbolContextCompUnit | 1482 eSymbolContextFunction | 1483 eSymbolContextBlock | 1484 eSymbolContextLineEntry)) 1485 { 1486 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1487 1488 DWARFDebugAranges* debug_aranges = DebugAranges(); 1489 DWARFDebugInfo* debug_info = DebugInfo(); 1490 if (debug_aranges) 1491 { 1492 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr); 1493 if (cu_offset != DW_INVALID_OFFSET) 1494 { 1495 uint32_t cu_idx; 1496 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get(); 1497 if (cu) 1498 { 1499 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1500 assert(sc.comp_unit != NULL); 1501 resolved |= eSymbolContextCompUnit; 1502 1503 if (resolve_scope & eSymbolContextLineEntry) 1504 { 1505 LineTable *line_table = sc.comp_unit->GetLineTable(); 1506 if (line_table == NULL) 1507 { 1508 if (ParseCompileUnitLineTable(sc)) 1509 line_table = sc.comp_unit->GetLineTable(); 1510 } 1511 if (line_table != NULL) 1512 { 1513 if (so_addr.IsLinkedAddress()) 1514 { 1515 Address linked_addr (so_addr); 1516 linked_addr.ResolveLinkedAddress(); 1517 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry)) 1518 { 1519 resolved |= eSymbolContextLineEntry; 1520 } 1521 } 1522 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry)) 1523 { 1524 resolved |= eSymbolContextLineEntry; 1525 } 1526 } 1527 } 1528 1529 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1530 { 1531 DWARFDebugInfoEntry *function_die = NULL; 1532 DWARFDebugInfoEntry *block_die = NULL; 1533 if (resolve_scope & eSymbolContextBlock) 1534 { 1535 cu->LookupAddress(file_vm_addr, &function_die, &block_die); 1536 } 1537 else 1538 { 1539 cu->LookupAddress(file_vm_addr, &function_die, NULL); 1540 } 1541 1542 if (function_die != NULL) 1543 { 1544 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1545 if (sc.function == NULL) 1546 sc.function = ParseCompileUnitFunction(sc, cu, function_die); 1547 } 1548 1549 if (sc.function != NULL) 1550 { 1551 resolved |= eSymbolContextFunction; 1552 1553 if (resolve_scope & eSymbolContextBlock) 1554 { 1555 BlockList& blocks = sc.function->GetBlocks(true); 1556 1557 if (block_die != NULL) 1558 sc.block = blocks.GetBlockByID(block_die->GetOffset()); 1559 else 1560 sc.block = blocks.GetBlockByID(function_die->GetOffset()); 1561 if (sc.block) 1562 resolved |= eSymbolContextBlock; 1563 } 1564 } 1565 } 1566 } 1567 } 1568 } 1569 } 1570 return resolved; 1571} 1572 1573 1574 1575uint32_t 1576SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 1577{ 1578 const uint32_t prev_size = sc_list.GetSize(); 1579 if (resolve_scope & eSymbolContextCompUnit) 1580 { 1581 DWARFDebugInfo* debug_info = DebugInfo(); 1582 if (debug_info) 1583 { 1584 uint32_t cu_idx; 1585 DWARFCompileUnit* cu = NULL; 1586 1587 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 1588 { 1589 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1590 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0; 1591 if (check_inlines || file_spec_matches_cu_file_spec) 1592 { 1593 SymbolContext sc (m_obj_file->GetModule()); 1594 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx); 1595 assert(sc.comp_unit != NULL); 1596 1597 uint32_t file_idx = UINT32_MAX; 1598 1599 // If we are looking for inline functions only and we don't 1600 // find it in the support files, we are done. 1601 if (check_inlines) 1602 { 1603 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1604 if (file_idx == UINT32_MAX) 1605 continue; 1606 } 1607 1608 if (line != 0) 1609 { 1610 LineTable *line_table = sc.comp_unit->GetLineTable(); 1611 1612 if (line_table != NULL && line != 0) 1613 { 1614 // We will have already looked up the file index if 1615 // we are searching for inline entries. 1616 if (!check_inlines) 1617 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1618 1619 if (file_idx != UINT32_MAX) 1620 { 1621 uint32_t found_line; 1622 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 1623 found_line = sc.line_entry.line; 1624 1625 while (line_idx != UINT_MAX) 1626 { 1627 sc.function = NULL; 1628 sc.block = NULL; 1629 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1630 { 1631 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 1632 if (file_vm_addr != LLDB_INVALID_ADDRESS) 1633 { 1634 DWARFDebugInfoEntry *function_die = NULL; 1635 DWARFDebugInfoEntry *block_die = NULL; 1636 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL); 1637 1638 if (function_die != NULL) 1639 { 1640 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1641 if (sc.function == NULL) 1642 sc.function = ParseCompileUnitFunction(sc, cu, function_die); 1643 } 1644 1645 if (sc.function != NULL) 1646 { 1647 BlockList& blocks = sc.function->GetBlocks(true); 1648 1649 if (block_die != NULL) 1650 sc.block = blocks.GetBlockByID(block_die->GetOffset()); 1651 else 1652 sc.block = blocks.GetBlockByID(function_die->GetOffset()); 1653 } 1654 } 1655 } 1656 1657 sc_list.Append(sc); 1658 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 1659 } 1660 } 1661 } 1662 else if (file_spec_matches_cu_file_spec && !check_inlines) 1663 { 1664 // only append the context if we aren't looking for inline call sites 1665 // by file and line and if the file spec matches that of the compile unit 1666 sc_list.Append(sc); 1667 } 1668 } 1669 else if (file_spec_matches_cu_file_spec && !check_inlines) 1670 { 1671 // only append the context if we aren't looking for inline call sites 1672 // by file and line and if the file spec matches that of the compile unit 1673 sc_list.Append(sc); 1674 } 1675 1676 if (!check_inlines) 1677 break; 1678 } 1679 } 1680 } 1681 } 1682 return sc_list.GetSize() - prev_size; 1683} 1684 1685void 1686SymbolFileDWARF::Index () 1687{ 1688 if (m_indexed) 1689 return; 1690 m_indexed = true; 1691 Timer scoped_timer (__PRETTY_FUNCTION__, 1692 "SymbolFileDWARF::Index (%s)", 1693 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1694 1695 DWARFDebugInfo* debug_info = DebugInfo(); 1696 if (debug_info) 1697 { 1698 uint32_t cu_idx = 0; 1699 const uint32_t num_compile_units = GetNumCompileUnits(); 1700 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 1701 { 1702 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); 1703 1704 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1; 1705 1706 cu->Index (m_base_name_to_function_die, 1707 m_full_name_to_function_die, 1708 m_method_name_to_function_die, 1709 m_selector_name_to_function_die, 1710 m_name_to_global_die, 1711 m_name_to_type_die); 1712 1713 // Keep memory down by clearing DIEs if this generate function 1714 // caused them to be parsed 1715 if (clear_dies) 1716 cu->ClearDIEs (true); 1717 } 1718 1719 m_base_name_to_function_die.Sort(); 1720 m_full_name_to_function_die.Sort(); 1721 m_method_name_to_function_die.Sort(); 1722 m_selector_name_to_function_die.Sort(); 1723 m_name_to_global_die.Sort(); 1724 m_name_to_type_die.Sort(); 1725 } 1726} 1727 1728uint32_t 1729SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 1730{ 1731 std::vector<dw_offset_t> die_offsets; 1732 1733 // If we aren't appending the results to this list, then clear the list 1734 if (!append) 1735 variables.Clear(); 1736 1737 // Remember how many variables are in the list before we search in case 1738 // we are appending the results to a variable list. 1739 const uint32_t original_size = variables.GetSize(); 1740 1741 // Index the DWARF if we haven't already 1742 if (!m_indexed) 1743 Index (); 1744 1745 const UniqueCStringMap<dw_offset_t>::Entry *entry; 1746 1747 for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString()); 1748 entry != NULL; 1749 entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry)) 1750 { 1751 DWARFCompileUnitSP cu_sp; 1752 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp); 1753 DWARFCompileUnit* cu = cu_sp.get(); 1754 if (die) 1755 { 1756 SymbolContext sc; 1757 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1758 assert (sc.module_sp); 1759 1760 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1761 assert(sc.comp_unit != NULL); 1762 1763 ParseVariables(sc, cu_sp.get(), die, false, false, &variables); 1764 1765 if (variables.GetSize() - original_size >= max_matches) 1766 break; 1767 } 1768 } 1769 1770 // Return the number of variable that were appended to the list 1771 return variables.GetSize() - original_size; 1772} 1773 1774uint32_t 1775SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 1776{ 1777 std::vector<dw_offset_t> die_offsets; 1778 1779 // If we aren't appending the results to this list, then clear the list 1780 if (!append) 1781 variables.Clear(); 1782 1783 // Remember how many variables are in the list before we search in case 1784 // we are appending the results to a variable list. 1785 const uint32_t original_size = variables.GetSize(); 1786 1787 // Index the DWARF if we haven't already 1788 if (!m_indexed) 1789 Index (); 1790 1791 // Create the pubnames information so we can quickly lookup external symbols by name 1792 const size_t num_entries = m_name_to_global_die.GetSize(); 1793 for (size_t i=0; i<num_entries; i++) 1794 { 1795 if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i))) 1796 continue; 1797 1798 const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i); 1799 1800 DWARFCompileUnitSP cu_sp; 1801 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp); 1802 DWARFCompileUnit* cu = cu_sp.get(); 1803 if (die) 1804 { 1805 SymbolContext sc; 1806 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1807 assert (sc.module_sp); 1808 1809 1810 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX); 1811 assert(sc.comp_unit != NULL); 1812 1813 ParseVariables(sc, cu_sp.get(), die, false, false, &variables); 1814 1815 if (variables.GetSize() - original_size >= max_matches) 1816 break; 1817 } 1818 } 1819 1820 // Return the number of variable that were appended to the list 1821 return variables.GetSize() - original_size; 1822} 1823 1824 1825void 1826SymbolFileDWARF::FindFunctions 1827( 1828 const ConstString &name, 1829 UniqueCStringMap<dw_offset_t> &name_to_die, 1830 SymbolContextList& sc_list 1831) 1832{ 1833 const UniqueCStringMap<dw_offset_t>::Entry *entry; 1834 1835 SymbolContext sc; 1836 for (entry = name_to_die.FindFirstValueForName (name.AsCString()); 1837 entry != NULL; 1838 entry = name_to_die.FindNextValueForName (name.AsCString(), entry)) 1839 { 1840 DWARFCompileUnitSP cu_sp; 1841 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp); 1842 if (die) 1843 { 1844 if (GetFunction (cu_sp.get(), die, sc)) 1845 { 1846 // We found the function, so we should find the line table 1847 // and line table entry as well 1848 LineTable *line_table = sc.comp_unit->GetLineTable(); 1849 if (line_table == NULL) 1850 { 1851 if (ParseCompileUnitLineTable(sc)) 1852 line_table = sc.comp_unit->GetLineTable(); 1853 } 1854 if (line_table != NULL) 1855 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry); 1856 1857 sc_list.Append(sc); 1858 } 1859 } 1860 } 1861 1862} 1863 1864uint32_t 1865SymbolFileDWARF::FindFunctions 1866( 1867 const ConstString &name, 1868 uint32_t name_type_mask, 1869 bool append, 1870 SymbolContextList& sc_list 1871) 1872{ 1873 Timer scoped_timer (__PRETTY_FUNCTION__, 1874 "SymbolFileDWARF::FindFunctions (name = '%s')", 1875 name.AsCString()); 1876 1877 std::vector<dw_offset_t> die_offsets; 1878 1879 // If we aren't appending the results to this list, then clear the list 1880 if (!append) 1881 sc_list.Clear(); 1882 1883 // Remember how many sc_list are in the list before we search in case 1884 // we are appending the results to a variable list. 1885 uint32_t original_size = sc_list.GetSize(); 1886 1887 // Index the DWARF if we haven't already 1888 if (!m_indexed) 1889 Index (); 1890 1891 if (name_type_mask & eFunctionNameTypeBase) 1892 FindFunctions (name, m_base_name_to_function_die, sc_list); 1893 1894 if (name_type_mask & eFunctionNameTypeFull) 1895 FindFunctions (name, m_full_name_to_function_die, sc_list); 1896 1897 if (name_type_mask & eFunctionNameTypeMethod) 1898 FindFunctions (name, m_method_name_to_function_die, sc_list); 1899 1900 if (name_type_mask & eFunctionNameTypeSelector) 1901 FindFunctions (name, m_selector_name_to_function_die, sc_list); 1902 1903 // Return the number of variable that were appended to the list 1904 return sc_list.GetSize() - original_size; 1905} 1906 1907 1908uint32_t 1909SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) 1910{ 1911 Timer scoped_timer (__PRETTY_FUNCTION__, 1912 "SymbolFileDWARF::FindFunctions (regex = '%s')", 1913 regex.GetText()); 1914 1915 std::vector<dw_offset_t> die_offsets; 1916 1917 // If we aren't appending the results to this list, then clear the list 1918 if (!append) 1919 sc_list.Clear(); 1920 1921 // Remember how many sc_list are in the list before we search in case 1922 // we are appending the results to a variable list. 1923 uint32_t original_size = sc_list.GetSize(); 1924 1925 // Index the DWARF if we haven't already 1926 if (!m_indexed) 1927 Index (); 1928 1929 // Create the pubnames information so we can quickly lookup external symbols by name 1930 // Create the pubnames information so we can quickly lookup external symbols by name 1931 const size_t num_entries = m_full_name_to_function_die.GetSize(); 1932 SymbolContext sc; 1933 for (size_t i=0; i<num_entries; i++) 1934 { 1935 if (!regex.Execute(m_full_name_to_function_die.GetCStringAtIndex (i))) 1936 continue; 1937 1938 const dw_offset_t die_offset = *m_full_name_to_function_die.GetValueAtIndex (i); 1939 1940 DWARFCompileUnitSP cu_sp; 1941 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp); 1942 if (die) 1943 { 1944 if (GetFunction (cu_sp.get(), die, sc)) 1945 { 1946 // We found the function, so we should find the line table 1947 // and line table entry as well 1948 LineTable *line_table = sc.comp_unit->GetLineTable(); 1949 if (line_table == NULL) 1950 { 1951 if (ParseCompileUnitLineTable(sc)) 1952 line_table = sc.comp_unit->GetLineTable(); 1953 } 1954 if (line_table != NULL) 1955 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry); 1956 1957 1958 sc_list.Append(sc); 1959 } 1960 } 1961 } 1962 1963 // Return the number of variable that were appended to the list 1964 return sc_list.GetSize() - original_size; 1965} 1966 1967#if 0 1968uint32_t 1969SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 1970{ 1971 // If we aren't appending the results to this list, then clear the list 1972 if (!append) 1973 types.Clear(); 1974 1975 // Create the pubnames information so we can quickly lookup external symbols by name 1976 DWARFDebugPubnames* pubtypes = DebugPubtypes(); 1977 if (pubtypes) 1978 { 1979 std::vector<dw_offset_t> die_offsets; 1980 if (!pubtypes->Find(name.AsCString(), false, die_offsets)) 1981 { 1982 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); 1983 if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets)) 1984 return 0; 1985 } 1986 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); 1987 } 1988 return 0; 1989} 1990 1991 1992uint32_t 1993SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 1994{ 1995 // If we aren't appending the results to this list, then clear the list 1996 if (!append) 1997 types.Clear(); 1998 1999 // Create the pubnames information so we can quickly lookup external symbols by name 2000 DWARFDebugPubnames* pubtypes = DebugPubtypes(); 2001 if (pubtypes) 2002 { 2003 std::vector<dw_offset_t> die_offsets; 2004 if (!pubtypes->Find(regex, die_offsets)) 2005 { 2006 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); 2007 if (pub_base_types && !pub_base_types->Find(regex, die_offsets)) 2008 return 0; 2009 } 2010 2011 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); 2012 } 2013 2014 return 0; 2015} 2016 2017 2018 2019uint32_t 2020SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) 2021{ 2022 // Remember how many sc_list are in the list before we search in case 2023 // we are appending the results to a variable list. 2024 uint32_t original_size = types.Size(); 2025 2026 const uint32_t num_die_offsets = die_offsets.size(); 2027 // Parse all of the types we found from the pubtypes matches 2028 uint32_t i; 2029 uint32_t num_matches = 0; 2030 for (i = 0; i < num_die_offsets; ++i) 2031 { 2032 dw_offset_t die_offset = die_offsets[i]; 2033 DWARFCompileUnitSP cu_sp; 2034 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2035 2036 assert(die != NULL); 2037 2038 bool get_type_for_die = true; 2039 if (encoding) 2040 { 2041 // Check if this type has already been uniqued and registers with the module? 2042 Type* type = (Type*)die->GetUserData(); 2043 if (type != NULL && type != DIE_IS_BEING_PARSED) 2044 { 2045 get_type_for_die = type->GetEncoding() == encoding; 2046 } 2047 else 2048 { 2049 dw_tag_t tag = die->Tag(); 2050 switch (encoding) 2051 { 2052 case Type::address: 2053 case Type::boolean: 2054 case Type::complex_float: 2055 case Type::float_type: 2056 case Type::signed_int: 2057 case Type::signed_char: 2058 case Type::unsigned_int: 2059 case Type::unsigned_char: 2060 case Type::imaginary_float: 2061 case Type::packed_decimal: 2062 case Type::numeric_string: 2063 case Type::edited_string: 2064 case Type::signed_fixed: 2065 case Type::unsigned_fixed: 2066 case Type::decimal_float: 2067 if (tag != DW_TAG_base_type) 2068 get_type_for_die = false; 2069 else 2070 { 2071 if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding) 2072 get_type_for_die = false; 2073 } 2074 break; 2075 2076 case Type::indirect_const: get_type_for_die = tag == DW_TAG_const_type; break; 2077 case Type::indirect_restrict: get_type_for_die = tag == DW_TAG_restrict_type; break; 2078 case Type::indirect_volatile: get_type_for_die = tag == DW_TAG_volatile_type; break; 2079 case Type::indirect_typedef: get_type_for_die = tag == DW_TAG_typedef; break; 2080 case Type::indirect_pointer: get_type_for_die = tag == DW_TAG_pointer_type; break; 2081 case Type::indirect_reference: get_type_for_die = tag == DW_TAG_reference_type; break; 2082 2083 case Type::user_defined_type: 2084 switch (tag) 2085 { 2086 case DW_TAG_array_type: 2087 get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid); 2088 break; 2089 2090 case DW_TAG_structure_type: 2091 case DW_TAG_union_type: 2092 case DW_TAG_class_type: 2093 get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid); 2094 break; 2095 2096 case DW_TAG_enumeration_type: 2097 get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid); 2098 break; 2099 2100 case DW_TAG_subprogram: 2101 case DW_TAG_subroutine_type: 2102 get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid); 2103 break; 2104 } 2105 } 2106 } 2107 } 2108 2109 if (get_type_for_die) 2110 { 2111 TypeSP owning_type_sp; 2112 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0)); 2113 2114 if (type_sp.get()) 2115 { 2116 // See if we are filtering results based on encoding? 2117 bool add_type = (encoding == Type::invalid); 2118 if (!add_type) 2119 { 2120 // We are filtering base on encoding, so lets check the resulting type encoding 2121 add_type = (encoding == type_sp->GetEncoding()); 2122 if (add_type) 2123 { 2124 // The type encoding matches, if this is a user defined type, lets 2125 // make sure the exact user define type uid matches if one was provided 2126 if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID) 2127 { 2128 UserDefType* udt = type_sp->GetUserDefinedType().get(); 2129 if (udt) 2130 add_type = udt->UserDefinedTypeUID() == udt_uid; 2131 } 2132 } 2133 } 2134 // Add the type to our list as long as everything matched 2135 if (add_type) 2136 { 2137 types.InsertUnique(type_sp); 2138 if (++num_matches >= max_matches) 2139 break; 2140 } 2141 } 2142 } 2143 } 2144 2145 // Return the number of variable that were appended to the list 2146 return types.Size() - original_size; 2147} 2148 2149#endif 2150 2151 2152size_t 2153SymbolFileDWARF::ParseChildParameters 2154( 2155 const SymbolContext& sc, 2156 TypeSP& type_sp, 2157 const DWARFCompileUnit* dwarf_cu, 2158 const DWARFDebugInfoEntry *parent_die, 2159 TypeList* type_list, 2160 std::vector<void *>& function_param_types, 2161 std::vector<clang::ParmVarDecl*>& function_param_decls 2162) 2163{ 2164 if (parent_die == NULL) 2165 return 0; 2166 2167 size_t count = 0; 2168 const DWARFDebugInfoEntry *die; 2169 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2170 { 2171 dw_tag_t tag = die->Tag(); 2172 switch (tag) 2173 { 2174 case DW_TAG_formal_parameter: 2175 { 2176 DWARFDebugInfoEntry::Attributes attributes; 2177 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2178 if (num_attributes > 0) 2179 { 2180 const char *name = NULL; 2181 Declaration decl; 2182 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; 2183 // one of None, Auto, Register, Extern, Static, PrivateExtern 2184 2185 clang::VarDecl::StorageClass storage = clang::VarDecl::None; 2186 uint32_t i; 2187 for (i=0; i<num_attributes; ++i) 2188 { 2189 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2190 DWARFFormValue form_value; 2191 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2192 { 2193 switch (attr) 2194 { 2195 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2196 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2197 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2198 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 2199 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; 2200 case DW_AT_location: 2201 // if (form_value.BlockData()) 2202 // { 2203 // const DataExtractor& debug_info_data = debug_info(); 2204 // uint32_t block_length = form_value.Unsigned(); 2205 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); 2206 // } 2207 // else 2208 // { 2209 // } 2210 // break; 2211 case DW_AT_artificial: 2212 case DW_AT_const_value: 2213 case DW_AT_default_value: 2214 case DW_AT_description: 2215 case DW_AT_endianity: 2216 case DW_AT_is_optional: 2217 case DW_AT_segment: 2218 case DW_AT_variable_parameter: 2219 default: 2220 case DW_AT_abstract_origin: 2221 case DW_AT_sibling: 2222 break; 2223 } 2224 } 2225 } 2226 Type *dc_type = ResolveTypeUID(param_type_die_offset); 2227 if (dc_type) 2228 { 2229 function_param_types.push_back (dc_type->GetOpaqueClangQualType()); 2230 2231 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage); 2232 assert(param_var_decl); 2233 function_param_decls.push_back(param_var_decl); 2234 } 2235 } 2236 } 2237 break; 2238 2239 default: 2240 break; 2241 } 2242 } 2243 return count; 2244} 2245 2246size_t 2247SymbolFileDWARF::ParseChildEnumerators 2248( 2249 const SymbolContext& sc, 2250 TypeSP& type_sp, 2251 void * enumerator_qual_type, 2252 uint32_t enumerator_byte_size, 2253 const DWARFCompileUnit* dwarf_cu, 2254 const DWARFDebugInfoEntry *parent_die 2255) 2256{ 2257 if (parent_die == NULL) 2258 return 0; 2259 2260 size_t enumerators_added = 0; 2261 const DWARFDebugInfoEntry *die; 2262 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2263 { 2264 const dw_tag_t tag = die->Tag(); 2265 if (tag == DW_TAG_enumerator) 2266 { 2267 DWARFDebugInfoEntry::Attributes attributes; 2268 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2269 if (num_child_attributes > 0) 2270 { 2271 const char *name = NULL; 2272 bool got_value = false; 2273 int64_t enum_value = 0; 2274 Declaration decl; 2275 2276 uint32_t i; 2277 for (i=0; i<num_child_attributes; ++i) 2278 { 2279 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2280 DWARFFormValue form_value; 2281 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2282 { 2283 switch (attr) 2284 { 2285 case DW_AT_const_value: 2286 got_value = true; 2287 enum_value = form_value.Unsigned(); 2288 break; 2289 2290 case DW_AT_name: 2291 name = form_value.AsCString(&get_debug_str_data()); 2292 break; 2293 2294 case DW_AT_description: 2295 default: 2296 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2297 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2298 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2299 case DW_AT_sibling: 2300 break; 2301 } 2302 } 2303 } 2304 2305 if (name && name[0] && got_value) 2306 { 2307 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2308 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8); 2309 ++enumerators_added; 2310 } 2311 } 2312 } 2313 } 2314 return enumerators_added; 2315} 2316 2317void 2318SymbolFileDWARF::ParseChildArrayInfo 2319( 2320 const SymbolContext& sc, 2321 const DWARFCompileUnit* dwarf_cu, 2322 const DWARFDebugInfoEntry *parent_die, 2323 int64_t& first_index, 2324 std::vector<uint64_t>& element_orders, 2325 uint32_t& byte_stride, 2326 uint32_t& bit_stride 2327) 2328{ 2329 if (parent_die == NULL) 2330 return; 2331 2332 const DWARFDebugInfoEntry *die; 2333 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2334 { 2335 const dw_tag_t tag = die->Tag(); 2336 switch (tag) 2337 { 2338 case DW_TAG_enumerator: 2339 { 2340 DWARFDebugInfoEntry::Attributes attributes; 2341 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2342 if (num_child_attributes > 0) 2343 { 2344 const char *name = NULL; 2345 bool got_value = false; 2346 int64_t enum_value = 0; 2347 2348 uint32_t i; 2349 for (i=0; i<num_child_attributes; ++i) 2350 { 2351 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2352 DWARFFormValue form_value; 2353 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2354 { 2355 switch (attr) 2356 { 2357 case DW_AT_const_value: 2358 got_value = true; 2359 enum_value = form_value.Unsigned(); 2360 break; 2361 2362 case DW_AT_name: 2363 name = form_value.AsCString(&get_debug_str_data()); 2364 break; 2365 2366 case DW_AT_description: 2367 default: 2368 case DW_AT_decl_file: 2369 case DW_AT_decl_line: 2370 case DW_AT_decl_column: 2371 case DW_AT_sibling: 2372 break; 2373 } 2374 } 2375 } 2376 } 2377 } 2378 break; 2379 2380 case DW_TAG_subrange_type: 2381 { 2382 DWARFDebugInfoEntry::Attributes attributes; 2383 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2384 if (num_child_attributes > 0) 2385 { 2386 const char *name = NULL; 2387 bool got_value = false; 2388 uint64_t byte_size = 0; 2389 int64_t enum_value = 0; 2390 uint64_t num_elements = 0; 2391 uint64_t lower_bound = 0; 2392 uint64_t upper_bound = 0; 2393 uint32_t i; 2394 for (i=0; i<num_child_attributes; ++i) 2395 { 2396 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2397 DWARFFormValue form_value; 2398 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2399 { 2400 switch (attr) 2401 { 2402 case DW_AT_const_value: 2403 got_value = true; 2404 enum_value = form_value.Unsigned(); 2405 break; 2406 2407 case DW_AT_name: 2408 name = form_value.AsCString(&get_debug_str_data()); 2409 break; 2410 2411 case DW_AT_count: 2412 num_elements = form_value.Unsigned(); 2413 break; 2414 2415 case DW_AT_bit_stride: 2416 bit_stride = form_value.Unsigned(); 2417 break; 2418 2419 case DW_AT_byte_stride: 2420 byte_stride = form_value.Unsigned(); 2421 break; 2422 2423 case DW_AT_byte_size: 2424 byte_size = form_value.Unsigned(); 2425 break; 2426 2427 case DW_AT_lower_bound: 2428 lower_bound = form_value.Unsigned(); 2429 break; 2430 2431 case DW_AT_upper_bound: 2432 upper_bound = form_value.Unsigned(); 2433 break; 2434 2435 default: 2436 //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 2437 2438 case DW_AT_abstract_origin: 2439 case DW_AT_accessibility: 2440 case DW_AT_allocated: 2441 case DW_AT_associated: 2442 case DW_AT_data_location: 2443 case DW_AT_declaration: 2444 case DW_AT_description: 2445 case DW_AT_sibling: 2446 case DW_AT_threads_scaled: 2447 case DW_AT_type: 2448 case DW_AT_visibility: 2449 break; 2450 } 2451 } 2452 } 2453 2454 if (upper_bound > lower_bound) 2455 num_elements = upper_bound - lower_bound + 1; 2456 2457 if (num_elements > 0) 2458 element_orders.push_back (num_elements); 2459 } 2460 } 2461 break; 2462 } 2463 } 2464} 2465 2466Type* 2467SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe) 2468{ 2469 if (type_die_offset != DW_INVALID_OFFSET) 2470 { 2471 DWARFCompileUnitSP cu_sp; 2472 const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp); 2473 assert(type_die != NULL); 2474 GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx); 2475 // Return the uniqued type if there is one 2476 Type* type = (Type*)type_die->GetUserData(); 2477 if (type == DIE_IS_BEING_PARSED && safe) 2478 return NULL; 2479 return type; 2480 } 2481 return NULL; 2482} 2483 2484TypeSP 2485SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx) 2486{ 2487 TypeSP type_sp; 2488 if (die != NULL) 2489 { 2490 assert(cu != NULL); 2491 Type *type_ptr = (Type *)die->GetUserData(); 2492 if (type_ptr == NULL) 2493 { 2494 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu)); 2495 bool type_is_new = false; 2496 type_sp = ParseType(sc, cu, die, type_is_new); 2497 type_ptr = (Type *)die->GetUserData(); 2498 if (owning_type_sp.get() == NULL) 2499 owning_type_sp = type_sp; 2500 } 2501 else if (type_ptr != DIE_IS_BEING_PARSED) 2502 { 2503 // Grab the existing type from the master types lists 2504 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID()); 2505 } 2506 2507 } 2508 return type_sp; 2509} 2510 2511clang::DeclContext * 2512SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset) 2513{ 2514 if (die_offset != DW_INVALID_OFFSET) 2515 { 2516 DWARFCompileUnitSP cu_sp; 2517 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2518 return GetClangDeclContextForDIE (cu_sp.get(), die); 2519 } 2520 return NULL; 2521} 2522 2523 2524 2525clang::DeclContext * 2526SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 2527{ 2528 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); 2529 if (pos != m_die_to_decl_ctx.end()) 2530 return pos->second; 2531 2532 while (die != NULL) 2533 { 2534 switch (die->Tag()) 2535 { 2536 case DW_TAG_namespace: 2537 { 2538 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL); 2539 if (namespace_name) 2540 { 2541 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2542 assert(type_list); 2543 Declaration decl; // TODO: fill in the decl object 2544 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent())); 2545 if (namespace_decl) 2546 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl; 2547 return namespace_decl; 2548 } 2549 } 2550 break; 2551 2552 default: 2553 break; 2554 } 2555 clang::DeclContext *decl_ctx; 2556 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET)); 2557 if (decl_ctx) 2558 return decl_ctx; 2559 2560 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET)); 2561 if (decl_ctx) 2562 return decl_ctx; 2563 2564 die = die->GetParent(); 2565 } 2566 return NULL; 2567} 2568 2569TypeSP 2570SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new) 2571{ 2572 TypeSP type_sp; 2573 2574 ClangASTContext::AccessType accessibility = ClangASTContext::eAccessNone; 2575 if (die != NULL) 2576 { 2577 dw_tag_t tag = die->Tag(); 2578 if (die->GetUserData() == NULL) 2579 { 2580 type_is_new = true; 2581 2582 bool is_forward_declaration = false; 2583 DWARFDebugInfoEntry::Attributes attributes; 2584 const char *type_name_cstr = NULL; 2585 ConstString type_name_dbstr; 2586 Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID; 2587 void *clang_type = NULL; 2588 2589 TypeList* type_list = m_obj_file->GetModule()->GetTypeList(); 2590 dw_attr_t attr; 2591 2592 switch (tag) 2593 { 2594 case DW_TAG_base_type: 2595 case DW_TAG_pointer_type: 2596 case DW_TAG_reference_type: 2597 case DW_TAG_typedef: 2598 case DW_TAG_const_type: 2599 case DW_TAG_restrict_type: 2600 case DW_TAG_volatile_type: 2601 { 2602 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2603 // Set a bit that lets us know that we are currently parsing this 2604 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2605 2606 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2607 Declaration decl; 2608 uint32_t encoding = 0; 2609 size_t byte_size = 0; 2610 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 2611 2612 if (num_attributes > 0) 2613 { 2614 uint32_t i; 2615 for (i=0; i<num_attributes; ++i) 2616 { 2617 attr = attributes.AttributeAtIndex(i); 2618 DWARFFormValue form_value; 2619 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2620 { 2621 switch (attr) 2622 { 2623 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2624 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2625 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2626 case DW_AT_name: 2627 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2628 type_name_dbstr.SetCString(type_name_cstr); 2629 break; 2630 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2631 case DW_AT_encoding: encoding = form_value.Unsigned(); break; 2632 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 2633 default: 2634 case DW_AT_sibling: 2635 break; 2636 } 2637 } 2638 } 2639 } 2640 2641 switch (tag) 2642 { 2643 default: 2644 case DW_TAG_base_type: 2645 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8); 2646 break; 2647 2648 case DW_TAG_pointer_type: 2649 // The encoding_uid will be embedded into the 2650 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2651 encoding_uid_type = Type::ePointerToTypeWithUID; 2652 break; 2653 2654 case DW_TAG_reference_type: 2655 // The encoding_uid will be embedded into the 2656 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2657 encoding_uid_type = Type::eLValueReferenceToTypeWithUID; 2658 break; 2659 2660 case DW_TAG_typedef: 2661 // The encoding_uid will be embedded into the 2662 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2663 encoding_uid_type = Type::eTypedefToTypeWithUID; 2664 break; 2665 2666 case DW_TAG_const_type: 2667 // The encoding_uid will be embedded into the 2668 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2669 encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type); 2670 break; 2671 2672 case DW_TAG_restrict_type: 2673 // The encoding_uid will be embedded into the 2674 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2675 encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type); 2676 break; 2677 2678 case DW_TAG_volatile_type: 2679 // The encoding_uid will be embedded into the 2680 // Type object and will be looked up when the Type::GetOpaqueClangQualType() 2681 encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type); 2682 break; 2683 } 2684 2685 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type)); 2686 2687 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2688 2689 2690// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); 2691// if (encoding_type != NULL) 2692// { 2693// if (encoding_type != DIE_IS_BEING_PARSED) 2694// type_sp->SetEncodingType(encoding_type); 2695// else 2696// m_indirect_fixups.push_back(type_sp.get()); 2697// } 2698 } 2699 break; 2700 2701 case DW_TAG_structure_type: 2702 case DW_TAG_union_type: 2703 case DW_TAG_class_type: 2704 { 2705 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2706 // Set a bit that lets us know that we are currently parsing this 2707 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2708 2709 size_t byte_size = 0; 2710 //bool struct_is_class = false; 2711 Declaration decl; 2712 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2713 if (num_attributes > 0) 2714 { 2715 uint32_t i; 2716 for (i=0; i<num_attributes; ++i) 2717 { 2718 attr = attributes.AttributeAtIndex(i); 2719 DWARFFormValue form_value; 2720 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2721 { 2722 switch (attr) 2723 { 2724 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2725 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2726 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2727 case DW_AT_name: 2728 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2729 type_name_dbstr.SetCString(type_name_cstr); 2730 break; 2731 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2732 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; break; 2733 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2734 case DW_AT_allocated: 2735 case DW_AT_associated: 2736 case DW_AT_data_location: 2737 case DW_AT_description: 2738 case DW_AT_start_scope: 2739 case DW_AT_visibility: 2740 default: 2741 case DW_AT_sibling: 2742 break; 2743 } 2744 } 2745 } 2746 } 2747 2748 int tag_decl_kind = -1; 2749 ClangASTContext::AccessType default_accessibility = ClangASTContext::eAccessNone; 2750 if (tag == DW_TAG_structure_type) 2751 { 2752 tag_decl_kind = clang::TTK_Struct; 2753 default_accessibility = ClangASTContext::eAccessPublic; 2754 } 2755 else if (tag == DW_TAG_union_type) 2756 { 2757 tag_decl_kind = clang::TTK_Union; 2758 default_accessibility = ClangASTContext::eAccessPublic; 2759 } 2760 else if (tag == DW_TAG_class_type) 2761 { 2762 tag_decl_kind = clang::TTK_Class; 2763 default_accessibility = ClangASTContext::eAccessPrivate; 2764 } 2765 2766 assert (tag_decl_kind != -1); 2767 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die)); 2768 2769 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); 2770 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 2771 2772 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2773 2774// assert(type_sp.get()); 2775// if (accessibility) 2776// type_sp->SetAccess(accessibility); 2777// 2778 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type); 2779 if (die->HasChildren()) 2780 { 2781 std::vector<clang::CXXBaseSpecifier *> base_classes; 2782 std::vector<int> member_accessibilities; 2783 bool is_a_class = false; 2784 ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class); 2785 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we 2786 // need to tell the clang type it is actually a class. 2787 if (is_a_class && tag_decl_kind != clang::TTK_Class) 2788 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class); 2789 2790 // Since DW_TAG_structure_type gets used for both classes 2791 // and structures, we may need to set any DW_TAG_member 2792 // fields to have a "private" access if none was specified. 2793 // When we parsed the child members we tracked that actual 2794 // accessibility value for each DW_TAG_member in the 2795 // "member_accessibilities" array. If the value for the 2796 // member is zero, then it was set to the "default_accessibility" 2797 // which for structs was "public". Below we correct this 2798 // by setting any fields to "private" that weren't correctly 2799 // set. 2800 if (is_a_class && !member_accessibilities.empty()) 2801 { 2802 // This is a class and all members that didn't have 2803 // their access specified are private. 2804 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, ClangASTContext::eAccessPrivate, &member_accessibilities.front(), member_accessibilities.size()); 2805 } 2806 2807 if (!base_classes.empty()) 2808 { 2809 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, &base_classes.front(), base_classes.size()); 2810 2811 // Clang will copy each CXXBaseSpecifier in "base_classes" 2812 // so we have to free them all. 2813 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), base_classes.size()); 2814 } 2815 2816 } 2817 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type); 2818 } 2819 break; 2820 2821 case DW_TAG_enumeration_type: 2822 { 2823 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2824 // Set a bit that lets us know that we are currently parsing this 2825 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2826 2827 size_t byte_size = 0; 2828 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; 2829 Declaration decl; 2830 2831 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2832 if (num_attributes > 0) 2833 { 2834 uint32_t i; 2835 2836 for (i=0; i<num_attributes; ++i) 2837 { 2838 attr = attributes.AttributeAtIndex(i); 2839 DWARFFormValue form_value; 2840 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2841 { 2842 switch (attr) 2843 { 2844 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2845 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2846 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2847 case DW_AT_name: 2848 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2849 type_name_dbstr.SetCString(type_name_cstr); 2850 break; 2851 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 2852 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 2853 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 2854 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2855 case DW_AT_allocated: 2856 case DW_AT_associated: 2857 case DW_AT_bit_stride: 2858 case DW_AT_byte_stride: 2859 case DW_AT_data_location: 2860 case DW_AT_description: 2861 case DW_AT_start_scope: 2862 case DW_AT_visibility: 2863 case DW_AT_specification: 2864 case DW_AT_abstract_origin: 2865 case DW_AT_sibling: 2866 break; 2867 } 2868 } 2869 } 2870 2871 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr); 2872 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); 2873 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type)); 2874 2875 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 2876 2877 if (die->HasChildren()) 2878 { 2879 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type); 2880 void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8); 2881 ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die); 2882 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type); 2883 } 2884 } 2885 } 2886 break; 2887 2888 case DW_TAG_subprogram: 2889 case DW_TAG_subroutine_type: 2890 { 2891 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 2892 // Set a bit that lets us know that we are currently parsing this 2893 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 2894 2895 const char *mangled = NULL; 2896 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 2897 Declaration decl; 2898 bool isVariadic = false; 2899 bool is_inline = false; 2900 unsigned type_quals = 0; 2901 clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern 2902 2903 2904 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 2905 if (num_attributes > 0) 2906 { 2907 uint32_t i; 2908 for (i=0; i<num_attributes; ++i) 2909 { 2910 attr = attributes.AttributeAtIndex(i); 2911 DWARFFormValue form_value; 2912 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2913 { 2914 switch (attr) 2915 { 2916 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2917 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2918 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2919 case DW_AT_name: 2920 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 2921 type_name_dbstr.SetCString(type_name_cstr); 2922 break; 2923 2924 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 2925 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 2926 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 2927 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 2928 case DW_AT_external: 2929 if (form_value.Unsigned()) 2930 { 2931 if (storage == clang::FunctionDecl::None) 2932 storage = clang::FunctionDecl::Extern; 2933 else 2934 storage = clang::FunctionDecl::PrivateExtern; 2935 } 2936 break; 2937 case DW_AT_inline: 2938 is_inline = form_value.Unsigned() != 0; 2939 break; 2940 2941 case DW_AT_allocated: 2942 case DW_AT_associated: 2943 case DW_AT_address_class: 2944 case DW_AT_artificial: 2945 case DW_AT_calling_convention: 2946 case DW_AT_data_location: 2947 case DW_AT_elemental: 2948 case DW_AT_entry_pc: 2949 case DW_AT_explicit: 2950 case DW_AT_frame_base: 2951 case DW_AT_high_pc: 2952 case DW_AT_low_pc: 2953 case DW_AT_object_pointer: 2954 case DW_AT_prototyped: 2955 case DW_AT_pure: 2956 case DW_AT_ranges: 2957 case DW_AT_recursive: 2958 case DW_AT_return_addr: 2959 case DW_AT_segment: 2960 case DW_AT_specification: 2961 case DW_AT_start_scope: 2962 case DW_AT_static_link: 2963 case DW_AT_trampoline: 2964 case DW_AT_visibility: 2965 case DW_AT_virtuality: 2966 case DW_AT_vtable_elem_location: 2967 case DW_AT_abstract_origin: 2968 case DW_AT_description: 2969 case DW_AT_sibling: 2970 break; 2971 } 2972 } 2973 } 2974 2975 void *return_clang_type = NULL; 2976 Type *func_type = ResolveTypeUID(type_die_offset); 2977 if (func_type) 2978 return_clang_type = func_type->GetOpaqueClangQualType(); 2979 else 2980 return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType(); 2981 2982 std::vector<void *> function_param_types; 2983 std::vector<clang::ParmVarDecl*> function_param_decls; 2984 2985 // Parse the function children for the parameters 2986 ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls); 2987 2988 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals); 2989 if (type_name_cstr) 2990 { 2991 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline); 2992 // Add the decl to our DIE to decl context map 2993 assert (function_decl); 2994 m_die_to_decl_ctx[die] = function_decl; 2995 if (!function_param_decls.empty()) 2996 type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size()); 2997 } 2998 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 2999 3000 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3001 assert(type_sp.get()); 3002 } 3003 } 3004 break; 3005 3006 case DW_TAG_array_type: 3007 { 3008 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag)); 3009 // Set a bit that lets us know that we are currently parsing this 3010 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED); 3011 3012 size_t byte_size = 0; 3013 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; 3014 Declaration decl; 3015 int64_t first_index = 0; 3016 uint32_t byte_stride = 0; 3017 uint32_t bit_stride = 0; 3018 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3019 3020 if (num_attributes > 0) 3021 { 3022 uint32_t i; 3023 for (i=0; i<num_attributes; ++i) 3024 { 3025 attr = attributes.AttributeAtIndex(i); 3026 DWARFFormValue form_value; 3027 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3028 { 3029 switch (attr) 3030 { 3031 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3032 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3033 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3034 case DW_AT_name: 3035 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3036 type_name_dbstr.SetCString(type_name_cstr); 3037 break; 3038 3039 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3040 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 3041 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; 3042 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; 3043 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3044 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3045 case DW_AT_allocated: 3046 case DW_AT_associated: 3047 case DW_AT_data_location: 3048 case DW_AT_description: 3049 case DW_AT_ordering: 3050 case DW_AT_start_scope: 3051 case DW_AT_visibility: 3052 case DW_AT_specification: 3053 case DW_AT_abstract_origin: 3054 case DW_AT_sibling: 3055 break; 3056 } 3057 } 3058 } 3059 3060 Type *element_type = ResolveTypeUID(type_die_offset); 3061 3062 if (element_type) 3063 { 3064 std::vector<uint64_t> element_orders; 3065 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); 3066 if (byte_stride == 0 && bit_stride == 0) 3067 byte_stride = element_type->GetByteSize(); 3068 void *array_element_type = element_type->GetOpaqueClangQualType(); 3069 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; 3070 uint64_t num_elements = 0; 3071 std::vector<uint64_t>::const_reverse_iterator pos; 3072 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); 3073 for (pos = element_orders.rbegin(); pos != end; ++pos) 3074 { 3075 num_elements = *pos; 3076 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride); 3077 array_element_type = clang_type; 3078 array_element_bit_stride = array_element_bit_stride * num_elements; 3079 } 3080 ConstString empty_name; 3081 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); 3082 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3083 } 3084 } 3085 } 3086 break; 3087 3088 case DW_TAG_ptr_to_member_type: 3089 { 3090 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 3091 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET; 3092 3093 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3094 3095 if (num_attributes > 0) { 3096 uint32_t i; 3097 for (i=0; i<num_attributes; ++i) 3098 { 3099 attr = attributes.AttributeAtIndex(i); 3100 DWARFFormValue form_value; 3101 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3102 { 3103 switch (attr) 3104 { 3105 case DW_AT_type: 3106 type_die_offset = form_value.Reference(dwarf_cu); break; 3107 case DW_AT_containing_type: 3108 containing_type_die_offset = form_value.Reference(dwarf_cu); break; 3109 } 3110 } 3111 } 3112 3113 Type *pointee_type = ResolveTypeUID(type_die_offset); 3114 Type *class_type = ResolveTypeUID(containing_type_die_offset); 3115 3116 void *pointee_clang_type = pointee_type->GetOpaqueClangQualType(); 3117 void *class_clang_type = class_type->GetOpaqueClangQualType(); 3118 3119 clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type); 3120 3121 size_t byte_size = ClangASTContext::GetTypeBitSize(type_list->GetClangASTContext().getASTContext(), clang_type) / 8; 3122 3123 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type)); 3124 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get()); 3125 } 3126 3127 break; 3128 } 3129 default: 3130 assert(false && "Unhandled type tag!"); 3131 break; 3132 } 3133 3134 if (type_sp.get()) 3135 { 3136 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3137 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3138 3139 SymbolContextScope * symbol_context_scope = NULL; 3140 if (sc_parent_tag == DW_TAG_compile_unit) 3141 { 3142 symbol_context_scope = sc.comp_unit; 3143 } 3144 else if (sc.function != NULL) 3145 { 3146 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); 3147 if (symbol_context_scope == NULL) 3148 symbol_context_scope = sc.function; 3149 } 3150 3151 if (symbol_context_scope != NULL) 3152 { 3153 type_sp->SetSymbolContextScope(symbol_context_scope); 3154 } 3155 3156// if (udt_sp.get()) 3157// { 3158// if (is_forward_declaration) 3159// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition); 3160// type_sp->SetUserDefinedType(udt_sp); 3161// } 3162 3163 if (type_sp.unique()) 3164 { 3165 // We are ready to put this type into the uniqued list up at the module level 3166 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp)); 3167 3168 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get()); 3169 3170 type_sp = uniqued_type_sp; 3171 } 3172 } 3173 } 3174 else 3175 { 3176 switch (tag) 3177 { 3178 case DW_TAG_base_type: 3179 case DW_TAG_pointer_type: 3180 case DW_TAG_reference_type: 3181 case DW_TAG_typedef: 3182 case DW_TAG_const_type: 3183 case DW_TAG_restrict_type: 3184 case DW_TAG_volatile_type: 3185 case DW_TAG_structure_type: 3186 case DW_TAG_union_type: 3187 case DW_TAG_class_type: 3188 case DW_TAG_enumeration_type: 3189 case DW_TAG_subprogram: 3190 case DW_TAG_subroutine_type: 3191 case DW_TAG_array_type: 3192 { 3193 Type *existing_type = (Type*)die->GetUserData(); 3194 if (existing_type != DIE_IS_BEING_PARSED) 3195 { 3196 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID()); 3197 } 3198 } 3199 break; 3200 default: 3201 //assert(!"invalid type tag..."); 3202 break; 3203 } 3204 } 3205 } 3206 return type_sp; 3207} 3208 3209size_t 3210SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children) 3211{ 3212 size_t types_added = 0; 3213 while (die != NULL) 3214 { 3215 bool type_is_new = false; 3216 if (ParseType(sc, dwarf_cu, die, type_is_new).get()) 3217 { 3218 if (type_is_new) 3219 ++types_added; 3220 } 3221 3222 if (parse_children && die->HasChildren()) 3223 { 3224 if (die->Tag() == DW_TAG_subprogram) 3225 { 3226 SymbolContext child_sc(sc); 3227 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get(); 3228 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true); 3229 } 3230 else 3231 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true); 3232 } 3233 3234 if (parse_siblings) 3235 die = die->GetSibling(); 3236 else 3237 die = NULL; 3238 } 3239 return types_added; 3240} 3241 3242 3243size_t 3244SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 3245{ 3246 assert(sc.comp_unit && sc.function); 3247 size_t functions_added = 0; 3248 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3249 if (dwarf_cu) 3250 { 3251 dw_offset_t function_die_offset = sc.function->GetID(); 3252 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); 3253 if (function_die) 3254 { 3255 ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true); 3256 } 3257 } 3258 3259 return functions_added; 3260} 3261 3262 3263size_t 3264SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 3265{ 3266 // At least a compile unit must be valid 3267 assert(sc.comp_unit); 3268 size_t types_added = 0; 3269 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3270 if (dwarf_cu) 3271 { 3272 if (sc.function) 3273 { 3274 dw_offset_t function_die_offset = sc.function->GetID(); 3275 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset); 3276 if (func_die && func_die->HasChildren()) 3277 { 3278 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true); 3279 } 3280 } 3281 else 3282 { 3283 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE(); 3284 if (dwarf_cu_die && dwarf_cu_die->HasChildren()) 3285 { 3286 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true); 3287 } 3288 } 3289 } 3290 3291 return types_added; 3292} 3293 3294size_t 3295SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 3296{ 3297 if (sc.comp_unit != NULL) 3298 { 3299 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3300 3301 if (dwarf_cu == NULL) 3302 return 0; 3303 3304 if (sc.function) 3305 { 3306 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); 3307 return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true); 3308 } 3309 else if (sc.comp_unit) 3310 { 3311 uint32_t vars_added = 0; 3312 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 3313 3314 if (variables.get() == NULL) 3315 { 3316 variables.reset(new VariableList()); 3317 sc.comp_unit->SetVariableList(variables); 3318 3319 // Index if we already haven't to make sure the compile units 3320 // get indexed and make their global DIE index list 3321 if (!m_indexed) 3322 Index (); 3323 3324 const size_t num_globals = dwarf_cu->GetNumGlobals(); 3325 for (size_t idx=0; idx<num_globals; ++idx) 3326 { 3327 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx))); 3328 if (var_sp) 3329 { 3330 variables->AddVariable(var_sp); 3331 ++vars_added; 3332 } 3333 } 3334 } 3335 return vars_added; 3336 } 3337 } 3338 return 0; 3339} 3340 3341 3342VariableSP 3343SymbolFileDWARF::ParseVariableDIE 3344( 3345 const SymbolContext& sc, 3346 const DWARFCompileUnit* dwarf_cu, 3347 const DWARFDebugInfoEntry *die 3348) 3349{ 3350 3351 VariableSP var_sp; 3352 3353 const dw_tag_t tag = die->Tag(); 3354 DWARFDebugInfoEntry::Attributes attributes; 3355 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); 3356 if (num_attributes > 0) 3357 { 3358 const char *name = NULL; 3359 Declaration decl; 3360 uint32_t i; 3361 TypeSP type_sp; 3362 Type *var_type = NULL; 3363 DWARFExpression location; 3364 bool is_external = false; 3365 bool is_artificial = false; 3366 ClangASTContext::AccessType accessibility = ClangASTContext::eAccessNone; 3367 3368 for (i=0; i<num_attributes; ++i) 3369 { 3370 dw_attr_t attr = attributes.AttributeAtIndex(i); 3371 DWARFFormValue form_value; 3372 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3373 { 3374 switch (attr) 3375 { 3376 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3377 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3378 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3379 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 3380 case DW_AT_type: var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break; 3381 case DW_AT_external: is_external = form_value.Unsigned() != 0; break; 3382 case DW_AT_location: 3383 { 3384 if (form_value.BlockData()) 3385 { 3386 const DataExtractor& debug_info_data = get_debug_info_data(); 3387 3388 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 3389 uint32_t block_length = form_value.Unsigned(); 3390 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL); 3391 } 3392 else 3393 { 3394 const DataExtractor& debug_loc_data = get_debug_loc_data(); 3395 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 3396 3397 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 3398 if (loc_list_length > 0) 3399 { 3400 Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList()); 3401 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address); 3402 } 3403 } 3404 } 3405 break; 3406 3407 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 3408 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3409 case DW_AT_const_value: 3410 case DW_AT_declaration: 3411 case DW_AT_description: 3412 case DW_AT_endianity: 3413 case DW_AT_segment: 3414 case DW_AT_start_scope: 3415 case DW_AT_visibility: 3416 default: 3417 case DW_AT_abstract_origin: 3418 case DW_AT_sibling: 3419 case DW_AT_specification: 3420 break; 3421 } 3422 } 3423 } 3424 3425 if (location.IsValid()) 3426 { 3427 assert(var_type != DIE_IS_BEING_PARSED); 3428 3429 ConstString var_name(name); 3430 3431 ValueType scope = eValueTypeInvalid; 3432 3433 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3434 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3435 3436 if (tag == DW_TAG_formal_parameter) 3437 scope = eValueTypeVariableArgument; 3438 else if (is_external || parent_tag == DW_TAG_compile_unit) 3439 scope = eValueTypeVariableGlobal; 3440 else 3441 scope = eValueTypeVariableLocal; 3442 3443 SymbolContextScope * symbol_context_scope = NULL; 3444 if (parent_tag == DW_TAG_compile_unit) 3445 { 3446 symbol_context_scope = sc.comp_unit; 3447 } 3448 else if (sc.function != NULL) 3449 { 3450 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); 3451 if (symbol_context_scope == NULL) 3452 symbol_context_scope = sc.function; 3453 } 3454 3455 assert(symbol_context_scope != NULL); 3456 var_sp.reset (new Variable(die->GetOffset(), 3457 var_name, 3458 var_type, 3459 scope, 3460 symbol_context_scope, 3461 &decl, 3462 location, 3463 is_external, 3464 is_artificial)); 3465 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get()); 3466 } 3467 } 3468 return var_sp; 3469} 3470 3471size_t 3472SymbolFileDWARF::ParseVariables 3473( 3474 const SymbolContext& sc, 3475 const DWARFCompileUnit* dwarf_cu, 3476 const DWARFDebugInfoEntry *orig_die, 3477 bool parse_siblings, 3478 bool parse_children, 3479 VariableList* cc_variable_list 3480) 3481{ 3482 if (orig_die == NULL) 3483 return 0; 3484 3485 size_t vars_added = 0; 3486 const DWARFDebugInfoEntry *die = orig_die; 3487 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); 3488 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3489 VariableListSP variables; 3490 switch (parent_tag) 3491 { 3492 case DW_TAG_compile_unit: 3493 if (sc.comp_unit != NULL) 3494 { 3495 variables = sc.comp_unit->GetVariableList(false); 3496 if (variables.get() == NULL) 3497 { 3498 variables.reset(new VariableList()); 3499 sc.comp_unit->SetVariableList(variables); 3500 } 3501 } 3502 else 3503 { 3504 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context..."); 3505 vars_added = 0; 3506 } 3507 break; 3508 3509 case DW_TAG_subprogram: 3510 case DW_TAG_inlined_subroutine: 3511 case DW_TAG_lexical_block: 3512 if (sc.function != NULL) 3513 { 3514 // Check to see if we already have parsed the variables for the given scope 3515 variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false); 3516 if (variables.get() == NULL) 3517 { 3518 variables.reset(new VariableList()); 3519 sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables); 3520 } 3521 } 3522 else 3523 { 3524 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context..."); 3525 vars_added = 0; 3526 } 3527 break; 3528 3529 default: 3530 assert(!"Didn't find appropriate parent DIE for variable list..."); 3531 break; 3532 } 3533 3534 // We need to have a variable list at this point that we can add variables to 3535 assert(variables.get()); 3536 3537 while (die != NULL) 3538 { 3539 dw_tag_t tag = die->Tag(); 3540 3541 // Check to see if we have already parsed this variable or constant? 3542 if (die->GetUserData() == NULL) 3543 { 3544 // We haven't already parsed it, lets do that now. 3545 if ((tag == DW_TAG_variable) || 3546 (tag == DW_TAG_constant) || 3547 (tag == DW_TAG_formal_parameter && sc.function)) 3548 { 3549 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die)); 3550 if (var_sp) 3551 { 3552 variables->AddVariable(var_sp); 3553 ++vars_added; 3554 } 3555 } 3556 } 3557 3558 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 3559 3560 if (!skip_children && parse_children && die->HasChildren()) 3561 { 3562 vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true); 3563 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children); 3564 } 3565 3566 if (parse_siblings) 3567 die = die->GetSibling(); 3568 else 3569 die = NULL; 3570 } 3571 3572 if (cc_variable_list) 3573 { 3574 cc_variable_list->AddVariables(variables.get()); 3575 } 3576 3577 return vars_added; 3578} 3579 3580//------------------------------------------------------------------ 3581// PluginInterface protocol 3582//------------------------------------------------------------------ 3583const char * 3584SymbolFileDWARF::GetPluginName() 3585{ 3586 return "SymbolFileDWARF"; 3587} 3588 3589const char * 3590SymbolFileDWARF::GetShortPluginName() 3591{ 3592 return GetPluginNameStatic(); 3593} 3594 3595uint32_t 3596SymbolFileDWARF::GetPluginVersion() 3597{ 3598 return 1; 3599} 3600 3601void 3602SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm) 3603{ 3604} 3605 3606Error 3607SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm) 3608{ 3609 Error error; 3610 error.SetErrorString("No plug-in command are currently supported."); 3611 return error; 3612} 3613 3614Log * 3615SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command) 3616{ 3617 return NULL; 3618} 3619 3620