[DWARF] Add (empty) DebugNamesDWARFIndex class and a setting to control its use

Summary:
This patch adds the skeleton for implementing the DWARF v5 name index
class. All of the methods are stubbed out and will be implemented in
subsequent patches. The interesting part of the patch is the addition of
a "ignore-file-indexes" setting to the dwarf plugin which enables a
user to force using manual indexing path in lldb (for example as a
debugging aid). I have also added a test that verifies that file indexes
are used by default.

Reviewers: JDevlieghere, clayborg, jingham

Subscribers: mgorny, mehdi_amini, aprantl, lldb-commits

Differential Revision: https://reviews.llvm.org/D47629

llvm-svn: 334088
This commit is contained in:
Pavel Labath 2018-06-06 11:35:23 +00:00
parent 86026bdaee
commit 9337b41cb5
10 changed files with 174 additions and 23 deletions

View File

@ -200,6 +200,8 @@ public:
//------------------------------------------------------------------
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;

View File

@ -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;

View File

@ -236,5 +236,13 @@ void AppleDWARFIndex::ReportInvalidDIEOffset(dw_offset_t offset,
}
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
}

View File

@ -1,5 +1,6 @@
add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
AppleDWARFIndex.cpp
DebugNamesDWARFIndex.cpp
DIERef.cpp
DWARFAbbreviationDeclaration.cpp
DWARFASTParserClang.cpp

View File

@ -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<const char *>(data.GetDataStart()),
data.GetByteSize()),
data.GetByteOrder() == eByteOrderLittle, data.GetAddressByteSize());
}
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
DWARFDataExtractor debug_str,
DWARFDebugInfo *debug_info) {
auto index_up = llvm::make_unique<llvm::DWARFDebugNames>(ToLLVM(debug_names),
ToLLVM(debug_str));
if (llvm::Error E = index_up->extract())
return std::move(E);
return std::unique_ptr<DebugNamesDWARFIndex>(new DebugNamesDWARFIndex(
module, std::move(index_up), debug_names, debug_str, debug_info));
}

View File

@ -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<std::unique_ptr<DebugNamesDWARFIndex>>
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 &regex,
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<DWARFDIE> &dies) override {}
void GetFunctions(const RegularExpression &regex,
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<llvm::DWARFDebugNames> 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<llvm::DWARFDebugNames> m_debug_names_up;
};
} // namespace lldb_private
#endif // LLDB_DEBUGNAMESDWARFINDEX_H

View File

@ -468,7 +468,7 @@ void ManualDWARFIndex::GetFunctions(const RegularExpression &regex,
}
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");

View File

@ -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 @@ namespace {
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 @@ public:
assert(option_value);
return option_value->GetCurrentValue();
}
bool IgnoreFileIndexes() const {
return m_collection_sp->GetPropertyAtIndexAsBoolean(
nullptr, ePropertyIgnoreIndexes, false);
}
};
typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
@ -432,6 +447,7 @@ TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
}
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 @@ 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);
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)
m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
DebugInfo());
if (m_index)
return;
DWARFDataExtractor debug_names;
LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
if (debug_names.GetByteSize() > 0) {
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> 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<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
DebugInfo());
}
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
@ -3685,10 +3720,7 @@ ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
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()) {

View File

@ -316,6 +316,8 @@ public:
DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
const DWARFDIE &die);
void Dump(lldb_private::Stream &s) override;
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@ -402,8 +404,6 @@ protected:
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;
}

View File

@ -392,6 +392,8 @@ void SymbolVendor::Dump(Stream *s) {
}
}
s->EOL();
if (m_sym_file_ap)
m_sym_file_ap->Dump(*s);
s->IndentMore();
m_type_list.Dump(s, show_context);