SymbolFileDWARF.cpp revision 8b7b2276132c7353cabd22000287b42badc26613
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#include "clang/Sema/DeclSpec.h" 24 25#include "llvm/Support/Casting.h" 26 27#include "lldb/Core/Module.h" 28#include "lldb/Core/PluginManager.h" 29#include "lldb/Core/RegularExpression.h" 30#include "lldb/Core/Scalar.h" 31#include "lldb/Core/Section.h" 32#include "lldb/Core/StreamFile.h" 33#include "lldb/Core/StreamString.h" 34#include "lldb/Core/Timer.h" 35#include "lldb/Core/Value.h" 36 37#include "lldb/Symbol/Block.h" 38#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" 39#include "lldb/Symbol/CompileUnit.h" 40#include "lldb/Symbol/LineTable.h" 41#include "lldb/Symbol/ObjectFile.h" 42#include "lldb/Symbol/SymbolVendor.h" 43#include "lldb/Symbol/VariableList.h" 44 45#include "lldb/Target/ObjCLanguageRuntime.h" 46#include "lldb/Target/CPPLanguageRuntime.h" 47 48#include "DWARFCompileUnit.h" 49#include "DWARFDebugAbbrev.h" 50#include "DWARFDebugAranges.h" 51#include "DWARFDebugInfo.h" 52#include "DWARFDebugInfoEntry.h" 53#include "DWARFDebugLine.h" 54#include "DWARFDebugPubnames.h" 55#include "DWARFDebugRanges.h" 56#include "DWARFDIECollection.h" 57#include "DWARFFormValue.h" 58#include "DWARFLocationList.h" 59#include "LogChannelDWARF.h" 60#include "SymbolFileDWARFDebugMap.h" 61 62#include <map> 63 64//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN 65 66#ifdef ENABLE_DEBUG_PRINTF 67#include <stdio.h> 68#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 69#else 70#define DEBUG_PRINTF(fmt, ...) 71#endif 72 73#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1) 74 75using namespace lldb; 76using namespace lldb_private; 77 78 79static AccessType 80DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility) 81{ 82 switch (dwarf_accessibility) 83 { 84 case DW_ACCESS_public: return eAccessPublic; 85 case DW_ACCESS_private: return eAccessPrivate; 86 case DW_ACCESS_protected: return eAccessProtected; 87 default: break; 88 } 89 return eAccessNone; 90} 91 92void 93SymbolFileDWARF::Initialize() 94{ 95 LogChannelDWARF::Initialize(); 96 PluginManager::RegisterPlugin (GetPluginNameStatic(), 97 GetPluginDescriptionStatic(), 98 CreateInstance); 99} 100 101void 102SymbolFileDWARF::Terminate() 103{ 104 PluginManager::UnregisterPlugin (CreateInstance); 105 LogChannelDWARF::Initialize(); 106} 107 108 109const char * 110SymbolFileDWARF::GetPluginNameStatic() 111{ 112 return "dwarf"; 113} 114 115const char * 116SymbolFileDWARF::GetPluginDescriptionStatic() 117{ 118 return "DWARF and DWARF3 debug symbol file reader."; 119} 120 121 122SymbolFile* 123SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) 124{ 125 return new SymbolFileDWARF(obj_file); 126} 127 128TypeList * 129SymbolFileDWARF::GetTypeList () 130{ 131 if (m_debug_map_symfile) 132 return m_debug_map_symfile->GetTypeList(); 133 return m_obj_file->GetModule()->GetTypeList(); 134 135} 136 137//---------------------------------------------------------------------- 138// Gets the first parent that is a lexical block, function or inlined 139// subroutine, or compile unit. 140//---------------------------------------------------------------------- 141static const DWARFDebugInfoEntry * 142GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die) 143{ 144 const DWARFDebugInfoEntry *die; 145 for (die = child_die->GetParent(); die != NULL; die = die->GetParent()) 146 { 147 dw_tag_t tag = die->Tag(); 148 149 switch (tag) 150 { 151 case DW_TAG_compile_unit: 152 case DW_TAG_subprogram: 153 case DW_TAG_inlined_subroutine: 154 case DW_TAG_lexical_block: 155 return die; 156 } 157 } 158 return NULL; 159} 160 161 162SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : 163 SymbolFile (objfile), 164 m_debug_map_symfile (NULL), 165 m_clang_tu_decl (NULL), 166 m_flags(), 167 m_data_debug_abbrev (), 168 m_data_debug_aranges (), 169 m_data_debug_frame (), 170 m_data_debug_info (), 171 m_data_debug_line (), 172 m_data_debug_loc (), 173 m_data_debug_ranges (), 174 m_data_debug_str (), 175 m_data_apple_names (), 176 m_data_apple_types (), 177 m_data_apple_namespaces (), 178 m_abbr(), 179 m_info(), 180 m_line(), 181 m_apple_names_ap (), 182 m_apple_types_ap (), 183 m_apple_namespaces_ap (), 184 m_function_basename_index(), 185 m_function_fullname_index(), 186 m_function_method_index(), 187 m_function_selector_index(), 188 m_objc_class_selectors_index(), 189 m_global_index(), 190 m_type_index(), 191 m_namespace_index(), 192 m_indexed (false), 193 m_is_external_ast_source (false), 194 m_ranges(), 195 m_unique_ast_type_map () 196{ 197} 198 199SymbolFileDWARF::~SymbolFileDWARF() 200{ 201 if (m_is_external_ast_source) 202 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource (); 203} 204 205static const ConstString & 206GetDWARFMachOSegmentName () 207{ 208 static ConstString g_dwarf_section_name ("__DWARF"); 209 return g_dwarf_section_name; 210} 211 212UniqueDWARFASTTypeMap & 213SymbolFileDWARF::GetUniqueDWARFASTTypeMap () 214{ 215 if (m_debug_map_symfile) 216 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap (); 217 return m_unique_ast_type_map; 218} 219 220ClangASTContext & 221SymbolFileDWARF::GetClangASTContext () 222{ 223 if (m_debug_map_symfile) 224 return m_debug_map_symfile->GetClangASTContext (); 225 226 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext(); 227 if (!m_is_external_ast_source) 228 { 229 m_is_external_ast_source = true; 230 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( 231 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl, 232 SymbolFileDWARF::CompleteObjCInterfaceDecl, 233 SymbolFileDWARF::FindExternalVisibleDeclsByName, 234 this)); 235 236 ast.SetExternalSource (ast_source_ap); 237 } 238 return ast; 239} 240 241void 242SymbolFileDWARF::InitializeObject() 243{ 244 // Install our external AST source callbacks so we can complete Clang types. 245 Module *module = m_obj_file->GetModule(); 246 if (module) 247 { 248 const SectionList *section_list = m_obj_file->GetSectionList(); 249 250 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 251 252 // Memory map the DWARF mach-o segment so we have everything mmap'ed 253 // to keep our heap memory usage down. 254 if (section) 255 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data); 256 } 257 get_apple_names_data(); 258 if (m_data_apple_names.GetByteSize() > 0) 259 { 260 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), true)); 261 if (!m_apple_names_ap->IsValid()) 262 m_apple_names_ap.reset(); 263 } 264 get_apple_types_data(); 265 if (m_data_apple_types.GetByteSize() > 0) 266 { 267 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), false)); 268 if (!m_apple_types_ap->IsValid()) 269 m_apple_types_ap.reset(); 270 } 271 272 get_apple_namespaces_data(); 273 if (m_data_apple_namespaces.GetByteSize() > 0) 274 { 275 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), false)); 276 if (!m_apple_namespaces_ap->IsValid()) 277 m_apple_namespaces_ap.reset(); 278 } 279 280} 281 282bool 283SymbolFileDWARF::SupportedVersion(uint16_t version) 284{ 285 return version == 2 || version == 3; 286} 287 288uint32_t 289SymbolFileDWARF::GetAbilities () 290{ 291 uint32_t abilities = 0; 292 if (m_obj_file != NULL) 293 { 294 const Section* section = NULL; 295 const SectionList *section_list = m_obj_file->GetSectionList(); 296 if (section_list == NULL) 297 return 0; 298 299 uint64_t debug_abbrev_file_size = 0; 300 uint64_t debug_aranges_file_size = 0; 301 uint64_t debug_frame_file_size = 0; 302 uint64_t debug_info_file_size = 0; 303 uint64_t debug_line_file_size = 0; 304 uint64_t debug_loc_file_size = 0; 305 uint64_t debug_macinfo_file_size = 0; 306 uint64_t debug_pubnames_file_size = 0; 307 uint64_t debug_pubtypes_file_size = 0; 308 uint64_t debug_ranges_file_size = 0; 309 uint64_t debug_str_file_size = 0; 310 311 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 312 313 if (section) 314 section_list = §ion->GetChildren (); 315 316 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get(); 317 if (section != NULL) 318 { 319 debug_info_file_size = section->GetByteSize(); 320 321 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get(); 322 if (section) 323 debug_abbrev_file_size = section->GetByteSize(); 324 else 325 m_flags.Set (flagsGotDebugAbbrevData); 326 327 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get(); 328 if (section) 329 debug_aranges_file_size = section->GetByteSize(); 330 else 331 m_flags.Set (flagsGotDebugArangesData); 332 333 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get(); 334 if (section) 335 debug_frame_file_size = section->GetByteSize(); 336 else 337 m_flags.Set (flagsGotDebugFrameData); 338 339 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get(); 340 if (section) 341 debug_line_file_size = section->GetByteSize(); 342 else 343 m_flags.Set (flagsGotDebugLineData); 344 345 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get(); 346 if (section) 347 debug_loc_file_size = section->GetByteSize(); 348 else 349 m_flags.Set (flagsGotDebugLocData); 350 351 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get(); 352 if (section) 353 debug_macinfo_file_size = section->GetByteSize(); 354 else 355 m_flags.Set (flagsGotDebugMacInfoData); 356 357 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get(); 358 if (section) 359 debug_pubnames_file_size = section->GetByteSize(); 360 else 361 m_flags.Set (flagsGotDebugPubNamesData); 362 363 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get(); 364 if (section) 365 debug_pubtypes_file_size = section->GetByteSize(); 366 else 367 m_flags.Set (flagsGotDebugPubTypesData); 368 369 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get(); 370 if (section) 371 debug_ranges_file_size = section->GetByteSize(); 372 else 373 m_flags.Set (flagsGotDebugRangesData); 374 375 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get(); 376 if (section) 377 debug_str_file_size = section->GetByteSize(); 378 else 379 m_flags.Set (flagsGotDebugStrData); 380 } 381 382 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) 383 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; 384 385 if (debug_line_file_size > 0) 386 abilities |= LineTables; 387 388 if (debug_aranges_file_size > 0) 389 abilities |= AddressAcceleratorTable; 390 391 if (debug_pubnames_file_size > 0) 392 abilities |= FunctionAcceleratorTable; 393 394 if (debug_pubtypes_file_size > 0) 395 abilities |= TypeAcceleratorTable; 396 397 if (debug_macinfo_file_size > 0) 398 abilities |= MacroInformation; 399 400 if (debug_frame_file_size > 0) 401 abilities |= CallFrameInformation; 402 } 403 return abilities; 404} 405 406const DataExtractor& 407SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data) 408{ 409 if (m_flags.IsClear (got_flag)) 410 { 411 m_flags.Set (got_flag); 412 const SectionList *section_list = m_obj_file->GetSectionList(); 413 if (section_list) 414 { 415 Section *section = section_list->FindSectionByType(sect_type, true).get(); 416 if (section) 417 { 418 // See if we memory mapped the DWARF segment? 419 if (m_dwarf_data.GetByteSize()) 420 { 421 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize()); 422 } 423 else 424 { 425 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0) 426 data.Clear(); 427 } 428 } 429 } 430 } 431 return data; 432} 433 434const DataExtractor& 435SymbolFileDWARF::get_debug_abbrev_data() 436{ 437 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); 438} 439 440const DataExtractor& 441SymbolFileDWARF::get_debug_aranges_data() 442{ 443 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges); 444} 445 446const DataExtractor& 447SymbolFileDWARF::get_debug_frame_data() 448{ 449 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); 450} 451 452const DataExtractor& 453SymbolFileDWARF::get_debug_info_data() 454{ 455 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info); 456} 457 458const DataExtractor& 459SymbolFileDWARF::get_debug_line_data() 460{ 461 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line); 462} 463 464const DataExtractor& 465SymbolFileDWARF::get_debug_loc_data() 466{ 467 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc); 468} 469 470const DataExtractor& 471SymbolFileDWARF::get_debug_ranges_data() 472{ 473 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges); 474} 475 476const DataExtractor& 477SymbolFileDWARF::get_debug_str_data() 478{ 479 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str); 480} 481 482const DataExtractor& 483SymbolFileDWARF::get_apple_names_data() 484{ 485 return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names); 486} 487 488const DataExtractor& 489SymbolFileDWARF::get_apple_types_data() 490{ 491 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types); 492} 493 494const DataExtractor& 495SymbolFileDWARF::get_apple_namespaces_data() 496{ 497 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces); 498} 499 500 501DWARFDebugAbbrev* 502SymbolFileDWARF::DebugAbbrev() 503{ 504 if (m_abbr.get() == NULL) 505 { 506 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data(); 507 if (debug_abbrev_data.GetByteSize() > 0) 508 { 509 m_abbr.reset(new DWARFDebugAbbrev()); 510 if (m_abbr.get()) 511 m_abbr->Parse(debug_abbrev_data); 512 } 513 } 514 return m_abbr.get(); 515} 516 517const DWARFDebugAbbrev* 518SymbolFileDWARF::DebugAbbrev() const 519{ 520 return m_abbr.get(); 521} 522 523 524DWARFDebugInfo* 525SymbolFileDWARF::DebugInfo() 526{ 527 if (m_info.get() == NULL) 528 { 529 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 530 if (get_debug_info_data().GetByteSize() > 0) 531 { 532 m_info.reset(new DWARFDebugInfo()); 533 if (m_info.get()) 534 { 535 m_info->SetDwarfData(this); 536 } 537 } 538 } 539 return m_info.get(); 540} 541 542const DWARFDebugInfo* 543SymbolFileDWARF::DebugInfo() const 544{ 545 return m_info.get(); 546} 547 548DWARFCompileUnit* 549SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid) 550{ 551 DWARFDebugInfo* info = DebugInfo(); 552 if (info) 553 return info->GetCompileUnit(cu_uid).get(); 554 return NULL; 555} 556 557 558DWARFDebugRanges* 559SymbolFileDWARF::DebugRanges() 560{ 561 if (m_ranges.get() == NULL) 562 { 563 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 564 if (get_debug_ranges_data().GetByteSize() > 0) 565 { 566 m_ranges.reset(new DWARFDebugRanges()); 567 if (m_ranges.get()) 568 m_ranges->Extract(this); 569 } 570 } 571 return m_ranges.get(); 572} 573 574const DWARFDebugRanges* 575SymbolFileDWARF::DebugRanges() const 576{ 577 return m_ranges.get(); 578} 579 580bool 581SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp) 582{ 583 if (curr_cu != NULL) 584 { 585 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly (); 586 if (cu_die) 587 { 588 const char * cu_die_name = cu_die->GetName(this, curr_cu); 589 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL); 590 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0); 591 if (cu_die_name) 592 { 593 FileSpec cu_file_spec; 594 595 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0') 596 { 597 // If we have a full path to the compile unit, we don't need to resolve 598 // the file. This can be expensive e.g. when the source files are NFS mounted. 599 cu_file_spec.SetFile (cu_die_name, false); 600 } 601 else 602 { 603 std::string fullpath(cu_comp_dir); 604 if (*fullpath.rbegin() != '/') 605 fullpath += '/'; 606 fullpath += cu_die_name; 607 cu_file_spec.SetFile (fullpath.c_str(), false); 608 } 609 610 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), cu_language)); 611 if (compile_unit_sp.get()) 612 { 613 curr_cu->SetUserData(compile_unit_sp.get()); 614 return true; 615 } 616 } 617 } 618 } 619 return false; 620} 621 622uint32_t 623SymbolFileDWARF::GetNumCompileUnits() 624{ 625 DWARFDebugInfo* info = DebugInfo(); 626 if (info) 627 return info->GetNumCompileUnits(); 628 return 0; 629} 630 631CompUnitSP 632SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) 633{ 634 CompUnitSP comp_unit; 635 DWARFDebugInfo* info = DebugInfo(); 636 if (info) 637 { 638 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx); 639 if (curr_cu != NULL) 640 { 641 // Our symbol vendor shouldn't be asking us to add a compile unit that 642 // has already been added to it, which this DWARF plug-in knows as it 643 // stores the lldb compile unit (CompileUnit) pointer in each 644 // DWARFCompileUnit object when it gets added. 645 assert(curr_cu->GetUserData() == NULL); 646 ParseCompileUnit(curr_cu, comp_unit); 647 } 648 } 649 return comp_unit; 650} 651 652static void 653AddRangesToBlock 654( 655 Block& block, 656 DWARFDebugRanges::RangeList& ranges, 657 addr_t block_base_addr 658) 659{ 660 ranges.SubtractOffset (block_base_addr); 661 size_t range_idx = 0; 662 const DWARFDebugRanges::Range *debug_range; 663 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++) 664 { 665 block.AddRange(VMRange (debug_range->begin_offset, debug_range->end_offset)); 666 } 667} 668 669 670Function * 671SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die) 672{ 673 DWARFDebugRanges::RangeList func_ranges; 674 const char *name = NULL; 675 const char *mangled = NULL; 676 int decl_file = 0; 677 int decl_line = 0; 678 int decl_column = 0; 679 int call_file = 0; 680 int call_line = 0; 681 int call_column = 0; 682 DWARFExpression frame_base; 683 684 assert (die->Tag() == DW_TAG_subprogram); 685 686 if (die->Tag() != DW_TAG_subprogram) 687 return NULL; 688 689 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base)) 690 { 691 // Union of all ranges in the function DIE (if the function is discontiguous) 692 AddressRange func_range; 693 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0); 694 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0); 695 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr) 696 { 697 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList()); 698 if (func_range.GetBaseAddress().IsValid()) 699 func_range.SetByteSize(highest_func_addr - lowest_func_addr); 700 } 701 702 if (func_range.GetBaseAddress().IsValid()) 703 { 704 Mangled func_name; 705 if (mangled) 706 func_name.SetValue(mangled, true); 707 else if (name) 708 func_name.SetValue(name, false); 709 710 FunctionSP func_sp; 711 std::auto_ptr<Declaration> decl_ap; 712 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 713 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 714 decl_line, 715 decl_column)); 716 717 // Supply the type _only_ if it has already been parsed 718 Type *func_type = m_die_to_type.lookup (die); 719 720 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); 721 722 func_range.GetBaseAddress().ResolveLinkedAddress(); 723 724 func_sp.reset(new Function (sc.comp_unit, 725 die->GetOffset(), // UserID is the DIE offset 726 die->GetOffset(), 727 func_name, 728 func_type, 729 func_range)); // first address range 730 731 if (func_sp.get() != NULL) 732 { 733 if (frame_base.IsValid()) 734 func_sp->GetFrameBaseExpression() = frame_base; 735 sc.comp_unit->AddFunction(func_sp); 736 return func_sp.get(); 737 } 738 } 739 } 740 return NULL; 741} 742 743size_t 744SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) 745{ 746 assert (sc.comp_unit); 747 size_t functions_added = 0; 748 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 749 if (dwarf_cu) 750 { 751 DWARFDIECollection function_dies; 752 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); 753 size_t func_idx; 754 for (func_idx = 0; func_idx < num_funtions; ++func_idx) 755 { 756 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx); 757 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL) 758 { 759 if (ParseCompileUnitFunction(sc, dwarf_cu, die)) 760 ++functions_added; 761 } 762 } 763 //FixupTypes(); 764 } 765 return functions_added; 766} 767 768bool 769SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) 770{ 771 assert (sc.comp_unit); 772 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 773 assert (curr_cu); 774 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly(); 775 776 if (cu_die) 777 { 778 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL); 779 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 780 781 // All file indexes in DWARF are one based and a file of index zero is 782 // supposed to be the compile unit itself. 783 support_files.Append (*sc.comp_unit); 784 785 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files); 786 } 787 return false; 788} 789 790struct ParseDWARFLineTableCallbackInfo 791{ 792 LineTable* line_table; 793 const SectionList *section_list; 794 lldb::addr_t prev_sect_file_base_addr; 795 lldb::addr_t curr_sect_file_base_addr; 796 bool is_oso_for_debug_map; 797 bool prev_in_final_executable; 798 DWARFDebugLine::Row prev_row; 799 SectionSP prev_section_sp; 800 SectionSP curr_section_sp; 801}; 802 803//---------------------------------------------------------------------- 804// ParseStatementTableCallback 805//---------------------------------------------------------------------- 806static void 807ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 808{ 809 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table; 810 if (state.row == DWARFDebugLine::State::StartParsingLineTable) 811 { 812 // Just started parsing the line table 813 } 814 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 815 { 816 // Done parsing line table, nothing to do for the cleanup 817 } 818 else 819 { 820 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData; 821 // We have a new row, lets append it 822 823 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false) 824 { 825 info->prev_section_sp = info->curr_section_sp; 826 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr; 827 // If this is an end sequence entry, then we subtract one from the 828 // address to make sure we get an address that is not the end of 829 // a section. 830 if (state.end_sequence && state.address != 0) 831 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1); 832 else 833 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address); 834 835 if (info->curr_section_sp.get()) 836 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress (); 837 else 838 info->curr_sect_file_base_addr = 0; 839 } 840 if (info->curr_section_sp.get()) 841 { 842 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr; 843 // Check for the fancy section magic to determine if we 844 845 if (info->is_oso_for_debug_map) 846 { 847 // When this is a debug map object file that contains DWARF 848 // (referenced from an N_OSO debug map nlist entry) we will have 849 // a file address in the file range for our section from the 850 // original .o file, and a load address in the executable that 851 // contains the debug map. 852 // 853 // If the sections for the file range and load range are 854 // different, we have a remapped section for the function and 855 // this address is resolved. If they are the same, then the 856 // function for this address didn't make it into the final 857 // executable. 858 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL; 859 860 // If we are doing DWARF with debug map, then we need to carefully 861 // add each line table entry as there may be gaps as functions 862 // get moved around or removed. 863 if (!info->prev_row.end_sequence && info->prev_section_sp.get()) 864 { 865 if (info->prev_in_final_executable) 866 { 867 bool terminate_previous_entry = false; 868 if (!curr_in_final_executable) 869 { 870 // Check for the case where the previous line entry 871 // in a function made it into the final executable, 872 // yet the current line entry falls in a function 873 // that didn't. The line table used to be contiguous 874 // through this address range but now it isn't. We 875 // need to terminate the previous line entry so 876 // that we can reconstruct the line range correctly 877 // for it and to keep the line table correct. 878 terminate_previous_entry = true; 879 } 880 else if (info->curr_section_sp.get() != info->prev_section_sp.get()) 881 { 882 // Check for cases where the line entries used to be 883 // contiguous address ranges, but now they aren't. 884 // This can happen when order files specify the 885 // ordering of the functions. 886 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr; 887 Section *curr_sect = info->curr_section_sp.get(); 888 Section *prev_sect = info->prev_section_sp.get(); 889 assert (curr_sect->GetLinkedSection()); 890 assert (prev_sect->GetLinkedSection()); 891 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address; 892 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset; 893 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset; 894 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr; 895 if (object_file_addr_delta != linked_file_addr_delta) 896 terminate_previous_entry = true; 897 } 898 899 if (terminate_previous_entry) 900 { 901 line_table->InsertLineEntry (info->prev_section_sp, 902 state.address - info->prev_sect_file_base_addr, 903 info->prev_row.line, 904 info->prev_row.column, 905 info->prev_row.file, 906 false, // is_stmt 907 false, // basic_block 908 false, // state.prologue_end 909 false, // state.epilogue_begin 910 true); // end_sequence); 911 } 912 } 913 } 914 915 if (curr_in_final_executable) 916 { 917 line_table->InsertLineEntry (info->curr_section_sp, 918 curr_line_section_offset, 919 state.line, 920 state.column, 921 state.file, 922 state.is_stmt, 923 state.basic_block, 924 state.prologue_end, 925 state.epilogue_begin, 926 state.end_sequence); 927 info->prev_section_sp = info->curr_section_sp; 928 } 929 else 930 { 931 // If the current address didn't make it into the final 932 // executable, the current section will be the __text 933 // segment in the .o file, so we need to clear this so 934 // we can catch the next function that did make it into 935 // the final executable. 936 info->prev_section_sp.reset(); 937 info->curr_section_sp.reset(); 938 } 939 940 info->prev_in_final_executable = curr_in_final_executable; 941 } 942 else 943 { 944 // We are not in an object file that contains DWARF for an 945 // N_OSO, this is just a normal DWARF file. The DWARF spec 946 // guarantees that the addresses will be in increasing order 947 // so, since we store line tables in file address order, we 948 // can always just append the line entry without needing to 949 // search for the correct insertion point (we don't need to 950 // use LineEntry::InsertLineEntry()). 951 line_table->AppendLineEntry (info->curr_section_sp, 952 curr_line_section_offset, 953 state.line, 954 state.column, 955 state.file, 956 state.is_stmt, 957 state.basic_block, 958 state.prologue_end, 959 state.epilogue_begin, 960 state.end_sequence); 961 } 962 } 963 964 info->prev_row = state; 965 } 966} 967 968bool 969SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) 970{ 971 assert (sc.comp_unit); 972 if (sc.comp_unit->GetLineTable() != NULL) 973 return true; 974 975 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 976 if (dwarf_cu) 977 { 978 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); 979 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 980 if (cu_line_offset != DW_INVALID_OFFSET) 981 { 982 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit)); 983 if (line_table_ap.get()) 984 { 985 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false}; 986 uint32_t offset = cu_line_offset; 987 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); 988 sc.comp_unit->SetLineTable(line_table_ap.release()); 989 return true; 990 } 991 } 992 } 993 return false; 994} 995 996size_t 997SymbolFileDWARF::ParseFunctionBlocks 998( 999 const SymbolContext& sc, 1000 Block *parent_block, 1001 DWARFCompileUnit* dwarf_cu, 1002 const DWARFDebugInfoEntry *die, 1003 addr_t subprogram_low_pc, 1004 uint32_t depth 1005) 1006{ 1007 size_t blocks_added = 0; 1008 while (die != NULL) 1009 { 1010 dw_tag_t tag = die->Tag(); 1011 1012 switch (tag) 1013 { 1014 case DW_TAG_inlined_subroutine: 1015 case DW_TAG_subprogram: 1016 case DW_TAG_lexical_block: 1017 { 1018 Block *block = NULL; 1019 if (tag == DW_TAG_subprogram) 1020 { 1021 // Skip any DW_TAG_subprogram DIEs that are inside 1022 // of a normal or inlined functions. These will be 1023 // parsed on their own as separate entities. 1024 1025 if (depth > 0) 1026 break; 1027 1028 block = parent_block; 1029 } 1030 else 1031 { 1032 BlockSP block_sp(new Block (die->GetOffset())); 1033 parent_block->AddChild(block_sp); 1034 block = block_sp.get(); 1035 } 1036 DWARFDebugRanges::RangeList ranges; 1037 const char *name = NULL; 1038 const char *mangled_name = NULL; 1039 1040 int decl_file = 0; 1041 int decl_line = 0; 1042 int decl_column = 0; 1043 int call_file = 0; 1044 int call_line = 0; 1045 int call_column = 0; 1046 if (die->GetDIENamesAndRanges (this, 1047 dwarf_cu, 1048 name, 1049 mangled_name, 1050 ranges, 1051 decl_file, decl_line, decl_column, 1052 call_file, call_line, call_column)) 1053 { 1054 if (tag == DW_TAG_subprogram) 1055 { 1056 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); 1057 subprogram_low_pc = ranges.LowestAddress(0); 1058 } 1059 else if (tag == DW_TAG_inlined_subroutine) 1060 { 1061 // We get called here for inlined subroutines in two ways. 1062 // The first time is when we are making the Function object 1063 // for this inlined concrete instance. Since we're creating a top level block at 1064 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to 1065 // adjust the containing address. 1066 // The second time is when we are parsing the blocks inside the function that contains 1067 // the inlined concrete instance. Since these will be blocks inside the containing "real" 1068 // function the offset will be for that function. 1069 if (subprogram_low_pc == LLDB_INVALID_ADDRESS) 1070 { 1071 subprogram_low_pc = ranges.LowestAddress(0); 1072 } 1073 } 1074 1075 AddRangesToBlock (*block, ranges, subprogram_low_pc); 1076 1077 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) 1078 { 1079 std::auto_ptr<Declaration> decl_ap; 1080 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 1081 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 1082 decl_line, decl_column)); 1083 1084 std::auto_ptr<Declaration> call_ap; 1085 if (call_file != 0 || call_line != 0 || call_column != 0) 1086 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), 1087 call_line, call_column)); 1088 1089 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get()); 1090 } 1091 1092 ++blocks_added; 1093 1094 if (die->HasChildren()) 1095 { 1096 blocks_added += ParseFunctionBlocks (sc, 1097 block, 1098 dwarf_cu, 1099 die->GetFirstChild(), 1100 subprogram_low_pc, 1101 depth + 1); 1102 } 1103 } 1104 } 1105 break; 1106 default: 1107 break; 1108 } 1109 1110 // Only parse siblings of the block if we are not at depth zero. A depth 1111 // of zero indicates we are currently parsing the top level 1112 // DW_TAG_subprogram DIE 1113 1114 if (depth == 0) 1115 die = NULL; 1116 else 1117 die = die->GetSibling(); 1118 } 1119 return blocks_added; 1120} 1121 1122size_t 1123SymbolFileDWARF::ParseChildMembers 1124( 1125 const SymbolContext& sc, 1126 DWARFCompileUnit* dwarf_cu, 1127 const DWARFDebugInfoEntry *parent_die, 1128 clang_type_t class_clang_type, 1129 const LanguageType class_language, 1130 std::vector<clang::CXXBaseSpecifier *>& base_classes, 1131 std::vector<int>& member_accessibilities, 1132 DWARFDIECollection& member_function_dies, 1133 AccessType& default_accessibility, 1134 bool &is_a_class 1135) 1136{ 1137 if (parent_die == NULL) 1138 return 0; 1139 1140 size_t count = 0; 1141 const DWARFDebugInfoEntry *die; 1142 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 1143 uint32_t member_idx = 0; 1144 1145 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 1146 { 1147 dw_tag_t tag = die->Tag(); 1148 1149 switch (tag) 1150 { 1151 case DW_TAG_member: 1152 { 1153 DWARFDebugInfoEntry::Attributes attributes; 1154 const size_t num_attributes = die->GetAttributes (this, 1155 dwarf_cu, 1156 fixed_form_sizes, 1157 attributes); 1158 if (num_attributes > 0) 1159 { 1160 Declaration decl; 1161 //DWARFExpression location; 1162 const char *name = NULL; 1163 bool is_artificial = false; 1164 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1165 AccessType accessibility = eAccessNone; 1166 //off_t member_offset = 0; 1167 size_t byte_size = 0; 1168 size_t bit_offset = 0; 1169 size_t bit_size = 0; 1170 uint32_t i; 1171 for (i=0; i<num_attributes && !is_artificial; ++i) 1172 { 1173 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1174 DWARFFormValue form_value; 1175 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1176 { 1177 switch (attr) 1178 { 1179 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1180 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1181 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1182 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 1183 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1184 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break; 1185 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; 1186 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 1187 case DW_AT_data_member_location: 1188// if (form_value.BlockData()) 1189// { 1190// Value initialValue(0); 1191// Value memberOffset(0); 1192// const DataExtractor& debug_info_data = get_debug_info_data(); 1193// uint32_t block_length = form_value.Unsigned(); 1194// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1195// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1196// { 1197// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1198// } 1199// } 1200 break; 1201 1202 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break; 1203 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 1204 case DW_AT_declaration: 1205 case DW_AT_description: 1206 case DW_AT_mutable: 1207 case DW_AT_visibility: 1208 default: 1209 case DW_AT_sibling: 1210 break; 1211 } 1212 } 1213 } 1214 1215 // FIXME: Make Clang ignore Objective-C accessibility for expressions 1216 1217 if (class_language == eLanguageTypeObjC || 1218 class_language == eLanguageTypeObjC_plus_plus) 1219 accessibility = eAccessNone; 1220 1221 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name)) 1222 { 1223 // Not all compilers will mark the vtable pointer 1224 // member as artificial (llvm-gcc). We can't have 1225 // the virtual members in our classes otherwise it 1226 // throws off all child offsets since we end up 1227 // having and extra pointer sized member in our 1228 // class layouts. 1229 is_artificial = true; 1230 } 1231 1232 if (is_artificial == false) 1233 { 1234 Type *member_type = ResolveTypeUID(encoding_uid); 1235 if (member_type) 1236 { 1237 if (accessibility == eAccessNone) 1238 accessibility = default_accessibility; 1239 member_accessibilities.push_back(accessibility); 1240 1241 GetClangASTContext().AddFieldToRecordType (class_clang_type, 1242 name, 1243 member_type->GetClangLayoutType(), 1244 accessibility, 1245 bit_size); 1246 } 1247 else 1248 { 1249 if (name) 1250 ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed", 1251 die->GetOffset(), 1252 name, 1253 encoding_uid); 1254 else 1255 ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed", 1256 die->GetOffset(), 1257 encoding_uid); 1258 } 1259 } 1260 } 1261 ++member_idx; 1262 } 1263 break; 1264 1265 case DW_TAG_subprogram: 1266 // Let the type parsing code handle this one for us. 1267 member_function_dies.Append (die); 1268 break; 1269 1270 case DW_TAG_inheritance: 1271 { 1272 is_a_class = true; 1273 if (default_accessibility == eAccessNone) 1274 default_accessibility = eAccessPrivate; 1275 // TODO: implement DW_TAG_inheritance type parsing 1276 DWARFDebugInfoEntry::Attributes attributes; 1277 const size_t num_attributes = die->GetAttributes (this, 1278 dwarf_cu, 1279 fixed_form_sizes, 1280 attributes); 1281 if (num_attributes > 0) 1282 { 1283 Declaration decl; 1284 DWARFExpression location; 1285 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1286 AccessType accessibility = default_accessibility; 1287 bool is_virtual = false; 1288 bool is_base_of_class = true; 1289 off_t member_offset = 0; 1290 uint32_t i; 1291 for (i=0; i<num_attributes; ++i) 1292 { 1293 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1294 DWARFFormValue form_value; 1295 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1296 { 1297 switch (attr) 1298 { 1299 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1300 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1301 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1302 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1303 case DW_AT_data_member_location: 1304 if (form_value.BlockData()) 1305 { 1306 Value initialValue(0); 1307 Value memberOffset(0); 1308 const DataExtractor& debug_info_data = get_debug_info_data(); 1309 uint32_t block_length = form_value.Unsigned(); 1310 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1311 if (DWARFExpression::Evaluate (NULL, 1312 NULL, 1313 NULL, 1314 NULL, 1315 NULL, 1316 debug_info_data, 1317 block_offset, 1318 block_length, 1319 eRegisterKindDWARF, 1320 &initialValue, 1321 memberOffset, 1322 NULL)) 1323 { 1324 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1325 } 1326 } 1327 break; 1328 1329 case DW_AT_accessibility: 1330 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 1331 break; 1332 1333 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 1334 default: 1335 case DW_AT_sibling: 1336 break; 1337 } 1338 } 1339 } 1340 1341 Type *base_class_type = ResolveTypeUID(encoding_uid); 1342 assert(base_class_type); 1343 1344 clang_type_t base_class_clang_type = base_class_type->GetClangFullType(); 1345 assert (base_class_clang_type); 1346 if (class_language == eLanguageTypeObjC) 1347 { 1348 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type); 1349 } 1350 else 1351 { 1352 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type, 1353 accessibility, 1354 is_virtual, 1355 is_base_of_class)); 1356 } 1357 } 1358 } 1359 break; 1360 1361 default: 1362 break; 1363 } 1364 } 1365 return count; 1366} 1367 1368 1369clang::DeclContext* 1370SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) 1371{ 1372 DWARFDebugInfo* debug_info = DebugInfo(); 1373 if (debug_info) 1374 { 1375 DWARFCompileUnitSP cu_sp; 1376 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1377 if (die) 1378 return GetClangDeclContextContainingDIE (cu_sp.get(), die); 1379 } 1380 return NULL; 1381} 1382 1383clang::DeclContext* 1384SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) 1385{ 1386 return GetClangDeclContextForDIEOffset (sc, type_uid); 1387} 1388 1389Type* 1390SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid) 1391{ 1392 DWARFDebugInfo* debug_info = DebugInfo(); 1393 if (debug_info) 1394 { 1395 DWARFCompileUnitSP cu_sp; 1396 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1397 if (type_die != NULL) 1398 { 1399 // We might be coming in in the middle of a type tree (a class 1400 // withing a class, an enum within a class), so parse any needed 1401 // parent DIEs before we get to this one... 1402 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu_sp.get(), type_die); 1403 switch (decl_ctx_die->Tag()) 1404 { 1405 case DW_TAG_structure_type: 1406 case DW_TAG_union_type: 1407 case DW_TAG_class_type: 1408 ResolveType(cu_sp.get(), decl_ctx_die); 1409 break; 1410 } 1411 return ResolveType (cu_sp.get(), type_die); 1412 } 1413 } 1414 return NULL; 1415} 1416 1417// This function is used when SymbolFileDWARFDebugMap owns a bunch of 1418// SymbolFileDWARF objects to detect if this DWARF file is the one that 1419// can resolve a clang_type. 1420bool 1421SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type) 1422{ 1423 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1424 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1425 return die != NULL; 1426} 1427 1428 1429lldb::clang_type_t 1430SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) 1431{ 1432 // We have a struct/union/class/enum that needs to be fully resolved. 1433 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1434 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1435 if (die == NULL) 1436 { 1437// if (m_debug_map_symfile) 1438// { 1439// Type *type = m_die_to_type[die]; 1440// if (type && type->GetSymbolFile() != this) 1441// return type->GetClangType(); 1442// } 1443 // We have already resolved this type... 1444 return clang_type; 1445 } 1446 // Once we start resolving this type, remove it from the forward declaration 1447 // map in case anyone child members or other types require this type to get resolved. 1448 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition 1449 // are done. 1450 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers); 1451 1452 1453 DWARFDebugInfo* debug_info = DebugInfo(); 1454 1455 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get(); 1456 Type *type = m_die_to_type.lookup (die); 1457 1458 const dw_tag_t tag = die->Tag(); 1459 1460 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n", 1461 die->GetOffset(), 1462 DW_TAG_value_to_name(tag), 1463 type->GetName().AsCString()); 1464 assert (clang_type); 1465 DWARFDebugInfoEntry::Attributes attributes; 1466 1467 ClangASTContext &ast = GetClangASTContext(); 1468 1469 switch (tag) 1470 { 1471 case DW_TAG_structure_type: 1472 case DW_TAG_union_type: 1473 case DW_TAG_class_type: 1474 ast.StartTagDeclarationDefinition (clang_type); 1475 if (die->HasChildren()) 1476 { 1477 LanguageType class_language = eLanguageTypeUnknown; 1478 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type); 1479 if (is_objc_class) 1480 class_language = eLanguageTypeObjC; 1481 1482 int tag_decl_kind = -1; 1483 AccessType default_accessibility = eAccessNone; 1484 if (tag == DW_TAG_structure_type) 1485 { 1486 tag_decl_kind = clang::TTK_Struct; 1487 default_accessibility = eAccessPublic; 1488 } 1489 else if (tag == DW_TAG_union_type) 1490 { 1491 tag_decl_kind = clang::TTK_Union; 1492 default_accessibility = eAccessPublic; 1493 } 1494 else if (tag == DW_TAG_class_type) 1495 { 1496 tag_decl_kind = clang::TTK_Class; 1497 default_accessibility = eAccessPrivate; 1498 } 1499 1500 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 1501 std::vector<clang::CXXBaseSpecifier *> base_classes; 1502 std::vector<int> member_accessibilities; 1503 bool is_a_class = false; 1504 // Parse members and base classes first 1505 DWARFDIECollection member_function_dies; 1506 1507 ParseChildMembers (sc, 1508 curr_cu, 1509 die, 1510 clang_type, 1511 class_language, 1512 base_classes, 1513 member_accessibilities, 1514 member_function_dies, 1515 default_accessibility, 1516 is_a_class); 1517 1518 // Now parse any methods if there were any... 1519 size_t num_functions = member_function_dies.Size(); 1520 if (num_functions > 0) 1521 { 1522 for (size_t i=0; i<num_functions; ++i) 1523 { 1524 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i)); 1525 } 1526 } 1527 1528 if (class_language == eLanguageTypeObjC) 1529 { 1530 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type)); 1531 if (!class_str.empty()) 1532 { 1533 1534 ConstString class_name (class_str.c_str()); 1535 DIEArray method_die_offsets; 1536 if (m_objc_class_selectors_index.Find (class_name, method_die_offsets)) 1537 { 1538 DWARFDebugInfo* debug_info = DebugInfo(); 1539 1540 DWARFCompileUnit* method_cu = NULL; 1541 const size_t num_matches = method_die_offsets.size(); 1542 for (size_t i=0; i<num_matches; ++i) 1543 { 1544 const dw_offset_t die_offset = method_die_offsets[i]; 1545 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu); 1546 1547 ResolveType (method_cu, method_die); 1548 } 1549 } 1550 } 1551 } 1552 1553 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we 1554 // need to tell the clang type it is actually a class. 1555 if (class_language != eLanguageTypeObjC) 1556 { 1557 if (is_a_class && tag_decl_kind != clang::TTK_Class) 1558 ast.SetTagTypeKind (clang_type, clang::TTK_Class); 1559 } 1560 1561 // Since DW_TAG_structure_type gets used for both classes 1562 // and structures, we may need to set any DW_TAG_member 1563 // fields to have a "private" access if none was specified. 1564 // When we parsed the child members we tracked that actual 1565 // accessibility value for each DW_TAG_member in the 1566 // "member_accessibilities" array. If the value for the 1567 // member is zero, then it was set to the "default_accessibility" 1568 // which for structs was "public". Below we correct this 1569 // by setting any fields to "private" that weren't correctly 1570 // set. 1571 if (is_a_class && !member_accessibilities.empty()) 1572 { 1573 // This is a class and all members that didn't have 1574 // their access specified are private. 1575 ast.SetDefaultAccessForRecordFields (clang_type, 1576 eAccessPrivate, 1577 &member_accessibilities.front(), 1578 member_accessibilities.size()); 1579 } 1580 1581 if (!base_classes.empty()) 1582 { 1583 ast.SetBaseClassesForClassType (clang_type, 1584 &base_classes.front(), 1585 base_classes.size()); 1586 1587 // Clang will copy each CXXBaseSpecifier in "base_classes" 1588 // so we have to free them all. 1589 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), 1590 base_classes.size()); 1591 } 1592 1593 } 1594 ast.CompleteTagDeclarationDefinition (clang_type); 1595 return clang_type; 1596 1597 case DW_TAG_enumeration_type: 1598 ast.StartTagDeclarationDefinition (clang_type); 1599 if (die->HasChildren()) 1600 { 1601 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 1602 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die); 1603 } 1604 ast.CompleteTagDeclarationDefinition (clang_type); 1605 return clang_type; 1606 1607 default: 1608 assert(false && "not a forward clang type decl!"); 1609 break; 1610 } 1611 return NULL; 1612} 1613 1614Type* 1615SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed) 1616{ 1617 if (type_die != NULL) 1618 { 1619 Type *type = m_die_to_type.lookup (type_die); 1620 if (type == NULL) 1621 type = GetTypeForDIE (curr_cu, type_die).get(); 1622 if (assert_not_being_parsed) 1623 assert (type != DIE_IS_BEING_PARSED); 1624 return type; 1625 } 1626 return NULL; 1627} 1628 1629CompileUnit* 1630SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx) 1631{ 1632 // Check if the symbol vendor already knows about this compile unit? 1633 if (curr_cu->GetUserData() == NULL) 1634 { 1635 // The symbol vendor doesn't know about this compile unit, we 1636 // need to parse and add it to the symbol vendor object. 1637 CompUnitSP dc_cu; 1638 ParseCompileUnit(curr_cu, dc_cu); 1639 if (dc_cu.get()) 1640 { 1641 // Figure out the compile unit index if we weren't given one 1642 if (cu_idx == UINT32_MAX) 1643 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx); 1644 1645 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); 1646 1647 if (m_debug_map_symfile) 1648 m_debug_map_symfile->SetCompileUnit(this, dc_cu); 1649 } 1650 } 1651 return (CompileUnit*)curr_cu->GetUserData(); 1652} 1653 1654bool 1655SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc) 1656{ 1657 sc.Clear(); 1658 // Check if the symbol vendor already knows about this compile unit? 1659 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 1660 1661 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get(); 1662 if (sc.function == NULL) 1663 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die); 1664 1665 if (sc.function) 1666 { 1667 sc.module_sp = sc.function->CalculateSymbolContextModule(); 1668 return true; 1669 } 1670 1671 return false; 1672} 1673 1674uint32_t 1675SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 1676{ 1677 Timer scoped_timer(__PRETTY_FUNCTION__, 1678 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)", 1679 so_addr.GetSection(), 1680 so_addr.GetOffset(), 1681 resolve_scope); 1682 uint32_t resolved = 0; 1683 if (resolve_scope & ( eSymbolContextCompUnit | 1684 eSymbolContextFunction | 1685 eSymbolContextBlock | 1686 eSymbolContextLineEntry)) 1687 { 1688 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1689 1690 DWARFDebugInfo* debug_info = DebugInfo(); 1691 if (debug_info) 1692 { 1693 dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); 1694 if (cu_offset != DW_INVALID_OFFSET) 1695 { 1696 uint32_t cu_idx; 1697 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get(); 1698 if (curr_cu) 1699 { 1700 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1701 assert(sc.comp_unit != NULL); 1702 resolved |= eSymbolContextCompUnit; 1703 1704 if (resolve_scope & eSymbolContextLineEntry) 1705 { 1706 LineTable *line_table = sc.comp_unit->GetLineTable(); 1707 if (line_table == NULL) 1708 { 1709 if (ParseCompileUnitLineTable(sc)) 1710 line_table = sc.comp_unit->GetLineTable(); 1711 } 1712 if (line_table != NULL) 1713 { 1714 if (so_addr.IsLinkedAddress()) 1715 { 1716 Address linked_addr (so_addr); 1717 linked_addr.ResolveLinkedAddress(); 1718 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry)) 1719 { 1720 resolved |= eSymbolContextLineEntry; 1721 } 1722 } 1723 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry)) 1724 { 1725 resolved |= eSymbolContextLineEntry; 1726 } 1727 } 1728 } 1729 1730 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1731 { 1732 DWARFDebugInfoEntry *function_die = NULL; 1733 DWARFDebugInfoEntry *block_die = NULL; 1734 if (resolve_scope & eSymbolContextBlock) 1735 { 1736 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die); 1737 } 1738 else 1739 { 1740 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL); 1741 } 1742 1743 if (function_die != NULL) 1744 { 1745 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1746 if (sc.function == NULL) 1747 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 1748 } 1749 1750 if (sc.function != NULL) 1751 { 1752 resolved |= eSymbolContextFunction; 1753 1754 if (resolve_scope & eSymbolContextBlock) 1755 { 1756 Block& block = sc.function->GetBlock (true); 1757 1758 if (block_die != NULL) 1759 sc.block = block.FindBlockByID (block_die->GetOffset()); 1760 else 1761 sc.block = block.FindBlockByID (function_die->GetOffset()); 1762 if (sc.block) 1763 resolved |= eSymbolContextBlock; 1764 } 1765 } 1766 } 1767 } 1768 } 1769 } 1770 } 1771 return resolved; 1772} 1773 1774 1775 1776uint32_t 1777SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 1778{ 1779 const uint32_t prev_size = sc_list.GetSize(); 1780 if (resolve_scope & eSymbolContextCompUnit) 1781 { 1782 DWARFDebugInfo* debug_info = DebugInfo(); 1783 if (debug_info) 1784 { 1785 uint32_t cu_idx; 1786 DWARFCompileUnit* curr_cu = NULL; 1787 1788 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 1789 { 1790 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1791 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0; 1792 if (check_inlines || file_spec_matches_cu_file_spec) 1793 { 1794 SymbolContext sc (m_obj_file->GetModule()); 1795 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1796 assert(sc.comp_unit != NULL); 1797 1798 uint32_t file_idx = UINT32_MAX; 1799 1800 // If we are looking for inline functions only and we don't 1801 // find it in the support files, we are done. 1802 if (check_inlines) 1803 { 1804 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); 1805 if (file_idx == UINT32_MAX) 1806 continue; 1807 } 1808 1809 if (line != 0) 1810 { 1811 LineTable *line_table = sc.comp_unit->GetLineTable(); 1812 1813 if (line_table != NULL && line != 0) 1814 { 1815 // We will have already looked up the file index if 1816 // we are searching for inline entries. 1817 if (!check_inlines) 1818 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); 1819 1820 if (file_idx != UINT32_MAX) 1821 { 1822 uint32_t found_line; 1823 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 1824 found_line = sc.line_entry.line; 1825 1826 while (line_idx != UINT32_MAX) 1827 { 1828 sc.function = NULL; 1829 sc.block = NULL; 1830 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1831 { 1832 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 1833 if (file_vm_addr != LLDB_INVALID_ADDRESS) 1834 { 1835 DWARFDebugInfoEntry *function_die = NULL; 1836 DWARFDebugInfoEntry *block_die = NULL; 1837 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL); 1838 1839 if (function_die != NULL) 1840 { 1841 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1842 if (sc.function == NULL) 1843 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 1844 } 1845 1846 if (sc.function != NULL) 1847 { 1848 Block& block = sc.function->GetBlock (true); 1849 1850 if (block_die != NULL) 1851 sc.block = block.FindBlockByID (block_die->GetOffset()); 1852 else 1853 sc.block = block.FindBlockByID (function_die->GetOffset()); 1854 } 1855 } 1856 } 1857 1858 sc_list.Append(sc); 1859 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 1860 } 1861 } 1862 } 1863 else if (file_spec_matches_cu_file_spec && !check_inlines) 1864 { 1865 // only append the context if we aren't looking for inline call sites 1866 // by file and line and if the file spec matches that of the compile unit 1867 sc_list.Append(sc); 1868 } 1869 } 1870 else if (file_spec_matches_cu_file_spec && !check_inlines) 1871 { 1872 // only append the context if we aren't looking for inline call sites 1873 // by file and line and if the file spec matches that of the compile unit 1874 sc_list.Append(sc); 1875 } 1876 1877 if (!check_inlines) 1878 break; 1879 } 1880 } 1881 } 1882 } 1883 return sc_list.GetSize() - prev_size; 1884} 1885 1886void 1887SymbolFileDWARF::Index () 1888{ 1889 if (m_indexed) 1890 return; 1891 m_indexed = true; 1892 Timer scoped_timer (__PRETTY_FUNCTION__, 1893 "SymbolFileDWARF::Index (%s)", 1894 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1895 1896 DWARFDebugInfo* debug_info = DebugInfo(); 1897 if (debug_info) 1898 { 1899 uint32_t cu_idx = 0; 1900 const uint32_t num_compile_units = GetNumCompileUnits(); 1901 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 1902 { 1903 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 1904 1905 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1; 1906 1907 curr_cu->Index (cu_idx, 1908 m_function_basename_index, 1909 m_function_fullname_index, 1910 m_function_method_index, 1911 m_function_selector_index, 1912 m_objc_class_selectors_index, 1913 m_global_index, 1914 m_type_index, 1915 m_namespace_index); 1916 1917 // Keep memory down by clearing DIEs if this generate function 1918 // caused them to be parsed 1919 if (clear_dies) 1920 curr_cu->ClearDIEs (true); 1921 } 1922 1923 m_function_basename_index.Finalize(); 1924 m_function_fullname_index.Finalize(); 1925 m_function_method_index.Finalize(); 1926 m_function_selector_index.Finalize(); 1927 m_objc_class_selectors_index.Finalize(); 1928 m_global_index.Finalize(); 1929 m_type_index.Finalize(); 1930 m_namespace_index.Finalize(); 1931 1932#if defined (ENABLE_DEBUG_PRINTF) 1933 StreamFile s(stdout, false); 1934 s.Printf ("DWARF index for '%s/%s':", 1935 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 1936 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1937 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 1938 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 1939 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 1940 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 1941 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 1942 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 1943 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 1944 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 1945#endif 1946 } 1947} 1948 1949uint32_t 1950SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 1951{ 1952 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 1953 1954 if (log) 1955 { 1956 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", name=\"%s\", append=%u, max_matches=%u, variables)", 1957 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 1958 m_obj_file->GetFileSpec().GetFilename().GetCString(), 1959 name.GetCString(), append, max_matches); 1960 } 1961 DWARFDebugInfo* info = DebugInfo(); 1962 if (info == NULL) 1963 return 0; 1964 1965 // If we aren't appending the results to this list, then clear the list 1966 if (!append) 1967 variables.Clear(); 1968 1969 // Remember how many variables are in the list before we search in case 1970 // we are appending the results to a variable list. 1971 const uint32_t original_size = variables.GetSize(); 1972 1973 DIEArray die_offsets; 1974 1975 if (m_apple_names_ap.get()) 1976 { 1977 const char *name_cstr = name.GetCString(); 1978 const char *base_name_start; 1979 const char *base_name_end = NULL; 1980 1981 if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end)) 1982 base_name_start = name_cstr; 1983 1984 m_apple_names_ap->FindByName (base_name_start, die_offsets); 1985 } 1986 else 1987 { 1988 // Index the DWARF if we haven't already 1989 if (!m_indexed) 1990 Index (); 1991 1992 m_global_index.Find (name, die_offsets); 1993 } 1994 1995 const size_t num_matches = die_offsets.size(); 1996 if (num_matches) 1997 { 1998 SymbolContext sc; 1999 sc.module_sp = m_obj_file->GetModule(); 2000 assert (sc.module_sp); 2001 2002 DWARFDebugInfo* debug_info = DebugInfo(); 2003 DWARFCompileUnit* dwarf_cu = NULL; 2004 const DWARFDebugInfoEntry* die = NULL; 2005 for (size_t i=0; i<num_matches; ++i) 2006 { 2007 const dw_offset_t die_offset = die_offsets[i]; 2008 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2009 2010 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 2011 assert(sc.comp_unit != NULL); 2012 2013 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 2014 2015 if (variables.GetSize() - original_size >= max_matches) 2016 break; 2017 } 2018 } 2019 2020 // Return the number of variable that were appended to the list 2021 return variables.GetSize() - original_size; 2022} 2023 2024uint32_t 2025SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 2026{ 2027 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2028 2029 if (log) 2030 { 2031 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", regex=\"%s\", append=%u, max_matches=%u, variables)", 2032 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2033 m_obj_file->GetFileSpec().GetFilename().GetCString(), 2034 regex.GetText(), append, max_matches); 2035 } 2036 2037 DWARFDebugInfo* info = DebugInfo(); 2038 if (info == NULL) 2039 return 0; 2040 2041 // If we aren't appending the results to this list, then clear the list 2042 if (!append) 2043 variables.Clear(); 2044 2045 // Remember how many variables are in the list before we search in case 2046 // we are appending the results to a variable list. 2047 const uint32_t original_size = variables.GetSize(); 2048 2049 DIEArray die_offsets; 2050 2051 if (m_apple_names_ap.get()) 2052 { 2053 m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets); 2054 } 2055 else 2056 { 2057 // Index the DWARF if we haven't already 2058 if (!m_indexed) 2059 Index (); 2060 2061 m_global_index.Find (regex, die_offsets); 2062 } 2063 2064 SymbolContext sc; 2065 sc.module_sp = m_obj_file->GetModule(); 2066 assert (sc.module_sp); 2067 2068 DWARFCompileUnit* dwarf_cu = NULL; 2069 const DWARFDebugInfoEntry* die = NULL; 2070 const size_t num_matches = die_offsets.size(); 2071 if (num_matches) 2072 { 2073 DWARFDebugInfo* debug_info = DebugInfo(); 2074 for (size_t i=0; i<num_matches; ++i) 2075 { 2076 const dw_offset_t die_offset = die_offsets[i]; 2077 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2078 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 2079 2080 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 2081 2082 if (variables.GetSize() - original_size >= max_matches) 2083 break; 2084 } 2085 } 2086 2087 // Return the number of variable that were appended to the list 2088 return variables.GetSize() - original_size; 2089} 2090 2091bool 2092SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset, 2093 DWARFCompileUnit *&dwarf_cu, 2094 SymbolContextList& sc_list) 2095{ 2096 SymbolContext sc; 2097 2098 DWARFDebugInfo* info = DebugInfo(); 2099 bool resolved_it = false; 2100 2101 if (info == NULL) 2102 return resolved_it; 2103 2104 DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2105 2106 // If we were passed a die that is not a function, just return false... 2107 if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine) 2108 return false; 2109 2110 const DWARFDebugInfoEntry* inlined_die = NULL; 2111 if (die->Tag() == DW_TAG_inlined_subroutine) 2112 { 2113 inlined_die = die; 2114 2115 while ((die = die->GetParent()) != NULL) 2116 { 2117 if (die->Tag() == DW_TAG_subprogram) 2118 break; 2119 } 2120 } 2121 assert (die->Tag() == DW_TAG_subprogram); 2122 if (GetFunction (dwarf_cu, die, sc)) 2123 { 2124 Address addr; 2125 // Parse all blocks if needed 2126 if (inlined_die) 2127 { 2128 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); 2129 assert (sc.block != NULL); 2130 if (sc.block->GetStartAddress (addr) == false) 2131 addr.Clear(); 2132 } 2133 else 2134 { 2135 sc.block = NULL; 2136 addr = sc.function->GetAddressRange().GetBaseAddress(); 2137 } 2138 2139 if (addr.IsValid()) 2140 { 2141 2142 // We found the function, so we should find the line table 2143 // and line table entry as well 2144 LineTable *line_table = sc.comp_unit->GetLineTable(); 2145 if (line_table == NULL) 2146 { 2147 if (ParseCompileUnitLineTable(sc)) 2148 line_table = sc.comp_unit->GetLineTable(); 2149 } 2150 if (line_table != NULL) 2151 line_table->FindLineEntryByAddress (addr, sc.line_entry); 2152 2153 sc_list.Append(sc); 2154 resolved_it = true; 2155 } 2156 } 2157 2158 return resolved_it; 2159} 2160 2161void 2162SymbolFileDWARF::FindFunctions (const ConstString &name, 2163 const NameToDIE &name_to_die, 2164 SymbolContextList& sc_list) 2165{ 2166 DIEArray die_offsets; 2167 if (name_to_die.Find (name, die_offsets)) 2168 { 2169 ParseFunctions (die_offsets, sc_list); 2170 } 2171} 2172 2173 2174void 2175SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, 2176 const NameToDIE &name_to_die, 2177 SymbolContextList& sc_list) 2178{ 2179 DIEArray die_offsets; 2180 if (name_to_die.Find (regex, die_offsets)) 2181 { 2182 ParseFunctions (die_offsets, sc_list); 2183 } 2184} 2185 2186 2187void 2188SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, 2189 const DWARFMappedHash::MemoryTable &memory_table, 2190 SymbolContextList& sc_list) 2191{ 2192 DIEArray die_offsets; 2193 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, die_offsets)) 2194 { 2195 ParseFunctions (die_offsets, sc_list); 2196 } 2197} 2198 2199void 2200SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets, 2201 SymbolContextList& sc_list) 2202{ 2203 const size_t num_matches = die_offsets.size(); 2204 if (num_matches) 2205 { 2206 SymbolContext sc; 2207 2208 DWARFCompileUnit* dwarf_cu = NULL; 2209 for (size_t i=0; i<num_matches; ++i) 2210 { 2211 const dw_offset_t die_offset = die_offsets[i]; 2212 ResolveFunction (die_offset, dwarf_cu, sc_list); 2213 } 2214 } 2215} 2216 2217bool 2218SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die, 2219 const DWARFCompileUnit *dwarf_cu, 2220 uint32_t name_type_mask, 2221 const char *partial_name, 2222 const char *base_name_start, 2223 const char *base_name_end) 2224{ 2225 // If we are looking only for methods, throw away all the ones that aren't in C++ classes: 2226 if (name_type_mask == eFunctionNameTypeMethod 2227 || name_type_mask == eFunctionNameTypeBase) 2228 { 2229 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset()); 2230 if (!containing_decl_ctx) 2231 return false; 2232 2233 bool is_cxx_method = (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord); 2234 2235 if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod) 2236 return false; 2237 if (is_cxx_method && name_type_mask == eFunctionNameTypeBase) 2238 return false; 2239 } 2240 2241 // Now we need to check whether the name we got back for this type matches the extra specifications 2242 // that were in the name we're looking up: 2243 if (base_name_start != partial_name || *base_name_end != '\0') 2244 { 2245 // First see if the stuff to the left matches the full name. To do that let's see if 2246 // we can pull out the mips linkage name attribute: 2247 2248 Mangled best_name; 2249 2250 DWARFDebugInfoEntry::Attributes attributes; 2251 die->GetAttributes(this, dwarf_cu, NULL, attributes); 2252 uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name); 2253 if (idx != UINT32_MAX) 2254 { 2255 DWARFFormValue form_value; 2256 if (attributes.ExtractFormValueAtIndex(this, idx, form_value)) 2257 { 2258 const char *name = form_value.AsCString(&get_debug_str_data()); 2259 best_name.SetValue (name, true); 2260 } 2261 } 2262 if (best_name) 2263 { 2264 const char *demangled = best_name.GetDemangledName().GetCString(); 2265 if (demangled) 2266 { 2267 std::string name_no_parens(partial_name, base_name_end - partial_name); 2268 if (strstr (demangled, name_no_parens.c_str()) == NULL) 2269 { 2270 printf ("name: \"%s\" didn't match full name: \"%s\".\n", partial_name, demangled); 2271 return false; 2272 } 2273 } 2274 } 2275 } 2276 2277 return true; 2278} 2279 2280uint32_t 2281SymbolFileDWARF::FindFunctions (const ConstString &name, 2282 uint32_t name_type_mask, 2283 bool append, 2284 SymbolContextList& sc_list) 2285{ 2286 Timer scoped_timer (__PRETTY_FUNCTION__, 2287 "SymbolFileDWARF::FindFunctions (name = '%s')", 2288 name.AsCString()); 2289 2290 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2291 2292 if (log) 2293 { 2294 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)", 2295 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2296 m_obj_file->GetFileSpec().GetFilename().GetCString(), 2297 name.GetCString(), name_type_mask, append); 2298 } 2299 2300 // If we aren't appending the results to this list, then clear the list 2301 if (!append) 2302 sc_list.Clear(); 2303 2304 // If name is empty then we won't find anything. 2305 if (name.IsEmpty()) 2306 return 0; 2307 2308 // Remember how many sc_list are in the list before we search in case 2309 // we are appending the results to a variable list. 2310 2311 const uint32_t original_size = sc_list.GetSize(); 2312 2313 const char *name_cstr = name.GetCString(); 2314 uint32_t effective_name_type_mask = eFunctionNameTypeNone; 2315 const char *base_name_start = name_cstr; 2316 const char *base_name_end = name_cstr + strlen(name_cstr); 2317 2318 if (name_type_mask & eFunctionNameTypeAuto) 2319 { 2320 if (CPPLanguageRuntime::IsCPPMangledName (name_cstr)) 2321 effective_name_type_mask = eFunctionNameTypeFull; 2322 else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr)) 2323 effective_name_type_mask = eFunctionNameTypeFull; 2324 else 2325 { 2326 if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr)) 2327 effective_name_type_mask |= eFunctionNameTypeSelector; 2328 2329 if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end)) 2330 effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase); 2331 } 2332 } 2333 else 2334 { 2335 effective_name_type_mask = name_type_mask; 2336 if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase) 2337 { 2338 // If they've asked for a CPP method or function name and it can't be that, we don't 2339 // even need to search for CPP methods or names. 2340 if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end)) 2341 { 2342 effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase); 2343 if (effective_name_type_mask == eFunctionNameTypeNone) 2344 return 0; 2345 } 2346 } 2347 2348 if (effective_name_type_mask & eFunctionNameTypeSelector) 2349 { 2350 if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr)) 2351 { 2352 effective_name_type_mask &= ~(eFunctionNameTypeSelector); 2353 if (effective_name_type_mask == eFunctionNameTypeNone) 2354 return 0; 2355 } 2356 } 2357 } 2358 2359 DWARFDebugInfo* info = DebugInfo(); 2360 if (info == NULL) 2361 return 0; 2362 2363 if (m_apple_names_ap.get()) 2364 { 2365 DIEArray die_offsets; 2366 2367 uint32_t num_matches = 0; 2368 2369 if (effective_name_type_mask & eFunctionNameTypeFull) 2370 { 2371 // If they asked for the full name, match what they typed. At some point we may 2372 // want to canonicalize this (strip double spaces, etc. For now, we just add all the 2373 // dies that we find by exact match. 2374 DWARFCompileUnit *dwarf_cu = NULL; 2375 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); 2376 for (uint32_t i = 0; i < num_matches; i++) 2377 ResolveFunction (die_offsets[i], dwarf_cu, sc_list); 2378 } 2379 else 2380 { 2381 DWARFCompileUnit* dwarf_cu = NULL; 2382 2383 if (effective_name_type_mask & eFunctionNameTypeSelector) 2384 { 2385 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); 2386 // Now make sure these are actually ObjC methods. In this case we can simply look up the name, 2387 // and if it is an ObjC method name, we're good. 2388 2389 for (uint32_t i = 0; i < num_matches; i++) 2390 { 2391 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); 2392 assert (die); 2393 2394 const char *die_name = die->GetName(this, dwarf_cu); 2395 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name)) 2396 ResolveFunction (die_offsets[i], dwarf_cu, sc_list); 2397 } 2398 die_offsets.clear(); 2399 } 2400 2401 if (effective_name_type_mask & eFunctionNameTypeMethod 2402 || effective_name_type_mask & eFunctionNameTypeBase) 2403 { 2404 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to 2405 // extract the base name, look that up, and if there is any other information in the name we were 2406 // passed in we have to post-filter based on that. 2407 2408 // FIXME: Arrange the logic above so that we don't calculate the base name twice: 2409 std::string base_name(base_name_start, base_name_end - base_name_start); 2410 num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets); 2411 2412 for (uint32_t i = 0; i < num_matches; i++) 2413 { 2414 dw_offset_t offset = die_offsets[i]; 2415 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (offset, &dwarf_cu); 2416 assert (die); 2417 if (!FunctionDieMatchesPartialName(die, 2418 dwarf_cu, 2419 effective_name_type_mask, 2420 name_cstr, 2421 base_name_start, 2422 base_name_end)) 2423 continue; 2424 2425 // If we get to here, the die is good, and we should add it: 2426 ResolveFunction (offset, dwarf_cu, sc_list); 2427 } 2428 die_offsets.clear(); 2429 } 2430 } 2431 } 2432 else 2433 { 2434 2435 // Index the DWARF if we haven't already 2436 if (!m_indexed) 2437 Index (); 2438 2439 if (name_type_mask & eFunctionNameTypeFull) 2440 FindFunctions (name, m_function_fullname_index, sc_list); 2441 2442 std::string base_name(base_name_start, base_name_end - base_name_start); 2443 ConstString base_name_const(base_name.c_str()); 2444 DIEArray die_offsets; 2445 DWARFCompileUnit *dwarf_cu = NULL; 2446 2447 if (effective_name_type_mask & eFunctionNameTypeBase) 2448 { 2449 uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets); 2450 { 2451 for (uint32_t i = 0; i < num_base; i++) 2452 { 2453 dw_offset_t offset = die_offsets[i]; 2454 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (offset, &dwarf_cu); 2455 assert (die); 2456 if (!FunctionDieMatchesPartialName(die, 2457 dwarf_cu, 2458 effective_name_type_mask, 2459 name_cstr, 2460 base_name_start, 2461 base_name_end)) 2462 continue; 2463 2464 // If we get to here, the die is good, and we should add it: 2465 ResolveFunction (offset, dwarf_cu, sc_list); 2466 } 2467 } 2468 die_offsets.clear(); 2469 } 2470 2471 if (name_type_mask & eFunctionNameTypeMethod) 2472 { 2473 uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets); 2474 { 2475 for (uint32_t i = 0; i < num_base; i++) 2476 { 2477 dw_offset_t offset = die_offsets[i]; 2478 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (offset, &dwarf_cu); 2479 assert (die); 2480 if (!FunctionDieMatchesPartialName(die, 2481 dwarf_cu, 2482 effective_name_type_mask, 2483 name_cstr, 2484 base_name_start, 2485 base_name_end)) 2486 continue; 2487 2488 // If we get to here, the die is good, and we should add it: 2489 ResolveFunction (offset, dwarf_cu, sc_list); 2490 } 2491 } 2492 die_offsets.clear(); 2493 } 2494 2495 if (name_type_mask & eFunctionNameTypeSelector) 2496 { 2497 FindFunctions (name, m_function_selector_index, sc_list); 2498 } 2499 2500 } 2501 2502 // Return the number of variable that were appended to the list 2503 return sc_list.GetSize() - original_size; 2504} 2505 2506uint32_t 2507SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) 2508{ 2509 Timer scoped_timer (__PRETTY_FUNCTION__, 2510 "SymbolFileDWARF::FindFunctions (regex = '%s')", 2511 regex.GetText()); 2512 2513 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2514 2515 if (log) 2516 { 2517 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", regex=\"%s\"append=%u, sc_list)", 2518 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2519 m_obj_file->GetFileSpec().GetFilename().GetCString(), 2520 regex.GetText(), append); 2521 } 2522 2523 2524 // If we aren't appending the results to this list, then clear the list 2525 if (!append) 2526 sc_list.Clear(); 2527 2528 // Remember how many sc_list are in the list before we search in case 2529 // we are appending the results to a variable list. 2530 uint32_t original_size = sc_list.GetSize(); 2531 2532 if (m_apple_names_ap.get()) 2533 { 2534 FindFunctions (regex, *m_apple_names_ap, sc_list); 2535 } 2536 else 2537 { 2538 // Index the DWARF if we haven't already 2539 if (!m_indexed) 2540 Index (); 2541 2542 FindFunctions (regex, m_function_basename_index, sc_list); 2543 2544 FindFunctions (regex, m_function_fullname_index, sc_list); 2545 } 2546 2547 // Return the number of variable that were appended to the list 2548 return sc_list.GetSize() - original_size; 2549} 2550 2551void 2552SymbolFileDWARF::ReportError (const char *format, ...) 2553{ 2554 ::fprintf (stderr, 2555 "error: %s/%s ", 2556 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2557 m_obj_file->GetFileSpec().GetFilename().GetCString()); 2558 2559 if (m_obj_file->GetModule()->GetObjectName()) 2560 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString()); 2561 2562 va_list args; 2563 va_start (args, format); 2564 vfprintf (stderr, format, args); 2565 va_end (args); 2566} 2567 2568void 2569SymbolFileDWARF::ReportWarning (const char *format, ...) 2570{ 2571 ::fprintf (stderr, 2572 "warning: %s/%s ", 2573 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2574 m_obj_file->GetFileSpec().GetFilename().GetCString()); 2575 2576 if (m_obj_file->GetModule()->GetObjectName()) 2577 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString()); 2578 2579 va_list args; 2580 va_start (args, format); 2581 vfprintf (stderr, format, args); 2582 va_end (args); 2583} 2584 2585uint32_t 2586SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) 2587{ 2588 DWARFDebugInfo* info = DebugInfo(); 2589 if (info == NULL) 2590 return 0; 2591 2592 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2593 2594 if (log) 2595 { 2596 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", sc, name=\"%s\", append=%u, max_matches=%u, type_list)", 2597 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2598 m_obj_file->GetFileSpec().GetFilename().GetCString(), 2599 name.GetCString(), append, max_matches); 2600 } 2601 2602 // If we aren't appending the results to this list, then clear the list 2603 if (!append) 2604 types.Clear(); 2605 2606 DIEArray die_offsets; 2607 2608 if (m_apple_types_ap.get()) 2609 { 2610 const char *name_cstr = name.GetCString(); 2611 m_apple_types_ap->FindByName (name_cstr, die_offsets); 2612 } 2613 else 2614 { 2615 if (!m_indexed) 2616 Index (); 2617 2618 m_type_index.Find (name, die_offsets); 2619 } 2620 2621 2622 const size_t num_matches = die_offsets.size(); 2623 2624 if (num_matches) 2625 { 2626 const uint32_t initial_types_size = types.GetSize(); 2627 DWARFCompileUnit* dwarf_cu = NULL; 2628 const DWARFDebugInfoEntry* die = NULL; 2629 DWARFDebugInfo* debug_info = DebugInfo(); 2630 for (size_t i=0; i<num_matches; ++i) 2631 { 2632 const dw_offset_t die_offset = die_offsets[i]; 2633 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2634 2635 Type *matching_type = ResolveType (dwarf_cu, die); 2636 if (matching_type) 2637 { 2638 // We found a type pointer, now find the shared pointer form our type list 2639 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); 2640 if (type_sp) 2641 { 2642 types.InsertUnique (type_sp); 2643 if (types.GetSize() >= max_matches) 2644 break; 2645 } 2646 else 2647 { 2648 ReportError ("error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID()); 2649 } 2650 } 2651 } 2652 return types.GetSize() - initial_types_size; 2653 } 2654 return 0; 2655} 2656 2657 2658ClangNamespaceDecl 2659SymbolFileDWARF::FindNamespace (const SymbolContext& sc, 2660 const ConstString &name) 2661{ 2662 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2663 2664 if (log) 2665 { 2666 log->Printf ("SymbolFileDWARF::FindNamespace (file=\"%s/%s\", sc, name=\"%s\")", 2667 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2668 m_obj_file->GetFileSpec().GetFilename().GetCString(), 2669 name.GetCString()); 2670 } 2671 2672 ClangNamespaceDecl namespace_decl; 2673 DWARFDebugInfo* info = DebugInfo(); 2674 if (info) 2675 { 2676 DIEArray die_offsets; 2677 2678 // Index if we already haven't to make sure the compile units 2679 // get indexed and make their global DIE index list 2680 if (m_apple_namespaces_ap.get()) 2681 { 2682 const char *name_cstr = name.GetCString(); 2683 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets); 2684 } 2685 else 2686 { 2687 if (!m_indexed) 2688 Index (); 2689 2690 m_namespace_index.Find (name, die_offsets); 2691 } 2692 2693 DWARFCompileUnit* dwarf_cu = NULL; 2694 const DWARFDebugInfoEntry* die = NULL; 2695 const size_t num_matches = die_offsets.size(); 2696 if (num_matches) 2697 { 2698 DWARFDebugInfo* debug_info = DebugInfo(); 2699 for (size_t i=0; i<num_matches; ++i) 2700 { 2701 const dw_offset_t die_offset = die_offsets[i]; 2702 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2703 2704 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die); 2705 if (clang_namespace_decl) 2706 { 2707 namespace_decl.SetASTContext (GetClangASTContext().getASTContext()); 2708 namespace_decl.SetNamespaceDecl (clang_namespace_decl); 2709 } 2710 } 2711 } 2712 } 2713 return namespace_decl; 2714} 2715 2716uint32_t 2717SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types) 2718{ 2719 // Remember how many sc_list are in the list before we search in case 2720 // we are appending the results to a variable list. 2721 uint32_t original_size = types.GetSize(); 2722 2723 const uint32_t num_die_offsets = die_offsets.size(); 2724 // Parse all of the types we found from the pubtypes matches 2725 uint32_t i; 2726 uint32_t num_matches = 0; 2727 for (i = 0; i < num_die_offsets; ++i) 2728 { 2729 Type *matching_type = ResolveTypeUID (die_offsets[i]); 2730 if (matching_type) 2731 { 2732 // We found a type pointer, now find the shared pointer form our type list 2733 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); 2734 assert (type_sp.get() != NULL); 2735 types.InsertUnique (type_sp); 2736 ++num_matches; 2737 if (num_matches >= max_matches) 2738 break; 2739 } 2740 } 2741 2742 // Return the number of variable that were appended to the list 2743 return types.GetSize() - original_size; 2744} 2745 2746 2747size_t 2748SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc, 2749 clang::DeclContext *containing_decl_ctx, 2750 TypeSP& type_sp, 2751 DWARFCompileUnit* dwarf_cu, 2752 const DWARFDebugInfoEntry *parent_die, 2753 bool skip_artificial, 2754 bool &is_static, 2755 TypeList* type_list, 2756 std::vector<clang_type_t>& function_param_types, 2757 std::vector<clang::ParmVarDecl*>& function_param_decls, 2758 unsigned &type_quals) 2759{ 2760 if (parent_die == NULL) 2761 return 0; 2762 2763 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2764 2765 size_t arg_idx = 0; 2766 const DWARFDebugInfoEntry *die; 2767 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2768 { 2769 dw_tag_t tag = die->Tag(); 2770 switch (tag) 2771 { 2772 case DW_TAG_formal_parameter: 2773 { 2774 DWARFDebugInfoEntry::Attributes attributes; 2775 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2776 if (num_attributes > 0) 2777 { 2778 const char *name = NULL; 2779 Declaration decl; 2780 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; 2781 bool is_artificial = false; 2782 // one of None, Auto, Register, Extern, Static, PrivateExtern 2783 2784 clang::StorageClass storage = clang::SC_None; 2785 uint32_t i; 2786 for (i=0; i<num_attributes; ++i) 2787 { 2788 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2789 DWARFFormValue form_value; 2790 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2791 { 2792 switch (attr) 2793 { 2794 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2795 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2796 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2797 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 2798 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; 2799 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 2800 case DW_AT_location: 2801 // if (form_value.BlockData()) 2802 // { 2803 // const DataExtractor& debug_info_data = debug_info(); 2804 // uint32_t block_length = form_value.Unsigned(); 2805 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); 2806 // } 2807 // else 2808 // { 2809 // } 2810 // break; 2811 case DW_AT_const_value: 2812 case DW_AT_default_value: 2813 case DW_AT_description: 2814 case DW_AT_endianity: 2815 case DW_AT_is_optional: 2816 case DW_AT_segment: 2817 case DW_AT_variable_parameter: 2818 default: 2819 case DW_AT_abstract_origin: 2820 case DW_AT_sibling: 2821 break; 2822 } 2823 } 2824 } 2825 2826 bool skip = false; 2827 if (skip_artificial) 2828 { 2829 if (is_artificial) 2830 { 2831 // In order to determine if a C++ member function is 2832 // "const" we have to look at the const-ness of "this"... 2833 // Ugly, but that 2834 if (arg_idx == 0) 2835 { 2836 if (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord) 2837 { 2838 // Often times compilers omit the "this" name for the 2839 // specification DIEs, so we can't rely upon the name 2840 // being in the formal parameter DIE... 2841 if (name == NULL || ::strcmp(name, "this")==0) 2842 { 2843 Type *this_type = ResolveTypeUID (param_type_die_offset); 2844 if (this_type) 2845 { 2846 uint32_t encoding_mask = this_type->GetEncodingMask(); 2847 if (encoding_mask & Type::eEncodingIsPointerUID) 2848 { 2849 is_static = false; 2850 2851 if (encoding_mask & (1u << Type::eEncodingIsConstUID)) 2852 type_quals |= clang::Qualifiers::Const; 2853 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) 2854 type_quals |= clang::Qualifiers::Volatile; 2855 } 2856 } 2857 } 2858 } 2859 } 2860 skip = true; 2861 } 2862 else 2863 { 2864 2865 // HACK: Objective C formal parameters "self" and "_cmd" 2866 // are not marked as artificial in the DWARF... 2867 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 2868 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus)) 2869 { 2870 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0)) 2871 skip = true; 2872 } 2873 } 2874 } 2875 2876 if (!skip) 2877 { 2878 Type *type = ResolveTypeUID(param_type_die_offset); 2879 if (type) 2880 { 2881 function_param_types.push_back (type->GetClangForwardType()); 2882 2883 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage); 2884 assert(param_var_decl); 2885 function_param_decls.push_back(param_var_decl); 2886 } 2887 } 2888 } 2889 arg_idx++; 2890 } 2891 break; 2892 2893 default: 2894 break; 2895 } 2896 } 2897 return arg_idx; 2898} 2899 2900size_t 2901SymbolFileDWARF::ParseChildEnumerators 2902( 2903 const SymbolContext& sc, 2904 clang_type_t enumerator_clang_type, 2905 uint32_t enumerator_byte_size, 2906 DWARFCompileUnit* dwarf_cu, 2907 const DWARFDebugInfoEntry *parent_die 2908) 2909{ 2910 if (parent_die == NULL) 2911 return 0; 2912 2913 size_t enumerators_added = 0; 2914 const DWARFDebugInfoEntry *die; 2915 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2916 2917 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2918 { 2919 const dw_tag_t tag = die->Tag(); 2920 if (tag == DW_TAG_enumerator) 2921 { 2922 DWARFDebugInfoEntry::Attributes attributes; 2923 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2924 if (num_child_attributes > 0) 2925 { 2926 const char *name = NULL; 2927 bool got_value = false; 2928 int64_t enum_value = 0; 2929 Declaration decl; 2930 2931 uint32_t i; 2932 for (i=0; i<num_child_attributes; ++i) 2933 { 2934 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2935 DWARFFormValue form_value; 2936 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2937 { 2938 switch (attr) 2939 { 2940 case DW_AT_const_value: 2941 got_value = true; 2942 enum_value = form_value.Unsigned(); 2943 break; 2944 2945 case DW_AT_name: 2946 name = form_value.AsCString(&get_debug_str_data()); 2947 break; 2948 2949 case DW_AT_description: 2950 default: 2951 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2952 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2953 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2954 case DW_AT_sibling: 2955 break; 2956 } 2957 } 2958 } 2959 2960 if (name && name[0] && got_value) 2961 { 2962 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type, 2963 enumerator_clang_type, 2964 decl, 2965 name, 2966 enum_value, 2967 enumerator_byte_size * 8); 2968 ++enumerators_added; 2969 } 2970 } 2971 } 2972 } 2973 return enumerators_added; 2974} 2975 2976void 2977SymbolFileDWARF::ParseChildArrayInfo 2978( 2979 const SymbolContext& sc, 2980 DWARFCompileUnit* dwarf_cu, 2981 const DWARFDebugInfoEntry *parent_die, 2982 int64_t& first_index, 2983 std::vector<uint64_t>& element_orders, 2984 uint32_t& byte_stride, 2985 uint32_t& bit_stride 2986) 2987{ 2988 if (parent_die == NULL) 2989 return; 2990 2991 const DWARFDebugInfoEntry *die; 2992 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2993 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2994 { 2995 const dw_tag_t tag = die->Tag(); 2996 switch (tag) 2997 { 2998 case DW_TAG_enumerator: 2999 { 3000 DWARFDebugInfoEntry::Attributes attributes; 3001 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 3002 if (num_child_attributes > 0) 3003 { 3004 const char *name = NULL; 3005 bool got_value = false; 3006 int64_t enum_value = 0; 3007 3008 uint32_t i; 3009 for (i=0; i<num_child_attributes; ++i) 3010 { 3011 const dw_attr_t attr = attributes.AttributeAtIndex(i); 3012 DWARFFormValue form_value; 3013 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3014 { 3015 switch (attr) 3016 { 3017 case DW_AT_const_value: 3018 got_value = true; 3019 enum_value = form_value.Unsigned(); 3020 break; 3021 3022 case DW_AT_name: 3023 name = form_value.AsCString(&get_debug_str_data()); 3024 break; 3025 3026 case DW_AT_description: 3027 default: 3028 case DW_AT_decl_file: 3029 case DW_AT_decl_line: 3030 case DW_AT_decl_column: 3031 case DW_AT_sibling: 3032 break; 3033 } 3034 } 3035 } 3036 } 3037 } 3038 break; 3039 3040 case DW_TAG_subrange_type: 3041 { 3042 DWARFDebugInfoEntry::Attributes attributes; 3043 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 3044 if (num_child_attributes > 0) 3045 { 3046 const char *name = NULL; 3047 bool got_value = false; 3048 uint64_t byte_size = 0; 3049 int64_t enum_value = 0; 3050 uint64_t num_elements = 0; 3051 uint64_t lower_bound = 0; 3052 uint64_t upper_bound = 0; 3053 uint32_t i; 3054 for (i=0; i<num_child_attributes; ++i) 3055 { 3056 const dw_attr_t attr = attributes.AttributeAtIndex(i); 3057 DWARFFormValue form_value; 3058 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3059 { 3060 switch (attr) 3061 { 3062 case DW_AT_const_value: 3063 got_value = true; 3064 enum_value = form_value.Unsigned(); 3065 break; 3066 3067 case DW_AT_name: 3068 name = form_value.AsCString(&get_debug_str_data()); 3069 break; 3070 3071 case DW_AT_count: 3072 num_elements = form_value.Unsigned(); 3073 break; 3074 3075 case DW_AT_bit_stride: 3076 bit_stride = form_value.Unsigned(); 3077 break; 3078 3079 case DW_AT_byte_stride: 3080 byte_stride = form_value.Unsigned(); 3081 break; 3082 3083 case DW_AT_byte_size: 3084 byte_size = form_value.Unsigned(); 3085 break; 3086 3087 case DW_AT_lower_bound: 3088 lower_bound = form_value.Unsigned(); 3089 break; 3090 3091 case DW_AT_upper_bound: 3092 upper_bound = form_value.Unsigned(); 3093 break; 3094 3095 default: 3096 case DW_AT_abstract_origin: 3097 case DW_AT_accessibility: 3098 case DW_AT_allocated: 3099 case DW_AT_associated: 3100 case DW_AT_data_location: 3101 case DW_AT_declaration: 3102 case DW_AT_description: 3103 case DW_AT_sibling: 3104 case DW_AT_threads_scaled: 3105 case DW_AT_type: 3106 case DW_AT_visibility: 3107 break; 3108 } 3109 } 3110 } 3111 3112 if (upper_bound > lower_bound) 3113 num_elements = upper_bound - lower_bound + 1; 3114 3115 if (num_elements > 0) 3116 element_orders.push_back (num_elements); 3117 } 3118 } 3119 break; 3120 } 3121 } 3122} 3123 3124TypeSP 3125SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die) 3126{ 3127 TypeSP type_sp; 3128 if (die != NULL) 3129 { 3130 assert(curr_cu != NULL); 3131 Type *type_ptr = m_die_to_type.lookup (die); 3132 if (type_ptr == NULL) 3133 { 3134 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu); 3135 assert (lldb_cu); 3136 SymbolContext sc(lldb_cu); 3137 type_sp = ParseType(sc, curr_cu, die, NULL); 3138 } 3139 else if (type_ptr != DIE_IS_BEING_PARSED) 3140 { 3141 // Grab the existing type from the master types lists 3142 type_sp = GetTypeList()->FindType(type_ptr->GetID()); 3143 } 3144 3145 } 3146 return type_sp; 3147} 3148 3149clang::DeclContext * 3150SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset) 3151{ 3152 if (die_offset != DW_INVALID_OFFSET) 3153 { 3154 DWARFCompileUnitSP cu_sp; 3155 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 3156 return GetClangDeclContextContainingDIE (cu_sp.get(), die); 3157 } 3158 return NULL; 3159} 3160 3161clang::DeclContext * 3162SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset) 3163{ 3164 if (die_offset != DW_INVALID_OFFSET) 3165 { 3166 DWARFDebugInfo* debug_info = DebugInfo(); 3167 if (debug_info) 3168 { 3169 DWARFCompileUnitSP cu_sp; 3170 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp); 3171 if (die) 3172 return GetClangDeclContextForDIE (sc, cu_sp.get(), die); 3173 } 3174 } 3175 return NULL; 3176} 3177 3178clang::NamespaceDecl * 3179SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 3180{ 3181 if (die->Tag() == DW_TAG_namespace) 3182 { 3183 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); 3184 if (namespace_name) 3185 { 3186 Declaration decl; // TODO: fill in the decl object 3187 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent())); 3188 if (namespace_decl) 3189 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); 3190 return namespace_decl; 3191 } 3192 } 3193 return NULL; 3194} 3195 3196clang::DeclContext * 3197SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 3198{ 3199 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die); 3200 if (clang_decl_ctx) 3201 return clang_decl_ctx; 3202 // If this DIE has a specification, or an abstract origin, then trace to those. 3203 3204 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET); 3205 if (die_offset != DW_INVALID_OFFSET) 3206 return GetClangDeclContextForDIEOffset (sc, die_offset); 3207 3208 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); 3209 if (die_offset != DW_INVALID_OFFSET) 3210 return GetClangDeclContextForDIEOffset (sc, die_offset); 3211 3212 // This is the DIE we want. Parse it, then query our map. 3213 3214 ParseType(sc, curr_cu, die, NULL); 3215 3216 clang_decl_ctx = GetCachedClangDeclContextForDIE (die); 3217 3218 return clang_decl_ctx; 3219} 3220 3221clang::DeclContext * 3222SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 3223{ 3224 if (m_clang_tu_decl == NULL) 3225 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl(); 3226 3227 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die); 3228 3229 if (decl_ctx_die) 3230 { 3231 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die); 3232 if (pos != m_die_to_decl_ctx.end()) 3233 return pos->second; 3234 3235 switch (decl_ctx_die->Tag()) 3236 { 3237 case DW_TAG_compile_unit: 3238 return m_clang_tu_decl; 3239 3240 case DW_TAG_namespace: 3241 { 3242 const char *namespace_name = decl_ctx_die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL); 3243 if (namespace_name) 3244 { 3245 Declaration decl; // TODO: fill in the decl object 3246 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (cu, decl_ctx_die)); 3247 if (namespace_decl) 3248 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, decl_ctx_die); 3249 return namespace_decl; 3250 } 3251 } 3252 break; 3253 3254 case DW_TAG_structure_type: 3255 case DW_TAG_union_type: 3256 case DW_TAG_class_type: 3257 { 3258 Type* type = ResolveType (cu, decl_ctx_die); 3259 if (type) 3260 { 3261 clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ()); 3262 if (decl_ctx) 3263 { 3264 LinkDeclContextToDIE (decl_ctx, decl_ctx_die); 3265 if (decl_ctx) 3266 return decl_ctx; 3267 } 3268 } 3269 } 3270 break; 3271 3272 default: 3273 break; 3274 } 3275 } 3276 return m_clang_tu_decl; 3277} 3278 3279 3280const DWARFDebugInfoEntry * 3281SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 3282{ 3283 if (cu && die) 3284 { 3285 const DWARFDebugInfoEntry * const decl_die = die; 3286 3287 while (die != NULL) 3288 { 3289 // If this is the original DIE that we are searching for a declaration 3290 // for, then don't look in the cache as we don't want our own decl 3291 // context to be our decl context... 3292 if (decl_die != die) 3293 { 3294 switch (die->Tag()) 3295 { 3296 case DW_TAG_compile_unit: 3297 case DW_TAG_namespace: 3298 case DW_TAG_structure_type: 3299 case DW_TAG_union_type: 3300 case DW_TAG_class_type: 3301 return die; 3302 3303 default: 3304 break; 3305 } 3306 } 3307 3308 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET); 3309 if (die_offset != DW_INVALID_OFFSET) 3310 { 3311 DWARFCompileUnit *spec_cu = cu; 3312 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu); 3313 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die); 3314 if (spec_die_decl_ctx_die) 3315 return spec_die_decl_ctx_die; 3316 } 3317 3318 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); 3319 if (die_offset != DW_INVALID_OFFSET) 3320 { 3321 DWARFCompileUnit *abs_cu = cu; 3322 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu); 3323 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die); 3324 if (abs_die_decl_ctx_die) 3325 return abs_die_decl_ctx_die; 3326 } 3327 3328 die = die->GetParent(); 3329 } 3330 } 3331 return NULL; 3332} 3333 3334 3335 3336// This function can be used when a DIE is found that is a forward declaration 3337// DIE and we want to try and find a type that has the complete definition. 3338TypeSP 3339SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, 3340 const DWARFDebugInfoEntry *die, 3341 const ConstString &type_name) 3342{ 3343 TypeSP type_sp; 3344 3345 if (cu == NULL || die == NULL || !type_name) 3346 return type_sp; 3347 3348 DIEArray die_offsets; 3349 3350 if (m_apple_types_ap.get()) 3351 { 3352 const char *name_cstr = type_name.GetCString(); 3353 m_apple_types_ap->FindByName (name_cstr, die_offsets); 3354 } 3355 else 3356 { 3357 if (!m_indexed) 3358 Index (); 3359 3360 m_type_index.Find (type_name, die_offsets); 3361 } 3362 3363 3364 const size_t num_matches = die_offsets.size(); 3365 3366 const dw_tag_t type_tag = die->Tag(); 3367 3368 DWARFCompileUnit* type_cu = NULL; 3369 const DWARFDebugInfoEntry* type_die = NULL; 3370 if (num_matches) 3371 { 3372 DWARFDebugInfo* debug_info = DebugInfo(); 3373 for (size_t i=0; i<num_matches; ++i) 3374 { 3375 const dw_offset_t die_offset = die_offsets[i]; 3376 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu); 3377 3378 if (type_die != die && type_die->Tag() == type_tag) 3379 { 3380 // Hold off on comparing parent DIE tags until 3381 // we know what happens with stuff in namespaces 3382 // for gcc and clang... 3383 //DWARFDebugInfoEntry *parent_die = die->GetParent(); 3384 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent(); 3385 //if (parent_die->Tag() == parent_type_die->Tag()) 3386 { 3387 Type *resolved_type = ResolveType (type_cu, type_die, false); 3388 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) 3389 { 3390 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n", 3391 die->GetOffset(), 3392 curr_cu->GetOffset(), 3393 m_obj_file->GetFileSpec().GetFilename().AsCString(), 3394 type_die->GetOffset(), 3395 type_cu->GetOffset()); 3396 3397 m_die_to_type[die] = resolved_type; 3398 type_sp = GetTypeList()->FindType(resolved_type->GetID()); 3399 if (!type_sp) 3400 { 3401 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset()); 3402 } 3403 break; 3404 } 3405 } 3406 } 3407 } 3408 } 3409 return type_sp; 3410} 3411 3412TypeSP 3413SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr) 3414{ 3415 TypeSP type_sp; 3416 3417 if (type_is_new_ptr) 3418 *type_is_new_ptr = false; 3419 3420 AccessType accessibility = eAccessNone; 3421 if (die != NULL) 3422 { 3423 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 3424 if (log && dwarf_cu) 3425 { 3426 StreamString s; 3427 die->DumpLocation (this, dwarf_cu, s); 3428 log->Printf ("SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData()); 3429 3430 } 3431 3432 Type *type_ptr = m_die_to_type.lookup (die); 3433 TypeList* type_list = GetTypeList(); 3434 if (type_ptr == NULL) 3435 { 3436 ClangASTContext &ast = GetClangASTContext(); 3437 if (type_is_new_ptr) 3438 *type_is_new_ptr = true; 3439 3440 const dw_tag_t tag = die->Tag(); 3441 3442 bool is_forward_declaration = false; 3443 DWARFDebugInfoEntry::Attributes attributes; 3444 const char *type_name_cstr = NULL; 3445 ConstString type_name_const_str; 3446 Type::ResolveState resolve_state = Type::eResolveStateUnresolved; 3447 size_t byte_size = 0; 3448 bool byte_size_valid = false; 3449 Declaration decl; 3450 3451 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; 3452 clang_type_t clang_type = NULL; 3453 3454 dw_attr_t attr; 3455 3456 switch (tag) 3457 { 3458 case DW_TAG_base_type: 3459 case DW_TAG_pointer_type: 3460 case DW_TAG_reference_type: 3461 case DW_TAG_typedef: 3462 case DW_TAG_const_type: 3463 case DW_TAG_restrict_type: 3464 case DW_TAG_volatile_type: 3465 { 3466 // Set a bit that lets us know that we are currently parsing this 3467 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3468 3469 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3470 uint32_t encoding = 0; 3471 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 3472 3473 if (num_attributes > 0) 3474 { 3475 uint32_t i; 3476 for (i=0; i<num_attributes; ++i) 3477 { 3478 attr = attributes.AttributeAtIndex(i); 3479 DWARFFormValue form_value; 3480 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3481 { 3482 switch (attr) 3483 { 3484 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3485 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3486 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3487 case DW_AT_name: 3488 3489 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3490 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't 3491 // include the "&"... 3492 if (tag == DW_TAG_reference_type) 3493 { 3494 if (strchr (type_name_cstr, '&') == NULL) 3495 type_name_cstr = NULL; 3496 } 3497 if (type_name_cstr) 3498 type_name_const_str.SetCString(type_name_cstr); 3499 break; 3500 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3501 case DW_AT_encoding: encoding = form_value.Unsigned(); break; 3502 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 3503 default: 3504 case DW_AT_sibling: 3505 break; 3506 } 3507 } 3508 } 3509 } 3510 3511 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid); 3512 3513 switch (tag) 3514 { 3515 default: 3516 break; 3517 3518 case DW_TAG_base_type: 3519 resolve_state = Type::eResolveStateFull; 3520 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, 3521 encoding, 3522 byte_size * 8); 3523 break; 3524 3525 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break; 3526 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break; 3527 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break; 3528 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break; 3529 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break; 3530 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break; 3531 } 3532 3533 if (type_name_cstr != NULL && sc.comp_unit != NULL && 3534 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus)) 3535 { 3536 static ConstString g_objc_type_name_id("id"); 3537 static ConstString g_objc_type_name_Class("Class"); 3538 static ConstString g_objc_type_name_selector("SEL"); 3539 3540 if (type_name_const_str == g_objc_type_name_id) 3541 { 3542 clang_type = ast.GetBuiltInType_objc_id(); 3543 resolve_state = Type::eResolveStateFull; 3544 3545 } 3546 else if (type_name_const_str == g_objc_type_name_Class) 3547 { 3548 clang_type = ast.GetBuiltInType_objc_Class(); 3549 resolve_state = Type::eResolveStateFull; 3550 } 3551 else if (type_name_const_str == g_objc_type_name_selector) 3552 { 3553 clang_type = ast.GetBuiltInType_objc_selector(); 3554 resolve_state = Type::eResolveStateFull; 3555 } 3556 } 3557 3558 type_sp.reset( new Type (die->GetOffset(), 3559 this, 3560 type_name_const_str, 3561 byte_size, 3562 NULL, 3563 encoding_uid, 3564 encoding_data_type, 3565 &decl, 3566 clang_type, 3567 resolve_state)); 3568 3569 m_die_to_type[die] = type_sp.get(); 3570 3571// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); 3572// if (encoding_type != NULL) 3573// { 3574// if (encoding_type != DIE_IS_BEING_PARSED) 3575// type_sp->SetEncodingType(encoding_type); 3576// else 3577// m_indirect_fixups.push_back(type_sp.get()); 3578// } 3579 } 3580 break; 3581 3582 case DW_TAG_structure_type: 3583 case DW_TAG_union_type: 3584 case DW_TAG_class_type: 3585 { 3586 // Set a bit that lets us know that we are currently parsing this 3587 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3588 3589 LanguageType class_language = eLanguageTypeUnknown; 3590 //bool struct_is_class = false; 3591 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3592 if (num_attributes > 0) 3593 { 3594 uint32_t i; 3595 for (i=0; i<num_attributes; ++i) 3596 { 3597 attr = attributes.AttributeAtIndex(i); 3598 DWARFFormValue form_value; 3599 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3600 { 3601 switch (attr) 3602 { 3603 case DW_AT_decl_file: 3604 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); 3605 break; 3606 3607 case DW_AT_decl_line: 3608 decl.SetLine(form_value.Unsigned()); 3609 break; 3610 3611 case DW_AT_decl_column: 3612 decl.SetColumn(form_value.Unsigned()); 3613 break; 3614 3615 case DW_AT_name: 3616 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3617 type_name_const_str.SetCString(type_name_cstr); 3618 break; 3619 3620 case DW_AT_byte_size: 3621 byte_size = form_value.Unsigned(); 3622 byte_size_valid = true; 3623 break; 3624 3625 case DW_AT_accessibility: 3626 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 3627 break; 3628 3629 case DW_AT_declaration: 3630 is_forward_declaration = form_value.Unsigned() != 0; 3631 break; 3632 3633 case DW_AT_APPLE_runtime_class: 3634 class_language = (LanguageType)form_value.Signed(); 3635 break; 3636 3637 case DW_AT_allocated: 3638 case DW_AT_associated: 3639 case DW_AT_data_location: 3640 case DW_AT_description: 3641 case DW_AT_start_scope: 3642 case DW_AT_visibility: 3643 default: 3644 case DW_AT_sibling: 3645 break; 3646 } 3647 } 3648 } 3649 } 3650 3651 UniqueDWARFASTType unique_ast_entry; 3652 if (decl.IsValid()) 3653 { 3654 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str, 3655 this, 3656 dwarf_cu, 3657 die, 3658 decl, 3659 byte_size_valid ? byte_size : -1, 3660 unique_ast_entry)) 3661 { 3662 // We have already parsed this type or from another 3663 // compile unit. GCC loves to use the "one definition 3664 // rule" which can result in multiple definitions 3665 // of the same class over and over in each compile 3666 // unit. 3667 type_sp = unique_ast_entry.m_type_sp; 3668 if (type_sp) 3669 { 3670 m_die_to_type[die] = type_sp.get(); 3671 return type_sp; 3672 } 3673 } 3674 } 3675 3676 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3677 3678 int tag_decl_kind = -1; 3679 AccessType default_accessibility = eAccessNone; 3680 if (tag == DW_TAG_structure_type) 3681 { 3682 tag_decl_kind = clang::TTK_Struct; 3683 default_accessibility = eAccessPublic; 3684 } 3685 else if (tag == DW_TAG_union_type) 3686 { 3687 tag_decl_kind = clang::TTK_Union; 3688 default_accessibility = eAccessPublic; 3689 } 3690 else if (tag == DW_TAG_class_type) 3691 { 3692 tag_decl_kind = clang::TTK_Class; 3693 default_accessibility = eAccessPrivate; 3694 } 3695 3696 3697 if (is_forward_declaration) 3698 { 3699 // We have a forward declaration to a type and we need 3700 // to try and find a full declaration. We look in the 3701 // current type index just in case we have a forward 3702 // declaration followed by an actual declarations in the 3703 // DWARF. If this fails, we need to look elsewhere... 3704 3705 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 3706 3707 if (!type_sp && m_debug_map_symfile) 3708 { 3709 // We weren't able to find a full declaration in 3710 // this DWARF, see if we have a declaration anywhere 3711 // else... 3712 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 3713 } 3714 3715 if (type_sp) 3716 { 3717 // We found a real definition for this type elsewhere 3718 // so lets use it and cache the fact that we found 3719 // a complete type for this die 3720 m_die_to_type[die] = type_sp.get(); 3721 return type_sp; 3722 } 3723 } 3724 assert (tag_decl_kind != -1); 3725 bool clang_type_was_created = false; 3726 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 3727 if (clang_type == NULL) 3728 { 3729 clang_type_was_created = true; 3730 clang_type = ast.CreateRecordType (type_name_cstr, 3731 tag_decl_kind, 3732 GetClangDeclContextContainingDIE (dwarf_cu, die), 3733 class_language); 3734 } 3735 3736 // Store a forward declaration to this class type in case any 3737 // parameters in any class methods need it for the clang 3738 // types for function prototypes. 3739 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 3740 type_sp.reset (new Type (die->GetOffset(), 3741 this, 3742 type_name_const_str, 3743 byte_size, 3744 NULL, 3745 LLDB_INVALID_UID, 3746 Type::eEncodingIsUID, 3747 &decl, 3748 clang_type, 3749 Type::eResolveStateForward)); 3750 3751 3752 // Add our type to the unique type map so we don't 3753 // end up creating many copies of the same type over 3754 // and over in the ASTContext for our module 3755 unique_ast_entry.m_type_sp = type_sp; 3756 unique_ast_entry.m_symfile = this; 3757 unique_ast_entry.m_cu = dwarf_cu; 3758 unique_ast_entry.m_die = die; 3759 unique_ast_entry.m_declaration = decl; 3760 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, 3761 unique_ast_entry); 3762 3763 if (die->HasChildren() == false && is_forward_declaration == false) 3764 { 3765 // No children for this struct/union/class, lets finish it 3766 ast.StartTagDeclarationDefinition (clang_type); 3767 ast.CompleteTagDeclarationDefinition (clang_type); 3768 } 3769 else if (clang_type_was_created) 3770 { 3771 // Leave this as a forward declaration until we need 3772 // to know the details of the type. lldb_private::Type 3773 // will automatically call the SymbolFile virtual function 3774 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" 3775 // When the definition needs to be defined. 3776 m_forward_decl_die_to_clang_type[die] = clang_type; 3777 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; 3778 ClangASTContext::SetHasExternalStorage (clang_type, true); 3779 } 3780 } 3781 break; 3782 3783 case DW_TAG_enumeration_type: 3784 { 3785 // Set a bit that lets us know that we are currently parsing this 3786 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3787 3788 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; 3789 3790 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3791 if (num_attributes > 0) 3792 { 3793 uint32_t i; 3794 3795 for (i=0; i<num_attributes; ++i) 3796 { 3797 attr = attributes.AttributeAtIndex(i); 3798 DWARFFormValue form_value; 3799 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3800 { 3801 switch (attr) 3802 { 3803 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3804 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3805 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3806 case DW_AT_name: 3807 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3808 type_name_const_str.SetCString(type_name_cstr); 3809 break; 3810 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 3811 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3812 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3813 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3814 case DW_AT_allocated: 3815 case DW_AT_associated: 3816 case DW_AT_bit_stride: 3817 case DW_AT_byte_stride: 3818 case DW_AT_data_location: 3819 case DW_AT_description: 3820 case DW_AT_start_scope: 3821 case DW_AT_visibility: 3822 case DW_AT_specification: 3823 case DW_AT_abstract_origin: 3824 case DW_AT_sibling: 3825 break; 3826 } 3827 } 3828 } 3829 3830 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3831 3832 clang_type_t enumerator_clang_type = NULL; 3833 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 3834 if (clang_type == NULL) 3835 { 3836 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, 3837 DW_ATE_signed, 3838 byte_size * 8); 3839 clang_type = ast.CreateEnumerationType (type_name_cstr, 3840 GetClangDeclContextContainingDIE (dwarf_cu, die), 3841 decl, 3842 enumerator_clang_type); 3843 } 3844 else 3845 { 3846 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type); 3847 assert (enumerator_clang_type != NULL); 3848 } 3849 3850 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 3851 3852 type_sp.reset( new Type (die->GetOffset(), 3853 this, 3854 type_name_const_str, 3855 byte_size, 3856 NULL, 3857 encoding_uid, 3858 Type::eEncodingIsUID, 3859 &decl, 3860 clang_type, 3861 Type::eResolveStateForward)); 3862 3863#if LEAVE_ENUMS_FORWARD_DECLARED 3864 // Leave this as a forward declaration until we need 3865 // to know the details of the type. lldb_private::Type 3866 // will automatically call the SymbolFile virtual function 3867 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" 3868 // When the definition needs to be defined. 3869 m_forward_decl_die_to_clang_type[die] = clang_type; 3870 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; 3871 ClangASTContext::SetHasExternalStorage (clang_type, true); 3872#else 3873 ast.StartTagDeclarationDefinition (clang_type); 3874 if (die->HasChildren()) 3875 { 3876 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu)); 3877 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die); 3878 } 3879 ast.CompleteTagDeclarationDefinition (clang_type); 3880#endif 3881 } 3882 } 3883 break; 3884 3885 case DW_TAG_inlined_subroutine: 3886 case DW_TAG_subprogram: 3887 case DW_TAG_subroutine_type: 3888 { 3889 // Set a bit that lets us know that we are currently parsing this 3890 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3891 3892 const char *mangled = NULL; 3893 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 3894 bool is_variadic = false; 3895 bool is_inline = false; 3896 bool is_static = false; 3897 bool is_virtual = false; 3898 bool is_explicit = false; 3899 dw_offset_t specification_die_offset = DW_INVALID_OFFSET; 3900 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET; 3901 3902 unsigned type_quals = 0; 3903 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern 3904 3905 3906 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3907 if (num_attributes > 0) 3908 { 3909 uint32_t i; 3910 for (i=0; i<num_attributes; ++i) 3911 { 3912 attr = attributes.AttributeAtIndex(i); 3913 DWARFFormValue form_value; 3914 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3915 { 3916 switch (attr) 3917 { 3918 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3919 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3920 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3921 case DW_AT_name: 3922 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3923 type_name_const_str.SetCString(type_name_cstr); 3924 break; 3925 3926 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 3927 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3928 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3929 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3930 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break; 3931 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 3932 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break; 3933 3934 case DW_AT_external: 3935 if (form_value.Unsigned()) 3936 { 3937 if (storage == clang::SC_None) 3938 storage = clang::SC_Extern; 3939 else 3940 storage = clang::SC_PrivateExtern; 3941 } 3942 break; 3943 3944 case DW_AT_specification: 3945 specification_die_offset = form_value.Reference(dwarf_cu); 3946 break; 3947 3948 case DW_AT_abstract_origin: 3949 abstract_origin_die_offset = form_value.Reference(dwarf_cu); 3950 break; 3951 3952 3953 case DW_AT_allocated: 3954 case DW_AT_associated: 3955 case DW_AT_address_class: 3956 case DW_AT_artificial: 3957 case DW_AT_calling_convention: 3958 case DW_AT_data_location: 3959 case DW_AT_elemental: 3960 case DW_AT_entry_pc: 3961 case DW_AT_frame_base: 3962 case DW_AT_high_pc: 3963 case DW_AT_low_pc: 3964 case DW_AT_object_pointer: 3965 case DW_AT_prototyped: 3966 case DW_AT_pure: 3967 case DW_AT_ranges: 3968 case DW_AT_recursive: 3969 case DW_AT_return_addr: 3970 case DW_AT_segment: 3971 case DW_AT_start_scope: 3972 case DW_AT_static_link: 3973 case DW_AT_trampoline: 3974 case DW_AT_visibility: 3975 case DW_AT_vtable_elem_location: 3976 case DW_AT_description: 3977 case DW_AT_sibling: 3978 break; 3979 } 3980 } 3981 } 3982 } 3983 3984 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3985 3986 clang_type_t return_clang_type = NULL; 3987 Type *func_type = NULL; 3988 3989 if (type_die_offset != DW_INVALID_OFFSET) 3990 func_type = ResolveTypeUID(type_die_offset); 3991 3992 if (func_type) 3993 return_clang_type = func_type->GetClangLayoutType(); 3994 else 3995 return_clang_type = ast.GetBuiltInType_void(); 3996 3997 3998 std::vector<clang_type_t> function_param_types; 3999 std::vector<clang::ParmVarDecl*> function_param_decls; 4000 4001 // Parse the function children for the parameters 4002 4003 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die); 4004 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind(); 4005 4006 const bool is_cxx_method = containing_decl_kind == clang::Decl::CXXRecord; 4007 // Start off static. This will be set to false in ParseChildParameters(...) 4008 // if we find a "this" paramters as the first parameter 4009 if (is_cxx_method) 4010 is_static = true; 4011 4012 if (die->HasChildren()) 4013 { 4014 bool skip_artificial = true; 4015 ParseChildParameters (sc, 4016 containing_decl_ctx, 4017 type_sp, 4018 dwarf_cu, 4019 die, 4020 skip_artificial, 4021 is_static, 4022 type_list, 4023 function_param_types, 4024 function_param_decls, 4025 type_quals); 4026 } 4027 4028 // clang_type will get the function prototype clang type after this call 4029 clang_type = ast.CreateFunctionType (return_clang_type, 4030 &function_param_types[0], 4031 function_param_types.size(), 4032 is_variadic, 4033 type_quals); 4034 4035 if (type_name_cstr) 4036 { 4037 bool type_handled = false; 4038 if (tag == DW_TAG_subprogram) 4039 { 4040 if (ObjCLanguageRuntime::IsPossibleObjCMethodName (type_name_cstr)) 4041 { 4042 // We need to find the DW_TAG_class_type or 4043 // DW_TAG_struct_type by name so we can add this 4044 // as a member function of the class. 4045 const char *class_name_start = type_name_cstr + 2; 4046 const char *class_name_end = ::strchr (class_name_start, ' '); 4047 SymbolContext empty_sc; 4048 clang_type_t class_opaque_type = NULL; 4049 if (class_name_start < class_name_end) 4050 { 4051 ConstString class_name (class_name_start, class_name_end - class_name_start); 4052 TypeList types; 4053 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types); 4054 if (match_count > 0) 4055 { 4056 for (uint32_t i=0; i<match_count; ++i) 4057 { 4058 Type *type = types.GetTypeAtIndex (i).get(); 4059 clang_type_t type_clang_forward_type = type->GetClangForwardType(); 4060 if (ClangASTContext::IsObjCClassType (type_clang_forward_type)) 4061 { 4062 class_opaque_type = type_clang_forward_type; 4063 break; 4064 } 4065 } 4066 } 4067 } 4068 4069 if (class_opaque_type) 4070 { 4071 // If accessibility isn't set to anything valid, assume public for 4072 // now... 4073 if (accessibility == eAccessNone) 4074 accessibility = eAccessPublic; 4075 4076 clang::ObjCMethodDecl *objc_method_decl; 4077 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type, 4078 type_name_cstr, 4079 clang_type, 4080 accessibility); 4081 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die); 4082 type_handled = objc_method_decl != NULL; 4083 } 4084 } 4085 else if (is_cxx_method) 4086 { 4087 // Look at the parent of this DIE and see if is is 4088 // a class or struct and see if this is actually a 4089 // C++ method 4090 Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]); 4091 if (class_type) 4092 { 4093 if (specification_die_offset != DW_INVALID_OFFSET) 4094 { 4095 // We have a specification which we are going to base our function 4096 // prototype off of, so we need this type to be completed so that the 4097 // m_die_to_decl_ctx for the method in the specification has a valid 4098 // clang decl context. 4099 class_type->GetClangFullType(); 4100 // If we have a specification, then the function type should have been 4101 // made with the specification and not with this die. 4102 DWARFCompileUnitSP spec_cu_sp; 4103 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp); 4104 clang::DeclContext *spec_clang_decl_ctx = GetCachedClangDeclContextForDIE (spec_die); 4105 if (spec_clang_decl_ctx) 4106 { 4107 LinkDeclContextToDIE(spec_clang_decl_ctx, die); 4108 } 4109 else 4110 { 4111 ReportWarning ("0x%8.8x: DW_AT_specification(0x%8.8x) has no decl\n", 4112 die->GetOffset(), 4113 specification_die_offset); 4114 } 4115 type_handled = true; 4116 } 4117 else if (abstract_origin_die_offset != DW_INVALID_OFFSET) 4118 { 4119 // We have a specification which we are going to base our function 4120 // prototype off of, so we need this type to be completed so that the 4121 // m_die_to_decl_ctx for the method in the abstract origin has a valid 4122 // clang decl context. 4123 class_type->GetClangFullType(); 4124 4125 DWARFCompileUnitSP abs_cu_sp; 4126 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp); 4127 clang::DeclContext *abs_clang_decl_ctx = GetCachedClangDeclContextForDIE (abs_die); 4128 if (abs_clang_decl_ctx) 4129 { 4130 LinkDeclContextToDIE (abs_clang_decl_ctx, die); 4131 } 4132 else 4133 { 4134 ReportWarning ("0x%8.8x: DW_AT_abstract_origin(0x%8.8x) has no decl\n", 4135 die->GetOffset(), 4136 abstract_origin_die_offset); 4137 } 4138 type_handled = true; 4139 } 4140 else 4141 { 4142 clang_type_t class_opaque_type = class_type->GetClangForwardType(); 4143 if (ClangASTContext::IsCXXClassType (class_opaque_type)) 4144 { 4145 // Neither GCC 4.2 nor clang++ currently set a valid accessibility 4146 // in the DWARF for C++ methods... Default to public for now... 4147 if (accessibility == eAccessNone) 4148 accessibility = eAccessPublic; 4149 4150 if (!is_static && !die->HasChildren()) 4151 { 4152 // We have a C++ member function with no children (this pointer!) 4153 // and clang will get mad if we try and make a function that isn't 4154 // well formed in the DWARF, so we will just skip it... 4155 type_handled = true; 4156 } 4157 else 4158 { 4159 clang::CXXMethodDecl *cxx_method_decl; 4160 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 4161 type_name_cstr, 4162 clang_type, 4163 accessibility, 4164 is_virtual, 4165 is_static, 4166 is_inline, 4167 is_explicit); 4168 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die); 4169 4170 type_handled = cxx_method_decl != NULL; 4171 } 4172 } 4173 } 4174 } 4175 } 4176 } 4177 4178 if (!type_handled) 4179 { 4180 // We just have a function that isn't part of a class 4181 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr, 4182 clang_type, 4183 storage, 4184 is_inline); 4185 4186 // Add the decl to our DIE to decl context map 4187 assert (function_decl); 4188 LinkDeclContextToDIE(function_decl, die); 4189 if (!function_param_decls.empty()) 4190 ast.SetFunctionParameters (function_decl, 4191 &function_param_decls.front(), 4192 function_param_decls.size()); 4193 } 4194 } 4195 type_sp.reset( new Type (die->GetOffset(), 4196 this, 4197 type_name_const_str, 4198 0, 4199 NULL, 4200 LLDB_INVALID_UID, 4201 Type::eEncodingIsUID, 4202 &decl, 4203 clang_type, 4204 Type::eResolveStateFull)); 4205 assert(type_sp.get()); 4206 } 4207 break; 4208 4209 case DW_TAG_array_type: 4210 { 4211 // Set a bit that lets us know that we are currently parsing this 4212 m_die_to_type[die] = DIE_IS_BEING_PARSED; 4213 4214 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; 4215 int64_t first_index = 0; 4216 uint32_t byte_stride = 0; 4217 uint32_t bit_stride = 0; 4218 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 4219 4220 if (num_attributes > 0) 4221 { 4222 uint32_t i; 4223 for (i=0; i<num_attributes; ++i) 4224 { 4225 attr = attributes.AttributeAtIndex(i); 4226 DWARFFormValue form_value; 4227 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 4228 { 4229 switch (attr) 4230 { 4231 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 4232 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 4233 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 4234 case DW_AT_name: 4235 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 4236 type_name_const_str.SetCString(type_name_cstr); 4237 break; 4238 4239 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 4240 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 4241 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; 4242 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; 4243 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 4244 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 4245 case DW_AT_allocated: 4246 case DW_AT_associated: 4247 case DW_AT_data_location: 4248 case DW_AT_description: 4249 case DW_AT_ordering: 4250 case DW_AT_start_scope: 4251 case DW_AT_visibility: 4252 case DW_AT_specification: 4253 case DW_AT_abstract_origin: 4254 case DW_AT_sibling: 4255 break; 4256 } 4257 } 4258 } 4259 4260 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 4261 4262 Type *element_type = ResolveTypeUID(type_die_offset); 4263 4264 if (element_type) 4265 { 4266 std::vector<uint64_t> element_orders; 4267 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); 4268 // We have an array that claims to have no members, lets give it at least one member... 4269 if (element_orders.empty()) 4270 element_orders.push_back (1); 4271 if (byte_stride == 0 && bit_stride == 0) 4272 byte_stride = element_type->GetByteSize(); 4273 clang_type_t array_element_type = element_type->GetClangFullType(); 4274 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; 4275 uint64_t num_elements = 0; 4276 std::vector<uint64_t>::const_reverse_iterator pos; 4277 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); 4278 for (pos = element_orders.rbegin(); pos != end; ++pos) 4279 { 4280 num_elements = *pos; 4281 clang_type = ast.CreateArrayType (array_element_type, 4282 num_elements, 4283 num_elements * array_element_bit_stride); 4284 array_element_type = clang_type; 4285 array_element_bit_stride = array_element_bit_stride * num_elements; 4286 } 4287 ConstString empty_name; 4288 type_sp.reset( new Type (die->GetOffset(), 4289 this, 4290 empty_name, 4291 array_element_bit_stride / 8, 4292 NULL, 4293 type_die_offset, 4294 Type::eEncodingIsUID, 4295 &decl, 4296 clang_type, 4297 Type::eResolveStateFull)); 4298 type_sp->SetEncodingType (element_type); 4299 } 4300 } 4301 } 4302 break; 4303 4304 case DW_TAG_ptr_to_member_type: 4305 { 4306 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 4307 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET; 4308 4309 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 4310 4311 if (num_attributes > 0) { 4312 uint32_t i; 4313 for (i=0; i<num_attributes; ++i) 4314 { 4315 attr = attributes.AttributeAtIndex(i); 4316 DWARFFormValue form_value; 4317 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 4318 { 4319 switch (attr) 4320 { 4321 case DW_AT_type: 4322 type_die_offset = form_value.Reference(dwarf_cu); break; 4323 case DW_AT_containing_type: 4324 containing_type_die_offset = form_value.Reference(dwarf_cu); break; 4325 } 4326 } 4327 } 4328 4329 Type *pointee_type = ResolveTypeUID(type_die_offset); 4330 Type *class_type = ResolveTypeUID(containing_type_die_offset); 4331 4332 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType(); 4333 clang_type_t class_clang_type = class_type->GetClangLayoutType(); 4334 4335 clang_type = ast.CreateMemberPointerType(pointee_clang_type, 4336 class_clang_type); 4337 4338 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(), 4339 clang_type) / 8; 4340 4341 type_sp.reset( new Type (die->GetOffset(), 4342 this, 4343 type_name_const_str, 4344 byte_size, 4345 NULL, 4346 LLDB_INVALID_UID, 4347 Type::eEncodingIsUID, 4348 NULL, 4349 clang_type, 4350 Type::eResolveStateForward)); 4351 } 4352 4353 break; 4354 } 4355 default: 4356 assert(false && "Unhandled type tag!"); 4357 break; 4358 } 4359 4360 if (type_sp.get()) 4361 { 4362 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 4363 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 4364 4365 SymbolContextScope * symbol_context_scope = NULL; 4366 if (sc_parent_tag == DW_TAG_compile_unit) 4367 { 4368 symbol_context_scope = sc.comp_unit; 4369 } 4370 else if (sc.function != NULL) 4371 { 4372 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 4373 if (symbol_context_scope == NULL) 4374 symbol_context_scope = sc.function; 4375 } 4376 4377 if (symbol_context_scope != NULL) 4378 { 4379 type_sp->SetSymbolContextScope(symbol_context_scope); 4380 } 4381 4382 // We are ready to put this type into the uniqued list up at the module level 4383 type_list->Insert (type_sp); 4384 4385 m_die_to_type[die] = type_sp.get(); 4386 } 4387 } 4388 else if (type_ptr != DIE_IS_BEING_PARSED) 4389 { 4390 type_sp = type_list->FindType(type_ptr->GetID()); 4391 } 4392 } 4393 return type_sp; 4394} 4395 4396size_t 4397SymbolFileDWARF::ParseTypes 4398( 4399 const SymbolContext& sc, 4400 DWARFCompileUnit* dwarf_cu, 4401 const DWARFDebugInfoEntry *die, 4402 bool parse_siblings, 4403 bool parse_children 4404) 4405{ 4406 size_t types_added = 0; 4407 while (die != NULL) 4408 { 4409 bool type_is_new = false; 4410 if (ParseType(sc, dwarf_cu, die, &type_is_new).get()) 4411 { 4412 if (type_is_new) 4413 ++types_added; 4414 } 4415 4416 if (parse_children && die->HasChildren()) 4417 { 4418 if (die->Tag() == DW_TAG_subprogram) 4419 { 4420 SymbolContext child_sc(sc); 4421 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get(); 4422 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true); 4423 } 4424 else 4425 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true); 4426 } 4427 4428 if (parse_siblings) 4429 die = die->GetSibling(); 4430 else 4431 die = NULL; 4432 } 4433 return types_added; 4434} 4435 4436 4437size_t 4438SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 4439{ 4440 assert(sc.comp_unit && sc.function); 4441 size_t functions_added = 0; 4442 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 4443 if (dwarf_cu) 4444 { 4445 dw_offset_t function_die_offset = sc.function->GetID(); 4446 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); 4447 if (function_die) 4448 { 4449 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0); 4450 } 4451 } 4452 4453 return functions_added; 4454} 4455 4456 4457size_t 4458SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 4459{ 4460 // At least a compile unit must be valid 4461 assert(sc.comp_unit); 4462 size_t types_added = 0; 4463 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 4464 if (dwarf_cu) 4465 { 4466 if (sc.function) 4467 { 4468 dw_offset_t function_die_offset = sc.function->GetID(); 4469 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset); 4470 if (func_die && func_die->HasChildren()) 4471 { 4472 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true); 4473 } 4474 } 4475 else 4476 { 4477 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE(); 4478 if (dwarf_cu_die && dwarf_cu_die->HasChildren()) 4479 { 4480 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true); 4481 } 4482 } 4483 } 4484 4485 return types_added; 4486} 4487 4488size_t 4489SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 4490{ 4491 if (sc.comp_unit != NULL) 4492 { 4493 DWARFDebugInfo* info = DebugInfo(); 4494 if (info == NULL) 4495 return 0; 4496 4497 uint32_t cu_idx = UINT32_MAX; 4498 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get(); 4499 4500 if (dwarf_cu == NULL) 4501 return 0; 4502 4503 if (sc.function) 4504 { 4505 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); 4506 4507 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS); 4508 assert (func_lo_pc != DW_INVALID_ADDRESS); 4509 4510 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true); 4511 4512 // Let all blocks know they have parse all their variables 4513 sc.function->GetBlock (false).SetDidParseVariables (true, true); 4514 4515 return num_variables; 4516 } 4517 else if (sc.comp_unit) 4518 { 4519 uint32_t vars_added = 0; 4520 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 4521 4522 if (variables.get() == NULL) 4523 { 4524 variables.reset(new VariableList()); 4525 sc.comp_unit->SetVariableList(variables); 4526 4527 DWARFCompileUnit* match_dwarf_cu = NULL; 4528 const DWARFDebugInfoEntry* die = NULL; 4529 DIEArray die_offsets; 4530 if (m_apple_names_ap.get()) 4531 { 4532 // TODO: implement finding all items in 4533 m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), 4534 dwarf_cu->GetNextCompileUnitOffset(), 4535 die_offsets); 4536 } 4537 else 4538 { 4539 // Index if we already haven't to make sure the compile units 4540 // get indexed and make their global DIE index list 4541 if (!m_indexed) 4542 Index (); 4543 4544 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), 4545 dwarf_cu->GetNextCompileUnitOffset(), 4546 die_offsets); 4547 } 4548 4549 const size_t num_matches = die_offsets.size(); 4550 if (num_matches) 4551 { 4552 DWARFDebugInfo* debug_info = DebugInfo(); 4553 for (size_t i=0; i<num_matches; ++i) 4554 { 4555 const dw_offset_t die_offset = die_offsets[i]; 4556 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu); 4557 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS)); 4558 if (var_sp) 4559 { 4560 variables->AddVariableIfUnique (var_sp); 4561 ++vars_added; 4562 } 4563 } 4564 } 4565 } 4566 return vars_added; 4567 } 4568 } 4569 return 0; 4570} 4571 4572 4573VariableSP 4574SymbolFileDWARF::ParseVariableDIE 4575( 4576 const SymbolContext& sc, 4577 DWARFCompileUnit* dwarf_cu, 4578 const DWARFDebugInfoEntry *die, 4579 const lldb::addr_t func_low_pc 4580) 4581{ 4582 4583 VariableSP var_sp (m_die_to_variable_sp[die]); 4584 if (var_sp) 4585 return var_sp; // Already been parsed! 4586 4587 const dw_tag_t tag = die->Tag(); 4588 4589 if ((tag == DW_TAG_variable) || 4590 (tag == DW_TAG_constant) || 4591 (tag == DW_TAG_formal_parameter && sc.function)) 4592 { 4593 DWARFDebugInfoEntry::Attributes attributes; 4594 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 4595 if (num_attributes > 0) 4596 { 4597 const char *name = NULL; 4598 const char *mangled = NULL; 4599 Declaration decl; 4600 uint32_t i; 4601 Type *var_type = NULL; 4602 DWARFExpression location; 4603 bool is_external = false; 4604 bool is_artificial = false; 4605 bool location_is_const_value_data = false; 4606 AccessType accessibility = eAccessNone; 4607 4608 for (i=0; i<num_attributes; ++i) 4609 { 4610 dw_attr_t attr = attributes.AttributeAtIndex(i); 4611 DWARFFormValue form_value; 4612 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 4613 { 4614 switch (attr) 4615 { 4616 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 4617 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 4618 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 4619 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 4620 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 4621 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break; 4622 case DW_AT_external: is_external = form_value.Unsigned() != 0; break; 4623 case DW_AT_const_value: 4624 location_is_const_value_data = true; 4625 // Fall through... 4626 case DW_AT_location: 4627 { 4628 if (form_value.BlockData()) 4629 { 4630 const DataExtractor& debug_info_data = get_debug_info_data(); 4631 4632 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 4633 uint32_t block_length = form_value.Unsigned(); 4634 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length); 4635 } 4636 else 4637 { 4638 const DataExtractor& debug_loc_data = get_debug_loc_data(); 4639 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 4640 4641 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 4642 if (loc_list_length > 0) 4643 { 4644 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); 4645 assert (func_low_pc != LLDB_INVALID_ADDRESS); 4646 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress()); 4647 } 4648 } 4649 } 4650 break; 4651 4652 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 4653 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 4654 case DW_AT_declaration: 4655 case DW_AT_description: 4656 case DW_AT_endianity: 4657 case DW_AT_segment: 4658 case DW_AT_start_scope: 4659 case DW_AT_visibility: 4660 default: 4661 case DW_AT_abstract_origin: 4662 case DW_AT_sibling: 4663 case DW_AT_specification: 4664 break; 4665 } 4666 } 4667 } 4668 4669 if (location.IsValid()) 4670 { 4671 assert(var_type != DIE_IS_BEING_PARSED); 4672 4673 ValueType scope = eValueTypeInvalid; 4674 4675 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 4676 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 4677 4678 if (tag == DW_TAG_formal_parameter) 4679 scope = eValueTypeVariableArgument; 4680 else if (is_external || parent_tag == DW_TAG_compile_unit) 4681 scope = eValueTypeVariableGlobal; 4682 else 4683 scope = eValueTypeVariableLocal; 4684 4685 SymbolContextScope * symbol_context_scope = NULL; 4686 switch (parent_tag) 4687 { 4688 case DW_TAG_subprogram: 4689 case DW_TAG_inlined_subroutine: 4690 case DW_TAG_lexical_block: 4691 if (sc.function) 4692 { 4693 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 4694 if (symbol_context_scope == NULL) 4695 symbol_context_scope = sc.function; 4696 } 4697 break; 4698 4699 default: 4700 symbol_context_scope = sc.comp_unit; 4701 break; 4702 } 4703 4704 if (symbol_context_scope) 4705 { 4706 var_sp.reset (new Variable(die->GetOffset(), 4707 name, 4708 mangled, 4709 var_type, 4710 scope, 4711 symbol_context_scope, 4712 &decl, 4713 location, 4714 is_external, 4715 is_artificial)); 4716 4717 var_sp->SetLocationIsConstantValueData (location_is_const_value_data); 4718 } 4719 else 4720 { 4721 // Not ready to parse this variable yet. It might be a global 4722 // or static variable that is in a function scope and the function 4723 // in the symbol context wasn't filled in yet 4724 return var_sp; 4725 } 4726 } 4727 } 4728 // Cache var_sp even if NULL (the variable was just a specification or 4729 // was missing vital information to be able to be displayed in the debugger 4730 // (missing location due to optimization, etc)) so we don't re-parse 4731 // this DIE over and over later... 4732 m_die_to_variable_sp[die] = var_sp; 4733 } 4734 return var_sp; 4735} 4736 4737 4738const DWARFDebugInfoEntry * 4739SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 4740 dw_offset_t spec_block_die_offset, 4741 DWARFCompileUnit **result_die_cu_handle) 4742{ 4743 // Give the concrete function die specified by "func_die_offset", find the 4744 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4745 // to "spec_block_die_offset" 4746 DWARFDebugInfo* info = DebugInfo(); 4747 4748 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle); 4749 if (die) 4750 { 4751 assert (*result_die_cu_handle); 4752 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle); 4753 } 4754 return NULL; 4755} 4756 4757 4758const DWARFDebugInfoEntry * 4759SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu, 4760 const DWARFDebugInfoEntry *die, 4761 dw_offset_t spec_block_die_offset, 4762 DWARFCompileUnit **result_die_cu_handle) 4763{ 4764 if (die) 4765 { 4766 switch (die->Tag()) 4767 { 4768 case DW_TAG_subprogram: 4769 case DW_TAG_inlined_subroutine: 4770 case DW_TAG_lexical_block: 4771 { 4772 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) 4773 { 4774 *result_die_cu_handle = dwarf_cu; 4775 return die; 4776 } 4777 4778 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset) 4779 { 4780 *result_die_cu_handle = dwarf_cu; 4781 return die; 4782 } 4783 } 4784 break; 4785 } 4786 4787 // Give the concrete function die specified by "func_die_offset", find the 4788 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4789 // to "spec_block_die_offset" 4790 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling()) 4791 { 4792 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu, 4793 child_die, 4794 spec_block_die_offset, 4795 result_die_cu_handle); 4796 if (result_die) 4797 return result_die; 4798 } 4799 } 4800 4801 *result_die_cu_handle = NULL; 4802 return NULL; 4803} 4804 4805size_t 4806SymbolFileDWARF::ParseVariables 4807( 4808 const SymbolContext& sc, 4809 DWARFCompileUnit* dwarf_cu, 4810 const lldb::addr_t func_low_pc, 4811 const DWARFDebugInfoEntry *orig_die, 4812 bool parse_siblings, 4813 bool parse_children, 4814 VariableList* cc_variable_list 4815) 4816{ 4817 if (orig_die == NULL) 4818 return 0; 4819 4820 VariableListSP variable_list_sp; 4821 4822 size_t vars_added = 0; 4823 const DWARFDebugInfoEntry *die = orig_die; 4824 while (die != NULL) 4825 { 4826 dw_tag_t tag = die->Tag(); 4827 4828 // Check to see if we have already parsed this variable or constant? 4829 if (m_die_to_variable_sp[die]) 4830 { 4831 if (cc_variable_list) 4832 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]); 4833 } 4834 else 4835 { 4836 // We haven't already parsed it, lets do that now. 4837 if ((tag == DW_TAG_variable) || 4838 (tag == DW_TAG_constant) || 4839 (tag == DW_TAG_formal_parameter && sc.function)) 4840 { 4841 if (variable_list_sp.get() == NULL) 4842 { 4843 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); 4844 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 4845 switch (parent_tag) 4846 { 4847 case DW_TAG_compile_unit: 4848 if (sc.comp_unit != NULL) 4849 { 4850 variable_list_sp = sc.comp_unit->GetVariableList(false); 4851 if (variable_list_sp.get() == NULL) 4852 { 4853 variable_list_sp.reset(new VariableList()); 4854 sc.comp_unit->SetVariableList(variable_list_sp); 4855 } 4856 } 4857 else 4858 { 4859 ReportError ("parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n", 4860 sc_parent_die->GetOffset(), 4861 DW_TAG_value_to_name (parent_tag), 4862 orig_die->GetOffset(), 4863 DW_TAG_value_to_name (orig_die->Tag())); 4864 } 4865 break; 4866 4867 case DW_TAG_subprogram: 4868 case DW_TAG_inlined_subroutine: 4869 case DW_TAG_lexical_block: 4870 if (sc.function != NULL) 4871 { 4872 // Check to see if we already have parsed the variables for the given scope 4873 4874 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 4875 if (block == NULL) 4876 { 4877 // This must be a specification or abstract origin with 4878 // a concrete block couterpart in the current function. We need 4879 // to find the concrete block so we can correctly add the 4880 // variable to it 4881 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu; 4882 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(), 4883 sc_parent_die->GetOffset(), 4884 &concrete_block_die_cu); 4885 if (concrete_block_die) 4886 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset()); 4887 } 4888 4889 if (block != NULL) 4890 { 4891 const bool can_create = false; 4892 variable_list_sp = block->GetBlockVariableList (can_create); 4893 if (variable_list_sp.get() == NULL) 4894 { 4895 variable_list_sp.reset(new VariableList()); 4896 block->SetVariableList(variable_list_sp); 4897 } 4898 } 4899 } 4900 break; 4901 4902 default: 4903 ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n", 4904 orig_die->GetOffset(), 4905 DW_TAG_value_to_name (orig_die->Tag())); 4906 break; 4907 } 4908 } 4909 4910 if (variable_list_sp) 4911 { 4912 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); 4913 if (var_sp) 4914 { 4915 variable_list_sp->AddVariableIfUnique (var_sp); 4916 if (cc_variable_list) 4917 cc_variable_list->AddVariableIfUnique (var_sp); 4918 ++vars_added; 4919 } 4920 } 4921 } 4922 } 4923 4924 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 4925 4926 if (!skip_children && parse_children && die->HasChildren()) 4927 { 4928 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list); 4929 } 4930 4931 if (parse_siblings) 4932 die = die->GetSibling(); 4933 else 4934 die = NULL; 4935 } 4936 return vars_added; 4937} 4938 4939//------------------------------------------------------------------ 4940// PluginInterface protocol 4941//------------------------------------------------------------------ 4942const char * 4943SymbolFileDWARF::GetPluginName() 4944{ 4945 return "SymbolFileDWARF"; 4946} 4947 4948const char * 4949SymbolFileDWARF::GetShortPluginName() 4950{ 4951 return GetPluginNameStatic(); 4952} 4953 4954uint32_t 4955SymbolFileDWARF::GetPluginVersion() 4956{ 4957 return 1; 4958} 4959 4960void 4961SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl) 4962{ 4963 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4964 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 4965 if (clang_type) 4966 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 4967} 4968 4969void 4970SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) 4971{ 4972 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4973 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 4974 if (clang_type) 4975 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 4976} 4977 4978void 4979SymbolFileDWARF::DumpIndexes () 4980{ 4981 StreamFile s(stdout, false); 4982 4983 s.Printf ("DWARF index for (%s) '%s/%s':", 4984 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), 4985 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 4986 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 4987 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 4988 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 4989 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 4990 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 4991 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 4992 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 4993 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 4994 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 4995} 4996 4997void 4998SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, 4999 const char *name, 5000 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 5001{ 5002 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context); 5003 5004 if (iter == m_decl_ctx_to_die.end()) 5005 return; 5006 5007 const DWARFDebugInfoEntry *context_die = iter->second; 5008 5009 if (!results) 5010 return; 5011 5012 DWARFDebugInfo* info = DebugInfo(); 5013 5014 DIEArray die_offsets; 5015 5016 DWARFCompileUnit* dwarf_cu = NULL; 5017 const DWARFDebugInfoEntry* die = NULL; 5018 size_t num_matches = m_type_index.Find (ConstString(name), die_offsets); 5019 5020 if (num_matches) 5021 { 5022 for (size_t i = 0; i < num_matches; ++i) 5023 { 5024 const dw_offset_t die_offset = die_offsets[i]; 5025 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 5026 5027 if (die->GetParent() != context_die) 5028 continue; 5029 5030 Type *matching_type = ResolveType (dwarf_cu, die); 5031 5032 lldb::clang_type_t type = matching_type->GetClangFullType(); 5033 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type); 5034 5035 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr())) 5036 { 5037 clang::TagDecl *tag_decl = tag_type->getDecl(); 5038 results->push_back(tag_decl); 5039 } 5040 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr())) 5041 { 5042 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); 5043 results->push_back(typedef_decl); 5044 } 5045 } 5046 } 5047} 5048 5049void 5050SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton, 5051 const clang::DeclContext *DC, 5052 clang::DeclarationName Name, 5053 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 5054{ 5055 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 5056 5057 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results); 5058} 5059