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