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,74 @@ +//===-- 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, + llvm::function_ref + resolve_function, + llvm::function_ref + get_decl_context_containing_uid, + const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, + bool include_inlines, SymbolContextList &sc_list) override {} + void GetFunctions( + const RegularExpression ®ex, DWARFDebugInfo &info, + llvm::function_ref + resolve_function, + bool include_inlines, SymbolContextList &sc_list) 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/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" @@ -117,7 +118,16 @@ enum { ePropertySymLinkPaths }; +PropertyDefinition g_experimental_properties[] = { + {"use-debug-names", OptionValue::eTypeBoolean, true, 0, nullptr, nullptr, + "Use .debug_names index section."}, + {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}, +}; +enum { ePropertyDebugNames }; + class PluginProperties : public Properties { + OptionValuePropertiesSP m_experimental_sp; + public: static ConstString GetSettingName() { return SymbolFileDWARF::GetPluginNameStatic(); @@ -126,6 +136,12 @@ PluginProperties() { m_collection_sp.reset(new OptionValueProperties(GetSettingName())); m_collection_sp->Initialize(g_properties); + ConstString experimental_name(Properties::GetExperimentalSettingsName()); + m_experimental_sp = std::make_shared(experimental_name); + m_experimental_sp->Initialize(g_experimental_properties); + m_collection_sp->AppendProperty( + ConstString(Properties::GetExperimentalSettingsName()), + ConstString("Experimental settings"), true, m_experimental_sp); } FileSpecList &GetSymLinkPaths() { @@ -135,6 +151,11 @@ assert(option_value); return option_value->GetCurrentValue(); } + + bool UseDebugNames() const { + return m_experimental_sp->GetPropertyAtIndexAsBoolean( + nullptr, ePropertyDebugNames, false); + } }; typedef std::shared_ptr SymbolFileDWARFPropertiesSP; @@ -432,6 +453,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(); @@ -452,9 +474,26 @@ apple_namespaces, apple_types, apple_objc, get_debug_str_data()); - if (!m_index) - m_index = llvm::make_unique(*GetObjectFile()->GetModule(), - DebugInfo()); + if (m_index) + return; + + DWARFDataExtractor debug_names; + LoadSectionData(eSectionTypeDWARFDebugNames, debug_names); + if (debug_names.GetByteSize() > 0 && + GetGlobalPluginProperties()->UseDebugNames()) { + 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) {