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