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