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 "llvm/Support/Casting.h" 14 15 #include "lldb/Core/ArchSpec.h" 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/ModuleList.h" 18 #include "lldb/Core/ModuleSpec.h" 19 #include "lldb/Core/PluginManager.h" 20 #include "lldb/Core/RegularExpression.h" 21 #include "lldb/Core/Scalar.h" 22 #include "lldb/Core/Section.h" 23 #include "lldb/Core/StreamFile.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Core/Timer.h" 26 #include "lldb/Core/Value.h" 27 28 #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" 29 30 #include "lldb/Host/FileSystem.h" 31 #include "lldb/Host/Host.h" 32 33 #include "lldb/Interpreter/OptionValueFileSpecList.h" 34 #include "lldb/Interpreter/OptionValueProperties.h" 35 36 #include "lldb/Symbol/Block.h" 37 #include "lldb/Symbol/ClangASTContext.h" 38 #include "lldb/Symbol/CompilerDecl.h" 39 #include "lldb/Symbol/CompilerDeclContext.h" 40 #include "lldb/Symbol/CompileUnit.h" 41 #include "lldb/Symbol/LineTable.h" 42 #include "lldb/Symbol/ObjectFile.h" 43 #include "lldb/Symbol/SymbolVendor.h" 44 #include "lldb/Symbol/TypeSystem.h" 45 #include "lldb/Symbol/VariableList.h" 46 #include "lldb/Symbol/TypeMap.h" 47 48 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" 49 #include "Plugins/Language/ObjC/ObjCLanguage.h" 50 51 #include "lldb/Target/Language.h" 52 53 #include "DWARFASTParser.h" 54 #include "DWARFCompileUnit.h" 55 #include "DWARFDebugAbbrev.h" 56 #include "DWARFDebugAranges.h" 57 #include "DWARFDebugInfo.h" 58 #include "DWARFDebugLine.h" 59 #include "DWARFDebugPubnames.h" 60 #include "DWARFDebugRanges.h" 61 #include "DWARFDeclContext.h" 62 #include "DWARFDIECollection.h" 63 #include "DWARFFormValue.h" 64 #include "LogChannelDWARF.h" 65 #include "SymbolFileDWARFDwo.h" 66 #include "SymbolFileDWARFDebugMap.h" 67 68 #include <map> 69 70 #include <ctype.h> 71 #include <string.h> 72 73 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN 74 75 #ifdef ENABLE_DEBUG_PRINTF 76 #include <stdio.h> 77 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) 78 #else 79 #define DEBUG_PRINTF(fmt, ...) 80 #endif 81 82 using namespace lldb; 83 using namespace lldb_private; 84 85 //static inline bool 86 //child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag) 87 //{ 88 // switch (tag) 89 // { 90 // default: 91 // break; 92 // case DW_TAG_subprogram: 93 // case DW_TAG_inlined_subroutine: 94 // case DW_TAG_class_type: 95 // case DW_TAG_structure_type: 96 // case DW_TAG_union_type: 97 // return true; 98 // } 99 // return false; 100 //} 101 // 102 103 namespace { 104 105 PropertyDefinition 106 g_properties[] = 107 { 108 { "comp-dir-symlink-paths" , OptionValue::eTypeFileSpecList, true, 0 , nullptr, nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time." }, 109 { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr } 110 }; 111 112 enum 113 { 114 ePropertySymLinkPaths 115 }; 116 117 118 class PluginProperties : public Properties 119 { 120 public: 121 static ConstString 122 GetSettingName() 123 { 124 return SymbolFileDWARF::GetPluginNameStatic(); 125 } 126 127 PluginProperties() 128 { 129 m_collection_sp.reset (new OptionValueProperties(GetSettingName())); 130 m_collection_sp->Initialize(g_properties); 131 } 132 133 FileSpecList& 134 GetSymLinkPaths() 135 { 136 OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths); 137 assert(option_value); 138 return option_value->GetCurrentValue(); 139 } 140 141 }; 142 143 typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP; 144 145 static const SymbolFileDWARFPropertiesSP& 146 GetGlobalPluginProperties() 147 { 148 static const auto g_settings_sp(std::make_shared<PluginProperties>()); 149 return g_settings_sp; 150 } 151 152 } // anonymous namespace end 153 154 155 static const char* 156 removeHostnameFromPathname(const char* path_from_dwarf) 157 { 158 if (!path_from_dwarf || !path_from_dwarf[0]) 159 { 160 return path_from_dwarf; 161 } 162 163 const char *colon_pos = strchr(path_from_dwarf, ':'); 164 if (nullptr == colon_pos) 165 { 166 return path_from_dwarf; 167 } 168 169 const char *slash_pos = strchr(path_from_dwarf, '/'); 170 if (slash_pos && (slash_pos < colon_pos)) 171 { 172 return path_from_dwarf; 173 } 174 175 // check whether we have a windows path, and so the first character 176 // is a drive-letter not a hostname. 177 if ( 178 colon_pos == path_from_dwarf + 1 && 179 isalpha(*path_from_dwarf) && 180 strlen(path_from_dwarf) > 2 && 181 '\\' == path_from_dwarf[2]) 182 { 183 return path_from_dwarf; 184 } 185 186 return colon_pos + 1; 187 } 188 189 static const char* 190 resolveCompDir(const char* path_from_dwarf) 191 { 192 if (!path_from_dwarf) 193 return nullptr; 194 195 // DWARF2/3 suggests the form hostname:pathname for compilation directory. 196 // Remove the host part if present. 197 const char* local_path = removeHostnameFromPathname(path_from_dwarf); 198 if (!local_path) 199 return nullptr; 200 201 bool is_symlink = false; 202 FileSpec local_path_spec(local_path, false); 203 const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths(); 204 for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i) 205 is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true); 206 207 if (!is_symlink) 208 return local_path; 209 210 if (!local_path_spec.IsSymbolicLink()) 211 return local_path; 212 213 FileSpec resolved_local_path_spec; 214 const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec); 215 if (error.Success()) 216 return resolved_local_path_spec.GetCString(); 217 218 return nullptr; 219 } 220 221 222 void 223 SymbolFileDWARF::Initialize() 224 { 225 LogChannelDWARF::Initialize(); 226 PluginManager::RegisterPlugin (GetPluginNameStatic(), 227 GetPluginDescriptionStatic(), 228 CreateInstance, 229 DebuggerInitialize); 230 } 231 232 void 233 SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) 234 { 235 if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName())) 236 { 237 const bool is_global_setting = true; 238 PluginManager::CreateSettingForSymbolFilePlugin(debugger, 239 GetGlobalPluginProperties()->GetValueProperties(), 240 ConstString ("Properties for the dwarf symbol-file plug-in."), 241 is_global_setting); 242 } 243 } 244 245 void 246 SymbolFileDWARF::Terminate() 247 { 248 PluginManager::UnregisterPlugin (CreateInstance); 249 LogChannelDWARF::Initialize(); 250 } 251 252 253 lldb_private::ConstString 254 SymbolFileDWARF::GetPluginNameStatic() 255 { 256 static ConstString g_name("dwarf"); 257 return g_name; 258 } 259 260 const char * 261 SymbolFileDWARF::GetPluginDescriptionStatic() 262 { 263 return "DWARF and DWARF3 debug symbol file reader."; 264 } 265 266 267 SymbolFile* 268 SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) 269 { 270 return new SymbolFileDWARF(obj_file); 271 } 272 273 TypeList * 274 SymbolFileDWARF::GetTypeList () 275 { 276 if (GetDebugMapSymfile ()) 277 return m_debug_map_symfile->GetTypeList(); 278 return m_obj_file->GetModule()->GetTypeList(); 279 280 } 281 void 282 SymbolFileDWARF::GetTypes (const DWARFDIE &die, 283 dw_offset_t min_die_offset, 284 dw_offset_t max_die_offset, 285 uint32_t type_mask, 286 TypeSet &type_set) 287 { 288 if (die) 289 { 290 const dw_offset_t die_offset = die.GetOffset(); 291 292 if (die_offset >= max_die_offset) 293 return; 294 295 if (die_offset >= min_die_offset) 296 { 297 const dw_tag_t tag = die.Tag(); 298 299 bool add_type = false; 300 301 switch (tag) 302 { 303 case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break; 304 case DW_TAG_unspecified_type: 305 case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break; 306 case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break; 307 case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break; 308 case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break; 309 case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break; 310 case DW_TAG_subroutine_type: 311 case DW_TAG_subprogram: 312 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break; 313 case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break; 314 case DW_TAG_rvalue_reference_type: 315 case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break; 316 case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break; 317 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break; 318 } 319 320 if (add_type) 321 { 322 const bool assert_not_being_parsed = true; 323 Type *type = ResolveTypeUID (die, assert_not_being_parsed); 324 if (type) 325 { 326 if (type_set.find(type) == type_set.end()) 327 type_set.insert(type); 328 } 329 } 330 } 331 332 for (DWARFDIE child_die = die.GetFirstChild(); 333 child_die.IsValid(); 334 child_die = child_die.GetSibling()) 335 { 336 GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set); 337 } 338 } 339 } 340 341 size_t 342 SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope, 343 uint32_t type_mask, 344 TypeList &type_list) 345 346 { 347 TypeSet type_set; 348 349 CompileUnit *comp_unit = NULL; 350 DWARFCompileUnit* dwarf_cu = NULL; 351 if (sc_scope) 352 comp_unit = sc_scope->CalculateSymbolContextCompileUnit(); 353 354 if (comp_unit) 355 { 356 dwarf_cu = GetDWARFCompileUnit(comp_unit); 357 if (dwarf_cu == 0) 358 return 0; 359 GetTypes (dwarf_cu->DIE(), 360 dwarf_cu->GetOffset(), 361 dwarf_cu->GetNextCompileUnitOffset(), 362 type_mask, 363 type_set); 364 } 365 else 366 { 367 DWARFDebugInfo* info = DebugInfo(); 368 if (info) 369 { 370 const size_t num_cus = info->GetNumCompileUnits(); 371 for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx) 372 { 373 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); 374 if (dwarf_cu) 375 { 376 GetTypes (dwarf_cu->DIE(), 377 0, 378 UINT32_MAX, 379 type_mask, 380 type_set); 381 } 382 } 383 } 384 } 385 386 std::set<CompilerType> compiler_type_set; 387 size_t num_types_added = 0; 388 for (Type *type : type_set) 389 { 390 CompilerType compiler_type = type->GetForwardCompilerType (); 391 if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) 392 { 393 compiler_type_set.insert(compiler_type); 394 type_list.Insert (type->shared_from_this()); 395 ++num_types_added; 396 } 397 } 398 return num_types_added; 399 } 400 401 402 //---------------------------------------------------------------------- 403 // Gets the first parent that is a lexical block, function or inlined 404 // subroutine, or compile unit. 405 //---------------------------------------------------------------------- 406 DWARFDIE 407 SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) 408 { 409 DWARFDIE die; 410 for (die = child_die.GetParent(); die; die = die.GetParent()) 411 { 412 dw_tag_t tag = die.Tag(); 413 414 switch (tag) 415 { 416 case DW_TAG_compile_unit: 417 case DW_TAG_subprogram: 418 case DW_TAG_inlined_subroutine: 419 case DW_TAG_lexical_block: 420 return die; 421 } 422 } 423 return DWARFDIE(); 424 } 425 426 427 SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : 428 SymbolFile (objfile), 429 UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID 430 m_debug_map_module_wp (), 431 m_debug_map_symfile (NULL), 432 m_flags(), 433 m_data_debug_abbrev (), 434 m_data_debug_aranges (), 435 m_data_debug_frame (), 436 m_data_debug_info (), 437 m_data_debug_line (), 438 m_data_debug_loc (), 439 m_data_debug_ranges (), 440 m_data_debug_str (), 441 m_data_apple_names (), 442 m_data_apple_types (), 443 m_data_apple_namespaces (), 444 m_abbr(), 445 m_info(), 446 m_line(), 447 m_apple_names_ap (), 448 m_apple_types_ap (), 449 m_apple_namespaces_ap (), 450 m_apple_objc_ap (), 451 m_function_basename_index(), 452 m_function_fullname_index(), 453 m_function_method_index(), 454 m_function_selector_index(), 455 m_objc_class_selectors_index(), 456 m_global_index(), 457 m_type_index(), 458 m_namespace_index(), 459 m_indexed (false), 460 m_using_apple_tables (false), 461 m_fetched_external_modules (false), 462 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate), 463 m_ranges(), 464 m_unique_ast_type_map () 465 { 466 } 467 468 SymbolFileDWARF::~SymbolFileDWARF() 469 { 470 } 471 472 static const ConstString & 473 GetDWARFMachOSegmentName () 474 { 475 static ConstString g_dwarf_section_name ("__DWARF"); 476 return g_dwarf_section_name; 477 } 478 479 UniqueDWARFASTTypeMap & 480 SymbolFileDWARF::GetUniqueDWARFASTTypeMap () 481 { 482 if (GetDebugMapSymfile ()) 483 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap (); 484 return m_unique_ast_type_map; 485 } 486 487 TypeSystem * 488 SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language) 489 { 490 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile (); 491 TypeSystem *type_system; 492 if (debug_map_symfile) 493 { 494 type_system = debug_map_symfile->GetTypeSystemForLanguage(language); 495 } 496 else 497 { 498 type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language); 499 if (type_system) 500 type_system->SetSymbolFile(this); 501 } 502 return type_system; 503 } 504 505 void 506 SymbolFileDWARF::InitializeObject() 507 { 508 ModuleSP module_sp (m_obj_file->GetModule()); 509 if (module_sp) 510 { 511 const SectionList *section_list = module_sp->GetSectionList(); 512 513 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 514 515 // Memory map the DWARF mach-o segment so we have everything mmap'ed 516 // to keep our heap memory usage down. 517 if (section) 518 m_obj_file->MemoryMapSectionData(section, m_dwarf_data); 519 } 520 get_apple_names_data(); 521 if (m_data_apple_names.GetByteSize() > 0) 522 { 523 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names")); 524 if (m_apple_names_ap->IsValid()) 525 m_using_apple_tables = true; 526 else 527 m_apple_names_ap.reset(); 528 } 529 get_apple_types_data(); 530 if (m_data_apple_types.GetByteSize() > 0) 531 { 532 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types")); 533 if (m_apple_types_ap->IsValid()) 534 m_using_apple_tables = true; 535 else 536 m_apple_types_ap.reset(); 537 } 538 539 get_apple_namespaces_data(); 540 if (m_data_apple_namespaces.GetByteSize() > 0) 541 { 542 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces")); 543 if (m_apple_namespaces_ap->IsValid()) 544 m_using_apple_tables = true; 545 else 546 m_apple_namespaces_ap.reset(); 547 } 548 549 get_apple_objc_data(); 550 if (m_data_apple_objc.GetByteSize() > 0) 551 { 552 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc")); 553 if (m_apple_objc_ap->IsValid()) 554 m_using_apple_tables = true; 555 else 556 m_apple_objc_ap.reset(); 557 } 558 } 559 560 bool 561 SymbolFileDWARF::SupportedVersion(uint16_t version) 562 { 563 return version == 2 || version == 3 || version == 4; 564 } 565 566 uint32_t 567 SymbolFileDWARF::CalculateAbilities () 568 { 569 uint32_t abilities = 0; 570 if (m_obj_file != NULL) 571 { 572 const Section* section = NULL; 573 const SectionList *section_list = m_obj_file->GetSectionList(); 574 if (section_list == NULL) 575 return 0; 576 577 uint64_t debug_abbrev_file_size = 0; 578 uint64_t debug_info_file_size = 0; 579 uint64_t debug_line_file_size = 0; 580 581 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 582 583 if (section) 584 section_list = §ion->GetChildren (); 585 586 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get(); 587 if (section != NULL) 588 { 589 debug_info_file_size = section->GetFileSize(); 590 591 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get(); 592 if (section) 593 debug_abbrev_file_size = section->GetFileSize(); 594 else 595 m_flags.Set (flagsGotDebugAbbrevData); 596 597 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get(); 598 if (!section) 599 m_flags.Set (flagsGotDebugArangesData); 600 601 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get(); 602 if (!section) 603 m_flags.Set (flagsGotDebugFrameData); 604 605 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get(); 606 if (section) 607 debug_line_file_size = section->GetFileSize(); 608 else 609 m_flags.Set (flagsGotDebugLineData); 610 611 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get(); 612 if (!section) 613 m_flags.Set (flagsGotDebugLocData); 614 615 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get(); 616 if (!section) 617 m_flags.Set (flagsGotDebugMacInfoData); 618 619 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get(); 620 if (!section) 621 m_flags.Set (flagsGotDebugPubNamesData); 622 623 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get(); 624 if (!section) 625 m_flags.Set (flagsGotDebugPubTypesData); 626 627 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get(); 628 if (!section) 629 m_flags.Set (flagsGotDebugRangesData); 630 631 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get(); 632 if (!section) 633 m_flags.Set (flagsGotDebugStrData); 634 } 635 else 636 { 637 const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString(); 638 if (symfile_dir_cstr) 639 { 640 if (strcasestr(symfile_dir_cstr, ".dsym")) 641 { 642 if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) 643 { 644 // We have a dSYM file that didn't have a any debug info. 645 // If the string table has a size of 1, then it was made from 646 // an executable with no debug info, or from an executable that 647 // was stripped. 648 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get(); 649 if (section && section->GetFileSize() == 1) 650 { 651 m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info."); 652 } 653 } 654 } 655 } 656 } 657 658 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) 659 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; 660 661 if (debug_line_file_size > 0) 662 abilities |= LineTables; 663 } 664 return abilities; 665 } 666 667 const DWARFDataExtractor& 668 SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data) 669 { 670 if (m_flags.IsClear (got_flag)) 671 { 672 ModuleSP module_sp (m_obj_file->GetModule()); 673 m_flags.Set (got_flag); 674 const SectionList *section_list = module_sp->GetSectionList(); 675 if (section_list) 676 { 677 SectionSP section_sp (section_list->FindSectionByType(sect_type, true)); 678 if (section_sp) 679 { 680 // See if we memory mapped the DWARF segment? 681 if (m_dwarf_data.GetByteSize()) 682 { 683 data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize()); 684 } 685 else 686 { 687 if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0) 688 data.Clear(); 689 } 690 } 691 } 692 } 693 return data; 694 } 695 696 const DWARFDataExtractor& 697 SymbolFileDWARF::get_debug_abbrev_data() 698 { 699 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); 700 } 701 702 const DWARFDataExtractor& 703 SymbolFileDWARF::get_debug_addr_data() 704 { 705 return GetCachedSectionData (flagsGotDebugAddrData, eSectionTypeDWARFDebugAddr, m_data_debug_addr); 706 } 707 708 const DWARFDataExtractor& 709 SymbolFileDWARF::get_debug_aranges_data() 710 { 711 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges); 712 } 713 714 const DWARFDataExtractor& 715 SymbolFileDWARF::get_debug_frame_data() 716 { 717 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); 718 } 719 720 const DWARFDataExtractor& 721 SymbolFileDWARF::get_debug_info_data() 722 { 723 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info); 724 } 725 726 const DWARFDataExtractor& 727 SymbolFileDWARF::get_debug_line_data() 728 { 729 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line); 730 } 731 732 const DWARFDataExtractor& 733 SymbolFileDWARF::get_debug_loc_data() 734 { 735 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc); 736 } 737 738 const DWARFDataExtractor& 739 SymbolFileDWARF::get_debug_ranges_data() 740 { 741 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges); 742 } 743 744 const DWARFDataExtractor& 745 SymbolFileDWARF::get_debug_str_data() 746 { 747 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str); 748 } 749 750 const DWARFDataExtractor& 751 SymbolFileDWARF::get_debug_str_offsets_data() 752 { 753 return GetCachedSectionData (flagsGotDebugStrOffsetsData, eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets); 754 } 755 756 const DWARFDataExtractor& 757 SymbolFileDWARF::get_apple_names_data() 758 { 759 return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names); 760 } 761 762 const DWARFDataExtractor& 763 SymbolFileDWARF::get_apple_types_data() 764 { 765 return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types); 766 } 767 768 const DWARFDataExtractor& 769 SymbolFileDWARF::get_apple_namespaces_data() 770 { 771 return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces); 772 } 773 774 const DWARFDataExtractor& 775 SymbolFileDWARF::get_apple_objc_data() 776 { 777 return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc); 778 } 779 780 781 DWARFDebugAbbrev* 782 SymbolFileDWARF::DebugAbbrev() 783 { 784 if (m_abbr.get() == NULL) 785 { 786 const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data(); 787 if (debug_abbrev_data.GetByteSize() > 0) 788 { 789 m_abbr.reset(new DWARFDebugAbbrev()); 790 if (m_abbr.get()) 791 m_abbr->Parse(debug_abbrev_data); 792 } 793 } 794 return m_abbr.get(); 795 } 796 797 const DWARFDebugAbbrev* 798 SymbolFileDWARF::DebugAbbrev() const 799 { 800 return m_abbr.get(); 801 } 802 803 804 DWARFDebugInfo* 805 SymbolFileDWARF::DebugInfo() 806 { 807 if (m_info.get() == NULL) 808 { 809 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", 810 __PRETTY_FUNCTION__, static_cast<void*>(this)); 811 if (get_debug_info_data().GetByteSize() > 0) 812 { 813 m_info.reset(new DWARFDebugInfo()); 814 if (m_info.get()) 815 { 816 m_info->SetDwarfData(this); 817 } 818 } 819 } 820 return m_info.get(); 821 } 822 823 const DWARFDebugInfo* 824 SymbolFileDWARF::DebugInfo() const 825 { 826 return m_info.get(); 827 } 828 829 DWARFCompileUnit* 830 SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) 831 { 832 if (!comp_unit) 833 return nullptr; 834 835 DWARFDebugInfo* info = DebugInfo(); 836 if (info) 837 { 838 if (GetDebugMapSymfile ()) 839 { 840 // The debug map symbol file made the compile units for this DWARF 841 // file which is .o file with DWARF in it, and we should have 842 // only 1 compile unit which is at offset zero in the DWARF. 843 // TODO: modify to support LTO .o files where each .o file might 844 // have multiple DW_TAG_compile_unit tags. 845 846 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0); 847 if (dwarf_cu && dwarf_cu->GetUserData() == NULL) 848 dwarf_cu->SetUserData(comp_unit); 849 return dwarf_cu; 850 } 851 else 852 { 853 // Just a normal DWARF file whose user ID for the compile unit is 854 // the DWARF offset itself 855 856 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()); 857 if (dwarf_cu && dwarf_cu->GetUserData() == NULL) 858 dwarf_cu->SetUserData(comp_unit); 859 return dwarf_cu; 860 861 } 862 } 863 return NULL; 864 } 865 866 867 DWARFDebugRanges* 868 SymbolFileDWARF::DebugRanges() 869 { 870 if (m_ranges.get() == NULL) 871 { 872 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", 873 __PRETTY_FUNCTION__, static_cast<void*>(this)); 874 if (get_debug_ranges_data().GetByteSize() > 0) 875 { 876 m_ranges.reset(new DWARFDebugRanges()); 877 if (m_ranges.get()) 878 m_ranges->Extract(this); 879 } 880 } 881 return m_ranges.get(); 882 } 883 884 const DWARFDebugRanges* 885 SymbolFileDWARF::DebugRanges() const 886 { 887 return m_ranges.get(); 888 } 889 890 lldb::CompUnitSP 891 SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) 892 { 893 CompUnitSP cu_sp; 894 if (dwarf_cu) 895 { 896 CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData(); 897 if (comp_unit) 898 { 899 // We already parsed this compile unit, had out a shared pointer to it 900 cu_sp = comp_unit->shared_from_this(); 901 } 902 else 903 { 904 if (dwarf_cu->GetSymbolFileDWARF() != this) 905 { 906 return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx); 907 } 908 else if (GetDebugMapSymfile ()) 909 { 910 // Let the debug map create the compile unit 911 cu_sp = m_debug_map_symfile->GetCompileUnit(this); 912 dwarf_cu->SetUserData(cu_sp.get()); 913 } 914 else 915 { 916 ModuleSP module_sp (m_obj_file->GetModule()); 917 if (module_sp) 918 { 919 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly (); 920 if (cu_die) 921 { 922 FileSpec cu_file_spec{cu_die.GetName(), false}; 923 if (cu_file_spec) 924 { 925 // If we have a full path to the compile unit, we don't need to resolve 926 // the file. This can be expensive e.g. when the source files are NFS mounted. 927 if (cu_file_spec.IsRelative()) 928 { 929 const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)}; 930 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir)); 931 } 932 933 std::string remapped_file; 934 if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file)) 935 cu_file_spec.SetFile(remapped_file, false); 936 } 937 938 LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); 939 940 bool is_optimized = dwarf_cu->GetIsOptimized (); 941 cu_sp.reset(new CompileUnit (module_sp, 942 dwarf_cu, 943 cu_file_spec, 944 dwarf_cu->GetID(), 945 cu_language, 946 is_optimized)); 947 if (cu_sp) 948 { 949 // If we just created a compile unit with an invalid file spec, try and get the 950 // first entry in the supports files from the line table as that should be the 951 // compile unit. 952 if (!cu_file_spec) 953 { 954 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1); 955 if (cu_file_spec) 956 { 957 (FileSpec &)(*cu_sp) = cu_file_spec; 958 // Also fix the invalid file spec which was copied from the compile unit. 959 cu_sp->GetSupportFiles().Replace(0, cu_file_spec); 960 } 961 } 962 963 dwarf_cu->SetUserData(cu_sp.get()); 964 965 // Figure out the compile unit index if we weren't given one 966 if (cu_idx == UINT32_MAX) 967 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); 968 969 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); 970 } 971 } 972 } 973 } 974 } 975 } 976 return cu_sp; 977 } 978 979 uint32_t 980 SymbolFileDWARF::GetNumCompileUnits() 981 { 982 DWARFDebugInfo* info = DebugInfo(); 983 if (info) 984 return info->GetNumCompileUnits(); 985 return 0; 986 } 987 988 CompUnitSP 989 SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) 990 { 991 CompUnitSP cu_sp; 992 DWARFDebugInfo* info = DebugInfo(); 993 if (info) 994 { 995 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx); 996 if (dwarf_cu) 997 cu_sp = ParseCompileUnit(dwarf_cu, cu_idx); 998 } 999 return cu_sp; 1000 } 1001 1002 Function * 1003 SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die) 1004 { 1005 if (die.IsValid()) 1006 { 1007 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); 1008 1009 if (type_system) 1010 { 1011 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); 1012 if (dwarf_ast) 1013 return dwarf_ast->ParseFunctionFromDWARF(sc, die); 1014 } 1015 } 1016 return nullptr; 1017 } 1018 1019 bool 1020 SymbolFileDWARF::FixupAddress (Address &addr) 1021 { 1022 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile (); 1023 if (debug_map_symfile) 1024 { 1025 return debug_map_symfile->LinkOSOAddress(addr); 1026 } 1027 // This is a normal DWARF file, no address fixups need to happen 1028 return true; 1029 } 1030 lldb::LanguageType 1031 SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc) 1032 { 1033 assert (sc.comp_unit); 1034 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); 1035 if (dwarf_cu) 1036 return dwarf_cu->GetLanguageType(); 1037 else 1038 return eLanguageTypeUnknown; 1039 } 1040 1041 size_t 1042 SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) 1043 { 1044 assert (sc.comp_unit); 1045 size_t functions_added = 0; 1046 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); 1047 if (dwarf_cu) 1048 { 1049 DWARFDIECollection function_dies; 1050 const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); 1051 size_t func_idx; 1052 for (func_idx = 0; func_idx < num_functions; ++func_idx) 1053 { 1054 DWARFDIE die = function_dies.GetDIEAtIndex(func_idx); 1055 if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL) 1056 { 1057 if (ParseCompileUnitFunction(sc, die)) 1058 ++functions_added; 1059 } 1060 } 1061 //FixupTypes(); 1062 } 1063 return functions_added; 1064 } 1065 1066 bool 1067 SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) 1068 { 1069 assert (sc.comp_unit); 1070 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); 1071 if (dwarf_cu) 1072 { 1073 const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly(); 1074 1075 if (cu_die) 1076 { 1077 const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)); 1078 1079 const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET); 1080 1081 // All file indexes in DWARF are one based and a file of index zero is 1082 // supposed to be the compile unit itself. 1083 support_files.Append (*sc.comp_unit); 1084 1085 return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files); 1086 } 1087 } 1088 return false; 1089 } 1090 1091 bool 1092 SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) 1093 { 1094 assert (sc.comp_unit); 1095 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); 1096 if (dwarf_cu) 1097 { 1098 if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage())) 1099 { 1100 UpdateExternalModuleListIfNeeded(); 1101 for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules) 1102 { 1103 imported_modules.push_back(external_type_module.second.m_name); 1104 } 1105 } 1106 } 1107 return false; 1108 } 1109 1110 struct ParseDWARFLineTableCallbackInfo 1111 { 1112 LineTable* line_table; 1113 std::unique_ptr<LineSequence> sequence_ap; 1114 lldb::addr_t addr_mask; 1115 }; 1116 1117 //---------------------------------------------------------------------- 1118 // ParseStatementTableCallback 1119 //---------------------------------------------------------------------- 1120 static void 1121 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 1122 { 1123 if (state.row == DWARFDebugLine::State::StartParsingLineTable) 1124 { 1125 // Just started parsing the line table 1126 } 1127 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 1128 { 1129 // Done parsing line table, nothing to do for the cleanup 1130 } 1131 else 1132 { 1133 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData; 1134 LineTable* line_table = info->line_table; 1135 1136 // If this is our first time here, we need to create a 1137 // sequence container. 1138 if (!info->sequence_ap.get()) 1139 { 1140 info->sequence_ap.reset(line_table->CreateLineSequenceContainer()); 1141 assert(info->sequence_ap.get()); 1142 } 1143 line_table->AppendLineEntryToSequence (info->sequence_ap.get(), 1144 state.address & info->addr_mask, 1145 state.line, 1146 state.column, 1147 state.file, 1148 state.is_stmt, 1149 state.basic_block, 1150 state.prologue_end, 1151 state.epilogue_begin, 1152 state.end_sequence); 1153 if (state.end_sequence) 1154 { 1155 // First, put the current sequence into the line table. 1156 line_table->InsertSequence(info->sequence_ap.get()); 1157 // Then, empty it to prepare for the next sequence. 1158 info->sequence_ap->Clear(); 1159 } 1160 } 1161 } 1162 1163 bool 1164 SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) 1165 { 1166 assert (sc.comp_unit); 1167 if (sc.comp_unit->GetLineTable() != NULL) 1168 return true; 1169 1170 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); 1171 if (dwarf_cu) 1172 { 1173 const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); 1174 if (dwarf_cu_die) 1175 { 1176 const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET); 1177 if (cu_line_offset != DW_INVALID_OFFSET) 1178 { 1179 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit)); 1180 if (line_table_ap.get()) 1181 { 1182 ParseDWARFLineTableCallbackInfo info; 1183 info.line_table = line_table_ap.get(); 1184 1185 /* 1186 * MIPS: 1187 * The SymbolContext may not have a valid target, thus we may not be able 1188 * to call Address::GetOpcodeLoadAddress() which would clear the bit #0 1189 * for MIPS. Use ArchSpec to clear the bit #0. 1190 */ 1191 ArchSpec arch; 1192 GetObjectFile()->GetArchitecture(arch); 1193 switch (arch.GetMachine()) 1194 { 1195 case llvm::Triple::mips: 1196 case llvm::Triple::mipsel: 1197 case llvm::Triple::mips64: 1198 case llvm::Triple::mips64el: 1199 info.addr_mask = ~((lldb::addr_t)1); 1200 break; 1201 default: 1202 info.addr_mask = ~((lldb::addr_t)0); 1203 break; 1204 } 1205 1206 lldb::offset_t offset = cu_line_offset; 1207 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); 1208 if (m_debug_map_symfile) 1209 { 1210 // We have an object file that has a line table with addresses 1211 // that are not linked. We need to link the line table and convert 1212 // the addresses that are relative to the .o file into addresses 1213 // for the main executable. 1214 sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get())); 1215 } 1216 else 1217 { 1218 sc.comp_unit->SetLineTable(line_table_ap.release()); 1219 return true; 1220 } 1221 } 1222 } 1223 } 1224 } 1225 return false; 1226 } 1227 1228 size_t 1229 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc, 1230 Block *parent_block, 1231 const DWARFDIE &orig_die, 1232 addr_t subprogram_low_pc, 1233 uint32_t depth) 1234 { 1235 size_t blocks_added = 0; 1236 DWARFDIE die = orig_die; 1237 while (die) 1238 { 1239 dw_tag_t tag = die.Tag(); 1240 1241 switch (tag) 1242 { 1243 case DW_TAG_inlined_subroutine: 1244 case DW_TAG_subprogram: 1245 case DW_TAG_lexical_block: 1246 { 1247 Block *block = NULL; 1248 if (tag == DW_TAG_subprogram) 1249 { 1250 // Skip any DW_TAG_subprogram DIEs that are inside 1251 // of a normal or inlined functions. These will be 1252 // parsed on their own as separate entities. 1253 1254 if (depth > 0) 1255 break; 1256 1257 block = parent_block; 1258 } 1259 else 1260 { 1261 BlockSP block_sp(new Block (die.GetID())); 1262 parent_block->AddChild(block_sp); 1263 block = block_sp.get(); 1264 } 1265 DWARFRangeList ranges; 1266 const char *name = NULL; 1267 const char *mangled_name = NULL; 1268 1269 int decl_file = 0; 1270 int decl_line = 0; 1271 int decl_column = 0; 1272 int call_file = 0; 1273 int call_line = 0; 1274 int call_column = 0; 1275 if (die.GetDIENamesAndRanges (name, 1276 mangled_name, 1277 ranges, 1278 decl_file, decl_line, decl_column, 1279 call_file, call_line, call_column, nullptr)) 1280 { 1281 if (tag == DW_TAG_subprogram) 1282 { 1283 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); 1284 subprogram_low_pc = ranges.GetMinRangeBase(0); 1285 } 1286 else if (tag == DW_TAG_inlined_subroutine) 1287 { 1288 // We get called here for inlined subroutines in two ways. 1289 // The first time is when we are making the Function object 1290 // for this inlined concrete instance. Since we're creating a top level block at 1291 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to 1292 // adjust the containing address. 1293 // The second time is when we are parsing the blocks inside the function that contains 1294 // the inlined concrete instance. Since these will be blocks inside the containing "real" 1295 // function the offset will be for that function. 1296 if (subprogram_low_pc == LLDB_INVALID_ADDRESS) 1297 { 1298 subprogram_low_pc = ranges.GetMinRangeBase(0); 1299 } 1300 } 1301 1302 const size_t num_ranges = ranges.GetSize(); 1303 for (size_t i = 0; i<num_ranges; ++i) 1304 { 1305 const DWARFRangeList::Entry &range = ranges.GetEntryRef (i); 1306 const addr_t range_base = range.GetRangeBase(); 1307 if (range_base >= subprogram_low_pc) 1308 block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize())); 1309 else 1310 { 1311 GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message", 1312 block->GetID(), 1313 range_base, 1314 range.GetRangeEnd(), 1315 subprogram_low_pc); 1316 } 1317 } 1318 block->FinalizeRanges (); 1319 1320 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) 1321 { 1322 std::unique_ptr<Declaration> decl_ap; 1323 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 1324 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 1325 decl_line, decl_column)); 1326 1327 std::unique_ptr<Declaration> call_ap; 1328 if (call_file != 0 || call_line != 0 || call_column != 0) 1329 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), 1330 call_line, call_column)); 1331 1332 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get()); 1333 } 1334 1335 ++blocks_added; 1336 1337 if (die.HasChildren()) 1338 { 1339 blocks_added += ParseFunctionBlocks (sc, 1340 block, 1341 die.GetFirstChild(), 1342 subprogram_low_pc, 1343 depth + 1); 1344 } 1345 } 1346 } 1347 break; 1348 default: 1349 break; 1350 } 1351 1352 // Only parse siblings of the block if we are not at depth zero. A depth 1353 // of zero indicates we are currently parsing the top level 1354 // DW_TAG_subprogram DIE 1355 1356 if (depth == 0) 1357 die.Clear(); 1358 else 1359 die = die.GetSibling(); 1360 } 1361 return blocks_added; 1362 } 1363 1364 bool 1365 SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die) 1366 { 1367 if (parent_die) 1368 { 1369 for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling()) 1370 { 1371 dw_tag_t tag = die.Tag(); 1372 bool check_virtuality = false; 1373 switch (tag) 1374 { 1375 case DW_TAG_inheritance: 1376 case DW_TAG_subprogram: 1377 check_virtuality = true; 1378 break; 1379 default: 1380 break; 1381 } 1382 if (check_virtuality) 1383 { 1384 if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0) 1385 return true; 1386 } 1387 } 1388 } 1389 return false; 1390 } 1391 1392 void 1393 SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx) 1394 { 1395 TypeSystem *type_system = decl_ctx.GetTypeSystem(); 1396 DWARFASTParser *ast_parser = type_system->GetDWARFParser(); 1397 std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx); 1398 1399 for (DWARFDIE decl_ctx_die : decl_ctx_die_list) 1400 for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling()) 1401 ast_parser->GetDeclForUIDFromDWARF(decl); 1402 } 1403 1404 CompilerDecl 1405 SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid) 1406 { 1407 if (UserIDMatches(type_uid)) 1408 { 1409 DWARFDebugInfo* debug_info = DebugInfo(); 1410 if (debug_info) 1411 { 1412 DWARFDIE die = debug_info->GetDIE(DIERef(type_uid)); 1413 if (die) 1414 { 1415 DWARFASTParser *dwarf_ast = die.GetDWARFParser(); 1416 if (dwarf_ast) 1417 return dwarf_ast->GetDeclForUIDFromDWARF(die); 1418 } 1419 } 1420 } 1421 return CompilerDecl(); 1422 } 1423 1424 CompilerDeclContext 1425 SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid) 1426 { 1427 if (UserIDMatches(type_uid)) 1428 { 1429 DWARFDebugInfo* debug_info = DebugInfo(); 1430 if (debug_info) 1431 { 1432 DWARFDIE die = debug_info->GetDIE(DIERef(type_uid)); 1433 if (die) 1434 { 1435 DWARFASTParser *dwarf_ast = die.GetDWARFParser(); 1436 if (dwarf_ast) 1437 return dwarf_ast->GetDeclContextForUIDFromDWARF(die); 1438 } 1439 } 1440 } 1441 return CompilerDeclContext(); 1442 } 1443 1444 CompilerDeclContext 1445 SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid) 1446 { 1447 if (UserIDMatches(type_uid)) 1448 { 1449 DWARFDebugInfo* debug_info = DebugInfo(); 1450 if (debug_info) 1451 { 1452 DWARFDIE die = debug_info->GetDIE(DIERef(type_uid)); 1453 if (die) 1454 { 1455 DWARFASTParser *dwarf_ast = die.GetDWARFParser(); 1456 if (dwarf_ast) 1457 return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); 1458 } 1459 } 1460 } 1461 return CompilerDeclContext(); 1462 } 1463 1464 1465 Type* 1466 SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid) 1467 { 1468 if (UserIDMatches(type_uid)) 1469 { 1470 DWARFDebugInfo* debug_info = DebugInfo(); 1471 if (debug_info) 1472 { 1473 DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid)); 1474 if (type_die) 1475 { 1476 const bool assert_not_being_parsed = true; 1477 return ResolveTypeUID (type_die, assert_not_being_parsed); 1478 } 1479 } 1480 } 1481 return NULL; 1482 } 1483 1484 Type* 1485 SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed) 1486 { 1487 if (die) 1488 { 1489 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 1490 if (log) 1491 GetObjectFile()->GetModule()->LogMessage (log, 1492 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'", 1493 die.GetOffset(), 1494 die.GetTagAsCString(), 1495 die.GetName()); 1496 1497 // We might be coming in in the middle of a type tree (a class 1498 // withing a class, an enum within a class), so parse any needed 1499 // parent DIEs before we get to this one... 1500 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die); 1501 if (decl_ctx_die) 1502 { 1503 if (log) 1504 { 1505 switch (decl_ctx_die.Tag()) 1506 { 1507 case DW_TAG_structure_type: 1508 case DW_TAG_union_type: 1509 case DW_TAG_class_type: 1510 { 1511 // Get the type, which could be a forward declaration 1512 if (log) 1513 GetObjectFile()->GetModule()->LogMessage (log, 1514 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x", 1515 die.GetOffset(), 1516 die.GetTagAsCString(), 1517 die.GetName(), 1518 decl_ctx_die.GetOffset()); 1519 } 1520 break; 1521 1522 default: 1523 break; 1524 } 1525 } 1526 } 1527 return ResolveType (die); 1528 } 1529 return NULL; 1530 } 1531 1532 // This function is used when SymbolFileDWARFDebugMap owns a bunch of 1533 // SymbolFileDWARF objects to detect if this DWARF file is the one that 1534 // can resolve a compiler_type. 1535 bool 1536 SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type) 1537 { 1538 CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type); 1539 return GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()); 1540 } 1541 1542 1543 bool 1544 SymbolFileDWARF::CompleteType (CompilerType &compiler_type) 1545 { 1546 // We have a struct/union/class/enum that needs to be fully resolved. 1547 CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type); 1548 auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType()); 1549 if (die_it == GetForwardDeclClangTypeToDie().end()) 1550 { 1551 // We have already resolved this type... 1552 return true; 1553 } 1554 1555 DWARFDebugInfo* debug_info = DebugInfo(); 1556 DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond()); 1557 1558 assert(UserIDMatches(die_it->getSecond().GetUID()) && "CompleteType called on the wrong SymbolFile"); 1559 1560 // Once we start resolving this type, remove it from the forward declaration 1561 // map in case anyone child members or other types require this type to get resolved. 1562 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition 1563 // are done. 1564 GetForwardDeclClangTypeToDie().erase (die_it); 1565 1566 Type *type = GetDIEToType().lookup (dwarf_die.GetDIE()); 1567 1568 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION)); 1569 if (log) 1570 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log, 1571 "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", 1572 dwarf_die.GetID(), 1573 dwarf_die.GetTagAsCString(), 1574 type->GetName().AsCString()); 1575 assert (compiler_type); 1576 DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser(); 1577 if (dwarf_ast) 1578 return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type); 1579 return false; 1580 } 1581 1582 Type* 1583 SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed) 1584 { 1585 if (die) 1586 { 1587 Type *type = GetDIEToType().lookup (die.GetDIE()); 1588 1589 if (type == NULL) 1590 type = GetTypeForDIE (die).get(); 1591 1592 if (assert_not_being_parsed) 1593 { 1594 if (type != DIE_IS_BEING_PARSED) 1595 return type; 1596 1597 GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s", 1598 die.GetOffset(), 1599 die.GetTagAsCString(), 1600 die.GetName()); 1601 1602 } 1603 else 1604 return type; 1605 } 1606 return nullptr; 1607 } 1608 1609 CompileUnit* 1610 SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) 1611 { 1612 // Check if the symbol vendor already knows about this compile unit? 1613 if (dwarf_cu->GetUserData() == NULL) 1614 { 1615 // The symbol vendor doesn't know about this compile unit, we 1616 // need to parse and add it to the symbol vendor object. 1617 return ParseCompileUnit(dwarf_cu, cu_idx).get(); 1618 } 1619 return (CompileUnit*)dwarf_cu->GetUserData(); 1620 } 1621 1622 size_t 1623 SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets) 1624 { 1625 method_die_offsets.clear(); 1626 if (m_using_apple_tables) 1627 { 1628 if (m_apple_objc_ap.get()) 1629 m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets); 1630 } 1631 else 1632 { 1633 if (!m_indexed) 1634 Index (); 1635 1636 m_objc_class_selectors_index.Find (class_name, method_die_offsets); 1637 } 1638 return method_die_offsets.size(); 1639 } 1640 1641 bool 1642 SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc) 1643 { 1644 sc.Clear(false); 1645 1646 if (die) 1647 { 1648 // Check if the symbol vendor already knows about this compile unit? 1649 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); 1650 1651 sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get(); 1652 if (sc.function == NULL) 1653 sc.function = ParseCompileUnitFunction(sc, die); 1654 1655 if (sc.function) 1656 { 1657 sc.module_sp = sc.function->CalculateSymbolContextModule(); 1658 return true; 1659 } 1660 } 1661 1662 return false; 1663 } 1664 1665 void 1666 SymbolFileDWARF::UpdateExternalModuleListIfNeeded() 1667 { 1668 if (m_fetched_external_modules) 1669 return; 1670 m_fetched_external_modules = true; 1671 1672 DWARFDebugInfo * debug_info = DebugInfo(); 1673 1674 const uint32_t num_compile_units = GetNumCompileUnits(); 1675 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 1676 { 1677 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 1678 1679 const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly(); 1680 if (die && die.HasChildren() == false) 1681 { 1682 const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX); 1683 const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX); 1684 1685 if (name_strp != UINT64_MAX) 1686 { 1687 if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end()) 1688 { 1689 const char *name = get_debug_str_data().PeekCStr(name_strp); 1690 const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp); 1691 if (name || dwo_path) 1692 { 1693 ModuleSP module_sp; 1694 if (dwo_path) 1695 { 1696 ModuleSpec dwo_module_spec; 1697 dwo_module_spec.GetFileSpec().SetFile(dwo_path, false); 1698 dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture(); 1699 //printf ("Loading dwo = '%s'\n", dwo_path); 1700 Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL); 1701 } 1702 1703 if (dwo_path_strp != LLDB_INVALID_UID) 1704 { 1705 m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp }; 1706 } 1707 else 1708 { 1709 // This hack should be removed promptly once clang emits both. 1710 m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp }; 1711 } 1712 } 1713 } 1714 } 1715 } 1716 } 1717 } 1718 1719 SymbolFileDWARF::GlobalVariableMap & 1720 SymbolFileDWARF::GetGlobalAranges() 1721 { 1722 if (!m_global_aranges_ap) 1723 { 1724 m_global_aranges_ap.reset (new GlobalVariableMap()); 1725 1726 ModuleSP module_sp = GetObjectFile()->GetModule(); 1727 if (module_sp) 1728 { 1729 const size_t num_cus = module_sp->GetNumCompileUnits(); 1730 for (size_t i = 0; i < num_cus; ++i) 1731 { 1732 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i); 1733 if (cu_sp) 1734 { 1735 VariableListSP globals_sp = cu_sp->GetVariableList(true); 1736 if (globals_sp) 1737 { 1738 const size_t num_globals = globals_sp->GetSize(); 1739 for (size_t g = 0; g < num_globals; ++g) 1740 { 1741 VariableSP var_sp = globals_sp->GetVariableAtIndex(g); 1742 if (var_sp && !var_sp->GetLocationIsConstantValueData()) 1743 { 1744 const DWARFExpression &location = var_sp->LocationExpression(); 1745 Value location_result; 1746 Error error; 1747 if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error)) 1748 { 1749 if (location_result.GetValueType() == Value::eValueTypeFileAddress) 1750 { 1751 lldb::addr_t file_addr = location_result.GetScalar().ULongLong(); 1752 lldb::addr_t byte_size = 1; 1753 if (var_sp->GetType()) 1754 byte_size = var_sp->GetType()->GetByteSize(); 1755 m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get())); 1756 } 1757 } 1758 } 1759 } 1760 } 1761 } 1762 } 1763 } 1764 m_global_aranges_ap->Sort(); 1765 } 1766 return *m_global_aranges_ap; 1767 } 1768 1769 1770 uint32_t 1771 SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 1772 { 1773 Timer scoped_timer(__PRETTY_FUNCTION__, 1774 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)", 1775 static_cast<void*>(so_addr.GetSection().get()), 1776 so_addr.GetOffset(), resolve_scope); 1777 uint32_t resolved = 0; 1778 if (resolve_scope & ( eSymbolContextCompUnit | 1779 eSymbolContextFunction | 1780 eSymbolContextBlock | 1781 eSymbolContextLineEntry | 1782 eSymbolContextVariable )) 1783 { 1784 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1785 1786 DWARFDebugInfo* debug_info = DebugInfo(); 1787 if (debug_info) 1788 { 1789 const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); 1790 if (cu_offset == DW_INVALID_OFFSET) 1791 { 1792 // Global variables are not in the compile unit address ranges. The only way to 1793 // currently find global variables is to iterate over the .debug_pubnames or the 1794 // __apple_names table and find all items in there that point to DW_TAG_variable 1795 // DIEs and then find the address that matches. 1796 if (resolve_scope & eSymbolContextVariable) 1797 { 1798 GlobalVariableMap &map = GetGlobalAranges(); 1799 const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr); 1800 if (entry && entry->data) 1801 { 1802 Variable *variable = entry->data; 1803 SymbolContextScope *scc = variable->GetSymbolContextScope(); 1804 if (scc) 1805 { 1806 scc->CalculateSymbolContext(&sc); 1807 sc.variable = variable; 1808 } 1809 return sc.GetResolvedMask(); 1810 } 1811 } 1812 } 1813 else 1814 { 1815 uint32_t cu_idx = DW_INVALID_INDEX; 1816 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx); 1817 if (dwarf_cu) 1818 { 1819 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); 1820 if (sc.comp_unit) 1821 { 1822 resolved |= eSymbolContextCompUnit; 1823 1824 bool force_check_line_table = false; 1825 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1826 { 1827 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr); 1828 DWARFDIE block_die; 1829 if (function_die) 1830 { 1831 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get(); 1832 if (sc.function == NULL) 1833 sc.function = ParseCompileUnitFunction(sc, function_die); 1834 1835 if (sc.function && (resolve_scope & eSymbolContextBlock)) 1836 block_die = function_die.LookupDeepestBlock(file_vm_addr); 1837 } 1838 else 1839 { 1840 // We might have had a compile unit that had discontiguous 1841 // address ranges where the gaps are symbols that don't have 1842 // any debug info. Discontiguous compile unit address ranges 1843 // should only happen when there aren't other functions from 1844 // other compile units in these gaps. This helps keep the size 1845 // of the aranges down. 1846 force_check_line_table = true; 1847 } 1848 1849 if (sc.function != NULL) 1850 { 1851 resolved |= eSymbolContextFunction; 1852 1853 if (resolve_scope & eSymbolContextBlock) 1854 { 1855 Block& block = sc.function->GetBlock (true); 1856 1857 if (block_die) 1858 sc.block = block.FindBlockByID (block_die.GetID()); 1859 else 1860 sc.block = block.FindBlockByID (function_die.GetID()); 1861 if (sc.block) 1862 resolved |= eSymbolContextBlock; 1863 } 1864 } 1865 } 1866 1867 if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table) 1868 { 1869 LineTable *line_table = sc.comp_unit->GetLineTable(); 1870 if (line_table != NULL) 1871 { 1872 // And address that makes it into this function should be in terms 1873 // of this debug file if there is no debug map, or it will be an 1874 // address in the .o file which needs to be fixed up to be in terms 1875 // of the debug map executable. Either way, calling FixupAddress() 1876 // will work for us. 1877 Address exe_so_addr (so_addr); 1878 if (FixupAddress(exe_so_addr)) 1879 { 1880 if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry)) 1881 { 1882 resolved |= eSymbolContextLineEntry; 1883 } 1884 } 1885 } 1886 } 1887 1888 if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) 1889 { 1890 // We might have had a compile unit that had discontiguous 1891 // address ranges where the gaps are symbols that don't have 1892 // any debug info. Discontiguous compile unit address ranges 1893 // should only happen when there aren't other functions from 1894 // other compile units in these gaps. This helps keep the size 1895 // of the aranges down. 1896 sc.comp_unit = NULL; 1897 resolved &= ~eSymbolContextCompUnit; 1898 } 1899 } 1900 else 1901 { 1902 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.", 1903 cu_offset, 1904 cu_idx); 1905 } 1906 } 1907 } 1908 } 1909 } 1910 return resolved; 1911 } 1912 1913 1914 1915 uint32_t 1916 SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 1917 { 1918 const uint32_t prev_size = sc_list.GetSize(); 1919 if (resolve_scope & eSymbolContextCompUnit) 1920 { 1921 DWARFDebugInfo* debug_info = DebugInfo(); 1922 if (debug_info) 1923 { 1924 uint32_t cu_idx; 1925 DWARFCompileUnit* dwarf_cu = NULL; 1926 1927 for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 1928 { 1929 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); 1930 const bool full_match = (bool)file_spec.GetDirectory(); 1931 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match); 1932 if (check_inlines || file_spec_matches_cu_file_spec) 1933 { 1934 SymbolContext sc (m_obj_file->GetModule()); 1935 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); 1936 if (sc.comp_unit) 1937 { 1938 uint32_t file_idx = UINT32_MAX; 1939 1940 // If we are looking for inline functions only and we don't 1941 // find it in the support files, we are done. 1942 if (check_inlines) 1943 { 1944 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); 1945 if (file_idx == UINT32_MAX) 1946 continue; 1947 } 1948 1949 if (line != 0) 1950 { 1951 LineTable *line_table = sc.comp_unit->GetLineTable(); 1952 1953 if (line_table != NULL && line != 0) 1954 { 1955 // We will have already looked up the file index if 1956 // we are searching for inline entries. 1957 if (!check_inlines) 1958 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); 1959 1960 if (file_idx != UINT32_MAX) 1961 { 1962 uint32_t found_line; 1963 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 1964 found_line = sc.line_entry.line; 1965 1966 while (line_idx != UINT32_MAX) 1967 { 1968 sc.function = NULL; 1969 sc.block = NULL; 1970 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1971 { 1972 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 1973 if (file_vm_addr != LLDB_INVALID_ADDRESS) 1974 { 1975 DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr); 1976 DWARFDIE block_die; 1977 if (function_die) 1978 { 1979 sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get(); 1980 if (sc.function == NULL) 1981 sc.function = ParseCompileUnitFunction(sc, function_die); 1982 1983 if (sc.function && (resolve_scope & eSymbolContextBlock)) 1984 block_die = function_die.LookupDeepestBlock(file_vm_addr); 1985 } 1986 1987 if (sc.function != NULL) 1988 { 1989 Block& block = sc.function->GetBlock (true); 1990 1991 if (block_die) 1992 sc.block = block.FindBlockByID (block_die.GetID()); 1993 else if (function_die) 1994 sc.block = block.FindBlockByID (function_die.GetID()); 1995 } 1996 } 1997 } 1998 1999 sc_list.Append(sc); 2000 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 2001 } 2002 } 2003 } 2004 else if (file_spec_matches_cu_file_spec && !check_inlines) 2005 { 2006 // only append the context if we aren't looking for inline call sites 2007 // by file and line and if the file spec matches that of the compile unit 2008 sc_list.Append(sc); 2009 } 2010 } 2011 else if (file_spec_matches_cu_file_spec && !check_inlines) 2012 { 2013 // only append the context if we aren't looking for inline call sites 2014 // by file and line and if the file spec matches that of the compile unit 2015 sc_list.Append(sc); 2016 } 2017 2018 if (!check_inlines) 2019 break; 2020 } 2021 } 2022 } 2023 } 2024 } 2025 return sc_list.GetSize() - prev_size; 2026 } 2027 2028 void 2029 SymbolFileDWARF::Index () 2030 { 2031 if (m_indexed) 2032 return; 2033 m_indexed = true; 2034 Timer scoped_timer (__PRETTY_FUNCTION__, 2035 "SymbolFileDWARF::Index (%s)", 2036 GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>")); 2037 2038 DWARFDebugInfo* debug_info = DebugInfo(); 2039 if (debug_info) 2040 { 2041 uint32_t cu_idx = 0; 2042 const uint32_t num_compile_units = GetNumCompileUnits(); 2043 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 2044 { 2045 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 2046 2047 bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1; 2048 2049 dwarf_cu->Index (m_function_basename_index, 2050 m_function_fullname_index, 2051 m_function_method_index, 2052 m_function_selector_index, 2053 m_objc_class_selectors_index, 2054 m_global_index, 2055 m_type_index, 2056 m_namespace_index); 2057 2058 // Keep memory down by clearing DIEs if this generate function 2059 // caused them to be parsed 2060 if (clear_dies) 2061 dwarf_cu->ClearDIEs (true); 2062 } 2063 2064 m_function_basename_index.Finalize(); 2065 m_function_fullname_index.Finalize(); 2066 m_function_method_index.Finalize(); 2067 m_function_selector_index.Finalize(); 2068 m_objc_class_selectors_index.Finalize(); 2069 m_global_index.Finalize(); 2070 m_type_index.Finalize(); 2071 m_namespace_index.Finalize(); 2072 2073 #if defined (ENABLE_DEBUG_PRINTF) 2074 StreamFile s(stdout, false); 2075 s.Printf ("DWARF index for '%s':", 2076 GetObjectFile()->GetFileSpec().GetPath().c_str()); 2077 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 2078 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 2079 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 2080 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 2081 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 2082 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 2083 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 2084 s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s); 2085 #endif 2086 } 2087 } 2088 2089 bool 2090 SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx) 2091 { 2092 if (decl_ctx == nullptr || !decl_ctx->IsValid()) 2093 { 2094 // Invalid namespace decl which means we aren't matching only things 2095 // in this symbol file, so return true to indicate it matches this 2096 // symbol file. 2097 return true; 2098 } 2099 2100 TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); 2101 TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr)); 2102 if (decl_ctx_type_system == type_system) 2103 return true; // The type systems match, return true 2104 2105 // The namespace AST was valid, and it does not match... 2106 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2107 2108 if (log) 2109 GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file"); 2110 2111 return false; 2112 } 2113 2114 uint32_t 2115 SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables) 2116 { 2117 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2118 2119 if (log) 2120 GetObjectFile()->GetModule()->LogMessage (log, 2121 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)", 2122 name.GetCString(), 2123 static_cast<const void*>(parent_decl_ctx), 2124 append, max_matches); 2125 2126 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 2127 return 0; 2128 2129 DWARFDebugInfo* info = DebugInfo(); 2130 if (info == NULL) 2131 return 0; 2132 2133 // If we aren't appending the results to this list, then clear the list 2134 if (!append) 2135 variables.Clear(); 2136 2137 // Remember how many variables are in the list before we search in case 2138 // we are appending the results to a variable list. 2139 const uint32_t original_size = variables.GetSize(); 2140 2141 DIEArray die_offsets; 2142 2143 if (m_using_apple_tables) 2144 { 2145 if (m_apple_names_ap.get()) 2146 { 2147 const char *name_cstr = name.GetCString(); 2148 llvm::StringRef basename; 2149 llvm::StringRef context; 2150 2151 if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename)) 2152 basename = name_cstr; 2153 2154 m_apple_names_ap->FindByName (basename.data(), die_offsets); 2155 } 2156 } 2157 else 2158 { 2159 // Index the DWARF if we haven't already 2160 if (!m_indexed) 2161 Index (); 2162 2163 m_global_index.Find (name, die_offsets); 2164 } 2165 2166 const size_t num_die_matches = die_offsets.size(); 2167 if (num_die_matches) 2168 { 2169 SymbolContext sc; 2170 sc.module_sp = m_obj_file->GetModule(); 2171 assert (sc.module_sp); 2172 2173 DWARFDebugInfo* debug_info = DebugInfo(); 2174 bool done = false; 2175 for (size_t i=0; i<num_die_matches && !done; ++i) 2176 { 2177 const DIERef& die_ref = die_offsets[i]; 2178 DWARFDIE die = debug_info->GetDIE (die_ref); 2179 2180 if (die) 2181 { 2182 switch (die.Tag()) 2183 { 2184 default: 2185 case DW_TAG_subprogram: 2186 case DW_TAG_inlined_subroutine: 2187 case DW_TAG_try_block: 2188 case DW_TAG_catch_block: 2189 break; 2190 2191 case DW_TAG_variable: 2192 { 2193 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); 2194 2195 if (parent_decl_ctx) 2196 { 2197 DWARFASTParser *dwarf_ast = die.GetDWARFParser(); 2198 if (dwarf_ast) 2199 { 2200 CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die); 2201 if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx) 2202 continue; 2203 } 2204 } 2205 2206 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); 2207 2208 if (variables.GetSize() - original_size >= max_matches) 2209 done = true; 2210 } 2211 break; 2212 } 2213 } 2214 else 2215 { 2216 if (m_using_apple_tables) 2217 { 2218 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n", 2219 die_ref.die_offset, name.GetCString()); 2220 } 2221 } 2222 } 2223 } 2224 2225 // Return the number of variable that were appended to the list 2226 const uint32_t num_matches = variables.GetSize() - original_size; 2227 if (log && num_matches > 0) 2228 { 2229 GetObjectFile()->GetModule()->LogMessage (log, 2230 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u", 2231 name.GetCString(), 2232 static_cast<const void*>(parent_decl_ctx), 2233 append, max_matches, 2234 num_matches); 2235 } 2236 return num_matches; 2237 } 2238 2239 uint32_t 2240 SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 2241 { 2242 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2243 2244 if (log) 2245 { 2246 GetObjectFile()->GetModule()->LogMessage (log, 2247 "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)", 2248 regex.GetText(), append, 2249 max_matches); 2250 } 2251 2252 DWARFDebugInfo* info = DebugInfo(); 2253 if (info == NULL) 2254 return 0; 2255 2256 // If we aren't appending the results to this list, then clear the list 2257 if (!append) 2258 variables.Clear(); 2259 2260 // Remember how many variables are in the list before we search in case 2261 // we are appending the results to a variable list. 2262 const uint32_t original_size = variables.GetSize(); 2263 2264 DIEArray die_offsets; 2265 2266 if (m_using_apple_tables) 2267 { 2268 if (m_apple_names_ap.get()) 2269 { 2270 DWARFMappedHash::DIEInfoArray hash_data_array; 2271 if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array)) 2272 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); 2273 } 2274 } 2275 else 2276 { 2277 // Index the DWARF if we haven't already 2278 if (!m_indexed) 2279 Index (); 2280 2281 m_global_index.Find (regex, die_offsets); 2282 } 2283 2284 SymbolContext sc; 2285 sc.module_sp = m_obj_file->GetModule(); 2286 assert (sc.module_sp); 2287 2288 const size_t num_matches = die_offsets.size(); 2289 if (num_matches) 2290 { 2291 DWARFDebugInfo* debug_info = DebugInfo(); 2292 for (size_t i=0; i<num_matches; ++i) 2293 { 2294 const DIERef& die_ref = die_offsets[i]; 2295 DWARFDIE die = debug_info->GetDIE (die_ref); 2296 2297 if (die) 2298 { 2299 sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX); 2300 2301 ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); 2302 2303 if (variables.GetSize() - original_size >= max_matches) 2304 break; 2305 } 2306 else 2307 { 2308 if (m_using_apple_tables) 2309 { 2310 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n", 2311 die_ref.die_offset, regex.GetText()); 2312 } 2313 } 2314 } 2315 } 2316 2317 // Return the number of variable that were appended to the list 2318 return variables.GetSize() - original_size; 2319 } 2320 2321 2322 bool 2323 SymbolFileDWARF::ResolveFunction (const DIERef& die_ref, 2324 bool include_inlines, 2325 SymbolContextList& sc_list) 2326 { 2327 DWARFDIE die = DebugInfo()->GetDIE (die_ref); 2328 return ResolveFunction (die, include_inlines, sc_list); 2329 } 2330 2331 2332 bool 2333 SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die, 2334 bool include_inlines, 2335 SymbolContextList& sc_list) 2336 { 2337 SymbolContext sc; 2338 2339 if (!orig_die) 2340 return false; 2341 2342 // If we were passed a die that is not a function, just return false... 2343 if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine))) 2344 return false; 2345 2346 DWARFDIE die = orig_die; 2347 DWARFDIE inlined_die; 2348 if (die.Tag() == DW_TAG_inlined_subroutine) 2349 { 2350 inlined_die = die; 2351 2352 while (1) 2353 { 2354 die = die.GetParent(); 2355 2356 if (die) 2357 { 2358 if (die.Tag() == DW_TAG_subprogram) 2359 break; 2360 } 2361 else 2362 break; 2363 } 2364 } 2365 assert (die && die.Tag() == DW_TAG_subprogram); 2366 if (GetFunction (die, sc)) 2367 { 2368 Address addr; 2369 // Parse all blocks if needed 2370 if (inlined_die) 2371 { 2372 Block &function_block = sc.function->GetBlock (true); 2373 sc.block = function_block.FindBlockByID (inlined_die.GetID()); 2374 if (sc.block == NULL) 2375 sc.block = function_block.FindBlockByID (inlined_die.GetOffset()); 2376 if (sc.block == NULL || sc.block->GetStartAddress (addr) == false) 2377 addr.Clear(); 2378 } 2379 else 2380 { 2381 sc.block = NULL; 2382 addr = sc.function->GetAddressRange().GetBaseAddress(); 2383 } 2384 2385 if (addr.IsValid()) 2386 { 2387 sc_list.Append(sc); 2388 return true; 2389 } 2390 } 2391 2392 return false; 2393 } 2394 2395 void 2396 SymbolFileDWARF::FindFunctions (const ConstString &name, 2397 const NameToDIE &name_to_die, 2398 bool include_inlines, 2399 SymbolContextList& sc_list) 2400 { 2401 DIEArray die_offsets; 2402 if (name_to_die.Find (name, die_offsets)) 2403 { 2404 ParseFunctions (die_offsets, include_inlines, sc_list); 2405 } 2406 } 2407 2408 2409 void 2410 SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, 2411 const NameToDIE &name_to_die, 2412 bool include_inlines, 2413 SymbolContextList& sc_list) 2414 { 2415 DIEArray die_offsets; 2416 if (name_to_die.Find (regex, die_offsets)) 2417 { 2418 ParseFunctions (die_offsets, include_inlines, sc_list); 2419 } 2420 } 2421 2422 2423 void 2424 SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, 2425 const DWARFMappedHash::MemoryTable &memory_table, 2426 bool include_inlines, 2427 SymbolContextList& sc_list) 2428 { 2429 DIEArray die_offsets; 2430 DWARFMappedHash::DIEInfoArray hash_data_array; 2431 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array)) 2432 { 2433 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); 2434 ParseFunctions (die_offsets, include_inlines, sc_list); 2435 } 2436 } 2437 2438 void 2439 SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets, 2440 bool include_inlines, 2441 SymbolContextList& sc_list) 2442 { 2443 const size_t num_matches = die_offsets.size(); 2444 if (num_matches) 2445 { 2446 for (size_t i=0; i<num_matches; ++i) 2447 ResolveFunction (die_offsets[i], include_inlines, sc_list); 2448 } 2449 } 2450 2451 bool 2452 SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx, 2453 const DWARFDIE &die) 2454 { 2455 // If we have no parent decl context to match this DIE matches, and if the parent 2456 // decl context isn't valid, we aren't trying to look for any particular decl 2457 // context so any die matches. 2458 if (decl_ctx == nullptr || !decl_ctx->IsValid()) 2459 return true; 2460 2461 if (die) 2462 { 2463 DWARFASTParser *dwarf_ast = die.GetDWARFParser(); 2464 if (dwarf_ast) 2465 { 2466 CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die); 2467 if (actual_decl_ctx) 2468 return actual_decl_ctx == *decl_ctx; 2469 } 2470 } 2471 return false; 2472 } 2473 2474 uint32_t 2475 SymbolFileDWARF::FindFunctions (const ConstString &name, 2476 const CompilerDeclContext *parent_decl_ctx, 2477 uint32_t name_type_mask, 2478 bool include_inlines, 2479 bool append, 2480 SymbolContextList& sc_list) 2481 { 2482 Timer scoped_timer (__PRETTY_FUNCTION__, 2483 "SymbolFileDWARF::FindFunctions (name = '%s')", 2484 name.AsCString()); 2485 2486 // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup() 2487 assert ((name_type_mask & eFunctionNameTypeAuto) == 0); 2488 2489 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2490 2491 if (log) 2492 { 2493 GetObjectFile()->GetModule()->LogMessage (log, 2494 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)", 2495 name.GetCString(), 2496 name_type_mask, 2497 append); 2498 } 2499 2500 // If we aren't appending the results to this list, then clear the list 2501 if (!append) 2502 sc_list.Clear(); 2503 2504 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 2505 return 0; 2506 2507 // If name is empty then we won't find anything. 2508 if (name.IsEmpty()) 2509 return 0; 2510 2511 // Remember how many sc_list are in the list before we search in case 2512 // we are appending the results to a variable list. 2513 2514 const char *name_cstr = name.GetCString(); 2515 2516 const uint32_t original_size = sc_list.GetSize(); 2517 2518 DWARFDebugInfo* info = DebugInfo(); 2519 if (info == NULL) 2520 return 0; 2521 2522 std::set<const DWARFDebugInfoEntry *> resolved_dies; 2523 if (m_using_apple_tables) 2524 { 2525 if (m_apple_names_ap.get()) 2526 { 2527 2528 DIEArray die_offsets; 2529 2530 uint32_t num_matches = 0; 2531 2532 if (name_type_mask & eFunctionNameTypeFull) 2533 { 2534 // If they asked for the full name, match what they typed. At some point we may 2535 // want to canonicalize this (strip double spaces, etc. For now, we just add all the 2536 // dies that we find by exact match. 2537 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); 2538 for (uint32_t i = 0; i < num_matches; i++) 2539 { 2540 const DIERef& die_ref = die_offsets[i]; 2541 DWARFDIE die = info->GetDIE (die_ref); 2542 if (die) 2543 { 2544 if (!DIEInDeclContext(parent_decl_ctx, die)) 2545 continue; // The containing decl contexts don't match 2546 2547 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) 2548 { 2549 if (ResolveFunction (die, include_inlines, sc_list)) 2550 resolved_dies.insert(die.GetDIE()); 2551 } 2552 } 2553 else 2554 { 2555 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 2556 die_ref.die_offset, name_cstr); 2557 } 2558 } 2559 } 2560 2561 if (name_type_mask & eFunctionNameTypeSelector) 2562 { 2563 if (parent_decl_ctx && parent_decl_ctx->IsValid()) 2564 return 0; // no selectors in namespaces 2565 2566 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); 2567 // Now make sure these are actually ObjC methods. In this case we can simply look up the name, 2568 // and if it is an ObjC method name, we're good. 2569 2570 for (uint32_t i = 0; i < num_matches; i++) 2571 { 2572 const DIERef& die_ref = die_offsets[i]; 2573 DWARFDIE die = info->GetDIE (die_ref); 2574 if (die) 2575 { 2576 const char *die_name = die.GetName(); 2577 if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) 2578 { 2579 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) 2580 { 2581 if (ResolveFunction (die, include_inlines, sc_list)) 2582 resolved_dies.insert(die.GetDIE()); 2583 } 2584 } 2585 } 2586 else 2587 { 2588 GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 2589 die_ref.die_offset, name_cstr); 2590 } 2591 } 2592 die_offsets.clear(); 2593 } 2594 2595 if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase) 2596 { 2597 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to 2598 // extract the base name, look that up, and if there is any other information in the name we were 2599 // passed in we have to post-filter based on that. 2600 2601 // FIXME: Arrange the logic above so that we don't calculate the base name twice: 2602 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); 2603 2604 for (uint32_t i = 0; i < num_matches; i++) 2605 { 2606 const DIERef& die_ref = die_offsets[i]; 2607 DWARFDIE die = info->GetDIE (die_ref); 2608 if (die) 2609 { 2610 if (!DIEInDeclContext(parent_decl_ctx, die)) 2611 continue; // The containing decl contexts don't match 2612 2613 2614 // If we get to here, the die is good, and we should add it: 2615 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list)) 2616 { 2617 bool keep_die = true; 2618 if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod)) 2619 { 2620 // We are looking for either basenames or methods, so we need to 2621 // trim out the ones we won't want by looking at the type 2622 SymbolContext sc; 2623 if (sc_list.GetLastContext(sc)) 2624 { 2625 if (sc.block) 2626 { 2627 // We have an inlined function 2628 } 2629 else if (sc.function) 2630 { 2631 Type *type = sc.function->GetType(); 2632 2633 if (type) 2634 { 2635 CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID()); 2636 if (decl_ctx.IsStructUnionOrClass()) 2637 { 2638 if (name_type_mask & eFunctionNameTypeBase) 2639 { 2640 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1); 2641 keep_die = false; 2642 } 2643 } 2644 else 2645 { 2646 if (name_type_mask & eFunctionNameTypeMethod) 2647 { 2648 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1); 2649 keep_die = false; 2650 } 2651 } 2652 } 2653 else 2654 { 2655 GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type", 2656 die_ref.die_offset); 2657 } 2658 } 2659 } 2660 } 2661 if (keep_die) 2662 resolved_dies.insert(die.GetDIE()); 2663 } 2664 } 2665 else 2666 { 2667 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 2668 die_ref.die_offset, name_cstr); 2669 } 2670 } 2671 die_offsets.clear(); 2672 } 2673 } 2674 } 2675 else 2676 { 2677 2678 // Index the DWARF if we haven't already 2679 if (!m_indexed) 2680 Index (); 2681 2682 if (name_type_mask & eFunctionNameTypeFull) 2683 { 2684 FindFunctions (name, m_function_fullname_index, include_inlines, sc_list); 2685 2686 // FIXME Temporary workaround for global/anonymous namespace 2687 // functions debugging FreeBSD and Linux binaries. 2688 // If we didn't find any functions in the global namespace try 2689 // looking in the basename index but ignore any returned 2690 // functions that have a namespace but keep functions which 2691 // have an anonymous namespace 2692 // TODO: The arch in the object file isn't correct for MSVC 2693 // binaries on windows, we should find a way to make it 2694 // correct and handle those symbols as well. 2695 if (sc_list.GetSize() == 0) 2696 { 2697 ArchSpec arch; 2698 if (!parent_decl_ctx && 2699 GetObjectFile()->GetArchitecture(arch) && 2700 (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() || 2701 arch.GetMachine() == llvm::Triple::hexagon)) 2702 { 2703 SymbolContextList temp_sc_list; 2704 FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list); 2705 SymbolContext sc; 2706 for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) 2707 { 2708 if (temp_sc_list.GetContextAtIndex(i, sc)) 2709 { 2710 ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled); 2711 ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled); 2712 // Mangled names on Linux and FreeBSD are of the form: 2713 // _ZN18function_namespace13function_nameEv. 2714 if (strncmp(mangled_name.GetCString(), "_ZN", 3) || 2715 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21)) 2716 { 2717 sc_list.Append(sc); 2718 } 2719 } 2720 } 2721 } 2722 } 2723 } 2724 DIEArray die_offsets; 2725 if (name_type_mask & eFunctionNameTypeBase) 2726 { 2727 uint32_t num_base = m_function_basename_index.Find(name, die_offsets); 2728 for (uint32_t i = 0; i < num_base; i++) 2729 { 2730 DWARFDIE die = info->GetDIE (die_offsets[i]); 2731 if (die) 2732 { 2733 if (!DIEInDeclContext(parent_decl_ctx, die)) 2734 continue; // The containing decl contexts don't match 2735 2736 // If we get to here, the die is good, and we should add it: 2737 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) 2738 { 2739 if (ResolveFunction (die, include_inlines, sc_list)) 2740 resolved_dies.insert(die.GetDIE()); 2741 } 2742 } 2743 } 2744 die_offsets.clear(); 2745 } 2746 2747 if (name_type_mask & eFunctionNameTypeMethod) 2748 { 2749 if (parent_decl_ctx && parent_decl_ctx->IsValid()) 2750 return 0; // no methods in namespaces 2751 2752 uint32_t num_base = m_function_method_index.Find(name, die_offsets); 2753 { 2754 for (uint32_t i = 0; i < num_base; i++) 2755 { 2756 DWARFDIE die = info->GetDIE (die_offsets[i]); 2757 if (die) 2758 { 2759 // If we get to here, the die is good, and we should add it: 2760 if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) 2761 { 2762 if (ResolveFunction (die, include_inlines, sc_list)) 2763 resolved_dies.insert(die.GetDIE()); 2764 } 2765 } 2766 } 2767 } 2768 die_offsets.clear(); 2769 } 2770 2771 if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid())) 2772 { 2773 FindFunctions (name, m_function_selector_index, include_inlines, sc_list); 2774 } 2775 2776 } 2777 2778 // Return the number of variable that were appended to the list 2779 const uint32_t num_matches = sc_list.GetSize() - original_size; 2780 2781 if (log && num_matches > 0) 2782 { 2783 GetObjectFile()->GetModule()->LogMessage (log, 2784 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u", 2785 name.GetCString(), 2786 name_type_mask, 2787 include_inlines, 2788 append, 2789 num_matches); 2790 } 2791 return num_matches; 2792 } 2793 2794 uint32_t 2795 SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) 2796 { 2797 Timer scoped_timer (__PRETTY_FUNCTION__, 2798 "SymbolFileDWARF::FindFunctions (regex = '%s')", 2799 regex.GetText()); 2800 2801 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2802 2803 if (log) 2804 { 2805 GetObjectFile()->GetModule()->LogMessage (log, 2806 "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)", 2807 regex.GetText(), 2808 append); 2809 } 2810 2811 2812 // If we aren't appending the results to this list, then clear the list 2813 if (!append) 2814 sc_list.Clear(); 2815 2816 // Remember how many sc_list are in the list before we search in case 2817 // we are appending the results to a variable list. 2818 uint32_t original_size = sc_list.GetSize(); 2819 2820 if (m_using_apple_tables) 2821 { 2822 if (m_apple_names_ap.get()) 2823 FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list); 2824 } 2825 else 2826 { 2827 // Index the DWARF if we haven't already 2828 if (!m_indexed) 2829 Index (); 2830 2831 FindFunctions (regex, m_function_basename_index, include_inlines, sc_list); 2832 2833 FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list); 2834 } 2835 2836 // Return the number of variable that were appended to the list 2837 return sc_list.GetSize() - original_size; 2838 } 2839 2840 uint32_t 2841 SymbolFileDWARF::FindTypes (const SymbolContext& sc, 2842 const ConstString &name, 2843 const CompilerDeclContext *parent_decl_ctx, 2844 bool append, 2845 uint32_t max_matches, 2846 TypeMap& types) 2847 { 2848 DWARFDebugInfo* info = DebugInfo(); 2849 if (info == NULL) 2850 return 0; 2851 2852 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2853 2854 if (log) 2855 { 2856 if (parent_decl_ctx) 2857 GetObjectFile()->GetModule()->LogMessage (log, 2858 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)", 2859 name.GetCString(), 2860 static_cast<const void*>(parent_decl_ctx), 2861 parent_decl_ctx->GetName().AsCString("<NULL>"), 2862 append, max_matches); 2863 else 2864 GetObjectFile()->GetModule()->LogMessage (log, 2865 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)", 2866 name.GetCString(), append, 2867 max_matches); 2868 } 2869 2870 // If we aren't appending the results to this list, then clear the list 2871 if (!append) 2872 types.Clear(); 2873 2874 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 2875 return 0; 2876 2877 DIEArray die_offsets; 2878 2879 if (m_using_apple_tables) 2880 { 2881 if (m_apple_types_ap.get()) 2882 { 2883 const char *name_cstr = name.GetCString(); 2884 m_apple_types_ap->FindByName (name_cstr, die_offsets); 2885 } 2886 } 2887 else 2888 { 2889 if (!m_indexed) 2890 Index (); 2891 2892 m_type_index.Find (name, die_offsets); 2893 } 2894 2895 const size_t num_die_matches = die_offsets.size(); 2896 2897 if (num_die_matches) 2898 { 2899 const uint32_t initial_types_size = types.GetSize(); 2900 DWARFDebugInfo* debug_info = DebugInfo(); 2901 for (size_t i=0; i<num_die_matches; ++i) 2902 { 2903 const DIERef& die_ref = die_offsets[i]; 2904 DWARFDIE die = debug_info->GetDIE (die_ref); 2905 2906 if (die) 2907 { 2908 if (!DIEInDeclContext(parent_decl_ctx, die)) 2909 continue; // The containing decl contexts don't match 2910 2911 Type *matching_type = ResolveType (die); 2912 if (matching_type) 2913 { 2914 // We found a type pointer, now find the shared pointer form our type list 2915 types.InsertUnique (matching_type->shared_from_this()); 2916 if (types.GetSize() >= max_matches) 2917 break; 2918 } 2919 } 2920 else 2921 { 2922 if (m_using_apple_tables) 2923 { 2924 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", 2925 die_ref.die_offset, name.GetCString()); 2926 } 2927 } 2928 2929 } 2930 const uint32_t num_matches = types.GetSize() - initial_types_size; 2931 if (log && num_matches) 2932 { 2933 if (parent_decl_ctx) 2934 { 2935 GetObjectFile()->GetModule()->LogMessage (log, 2936 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", 2937 name.GetCString(), 2938 static_cast<const void*>(parent_decl_ctx), 2939 parent_decl_ctx->GetName().AsCString("<NULL>"), 2940 append, max_matches, 2941 num_matches); 2942 } 2943 else 2944 { 2945 GetObjectFile()->GetModule()->LogMessage (log, 2946 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u", 2947 name.GetCString(), 2948 append, max_matches, 2949 num_matches); 2950 } 2951 } 2952 return num_matches; 2953 } 2954 return 0; 2955 } 2956 2957 2958 CompilerDeclContext 2959 SymbolFileDWARF::FindNamespace (const SymbolContext& sc, 2960 const ConstString &name, 2961 const CompilerDeclContext *parent_decl_ctx) 2962 { 2963 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2964 2965 if (log) 2966 { 2967 GetObjectFile()->GetModule()->LogMessage (log, 2968 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")", 2969 name.GetCString()); 2970 } 2971 2972 CompilerDeclContext namespace_decl_ctx; 2973 2974 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 2975 return namespace_decl_ctx; 2976 2977 2978 DWARFDebugInfo* info = DebugInfo(); 2979 if (info) 2980 { 2981 DIEArray die_offsets; 2982 2983 // Index if we already haven't to make sure the compile units 2984 // get indexed and make their global DIE index list 2985 if (m_using_apple_tables) 2986 { 2987 if (m_apple_namespaces_ap.get()) 2988 { 2989 const char *name_cstr = name.GetCString(); 2990 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets); 2991 } 2992 } 2993 else 2994 { 2995 if (!m_indexed) 2996 Index (); 2997 2998 m_namespace_index.Find (name, die_offsets); 2999 } 3000 3001 const size_t num_matches = die_offsets.size(); 3002 if (num_matches) 3003 { 3004 DWARFDebugInfo* debug_info = DebugInfo(); 3005 for (size_t i=0; i<num_matches; ++i) 3006 { 3007 const DIERef& die_ref = die_offsets[i]; 3008 DWARFDIE die = debug_info->GetDIE (die_ref); 3009 3010 if (die) 3011 { 3012 if (!DIEInDeclContext (parent_decl_ctx, die)) 3013 continue; // The containing decl contexts don't match 3014 3015 DWARFASTParser *dwarf_ast = die.GetDWARFParser(); 3016 if (dwarf_ast) 3017 { 3018 namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die); 3019 if (namespace_decl_ctx) 3020 break; 3021 } 3022 } 3023 else 3024 { 3025 if (m_using_apple_tables) 3026 { 3027 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n", 3028 die_ref.die_offset, name.GetCString()); 3029 } 3030 } 3031 3032 } 3033 } 3034 } 3035 if (log && namespace_decl_ctx) 3036 { 3037 GetObjectFile()->GetModule()->LogMessage (log, 3038 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"", 3039 name.GetCString(), 3040 static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()), 3041 static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()), 3042 namespace_decl_ctx.GetName().AsCString("<NULL>")); 3043 } 3044 3045 return namespace_decl_ctx; 3046 } 3047 3048 TypeSP 3049 SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die) 3050 { 3051 TypeSP type_sp; 3052 if (die) 3053 { 3054 Type *type_ptr = GetDIEToType().lookup (die.GetDIE()); 3055 if (type_ptr == NULL) 3056 { 3057 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU()); 3058 assert (lldb_cu); 3059 SymbolContext sc(lldb_cu); 3060 const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE(); 3061 while (parent_die != nullptr) 3062 { 3063 if (parent_die->Tag() == DW_TAG_subprogram) 3064 break; 3065 parent_die = parent_die->GetParent(); 3066 } 3067 SymbolContext sc_backup = sc; 3068 if (parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc)) 3069 sc = sc_backup; 3070 3071 type_sp = ParseType(sc, die, NULL); 3072 } 3073 else if (type_ptr != DIE_IS_BEING_PARSED) 3074 { 3075 // Grab the existing type from the master types lists 3076 type_sp = type_ptr->shared_from_this(); 3077 } 3078 3079 } 3080 return type_sp; 3081 } 3082 3083 3084 DWARFDIE 3085 SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die) 3086 { 3087 if (orig_die) 3088 { 3089 DWARFDIE die = orig_die; 3090 3091 while (die) 3092 { 3093 // If this is the original DIE that we are searching for a declaration 3094 // for, then don't look in the cache as we don't want our own decl 3095 // context to be our decl context... 3096 if (orig_die != die) 3097 { 3098 switch (die.Tag()) 3099 { 3100 case DW_TAG_compile_unit: 3101 case DW_TAG_namespace: 3102 case DW_TAG_structure_type: 3103 case DW_TAG_union_type: 3104 case DW_TAG_class_type: 3105 case DW_TAG_lexical_block: 3106 case DW_TAG_subprogram: 3107 return die; 3108 3109 default: 3110 break; 3111 } 3112 } 3113 3114 DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification); 3115 if (spec_die) 3116 { 3117 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die); 3118 if (decl_ctx_die) 3119 return decl_ctx_die; 3120 } 3121 3122 DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin); 3123 if (abs_die) 3124 { 3125 DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die); 3126 if (decl_ctx_die) 3127 return decl_ctx_die; 3128 } 3129 3130 die = die.GetParent(); 3131 } 3132 } 3133 return DWARFDIE(); 3134 } 3135 3136 3137 Symbol * 3138 SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name) 3139 { 3140 Symbol *objc_class_symbol = NULL; 3141 if (m_obj_file) 3142 { 3143 Symtab *symtab = m_obj_file->GetSymtab (); 3144 if (symtab) 3145 { 3146 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name, 3147 eSymbolTypeObjCClass, 3148 Symtab::eDebugNo, 3149 Symtab::eVisibilityAny); 3150 } 3151 } 3152 return objc_class_symbol; 3153 } 3154 3155 // Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't 3156 // then we can end up looking through all class types for a complete type and never find 3157 // the full definition. We need to know if this attribute is supported, so we determine 3158 // this here and cache th result. We also need to worry about the debug map DWARF file 3159 // if we are doing darwin DWARF in .o file debugging. 3160 bool 3161 SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu) 3162 { 3163 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) 3164 { 3165 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 3166 if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type()) 3167 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 3168 else 3169 { 3170 DWARFDebugInfo* debug_info = DebugInfo(); 3171 const uint32_t num_compile_units = GetNumCompileUnits(); 3172 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 3173 { 3174 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 3175 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) 3176 { 3177 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 3178 break; 3179 } 3180 } 3181 } 3182 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ()) 3183 return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this); 3184 } 3185 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 3186 } 3187 3188 // This function can be used when a DIE is found that is a forward declaration 3189 // DIE and we want to try and find a type that has the complete definition. 3190 TypeSP 3191 SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die, 3192 const ConstString &type_name, 3193 bool must_be_implementation) 3194 { 3195 3196 TypeSP type_sp; 3197 3198 if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name))) 3199 return type_sp; 3200 3201 DIEArray die_offsets; 3202 3203 if (m_using_apple_tables) 3204 { 3205 if (m_apple_types_ap.get()) 3206 { 3207 const char *name_cstr = type_name.GetCString(); 3208 m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation); 3209 } 3210 } 3211 else 3212 { 3213 if (!m_indexed) 3214 Index (); 3215 3216 m_type_index.Find (type_name, die_offsets); 3217 } 3218 3219 const size_t num_matches = die_offsets.size(); 3220 3221 if (num_matches) 3222 { 3223 DWARFDebugInfo* debug_info = DebugInfo(); 3224 for (size_t i=0; i<num_matches; ++i) 3225 { 3226 const DIERef& die_ref = die_offsets[i]; 3227 DWARFDIE type_die = debug_info->GetDIE (die_ref); 3228 3229 if (type_die) 3230 { 3231 bool try_resolving_type = false; 3232 3233 // Don't try and resolve the DIE we are looking for with the DIE itself! 3234 if (type_die != die) 3235 { 3236 switch (type_die.Tag()) 3237 { 3238 case DW_TAG_class_type: 3239 case DW_TAG_structure_type: 3240 try_resolving_type = true; 3241 break; 3242 default: 3243 break; 3244 } 3245 } 3246 3247 if (try_resolving_type) 3248 { 3249 if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type()) 3250 try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0); 3251 3252 if (try_resolving_type) 3253 { 3254 Type *resolved_type = ResolveType (type_die, false); 3255 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) 3256 { 3257 DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n", 3258 die.GetID(), 3259 m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"), 3260 type_die.GetID(), 3261 type_cu->GetID()); 3262 3263 if (die) 3264 GetDIEToType()[die.GetDIE()] = resolved_type; 3265 type_sp = resolved_type->shared_from_this(); 3266 break; 3267 } 3268 } 3269 } 3270 } 3271 else 3272 { 3273 if (m_using_apple_tables) 3274 { 3275 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", 3276 die_ref.die_offset, type_name.GetCString()); 3277 } 3278 } 3279 3280 } 3281 } 3282 return type_sp; 3283 } 3284 3285 3286 //---------------------------------------------------------------------- 3287 // This function helps to ensure that the declaration contexts match for 3288 // two different DIEs. Often times debug information will refer to a 3289 // forward declaration of a type (the equivalent of "struct my_struct;". 3290 // There will often be a declaration of that type elsewhere that has the 3291 // full definition. When we go looking for the full type "my_struct", we 3292 // will find one or more matches in the accelerator tables and we will 3293 // then need to make sure the type was in the same declaration context 3294 // as the original DIE. This function can efficiently compare two DIEs 3295 // and will return true when the declaration context matches, and false 3296 // when they don't. 3297 //---------------------------------------------------------------------- 3298 bool 3299 SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1, 3300 const DWARFDIE &die2) 3301 { 3302 if (die1 == die2) 3303 return true; 3304 3305 DWARFDIECollection decl_ctx_1; 3306 DWARFDIECollection decl_ctx_2; 3307 //The declaration DIE stack is a stack of the declaration context 3308 // DIEs all the way back to the compile unit. If a type "T" is 3309 // declared inside a class "B", and class "B" is declared inside 3310 // a class "A" and class "A" is in a namespace "lldb", and the 3311 // namespace is in a compile unit, there will be a stack of DIEs: 3312 // 3313 // [0] DW_TAG_class_type for "B" 3314 // [1] DW_TAG_class_type for "A" 3315 // [2] DW_TAG_namespace for "lldb" 3316 // [3] DW_TAG_compile_unit for the source file. 3317 // 3318 // We grab both contexts and make sure that everything matches 3319 // all the way back to the compiler unit. 3320 3321 // First lets grab the decl contexts for both DIEs 3322 die1.GetDeclContextDIEs (decl_ctx_1); 3323 die2.GetDeclContextDIEs (decl_ctx_2); 3324 // Make sure the context arrays have the same size, otherwise 3325 // we are done 3326 const size_t count1 = decl_ctx_1.Size(); 3327 const size_t count2 = decl_ctx_2.Size(); 3328 if (count1 != count2) 3329 return false; 3330 3331 // Make sure the DW_TAG values match all the way back up the 3332 // compile unit. If they don't, then we are done. 3333 DWARFDIE decl_ctx_die1; 3334 DWARFDIE decl_ctx_die2; 3335 size_t i; 3336 for (i=0; i<count1; i++) 3337 { 3338 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i); 3339 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i); 3340 if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag()) 3341 return false; 3342 } 3343 #if defined LLDB_CONFIGURATION_DEBUG 3344 3345 // Make sure the top item in the decl context die array is always 3346 // DW_TAG_compile_unit. If it isn't then something went wrong in 3347 // the DWARFDIE::GetDeclContextDIEs() function... 3348 assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit); 3349 3350 #endif 3351 // Always skip the compile unit when comparing by only iterating up to 3352 // "count - 1". Here we compare the names as we go. 3353 for (i=0; i<count1 - 1; i++) 3354 { 3355 decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i); 3356 decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i); 3357 const char *name1 = decl_ctx_die1.GetName(); 3358 const char *name2 = decl_ctx_die2.GetName(); 3359 // If the string was from a DW_FORM_strp, then the pointer will often 3360 // be the same! 3361 if (name1 == name2) 3362 continue; 3363 3364 // Name pointers are not equal, so only compare the strings 3365 // if both are not NULL. 3366 if (name1 && name2) 3367 { 3368 // If the strings don't compare, we are done... 3369 if (strcmp(name1, name2) != 0) 3370 return false; 3371 } 3372 else 3373 { 3374 // One name was NULL while the other wasn't 3375 return false; 3376 } 3377 } 3378 // We made it through all of the checks and the declaration contexts 3379 // are equal. 3380 return true; 3381 } 3382 3383 3384 TypeSP 3385 SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx) 3386 { 3387 TypeSP type_sp; 3388 3389 const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize(); 3390 if (dwarf_decl_ctx_count > 0) 3391 { 3392 const ConstString type_name(dwarf_decl_ctx[0].name); 3393 const dw_tag_t tag = dwarf_decl_ctx[0].tag; 3394 3395 if (type_name) 3396 { 3397 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS)); 3398 if (log) 3399 { 3400 GetObjectFile()->GetModule()->LogMessage (log, 3401 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')", 3402 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), 3403 dwarf_decl_ctx.GetQualifiedName()); 3404 } 3405 3406 DIEArray die_offsets; 3407 3408 if (m_using_apple_tables) 3409 { 3410 if (m_apple_types_ap.get()) 3411 { 3412 const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag); 3413 const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash); 3414 if (has_tag && has_qualified_name_hash) 3415 { 3416 const char *qualified_name = dwarf_decl_ctx.GetQualifiedName(); 3417 const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name); 3418 if (log) 3419 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()"); 3420 m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets); 3421 } 3422 else if (has_tag) 3423 { 3424 if (log) 3425 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()"); 3426 m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets); 3427 } 3428 else 3429 { 3430 m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets); 3431 } 3432 } 3433 } 3434 else 3435 { 3436 if (!m_indexed) 3437 Index (); 3438 3439 m_type_index.Find (type_name, die_offsets); 3440 } 3441 3442 const size_t num_matches = die_offsets.size(); 3443 3444 3445 if (num_matches) 3446 { 3447 DWARFDebugInfo* debug_info = DebugInfo(); 3448 for (size_t i=0; i<num_matches; ++i) 3449 { 3450 const DIERef& die_ref = die_offsets[i]; 3451 DWARFDIE type_die = debug_info->GetDIE (die_ref); 3452 3453 if (type_die) 3454 { 3455 bool try_resolving_type = false; 3456 3457 // Don't try and resolve the DIE we are looking for with the DIE itself! 3458 const dw_tag_t type_tag = type_die.Tag(); 3459 // Make sure the tags match 3460 if (type_tag == tag) 3461 { 3462 // The tags match, lets try resolving this type 3463 try_resolving_type = true; 3464 } 3465 else 3466 { 3467 // The tags don't match, but we need to watch our for a 3468 // forward declaration for a struct and ("struct foo") 3469 // ends up being a class ("class foo { ... };") or 3470 // vice versa. 3471 switch (type_tag) 3472 { 3473 case DW_TAG_class_type: 3474 // We had a "class foo", see if we ended up with a "struct foo { ... };" 3475 try_resolving_type = (tag == DW_TAG_structure_type); 3476 break; 3477 case DW_TAG_structure_type: 3478 // We had a "struct foo", see if we ended up with a "class foo { ... };" 3479 try_resolving_type = (tag == DW_TAG_class_type); 3480 break; 3481 default: 3482 // Tags don't match, don't event try to resolve 3483 // using this type whose name matches.... 3484 break; 3485 } 3486 } 3487 3488 if (try_resolving_type) 3489 { 3490 DWARFDeclContext type_dwarf_decl_ctx; 3491 type_die.GetDWARFDeclContext (type_dwarf_decl_ctx); 3492 3493 if (log) 3494 { 3495 GetObjectFile()->GetModule()->LogMessage (log, 3496 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)", 3497 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), 3498 dwarf_decl_ctx.GetQualifiedName(), 3499 type_die.GetOffset(), 3500 type_dwarf_decl_ctx.GetQualifiedName()); 3501 } 3502 3503 // Make sure the decl contexts match all the way up 3504 if (dwarf_decl_ctx == type_dwarf_decl_ctx) 3505 { 3506 Type *resolved_type = ResolveType (type_die, false); 3507 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) 3508 { 3509 type_sp = resolved_type->shared_from_this(); 3510 break; 3511 } 3512 } 3513 } 3514 else 3515 { 3516 if (log) 3517 { 3518 std::string qualified_name; 3519 type_die.GetQualifiedName(qualified_name); 3520 GetObjectFile()->GetModule()->LogMessage (log, 3521 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)", 3522 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), 3523 dwarf_decl_ctx.GetQualifiedName(), 3524 type_die.GetOffset(), 3525 qualified_name.c_str()); 3526 } 3527 } 3528 } 3529 else 3530 { 3531 if (m_using_apple_tables) 3532 { 3533 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", 3534 die_ref.die_offset, type_name.GetCString()); 3535 } 3536 } 3537 3538 } 3539 } 3540 } 3541 } 3542 return type_sp; 3543 } 3544 3545 TypeSP 3546 SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr) 3547 { 3548 TypeSP type_sp; 3549 3550 if (die) 3551 { 3552 TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); 3553 3554 if (type_system) 3555 { 3556 DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); 3557 if (dwarf_ast) 3558 { 3559 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); 3560 type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr); 3561 if (type_sp) 3562 { 3563 TypeList* type_list = GetTypeList(); 3564 if (type_list) 3565 type_list->Insert(type_sp); 3566 } 3567 } 3568 } 3569 } 3570 3571 return type_sp; 3572 } 3573 3574 size_t 3575 SymbolFileDWARF::ParseTypes 3576 ( 3577 const SymbolContext& sc, 3578 const DWARFDIE &orig_die, 3579 bool parse_siblings, 3580 bool parse_children 3581 ) 3582 { 3583 size_t types_added = 0; 3584 DWARFDIE die = orig_die; 3585 while (die) 3586 { 3587 bool type_is_new = false; 3588 if (ParseType(sc, die, &type_is_new).get()) 3589 { 3590 if (type_is_new) 3591 ++types_added; 3592 } 3593 3594 if (parse_children && die.HasChildren()) 3595 { 3596 if (die.Tag() == DW_TAG_subprogram) 3597 { 3598 SymbolContext child_sc(sc); 3599 child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); 3600 types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true); 3601 } 3602 else 3603 types_added += ParseTypes(sc, die.GetFirstChild(), true, true); 3604 } 3605 3606 if (parse_siblings) 3607 die = die.GetSibling(); 3608 else 3609 die.Clear(); 3610 } 3611 return types_added; 3612 } 3613 3614 3615 size_t 3616 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 3617 { 3618 assert(sc.comp_unit && sc.function); 3619 size_t functions_added = 0; 3620 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); 3621 if (dwarf_cu) 3622 { 3623 const dw_offset_t function_die_offset = sc.function->GetID(); 3624 DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset); 3625 if (function_die) 3626 { 3627 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0); 3628 } 3629 } 3630 3631 return functions_added; 3632 } 3633 3634 3635 size_t 3636 SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 3637 { 3638 // At least a compile unit must be valid 3639 assert(sc.comp_unit); 3640 size_t types_added = 0; 3641 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); 3642 if (dwarf_cu) 3643 { 3644 if (sc.function) 3645 { 3646 dw_offset_t function_die_offset = sc.function->GetID(); 3647 DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset); 3648 if (func_die && func_die.HasChildren()) 3649 { 3650 types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true); 3651 } 3652 } 3653 else 3654 { 3655 DWARFDIE dwarf_cu_die = dwarf_cu->DIE(); 3656 if (dwarf_cu_die && dwarf_cu_die.HasChildren()) 3657 { 3658 types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true); 3659 } 3660 } 3661 } 3662 3663 return types_added; 3664 } 3665 3666 size_t 3667 SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 3668 { 3669 if (sc.comp_unit != NULL) 3670 { 3671 DWARFDebugInfo* info = DebugInfo(); 3672 if (info == NULL) 3673 return 0; 3674 3675 if (sc.function) 3676 { 3677 DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID())); 3678 3679 const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS); 3680 if (func_lo_pc != LLDB_INVALID_ADDRESS) 3681 { 3682 const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true); 3683 3684 // Let all blocks know they have parse all their variables 3685 sc.function->GetBlock (false).SetDidParseVariables (true, true); 3686 return num_variables; 3687 } 3688 } 3689 else if (sc.comp_unit) 3690 { 3691 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()); 3692 3693 if (dwarf_cu == NULL) 3694 return 0; 3695 3696 uint32_t vars_added = 0; 3697 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 3698 3699 if (variables.get() == NULL) 3700 { 3701 variables.reset(new VariableList()); 3702 sc.comp_unit->SetVariableList(variables); 3703 3704 DIEArray die_offsets; 3705 if (m_using_apple_tables) 3706 { 3707 if (m_apple_names_ap.get()) 3708 { 3709 DWARFMappedHash::DIEInfoArray hash_data_array; 3710 if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), 3711 dwarf_cu->GetNextCompileUnitOffset(), 3712 hash_data_array)) 3713 { 3714 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); 3715 } 3716 } 3717 } 3718 else 3719 { 3720 // Index if we already haven't to make sure the compile units 3721 // get indexed and make their global DIE index list 3722 if (!m_indexed) 3723 Index (); 3724 3725 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), 3726 die_offsets); 3727 } 3728 3729 const size_t num_matches = die_offsets.size(); 3730 if (num_matches) 3731 { 3732 DWARFDebugInfo* debug_info = DebugInfo(); 3733 for (size_t i=0; i<num_matches; ++i) 3734 { 3735 const DIERef& die_ref = die_offsets[i]; 3736 DWARFDIE die = debug_info->GetDIE (die_ref); 3737 if (die) 3738 { 3739 VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); 3740 if (var_sp) 3741 { 3742 variables->AddVariableIfUnique (var_sp); 3743 ++vars_added; 3744 } 3745 } 3746 else 3747 { 3748 if (m_using_apple_tables) 3749 { 3750 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset); 3751 } 3752 } 3753 3754 } 3755 } 3756 } 3757 return vars_added; 3758 } 3759 } 3760 return 0; 3761 } 3762 3763 VariableSP 3764 SymbolFileDWARF::ParseVariableDIE 3765 ( 3766 const SymbolContext& sc, 3767 const DWARFDIE &die, 3768 const lldb::addr_t func_low_pc 3769 ) 3770 { 3771 if (die.GetDWARF() != this) 3772 return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc); 3773 3774 VariableSP var_sp; 3775 if (!die) 3776 return var_sp; 3777 3778 var_sp = GetDIEToVariable()[die.GetDIE()]; 3779 if (var_sp) 3780 return var_sp; // Already been parsed! 3781 3782 const dw_tag_t tag = die.Tag(); 3783 ModuleSP module = GetObjectFile()->GetModule(); 3784 3785 if ((tag == DW_TAG_variable) || 3786 (tag == DW_TAG_constant) || 3787 (tag == DW_TAG_formal_parameter && sc.function)) 3788 { 3789 DWARFAttributes attributes; 3790 const size_t num_attributes = die.GetAttributes(attributes); 3791 DWARFDIE spec_die; 3792 if (num_attributes > 0) 3793 { 3794 const char *name = NULL; 3795 const char *mangled = NULL; 3796 Declaration decl; 3797 uint32_t i; 3798 DWARFFormValue type_die_form; 3799 DWARFExpression location(die.GetCU()); 3800 bool is_external = false; 3801 bool is_artificial = false; 3802 bool location_is_const_value_data = false; 3803 bool has_explicit_location = false; 3804 DWARFFormValue const_value; 3805 //AccessType accessibility = eAccessNone; 3806 3807 for (i=0; i<num_attributes; ++i) 3808 { 3809 dw_attr_t attr = attributes.AttributeAtIndex(i); 3810 DWARFFormValue form_value; 3811 3812 if (attributes.ExtractFormValueAtIndex(i, form_value)) 3813 { 3814 switch (attr) 3815 { 3816 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3817 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3818 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3819 case DW_AT_name: name = form_value.AsCString(); break; 3820 case DW_AT_linkage_name: 3821 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break; 3822 case DW_AT_type: type_die_form = form_value; break; 3823 case DW_AT_external: is_external = form_value.Boolean(); break; 3824 case DW_AT_const_value: 3825 // If we have already found a DW_AT_location attribute, ignore this attribute. 3826 if (!has_explicit_location) 3827 { 3828 location_is_const_value_data = true; 3829 // The constant value will be either a block, a data value or a string. 3830 const DWARFDataExtractor& debug_info_data = get_debug_info_data(); 3831 if (DWARFFormValue::IsBlockForm(form_value.Form())) 3832 { 3833 // Retrieve the value as a block expression. 3834 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 3835 uint32_t block_length = form_value.Unsigned(); 3836 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length); 3837 } 3838 else if (DWARFFormValue::IsDataForm(form_value.Form())) 3839 { 3840 // Retrieve the value as a data expression. 3841 DWARFFormValue::FixedFormSizes fixed_form_sizes = 3842 DWARFFormValue::GetFixedFormSizesForAddressSize ( 3843 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), 3844 attributes.CompileUnitAtIndex(i)->IsDWARF64()); 3845 uint32_t data_offset = attributes.DIEOffsetAtIndex(i); 3846 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form()); 3847 if (data_length == 0) 3848 { 3849 const uint8_t *data_pointer = form_value.BlockData(); 3850 if (data_pointer) 3851 { 3852 form_value.Unsigned(); 3853 } 3854 else if (DWARFFormValue::IsDataForm(form_value.Form())) 3855 { 3856 // we need to get the byte size of the type later after we create the variable 3857 const_value = form_value; 3858 } 3859 } 3860 else 3861 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); 3862 } 3863 else 3864 { 3865 // Retrieve the value as a string expression. 3866 if (form_value.Form() == DW_FORM_strp) 3867 { 3868 DWARFFormValue::FixedFormSizes fixed_form_sizes = 3869 DWARFFormValue::GetFixedFormSizesForAddressSize ( 3870 attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), 3871 attributes.CompileUnitAtIndex(i)->IsDWARF64()); 3872 uint32_t data_offset = attributes.DIEOffsetAtIndex(i); 3873 uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form()); 3874 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); 3875 } 3876 else 3877 { 3878 const char *str = form_value.AsCString(); 3879 uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart(); 3880 uint32_t string_length = strlen(str) + 1; 3881 location.CopyOpcodeData(module, debug_info_data, string_offset, string_length); 3882 } 3883 } 3884 } 3885 break; 3886 case DW_AT_location: 3887 { 3888 location_is_const_value_data = false; 3889 has_explicit_location = true; 3890 if (form_value.BlockData()) 3891 { 3892 const DWARFDataExtractor& debug_info_data = get_debug_info_data(); 3893 3894 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 3895 uint32_t block_length = form_value.Unsigned(); 3896 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length); 3897 } 3898 else 3899 { 3900 const DWARFDataExtractor& debug_loc_data = get_debug_loc_data(); 3901 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 3902 3903 size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset); 3904 if (loc_list_length > 0) 3905 { 3906 location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length); 3907 assert (func_low_pc != LLDB_INVALID_ADDRESS); 3908 location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress()); 3909 } 3910 } 3911 } 3912 break; 3913 case DW_AT_specification: 3914 { 3915 DWARFDebugInfo* debug_info = DebugInfo(); 3916 if (debug_info) 3917 spec_die = debug_info->GetDIE(DIERef(form_value)); 3918 break; 3919 } 3920 case DW_AT_artificial: is_artificial = form_value.Boolean(); break; 3921 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3922 case DW_AT_declaration: 3923 case DW_AT_description: 3924 case DW_AT_endianity: 3925 case DW_AT_segment: 3926 case DW_AT_start_scope: 3927 case DW_AT_visibility: 3928 default: 3929 case DW_AT_abstract_origin: 3930 case DW_AT_sibling: 3931 break; 3932 } 3933 } 3934 } 3935 3936 const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die); 3937 const dw_tag_t parent_tag = die.GetParent().Tag(); 3938 bool is_static_member = parent_tag == DW_TAG_compile_unit && (parent_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type); 3939 3940 ValueType scope = eValueTypeInvalid; 3941 3942 const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die); 3943 SymbolContextScope * symbol_context_scope = NULL; 3944 3945 if (!mangled) 3946 { 3947 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to 3948 // generate fully qualified names of global variables with commands like "frame var j". 3949 // For example, if j were an int variable holding a value 4 and declared in a namespace 3950 // B which in turn is contained in a namespace A, the command "frame var j" returns 3951 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able 3952 // to generate a fully qualified name from the declaration context. 3953 if (parent_tag == DW_TAG_compile_unit && 3954 Language::LanguageIsCPlusPlus(die.GetLanguage())) 3955 { 3956 DWARFDeclContext decl_ctx; 3957 3958 die.GetDWARFDeclContext(decl_ctx); 3959 mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); 3960 } 3961 } 3962 3963 // DWARF doesn't specify if a DW_TAG_variable is a local, global 3964 // or static variable, so we have to do a little digging by 3965 // looking at the location of a variable to see if it contains 3966 // a DW_OP_addr opcode _somewhere_ in the definition. I say 3967 // somewhere because clang likes to combine small global variables 3968 // into the same symbol and have locations like: 3969 // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus 3970 // So if we don't have a DW_TAG_formal_parameter, we can look at 3971 // the location to see if it contains a DW_OP_addr opcode, and 3972 // then we can correctly classify our variables. 3973 if (tag == DW_TAG_formal_parameter) 3974 scope = eValueTypeVariableArgument; 3975 else 3976 { 3977 bool op_error = false; 3978 // Check if the location has a DW_OP_addr with any address value... 3979 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS; 3980 if (!location_is_const_value_data) 3981 { 3982 location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error); 3983 if (op_error) 3984 { 3985 StreamString strm; 3986 location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL); 3987 GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str()); 3988 } 3989 } 3990 3991 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS) 3992 { 3993 if (is_external) 3994 scope = eValueTypeVariableGlobal; 3995 else 3996 scope = eValueTypeVariableStatic; 3997 3998 3999 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile (); 4000 4001 if (debug_map_symfile) 4002 { 4003 // When leaving the DWARF in the .o files on darwin, 4004 // when we have a global variable that wasn't initialized, 4005 // the .o file might not have allocated a virtual 4006 // address for the global variable. In this case it will 4007 // have created a symbol for the global variable 4008 // that is undefined/data and external and the value will 4009 // be the byte size of the variable. When we do the 4010 // address map in SymbolFileDWARFDebugMap we rely on 4011 // having an address, we need to do some magic here 4012 // so we can get the correct address for our global 4013 // variable. The address for all of these entries 4014 // will be zero, and there will be an undefined symbol 4015 // in this object file, and the executable will have 4016 // a matching symbol with a good address. So here we 4017 // dig up the correct address and replace it in the 4018 // location for the variable, and set the variable's 4019 // symbol context scope to be that of the main executable 4020 // so the file address will resolve correctly. 4021 bool linked_oso_file_addr = false; 4022 if (is_external && location_DW_OP_addr == 0) 4023 { 4024 // we have a possible uninitialized extern global 4025 ConstString const_name(mangled ? mangled : name); 4026 ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile(); 4027 if (debug_map_objfile) 4028 { 4029 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(); 4030 if (debug_map_symtab) 4031 { 4032 Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name, 4033 eSymbolTypeData, 4034 Symtab::eDebugYes, 4035 Symtab::eVisibilityExtern); 4036 if (exe_symbol) 4037 { 4038 if (exe_symbol->ValueIsAddress()) 4039 { 4040 const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress(); 4041 if (exe_file_addr != LLDB_INVALID_ADDRESS) 4042 { 4043 if (location.Update_DW_OP_addr (exe_file_addr)) 4044 { 4045 linked_oso_file_addr = true; 4046 symbol_context_scope = exe_symbol; 4047 } 4048 } 4049 } 4050 } 4051 } 4052 } 4053 } 4054 4055 if (!linked_oso_file_addr) 4056 { 4057 // The DW_OP_addr is not zero, but it contains a .o file address which 4058 // needs to be linked up correctly. 4059 const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr); 4060 if (exe_file_addr != LLDB_INVALID_ADDRESS) 4061 { 4062 // Update the file address for this variable 4063 location.Update_DW_OP_addr (exe_file_addr); 4064 } 4065 else 4066 { 4067 // Variable didn't make it into the final executable 4068 return var_sp; 4069 } 4070 } 4071 } 4072 } 4073 else 4074 { 4075 scope = eValueTypeVariableLocal; 4076 } 4077 } 4078 4079 if (symbol_context_scope == NULL) 4080 { 4081 switch (parent_tag) 4082 { 4083 case DW_TAG_subprogram: 4084 case DW_TAG_inlined_subroutine: 4085 case DW_TAG_lexical_block: 4086 if (sc.function) 4087 { 4088 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); 4089 if (symbol_context_scope == NULL) 4090 symbol_context_scope = sc.function; 4091 } 4092 break; 4093 4094 default: 4095 symbol_context_scope = sc.comp_unit; 4096 break; 4097 } 4098 } 4099 4100 if (symbol_context_scope) 4101 { 4102 SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID())); 4103 4104 if (const_value.Form() && type_sp && type_sp->GetType()) 4105 location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize()); 4106 4107 var_sp.reset (new Variable (die.GetID(), 4108 name, 4109 mangled, 4110 type_sp, 4111 scope, 4112 symbol_context_scope, 4113 &decl, 4114 location, 4115 is_external, 4116 is_artificial, 4117 is_static_member)); 4118 4119 var_sp->SetLocationIsConstantValueData (location_is_const_value_data); 4120 } 4121 else 4122 { 4123 // Not ready to parse this variable yet. It might be a global 4124 // or static variable that is in a function scope and the function 4125 // in the symbol context wasn't filled in yet 4126 return var_sp; 4127 } 4128 } 4129 // Cache var_sp even if NULL (the variable was just a specification or 4130 // was missing vital information to be able to be displayed in the debugger 4131 // (missing location due to optimization, etc)) so we don't re-parse 4132 // this DIE over and over later... 4133 GetDIEToVariable()[die.GetDIE()] = var_sp; 4134 if (spec_die) 4135 GetDIEToVariable()[spec_die.GetDIE()] = var_sp; 4136 } 4137 return var_sp; 4138 } 4139 4140 4141 DWARFDIE 4142 SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref, 4143 dw_offset_t spec_block_die_offset) 4144 { 4145 // Give the concrete function die specified by "func_die_offset", find the 4146 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4147 // to "spec_block_die_offset" 4148 return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset); 4149 } 4150 4151 4152 DWARFDIE 4153 SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die, 4154 dw_offset_t spec_block_die_offset) 4155 { 4156 if (die) 4157 { 4158 switch (die.Tag()) 4159 { 4160 case DW_TAG_subprogram: 4161 case DW_TAG_inlined_subroutine: 4162 case DW_TAG_lexical_block: 4163 { 4164 if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) 4165 return die; 4166 4167 if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset) 4168 return die; 4169 } 4170 break; 4171 } 4172 4173 // Give the concrete function die specified by "func_die_offset", find the 4174 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4175 // to "spec_block_die_offset" 4176 for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling()) 4177 { 4178 DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset); 4179 if (result_die) 4180 return result_die; 4181 } 4182 } 4183 4184 return DWARFDIE(); 4185 } 4186 4187 size_t 4188 SymbolFileDWARF::ParseVariables (const SymbolContext& sc, 4189 const DWARFDIE &orig_die, 4190 const lldb::addr_t func_low_pc, 4191 bool parse_siblings, 4192 bool parse_children, 4193 VariableList* cc_variable_list) 4194 { 4195 if (!orig_die) 4196 return 0; 4197 4198 VariableListSP variable_list_sp; 4199 4200 size_t vars_added = 0; 4201 DWARFDIE die = orig_die; 4202 while (die) 4203 { 4204 dw_tag_t tag = die.Tag(); 4205 4206 // Check to see if we have already parsed this variable or constant? 4207 VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]; 4208 if (var_sp) 4209 { 4210 if (cc_variable_list) 4211 cc_variable_list->AddVariableIfUnique (var_sp); 4212 } 4213 else 4214 { 4215 // We haven't already parsed it, lets do that now. 4216 if ((tag == DW_TAG_variable) || 4217 (tag == DW_TAG_constant) || 4218 (tag == DW_TAG_formal_parameter && sc.function)) 4219 { 4220 if (variable_list_sp.get() == NULL) 4221 { 4222 DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die); 4223 dw_tag_t parent_tag = sc_parent_die.Tag(); 4224 switch (parent_tag) 4225 { 4226 case DW_TAG_compile_unit: 4227 if (sc.comp_unit != NULL) 4228 { 4229 variable_list_sp = sc.comp_unit->GetVariableList(false); 4230 if (variable_list_sp.get() == NULL) 4231 { 4232 variable_list_sp.reset(new VariableList()); 4233 sc.comp_unit->SetVariableList(variable_list_sp); 4234 } 4235 } 4236 else 4237 { 4238 GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n", 4239 sc_parent_die.GetID(), 4240 sc_parent_die.GetTagAsCString(), 4241 orig_die.GetID(), 4242 orig_die.GetTagAsCString()); 4243 } 4244 break; 4245 4246 case DW_TAG_subprogram: 4247 case DW_TAG_inlined_subroutine: 4248 case DW_TAG_lexical_block: 4249 if (sc.function != NULL) 4250 { 4251 // Check to see if we already have parsed the variables for the given scope 4252 4253 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); 4254 if (block == NULL) 4255 { 4256 // This must be a specification or abstract origin with 4257 // a concrete block counterpart in the current function. We need 4258 // to find the concrete block so we can correctly add the 4259 // variable to it 4260 const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()), 4261 sc_parent_die.GetOffset()); 4262 if (concrete_block_die) 4263 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID()); 4264 } 4265 4266 if (block != NULL) 4267 { 4268 const bool can_create = false; 4269 variable_list_sp = block->GetBlockVariableList (can_create); 4270 if (variable_list_sp.get() == NULL) 4271 { 4272 variable_list_sp.reset(new VariableList()); 4273 block->SetVariableList(variable_list_sp); 4274 } 4275 } 4276 } 4277 break; 4278 4279 default: 4280 GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n", 4281 orig_die.GetID(), 4282 orig_die.GetTagAsCString()); 4283 break; 4284 } 4285 } 4286 4287 if (variable_list_sp) 4288 { 4289 VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc)); 4290 if (var_sp) 4291 { 4292 variable_list_sp->AddVariableIfUnique (var_sp); 4293 if (cc_variable_list) 4294 cc_variable_list->AddVariableIfUnique (var_sp); 4295 ++vars_added; 4296 } 4297 } 4298 } 4299 } 4300 4301 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 4302 4303 if (!skip_children && parse_children && die.HasChildren()) 4304 { 4305 vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list); 4306 } 4307 4308 if (parse_siblings) 4309 die = die.GetSibling(); 4310 else 4311 die.Clear(); 4312 } 4313 return vars_added; 4314 } 4315 4316 //------------------------------------------------------------------ 4317 // PluginInterface protocol 4318 //------------------------------------------------------------------ 4319 ConstString 4320 SymbolFileDWARF::GetPluginName() 4321 { 4322 return GetPluginNameStatic(); 4323 } 4324 4325 uint32_t 4326 SymbolFileDWARF::GetPluginVersion() 4327 { 4328 return 1; 4329 } 4330 4331 void 4332 SymbolFileDWARF::DumpIndexes () 4333 { 4334 StreamFile s(stdout, false); 4335 4336 s.Printf ("DWARF index for (%s) '%s':", 4337 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), 4338 GetObjectFile()->GetFileSpec().GetPath().c_str()); 4339 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 4340 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 4341 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 4342 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 4343 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 4344 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 4345 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 4346 s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s); 4347 } 4348 4349 4350 SymbolFileDWARFDebugMap * 4351 SymbolFileDWARF::GetDebugMapSymfile () 4352 { 4353 if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) 4354 { 4355 lldb::ModuleSP module_sp (m_debug_map_module_wp.lock()); 4356 if (module_sp) 4357 { 4358 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); 4359 if (sym_vendor) 4360 m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile(); 4361 } 4362 } 4363 return m_debug_map_symfile; 4364 } 4365 4366 DWARFExpression::LocationListFormat 4367 SymbolFileDWARF::GetLocationListFormat() const 4368 { 4369 return DWARFExpression::RegularLocationList; 4370 } 4371