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