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