Index: lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp =================================================================== --- /dev/null +++ lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp @@ -0,0 +1,14 @@ +// Test that we use the DWARF v5 name indexes. + +// REQUIRES: lld + +// RUN: clang %s -g -c -emit-llvm -o - --target=x86_64-pc-linux | \ +// RUN: llc -accel-tables=Dwarf -filetype=obj -o %t.o +// RUN: ld.lld %t.o -o %t +// RUN: lldb-test symbols %t | FileCheck %s + +// CHECK: Name Index +// CHECK: String: 0x{{.*}} "_start" +// CHECK: Tag: DW_TAG_subprogram + +extern "C" void _start() {} Index: lit/SymbolFile/DWARF/find-basic-variable.cpp =================================================================== --- lit/SymbolFile/DWARF/find-basic-variable.cpp +++ lit/SymbolFile/DWARF/find-basic-variable.cpp @@ -20,6 +20,18 @@ // RUN: FileCheck --check-prefix=REGEX %s // RUN: lldb-test symbols --name=not_there --find=variable %t | \ // RUN: FileCheck --check-prefix=EMPTY %s +// +// RUN: clang %s -g -c -emit-llvm -o - --target=x86_64-pc-linux | \ +// RUN: llc -accel-tables=Dwarf -filetype=obj -o %t.o +// RUN: ld.lld %t.o -o %t +// RUN: lldb-test symbols --name=foo --find=variable --context=context %t | \ +// RUN: FileCheck --check-prefix=CONTEXT %s +// RUN: lldb-test symbols --name=foo --find=variable %t | \ +// RUN: FileCheck --check-prefix=NAME %s +// RUN: lldb-test symbols --regex --name=foo --find=variable %t | \ +// RUN: FileCheck --check-prefix=REGEX %s +// RUN: lldb-test symbols --name=not_there --find=variable %t | \ +// RUN: FileCheck --check-prefix=EMPTY %s // EMPTY: Found 0 variables: // NAME: Found 4 variables: Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -11,6 +11,7 @@ #define LLDB_DEBUGNAMESDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" +#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "lldb/Utility/ConstString.h" #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" @@ -23,9 +24,9 @@ void Preload() override {} - void GetGlobalVariables(ConstString name, DIEArray &offsets) override {} + void GetGlobalVariables(ConstString name, DIEArray &offsets) override; void GetGlobalVariables(const RegularExpression ®ex, - DIEArray &offsets) override {} + 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, @@ -42,7 +43,7 @@ void ReportInvalidDIEOffset(dw_offset_t offset, llvm::StringRef name) override {} - void Dump(Stream &s) override {} + void Dump(Stream &s) override; private: DebugNamesDWARFIndex(Module &module, @@ -57,7 +58,12 @@ DWARFDataExtractor m_debug_names_data; DWARFDataExtractor m_debug_str_data; - std::unique_ptr m_debug_names_up; + using DebugNames = llvm::DWARFDebugNames; + std::unique_ptr m_debug_names_up; + + void Append(const DebugNames::Entry &entry, DIEArray &offsets); + void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, + llvm::StringRef name); }; } // namespace lldb_private Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -9,6 +9,8 @@ #include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h" +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" + using namespace lldb_private; using namespace lldb; @@ -23,11 +25,76 @@ 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)); + 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)); } + +void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry, + DIEArray &offsets) { + llvm::Optional cu_offset = entry.getCUOffset(); + llvm::Optional 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 name, + DIEArray &offsets) { + const char *name_cstr = name.GetCString(); + llvm::StringRef basename; + llvm::StringRef context; + + if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, + basename)) + basename = name_cstr; + + for (const DebugNames::Entry &entry : + m_debug_names_up->equal_range(basename)) { + 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 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()); +}