diff options
5 files changed, 71 insertions, 18 deletions
diff --git a/lldb/lit/SymbolFile/DWARF/dwarf5-partial-index.cpp b/lldb/lit/SymbolFile/DWARF/dwarf5-partial-index.cpp new file mode 100644 index 00000000000..36c6dde723b --- /dev/null +++ b/lldb/lit/SymbolFile/DWARF/dwarf5-partial-index.cpp @@ -0,0 +1,25 @@ +// Test that we return complete results when only a part of the binary is built +// with an index. + +// REQUIRES: lld + +// RUN: clang %s -g -c -emit-llvm -o - --target=x86_64-pc-linux -DONE | \ +// RUN: llc -accel-tables=Dwarf -filetype=obj -o %t-1.o +// RUN: clang %s -g -c -emit-llvm -o - --target=x86_64-pc-linux -DTWO | \ +// RUN: llc -accel-tables=Disable -filetype=obj -o %t-2.o +// RUN: ld.lld %t-1.o %t-2.o -o %t +// RUN: lldb-test symbols --find=variable --name=foo %t | FileCheck %s + +// CHECK: Found 2 variables: +#ifdef ONE +namespace one { +int foo; +// CHECK-DAG: name = "foo", {{.*}} decl = dwarf5-partial-index.cpp:[[@LINE-1]] +} // namespace one +extern "C" void _start() {} +#else +namespace two { +int foo; +// CHECK-DAG: name = "foo", {{.*}} decl = dwarf5-partial-index.cpp:[[@LINE-1]] +} // namespace two +#endif diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index d7d6e5070a0..c35dfa9f13a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -34,6 +34,16 @@ DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, module, std::move(index_up), debug_names, debug_str, debug_info)); } +llvm::DenseSet<dw_offset_t> +DebugNamesDWARFIndex::GetUnits(const DebugNames &debug_names) { + llvm::DenseSet<dw_offset_t> result; + for (const DebugNames::NameIndex &ni : debug_names) { + for (uint32_t cu = 0; cu < ni.getCUCount(); ++cu) + result.insert(ni.getCUOffset(cu)); + } + return result; +} + void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry, DIEArray &offsets) { llvm::Optional<uint64_t> cu_offset = entry.getCUOffset(); @@ -55,6 +65,8 @@ void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error, void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) { + m_fallback.GetGlobalVariables(basename, offsets); + for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(basename.GetStringRef())) { if (entry.tag() != DW_TAG_variable) @@ -66,6 +78,8 @@ void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename, void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, DIEArray &offsets) { + m_fallback.GetGlobalVariables(regex, offsets); + for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { if (!regex.Execute(nte.getString())) @@ -85,6 +99,8 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression ®ex, } void DebugNamesDWARFIndex::Dump(Stream &s) { + m_fallback.Dump(s); + std::string data; llvm::raw_string_ostream os(data); m_debug_names_up->dump(os); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index bd18797eee6..ed82d74644b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -12,6 +12,7 @@ #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" +#include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" #include "lldb/Utility/ConstString.h" #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" @@ -22,7 +23,7 @@ public: Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, DWARFDebugInfo *debug_info); - void Preload() override {} + void Preload() override { m_fallback.Preload(); } void GetGlobalVariables(ConstString basename, DIEArray &offsets) override; void GetGlobalVariables(const RegularExpression ®ex, @@ -51,7 +52,8 @@ private: DWARFDataExtractor debug_names_data, DWARFDataExtractor debug_str_data, DWARFDebugInfo *debug_info) - : DWARFIndex(module), m_debug_names_up(std::move(debug_names_up)) {} + : DWARFIndex(module), m_debug_names_up(std::move(debug_names_up)), + m_fallback(module, debug_info, GetUnits(*m_debug_names_up)) {} // LLVM DWARFDebugNames will hold a non-owning reference to this data, so keep // track of the ownership here. @@ -60,10 +62,13 @@ private: using DebugNames = llvm::DWARFDebugNames; std::unique_ptr<DebugNames> m_debug_names_up; + ManualDWARFIndex m_fallback; void Append(const DebugNames::Entry &entry, DIEArray &offsets); void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, llvm::StringRef name); + + static llvm::DenseSet<dw_offset_t> GetUnits(const DebugNames &debug_names); }; } // namespace lldb_private diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index ffab5e5eb60..98c782caed8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -32,28 +32,30 @@ void ManualDWARFIndex::Index() { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info)); - const uint32_t num_compile_units = debug_info.GetNumCompileUnits(); - if (num_compile_units == 0) + std::vector<DWARFUnit *> units_to_index; + units_to_index.reserve(debug_info.GetNumCompileUnits()); + for (size_t U = 0; U < debug_info.GetNumCompileUnits(); ++U) { + DWARFUnit *unit = debug_info.GetCompileUnitAtIndex(U); + if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0) + units_to_index.push_back(unit); + } + if (units_to_index.empty()) return; - std::vector<IndexSet> sets(num_compile_units); + std::vector<IndexSet> sets(units_to_index.size()); //---------------------------------------------------------------------- // Keep memory down by clearing DIEs for any compile units if indexing // caused us to load the compile unit's DIEs. //---------------------------------------------------------------------- - std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> - clear_cu_dies(num_compile_units); + std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies( + units_to_index.size()); auto parser_fn = [&](size_t cu_idx) { - DWARFUnit *dwarf_cu = debug_info.GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu) - IndexUnit(*dwarf_cu, sets[cu_idx]); + IndexUnit(*units_to_index[cu_idx], sets[cu_idx]); }; - auto extract_fn = [&debug_info, &clear_cu_dies](size_t cu_idx) { - DWARFUnit *dwarf_cu = debug_info.GetCompileUnitAtIndex(cu_idx); - if (dwarf_cu) - clear_cu_dies[cu_idx] = dwarf_cu->ExtractDIEsScoped(); + auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) { + clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped(); }; // Create a task runner that extracts dies for each DWARF compile unit in a @@ -66,12 +68,12 @@ void ManualDWARFIndex::Index() { // to wait until all compile units have been indexed in case a DIE in one // compile unit refers to another and the indexes accesses those DIEs. //---------------------------------------------------------------------- - TaskMapOverInt(0, num_compile_units, extract_fn); + TaskMapOverInt(0, units_to_index.size(), extract_fn); // Now create a task runner that can index each DWARF compile unit in a // separate thread so we can index quickly. - TaskMapOverInt(0, num_compile_units, parser_fn); + TaskMapOverInt(0, units_to_index.size(), parser_fn); auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) { NameToDIE &result = m_set.*index; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index 9ce446a5af6..79ab1d95b38 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -12,12 +12,15 @@ #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/NameToDIE.h" +#include "llvm/ADT/DenseSet.h" namespace lldb_private { class ManualDWARFIndex : public DWARFIndex { public: - ManualDWARFIndex(Module &module, DWARFDebugInfo *debug_info) - : DWARFIndex(module), m_debug_info(debug_info) {} + ManualDWARFIndex(Module &module, DWARFDebugInfo *debug_info, + llvm::DenseSet<dw_offset_t> units_to_avoid = {}) + : DWARFIndex(module), m_debug_info(debug_info), + m_units_to_avoid(std::move(units_to_avoid)) {} void Preload() override { Index(); } @@ -62,6 +65,8 @@ private: /// Non-null value means we haven't built the index yet. DWARFDebugInfo *m_debug_info; + /// Which dwarf units should we skip while building the index. + llvm::DenseSet<dw_offset_t> m_units_to_avoid; IndexSet m_set; }; |