Index: include/lldb/Symbol/SymbolFile.h =================================================================== --- include/lldb/Symbol/SymbolFile.h +++ include/lldb/Symbol/SymbolFile.h @@ -200,6 +200,8 @@ //------------------------------------------------------------------ virtual void SectionFileAddressesChanged() {} + virtual void Dump(Stream &s) {} + protected: ObjectFile *m_obj_file; // The object file that symbols can be extracted from. uint32_t m_abilities; Index: lit/SymbolFile/DWARF/apple-index-is-used.cpp =================================================================== --- /dev/null +++ lit/SymbolFile/DWARF/apple-index-is-used.cpp @@ -0,0 +1,8 @@ +// Test that we use the apple indexes. +// RUN: clang %s -g -c -o %t --target=x86_64-apple-macosx +// RUN: lldb-test symbols %t | FileCheck %s + +// CHECK: .apple_names index present +// CHECK: .apple_types index present + +int foo; Index: source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -236,5 +236,13 @@ } void AppleDWARFIndex::Dump(Stream &s) { - // TODO: Implement dumping. + if (m_apple_names_up) + s.PutCString(".apple_names index present\n"); + if (m_apple_namespaces_up) + s.PutCString(".apple_namespaces index present\n"); + if (m_apple_types_up) + s.PutCString(".apple_types index present\n"); + if (m_apple_objc_up) + s.PutCString(".apple_objc index present\n"); + // TODO: Dump index contents } Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN AppleDWARFIndex.cpp + DebugNamesDWARFIndex.cpp DIERef.cpp DWARFAbbreviationDeclaration.cpp DWARFASTParserClang.cpp Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -0,0 +1,65 @@ +//===-- DebugNamesDWARFIndex.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_DEBUGNAMESDWARFINDEX_H +#define LLDB_DEBUGNAMESDWARFINDEX_H + +#include "Plugins/SymbolFile/DWARF/DWARFIndex.h" +#include "lldb/Utility/ConstString.h" +#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" + +namespace lldb_private { +class DebugNamesDWARFIndex : public DWARFIndex { +public: + static llvm::Expected> + Create(Module &module, DWARFDataExtractor debug_names, + DWARFDataExtractor debug_str, DWARFDebugInfo *debug_info); + + void Preload() override {} + + void GetGlobalVariables(ConstString name, DIEArray &offsets) override {} + void GetGlobalVariables(const RegularExpression ®ex, + DIEArray &offsets) override {} + void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override {} + void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {} + void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation, + DIEArray &offsets) override {} + void GetTypes(ConstString name, DIEArray &offsets) override {} + void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override {} + void GetNamespaces(ConstString name, DIEArray &offsets) override {} + void GetFunctions(ConstString name, DWARFDebugInfo &info, + const CompilerDeclContext &parent_decl_ctx, + uint32_t name_type_mask, + std::vector &dies) override {} + void GetFunctions(const RegularExpression ®ex, + DIEArray &offsets) override {} + + void ReportInvalidDIEOffset(dw_offset_t offset, + llvm::StringRef name) override {} + void Dump(Stream &s) override {} + +private: + DebugNamesDWARFIndex(Module &module, + std::unique_ptr debug_names_up, + DWARFDataExtractor debug_names_data, + DWARFDataExtractor debug_str_data, + DWARFDebugInfo *debug_info) + : DWARFIndex(module), m_debug_names_up(std::move(debug_names_up)) {} + + // LLVM DWARFDebugNames will hold a non-owning reference to this data, so keep + // track of the ownership here. + DWARFDataExtractor m_debug_names_data; + DWARFDataExtractor m_debug_str_data; + + std::unique_ptr m_debug_names_up; +}; + +} // namespace lldb_private + +#endif // LLDB_DEBUGNAMESDWARFINDEX_H Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -0,0 +1,33 @@ +//===-- DebugNamesDWARFIndex.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h" + +using namespace lldb_private; +using namespace lldb; + +static llvm::DWARFDataExtractor ToLLVM(const DWARFDataExtractor &data) { + return llvm::DWARFDataExtractor( + llvm::StringRef(reinterpret_cast(data.GetDataStart()), + data.GetByteSize()), + data.GetByteOrder() == eByteOrderLittle, data.GetAddressByteSize()); +} + +llvm::Expected> +DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, + DWARFDataExtractor debug_str, + DWARFDebugInfo *debug_info) { + auto index_up = llvm::make_unique(ToLLVM(debug_names), + ToLLVM(debug_str)); + if (llvm::Error E = index_up->extract()) + return std::move(E); + + return std::unique_ptr(new DebugNamesDWARFIndex( + module, std::move(index_up), debug_names, debug_str, debug_info)); +} Index: source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -468,7 +468,7 @@ } void ManualDWARFIndex::Dump(Stream &s) { - s.Format("DWARF index for ({0}) '{1:F}':", + s.Format("Manual DWARF index for ({0}) '{1:F}':", m_module.GetArchitecture().GetArchitectureName(), m_module.GetObjectFile()->GetFileSpec()); s.Printf("\nFunction basenames:\n"); Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -316,6 +316,8 @@ DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, const DWARFDIE &die); + void Dump(lldb_private::Stream &s) override; + protected: typedef llvm::DenseMap DIEToTypePtr; @@ -402,8 +404,6 @@ lldb::TypeSP GetTypeForDIE(const DWARFDIE &die, bool resolve_function_context = false); - void DumpIndexes(); - void SetDebugMapModule(const lldb::ModuleSP &module_sp) { m_debug_map_module_wp = module_sp; } Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -64,6 +64,7 @@ #include "DWARFDeclContext.h" #include "DWARFFormValue.h" #include "DWARFUnit.h" +#include "DebugNamesDWARFIndex.h" #include "LogChannelDWARF.h" #include "ManualDWARFIndex.h" #include "SymbolFileDWARFDebugMap.h" @@ -111,11 +112,20 @@ PropertyDefinition g_properties[] = { {"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."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + nullptr, + "If the DW_AT_comp_dir matches any of these paths the symbolic " + "links will be resolved at DWARF parse time."}, + {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, + nullptr, + "Ignore indexes present in the object files and always index DWARF " + "manually."}, + {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}, +}; -enum { ePropertySymLinkPaths }; +enum { + ePropertySymLinkPaths, + ePropertyIgnoreIndexes, +}; class PluginProperties : public Properties { public: @@ -135,6 +145,11 @@ assert(option_value); return option_value->GetCurrentValue(); } + + bool IgnoreFileIndexes() const { + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, ePropertyIgnoreIndexes, false); + } }; typedef std::shared_ptr SymbolFileDWARFPropertiesSP; @@ -432,6 +447,7 @@ } void SymbolFileDWARF::InitializeObject() { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); ModuleSP module_sp(m_obj_file->GetModule()); if (module_sp) { const SectionList *section_list = module_sp->GetSectionList(); @@ -442,19 +458,38 @@ 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); + if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) { + 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); + + m_index = AppleDWARFIndex::Create( + *GetObjectFile()->GetModule(), apple_names, apple_namespaces, + apple_types, apple_objc, get_debug_str_data()); - m_index = AppleDWARFIndex::Create(*GetObjectFile()->GetModule(), apple_names, - apple_namespaces, apple_types, apple_objc, - get_debug_str_data()); + if (m_index) + return; - if (!m_index) - m_index = llvm::make_unique(*GetObjectFile()->GetModule(), - DebugInfo()); + DWARFDataExtractor debug_names; + LoadSectionData(eSectionTypeDWARFDebugNames, debug_names); + if (debug_names.GetByteSize() > 0) { + llvm::Expected> index_or = + DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(), + debug_names, get_debug_str_data(), + DebugInfo()); + if (index_or) { + m_index = std::move(*index_or); + return; + } + LLDB_LOG_ERROR(log, index_or.takeError(), + "Unable to read .debug_names data: {0}"); + } + } + + m_index = llvm::make_unique(*GetObjectFile()->GetModule(), + DebugInfo()); } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { @@ -3685,10 +3720,7 @@ uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } -void SymbolFileDWARF::DumpIndexes() { - StreamFile s(stdout, false); - m_index->Dump(s); -} +void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); } SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) { Index: source/Symbol/SymbolVendor.cpp =================================================================== --- source/Symbol/SymbolVendor.cpp +++ source/Symbol/SymbolVendor.cpp @@ -392,6 +392,8 @@ } } s->EOL(); + if (m_sym_file_ap) + m_sym_file_ap->Dump(*s); s->IndentMore(); m_type_list.Dump(s, show_context);