summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp730
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 &regex,
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 &regex,
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 &regex,
+ 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 &regex,
+ 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 &regex,
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() {
OpenPOWER on IntegriCloud