diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 730 |
1 files changed, 663 insertions, 67 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 4ad85fb9b58..edee05223b9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -49,11 +49,16 @@ #include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/VariableList.h" +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" + #include "lldb/Target/Language.h" -#include "AppleDWARFIndex.h" +#include "lldb/Host/TaskPool.h" + #include "DWARFASTParser.h" #include "DWARFASTParserClang.h" +#include "DWARFUnit.h" #include "DWARFDIECollection.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" @@ -63,9 +68,7 @@ #include "DWARFDebugRanges.h" #include "DWARFDeclContext.h" #include "DWARFFormValue.h" -#include "DWARFUnit.h" #include "LogChannelDWARF.h" -#include "ManualDWARFIndex.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDwp.h" @@ -390,16 +393,21 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) { } SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile) - : SymbolFile(objfile), UserID(uint64_t(DW_INVALID_OFFSET) - << 32), // Used by SymbolFileDWARFDebugMap to - // when this class parses .o files to - // contain the .o file index/ID + : SymbolFile(objfile), + UserID(uint64_t(DW_INVALID_OFFSET) << 32), // Used by SymbolFileDWARFDebugMap to when + // this class parses .o files to contain + // the .o file index/ID m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(), m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(), m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(), m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(), - m_line(), m_fetched_external_modules(false), + m_line(), m_apple_names_ap(), m_apple_types_ap(), m_apple_namespaces_ap(), + m_apple_objc_ap(), m_function_basename_index(), + m_function_fullname_index(), m_function_method_index(), + m_function_selector_index(), m_objc_class_selectors_index(), + m_global_index(), m_type_index(), m_namespace_index(), m_indexed(false), + m_using_apple_tables(false), m_fetched_external_modules(false), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(), m_unique_ast_type_map() {} @@ -442,19 +450,45 @@ void SymbolFileDWARF::InitializeObject() { m_obj_file->ReadSectionData(section, m_dwarf_data); } - DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc; - LoadSectionData(eSectionTypeDWARFAppleNames, apple_names); - LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces); - LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types); - LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc); + get_apple_names_data(); + if (m_data_apple_names.m_data.GetByteSize() > 0) { + m_apple_names_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_names.m_data, get_debug_str_data(), ".apple_names")); + if (m_apple_names_ap->IsValid()) + m_using_apple_tables = true; + else + m_apple_names_ap.reset(); + } + get_apple_types_data(); + if (m_data_apple_types.m_data.GetByteSize() > 0) { + m_apple_types_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_types.m_data, get_debug_str_data(), ".apple_types")); + if (m_apple_types_ap->IsValid()) + m_using_apple_tables = true; + else + m_apple_types_ap.reset(); + } - m_index = AppleDWARFIndex::Create(*GetObjectFile()->GetModule(), apple_names, - apple_namespaces, apple_types, apple_objc, - get_debug_str_data()); + get_apple_namespaces_data(); + if (m_data_apple_namespaces.m_data.GetByteSize() > 0) { + m_apple_namespaces_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_namespaces.m_data, get_debug_str_data(), + ".apple_namespaces")); + if (m_apple_namespaces_ap->IsValid()) + m_using_apple_tables = true; + else + m_apple_namespaces_ap.reset(); + } - if (!m_index) - m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), - DebugInfo()); + get_apple_objc_data(); + if (m_data_apple_objc.m_data.GetByteSize() > 0) { + m_apple_objc_ap.reset(new DWARFMappedHash::MemoryTable( + m_data_apple_objc.m_data, get_debug_str_data(), ".apple_objc")); + if (m_apple_objc_ap->IsValid()) + m_using_apple_tables = true; + else + m_apple_objc_ap.reset(); + } } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { @@ -1475,7 +1509,16 @@ SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu, size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name, DIEArray &method_die_offsets) { method_die_offsets.clear(); - m_index->GetObjCMethods(class_name, method_die_offsets); + if (m_using_apple_tables) { + if (m_apple_objc_ap.get()) + m_apple_objc_ap->FindByName(class_name.GetStringRef(), + method_die_offsets); + } else { + if (!m_indexed) + Index(); + + m_objc_class_selectors_index.Find(class_name, method_die_offsets); + } return method_die_offsets.size(); } @@ -1938,7 +1981,133 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, void SymbolFileDWARF::PreloadSymbols() { std::lock_guard<std::recursive_mutex> guard( GetObjectFile()->GetModule()->GetMutex()); - m_index->Preload(); + Index(); +} + +void SymbolFileDWARF::Index() { + if (m_indexed) + return; + m_indexed = true; + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer( + func_cat, "SymbolFileDWARF::Index (%s)", + GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>")); + + DWARFDebugInfo *debug_info = DebugInfo(); + if (debug_info) { + const uint32_t num_compile_units = GetNumCompileUnits(); + if (num_compile_units == 0) + return; + + std::vector<NameToDIE> function_basename_index(num_compile_units); + std::vector<NameToDIE> function_fullname_index(num_compile_units); + std::vector<NameToDIE> function_method_index(num_compile_units); + std::vector<NameToDIE> function_selector_index(num_compile_units); + std::vector<NameToDIE> objc_class_selectors_index(num_compile_units); + std::vector<NameToDIE> global_index(num_compile_units); + std::vector<NameToDIE> type_index(num_compile_units); + std::vector<NameToDIE> namespace_index(num_compile_units); + + // std::vector<bool> might be implemented using bit test-and-set, so use + // uint8_t instead. + std::vector<uint8_t> clear_cu_dies(num_compile_units, false); + auto parser_fn = [debug_info, &function_basename_index, + &function_fullname_index, &function_method_index, + &function_selector_index, &objc_class_selectors_index, + &global_index, &type_index, + &namespace_index](size_t cu_idx) { + DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + if (dwarf_cu) { + dwarf_cu->Index( + function_basename_index[cu_idx], function_fullname_index[cu_idx], + function_method_index[cu_idx], function_selector_index[cu_idx], + objc_class_selectors_index[cu_idx], global_index[cu_idx], + type_index[cu_idx], namespace_index[cu_idx]); + } + }; + + auto extract_fn = [debug_info, &clear_cu_dies](size_t cu_idx) { + DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + if (dwarf_cu) { + // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the DIEs + // for a compile unit have already been parsed. + if (dwarf_cu->ExtractDIEsIfNeeded(false) > 1) + clear_cu_dies[cu_idx] = true; + } + }; + + // Create a task runner that extracts dies for each DWARF compile unit in a + // separate thread + //---------------------------------------------------------------------- + // First figure out which compile units didn't have their DIEs already + // parsed and remember this. If no DIEs were parsed prior to this index + // function call, we are going to want to clear the CU dies after we are + // done indexing to make sure we don't pull in all DWARF dies, but we need + // to wait until all compile units have been indexed in case a DIE in one + // compile unit refers to another and the indexes accesses those DIEs. + //---------------------------------------------------------------------- + TaskMapOverInt(0, num_compile_units, extract_fn); + + // Now create a task runner that can index each DWARF compile unit in a + // separate thread so we can index quickly. + + TaskMapOverInt(0, num_compile_units, parser_fn); + + auto finalize_fn = [](NameToDIE &index, std::vector<NameToDIE> &srcs) { + for (auto &src : srcs) + index.Append(src); + index.Finalize(); + }; + + TaskPool::RunTasks( + [&]() { + finalize_fn(m_function_basename_index, function_basename_index); + }, + [&]() { + finalize_fn(m_function_fullname_index, function_fullname_index); + }, + [&]() { finalize_fn(m_function_method_index, function_method_index); }, + [&]() { + finalize_fn(m_function_selector_index, function_selector_index); + }, + [&]() { + finalize_fn(m_objc_class_selectors_index, objc_class_selectors_index); + }, + [&]() { finalize_fn(m_global_index, global_index); }, + [&]() { finalize_fn(m_type_index, type_index); }, + [&]() { finalize_fn(m_namespace_index, namespace_index); }); + + //---------------------------------------------------------------------- + // Keep memory down by clearing DIEs for any compile units if indexing + // caused us to load the compile unit's DIEs. + //---------------------------------------------------------------------- + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + if (clear_cu_dies[cu_idx]) + debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true); + } + +#if defined(ENABLE_DEBUG_PRINTF) + StreamFile s(stdout, false); + s.Printf("DWARF index for '%s':", + GetObjectFile()->GetFileSpec().GetPath().c_str()); + s.Printf("\nFunction basenames:\n"); + m_function_basename_index.Dump(&s); + s.Printf("\nFunction fullnames:\n"); + m_function_fullname_index.Dump(&s); + s.Printf("\nFunction methods:\n"); + m_function_method_index.Dump(&s); + s.Printf("\nFunction selectors:\n"); + m_function_selector_index.Dump(&s); + s.Printf("\nObjective C class selectors:\n"); + m_objc_class_selectors_index.Dump(&s); + s.Printf("\nGlobals and statics:\n"); + m_global_index.Dump(&s); + s.Printf("\nTypes:\n"); + m_type_index.Dump(&s); + s.Printf("\nNamespaces:\n"); + m_namespace_index.Dump(&s); +#endif + } } bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( @@ -1994,7 +2163,27 @@ uint32_t SymbolFileDWARF::FindGlobalVariables( const uint32_t original_size = variables.GetSize(); DIEArray die_offsets; - m_index->GetGlobalVariables(name, die_offsets); + + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + const char *name_cstr = name.GetCString(); + llvm::StringRef basename; + llvm::StringRef context; + + if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, + basename)) + basename = name_cstr; + + m_apple_names_ap->FindByName(basename, die_offsets); + } + } else { + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); + + m_global_index.Find(name, die_offsets); + } + const size_t num_die_matches = die_offsets.size(); if (num_die_matches) { SymbolContext sc; @@ -2037,8 +2226,12 @@ uint32_t SymbolFileDWARF::FindGlobalVariables( } break; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, name.GetCString()); + } } } } @@ -2080,7 +2273,21 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, const uint32_t original_size = variables.GetSize(); DIEArray die_offsets; - m_index->GetGlobalVariables(regex, die_offsets); + + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + DWARFMappedHash::DIEInfoArray hash_data_array; + if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex(regex, + hash_data_array)) + DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets); + } + } else { + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); + + m_global_index.Find(regex, die_offsets); + } SymbolContext sc; sc.module_sp = m_obj_file->GetModule(); @@ -2099,8 +2306,14 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, if (variables.GetSize() - original_size >= max_matches) break; - } else - m_index->ReportInvalidDIEOffset(die_ref.die_offset, regex.GetText()); + } else { + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for regex '%s')\n", + die_ref.die_offset, regex.GetText().str().c_str()); + } + } } } @@ -2168,6 +2381,48 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, return false; } +void SymbolFileDWARF::FindFunctions(const ConstString &name, + const NameToDIE &name_to_die, + bool include_inlines, + SymbolContextList &sc_list) { + DIEArray die_offsets; + if (name_to_die.Find(name, die_offsets)) { + ParseFunctions(die_offsets, include_inlines, sc_list); + } +} + +void SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, + const NameToDIE &name_to_die, + bool include_inlines, + SymbolContextList &sc_list) { + DIEArray die_offsets; + if (name_to_die.Find(regex, die_offsets)) { + ParseFunctions(die_offsets, include_inlines, sc_list); + } +} + +void SymbolFileDWARF::FindFunctions( + const RegularExpression ®ex, + const DWARFMappedHash::MemoryTable &memory_table, bool include_inlines, + SymbolContextList &sc_list) { + DIEArray die_offsets; + DWARFMappedHash::DIEInfoArray hash_data_array; + if (memory_table.AppendAllDIEsThatMatchingRegex(regex, hash_data_array)) { + DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets); + ParseFunctions(die_offsets, include_inlines, sc_list); + } +} + +void SymbolFileDWARF::ParseFunctions(const DIEArray &die_offsets, + bool include_inlines, + SymbolContextList &sc_list) { + const size_t num_matches = die_offsets.size(); + if (num_matches) { + for (size_t i = 0; i < num_matches; ++i) + ResolveFunction(die_offsets[i], include_inlines, sc_list); + } +} + bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, const DWARFDIE &die) { // If we have no parent decl context to match this DIE matches, and if the @@ -2230,16 +2485,210 @@ SymbolFileDWARF::FindFunctions(const ConstString &name, if (info == NULL) return 0; - m_index->GetFunctions(name, *info, - [this](const DWARFDIE &die, bool include_inlines, - lldb_private::SymbolContextList &sc_list) { - return ResolveFunction(die, include_inlines, sc_list); - }, - [this](lldb::user_id_t type_uid) { - return GetDeclContextContainingUID(type_uid); - }, - parent_decl_ctx, name_type_mask, include_inlines, - sc_list); + std::set<const DWARFDebugInfoEntry *> resolved_dies; + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + + DIEArray die_offsets; + + uint32_t num_matches = 0; + + if (name_type_mask & eFunctionNameTypeFull) { + // If they asked for the full name, match what they typed. At some + // point we may want to canonicalize this (strip double spaces, etc. + // For now, we just add all the dies that we find by exact match. + num_matches = + m_apple_names_ap->FindByName(name.GetStringRef(), die_offsets); + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } + } else { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')", + die_ref.die_offset, name.GetCString()); + } + } + } + + if (name_type_mask & eFunctionNameTypeSelector) { + if (parent_decl_ctx && parent_decl_ctx->IsValid()) + return 0; // no selectors in namespaces + + num_matches = + m_apple_names_ap->FindByName(name.GetStringRef(), die_offsets); + // Now make sure these are actually ObjC methods. In this case we can + // simply look up the name, and if it is an ObjC method name, we're + // good. + + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + const char *die_name = die.GetName(); + if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) { + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } + } + } else { + GetObjectFile()->GetModule()->ReportError( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')", + die_ref.die_offset, name.GetCString()); + } + } + die_offsets.clear(); + } + + if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || + name_type_mask & eFunctionNameTypeBase) { + // The apple_names table stores just the "base name" of C++ methods in + // the table. So we have to extract the base name, look that up, and + // if there is any other information in the name we were passed in we + // have to post-filter based on that. + + // FIXME: Arrange the logic above so that we don't calculate the base + // name twice: + num_matches = + m_apple_names_ap->FindByName(name.GetStringRef(), die_offsets); + + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + // If we get to here, the die is good, and we should add it: + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && + ResolveFunction(die, include_inlines, sc_list)) { + bool keep_die = true; + if ((name_type_mask & + (eFunctionNameTypeBase | eFunctionNameTypeMethod)) != + (eFunctionNameTypeBase | eFunctionNameTypeMethod)) { + // We are looking for either basenames or methods, so we need + // to trim out the ones we won't want by looking at the type + SymbolContext sc; + if (sc_list.GetLastContext(sc)) { + if (sc.block) { + // We have an inlined function + } else if (sc.function) { + Type *type = sc.function->GetType(); + + if (type) { + CompilerDeclContext decl_ctx = + GetDeclContextContainingUID(type->GetID()); + if (decl_ctx.IsStructUnionOrClass()) { + if (name_type_mask & eFunctionNameTypeBase) { + sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1); + keep_die = false; + } + } else { + if (name_type_mask & eFunctionNameTypeMethod) { + sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1); + keep_die = false; + } + } + } else { + GetObjectFile()->GetModule()->ReportWarning( + "function at die offset 0x%8.8x had no function type", + die_ref.die_offset); + } + } + } + } + if (keep_die) + resolved_dies.insert(die.GetDIE()); + } + } else { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_names " + "accelerator table had bad die 0x%8.8x for '%s')", + die_ref.die_offset, name.GetCString()); + } + } + die_offsets.clear(); + } + } + } else { + + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); + + DIEArray die_offsets; + if (name_type_mask & eFunctionNameTypeFull) { + uint32_t num_matches = m_function_basename_index.Find(name, die_offsets); + num_matches += m_function_method_index.Find(name, die_offsets); + num_matches += m_function_fullname_index.Find(name, die_offsets); + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } + } + } + die_offsets.clear(); + } + if (name_type_mask & eFunctionNameTypeBase) { + uint32_t num_base = m_function_basename_index.Find(name, die_offsets); + for (uint32_t i = 0; i < num_base; i++) { + DWARFDIE die = info->GetDIE(die_offsets[i]); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match + + // If we get to here, the die is good, and we should add it: + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } + } + } + die_offsets.clear(); + } + + if (name_type_mask & eFunctionNameTypeMethod) { + if (parent_decl_ctx && parent_decl_ctx->IsValid()) + return 0; // no methods in namespaces + + uint32_t num_base = m_function_method_index.Find(name, die_offsets); + { + for (uint32_t i = 0; i < num_base; i++) { + DWARFDIE die = info->GetDIE(die_offsets[i]); + if (die) { + // If we get to here, the die is good, and we should add it: + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); + } + } + } + } + die_offsets.clear(); + } + + if ((name_type_mask & eFunctionNameTypeSelector) && + (!parent_decl_ctx || !parent_decl_ctx->IsValid())) { + FindFunctions(name, m_function_selector_index, include_inlines, sc_list); + } + } // Return the number of variable that were appended to the list const uint32_t num_matches = sc_list.GetSize() - original_size; @@ -2275,20 +2724,22 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression ®ex, if (!append) sc_list.Clear(); - DWARFDebugInfo *info = DebugInfo(); - if (!info) - return 0; - // Remember how many sc_list are in the list before we search in case we are // appending the results to a variable list. uint32_t original_size = sc_list.GetSize(); - m_index->GetFunctions(regex, *info, - [this](const DWARFDIE &die, bool include_inlines, - lldb_private::SymbolContextList &sc_list) { - return ResolveFunction(die, include_inlines, sc_list); - }, - include_inlines, sc_list); + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) + FindFunctions(regex, *m_apple_names_ap, include_inlines, sc_list); + } else { + // Index the DWARF if we haven't already + if (!m_indexed) + Index(); + + FindFunctions(regex, m_function_basename_index, include_inlines, sc_list); + + FindFunctions(regex, m_function_fullname_index, include_inlines, sc_list); + } // Return the number of variable that were appended to the list return sc_list.GetSize() - original_size; @@ -2365,7 +2816,18 @@ uint32_t SymbolFileDWARF::FindTypes( return 0; DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); + + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + m_apple_types_ap->FindByName(name.GetStringRef(), die_offsets); + } + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(name, die_offsets); + } + const size_t num_die_matches = die_offsets.size(); if (num_die_matches) { @@ -2387,8 +2849,12 @@ uint32_t SymbolFileDWARF::FindTypes( break; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, name.GetCString()); + } } } const uint32_t num_matches = types.GetSize() - initial_types_size; @@ -2437,13 +2903,24 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, if (context.empty()) return 0; + DIEArray die_offsets; + ConstString name = context.back().name; if (!name) return 0; - DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + m_apple_types_ap->FindByName(name.GetStringRef(), die_offsets); + } + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(name, die_offsets); + } + const size_t num_die_matches = die_offsets.size(); if (num_die_matches) { @@ -2466,8 +2943,12 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, ++num_matches; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, name.GetCString()); + } } } return num_matches; @@ -2494,7 +2975,20 @@ SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name, DWARFDebugInfo *info = DebugInfo(); if (info) { DIEArray die_offsets; - m_index->GetNamespaces(name, die_offsets); + + // Index if we already haven't to make sure the compile units get indexed + // and make their global DIE index list + if (m_using_apple_tables) { + if (m_apple_namespaces_ap.get()) { + m_apple_namespaces_ap->FindByName(name.GetStringRef(), die_offsets); + } + } else { + if (!m_indexed) + Index(); + + m_namespace_index.Find(name, die_offsets); + } + const size_t num_matches = die_offsets.size(); if (num_matches) { for (size_t i = 0; i < num_matches; ++i) { @@ -2512,8 +3006,13 @@ SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name, break; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified " + "(.apple_namespaces accelerator table had bad die 0x%8.8x for " + "'%s')\n", + die_ref.die_offset, name.GetCString()); + } } } } @@ -2670,7 +3169,18 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( return type_sp; DIEArray die_offsets; - m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets); + + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + m_apple_types_ap->FindCompleteObjCClassByName( + type_name.GetStringRef(), die_offsets, must_be_implementation); + } + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(type_name, die_offsets); + } const size_t num_matches = die_offsets.size(); @@ -2719,8 +3229,12 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( } } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - type_name.GetStringRef()); + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, type_name.GetCString()); + } } } } @@ -2839,7 +3353,41 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( } DIEArray die_offsets; - m_index->GetTypes(dwarf_decl_ctx, die_offsets); + + if (m_using_apple_tables) { + if (m_apple_types_ap.get()) { + const bool has_tag = + m_apple_types_ap->GetHeader().header_data.ContainsAtom( + DWARFMappedHash::eAtomTypeTag); + const bool has_qualified_name_hash = + m_apple_types_ap->GetHeader().header_data.ContainsAtom( + DWARFMappedHash::eAtomTypeQualNameHash); + if (has_tag && has_qualified_name_hash) { + const char *qualified_name = dwarf_decl_ctx.GetQualifiedName(); + const uint32_t qualified_name_hash = llvm::djbHash(qualified_name); + if (log) + GetObjectFile()->GetModule()->LogMessage( + log, "FindByNameAndTagAndQualifiedNameHash()"); + m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash( + type_name.GetStringRef(), tag, qualified_name_hash, + die_offsets); + } else if (has_tag) { + if (log) + GetObjectFile()->GetModule()->LogMessage(log, + "FindByNameAndTag()"); + m_apple_types_ap->FindByNameAndTag(type_name.GetStringRef(), tag, + die_offsets); + } else { + m_apple_types_ap->FindByName(type_name.GetStringRef(), die_offsets); + } + } + } else { + if (!m_indexed) + Index(); + + m_type_index.Find(type_name, die_offsets); + } + const size_t num_matches = die_offsets.size(); // Get the type system that we are looking to find a type for. We will @@ -2929,8 +3477,12 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( } } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - type_name.GetStringRef()); + if (m_using_apple_tables) { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected( + "the DWARF debug information has been modified (.apple_types " + "accelerator table had bad die 0x%8.8x for '%s')\n", + die_ref.die_offset, type_name.GetCString()); + } } } } @@ -3085,7 +3637,25 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { sc.comp_unit->SetVariableList(variables); DIEArray die_offsets; - m_index->GetGlobalVariables(*dwarf_cu, die_offsets); + if (m_using_apple_tables) { + if (m_apple_names_ap.get()) { + DWARFMappedHash::DIEInfoArray hash_data_array; + if (m_apple_names_ap->AppendAllDIEsInRange( + dwarf_cu->GetOffset(), dwarf_cu->GetNextCompileUnitOffset(), + hash_data_array)) { + DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets); + } + } + } else { + // Index if we already haven't to make sure the compile units get + // indexed and make their global DIE index list + if (!m_indexed) + Index(); + + m_global_index.FindAllEntriesForCompileUnit(dwarf_cu->GetOffset(), + die_offsets); + } + const size_t num_matches = die_offsets.size(); if (num_matches) { for (size_t i = 0; i < num_matches; ++i) { @@ -3098,8 +3668,14 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { variables->AddVariableIfUnique(var_sp); ++vars_added; } - } else - m_index->ReportInvalidDIEOffset(die_ref.die_offset, ""); + } else { + if (m_using_apple_tables) { + 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); + } + } } } } @@ -3693,7 +4269,27 @@ uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } void SymbolFileDWARF::DumpIndexes() { StreamFile s(stdout, false); - m_index->Dump(s); + + s.Printf( + "DWARF index for (%s) '%s':", + GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), + GetObjectFile()->GetFileSpec().GetPath().c_str()); + s.Printf("\nFunction basenames:\n"); + m_function_basename_index.Dump(&s); + s.Printf("\nFunction fullnames:\n"); + m_function_fullname_index.Dump(&s); + s.Printf("\nFunction methods:\n"); + m_function_method_index.Dump(&s); + s.Printf("\nFunction selectors:\n"); + m_function_selector_index.Dump(&s); + s.Printf("\nObjective C class selectors:\n"); + m_objc_class_selectors_index.Dump(&s); + s.Printf("\nGlobals and statics:\n"); + m_global_index.Dump(&s); + s.Printf("\nTypes:\n"); + m_type_index.Dump(&s); + s.Printf("\nNamespaces:\n"); + m_namespace_index.Dump(&s); } SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { |