Summary: This patch adds the ability to lookup variables to the DWARF v5 index class. During review we discovered an inconsistency between how the existing two indexes handle looking up qualified names of the variables: - manual index would return a value if the input string exactly matched the demangled name of some variable. - apple index ignored the context and returned any variable with the same base name. So, this patch also rectifies that situation: - it removes all context handling from the index classes. The GetGlobalVariables functions now just take a base name. For manual index, this meant we can stop putting demangled names into the variable index (this matches the behavior for functions). - context extraction is put into SymbolFileDWARF, so that it is common to all indexes. - additional filtering based on the context is also done in SymbolFileDWARF. This is done via a simple substring search, which is not ideal, but it matches what we are doing for functions (cf. Module::LookupInfo::Prune). Reviewers: clayborg, JDevlieghere Subscribers: aprantl, lldb-commits Differential Revision: https://reviews.llvm.org/D47781 llvm-svn: 334181
93 lines
3.4 KiB
C++
93 lines
3.4 KiB
C++
//===-- 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"
|
|
#include "lldb/Utility/RegularExpression.h"
|
|
#include "lldb/Utility/Stream.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<DebugNames>(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));
|
|
}
|
|
|
|
void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
|
|
DIEArray &offsets) {
|
|
llvm::Optional<uint64_t> cu_offset = entry.getCUOffset();
|
|
llvm::Optional<uint64_t> die_offset = entry.getDIESectionOffset();
|
|
if (cu_offset && die_offset)
|
|
offsets.emplace_back(*cu_offset, *die_offset);
|
|
}
|
|
|
|
void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
|
|
const DebugNames::NameIndex &ni,
|
|
llvm::StringRef name) {
|
|
// Ignore SentinelErrors, log everything else.
|
|
LLDB_LOG_ERROR(
|
|
LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS),
|
|
handleErrors(std::move(error), [](const DebugNames::SentinelError &) {}),
|
|
"Failed to parse index entries for index at {1:x}, name {2}: {0}",
|
|
ni.getUnitOffset(), name);
|
|
}
|
|
|
|
void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename,
|
|
DIEArray &offsets) {
|
|
for (const DebugNames::Entry &entry :
|
|
m_debug_names_up->equal_range(basename.GetStringRef())) {
|
|
if (entry.tag() != DW_TAG_variable)
|
|
continue;
|
|
|
|
Append(entry, offsets);
|
|
}
|
|
}
|
|
|
|
void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex,
|
|
DIEArray &offsets) {
|
|
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
|
|
for (DebugNames::NameTableEntry nte: ni) {
|
|
if (!regex.Execute(nte.getString()))
|
|
continue;
|
|
|
|
uint32_t entry_offset = nte.getEntryOffset();
|
|
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
|
|
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
|
|
if (entry_or->tag() != DW_TAG_variable)
|
|
continue;
|
|
|
|
Append(*entry_or, offsets);
|
|
}
|
|
MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
|
|
}
|
|
}
|
|
}
|
|
|
|
void DebugNamesDWARFIndex::Dump(Stream &s) {
|
|
std::string data;
|
|
llvm::raw_string_ostream os(data);
|
|
m_debug_names_up->dump(os);
|
|
s.PutCString(os.str());
|
|
}
|