summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp14
-rw-r--r--lldb/lit/SymbolFile/DWARF/find-basic-variable.cpp12
-rw-r--r--lldb/lit/SymbolFile/DWARF/find-qualified-variable.cpp15
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp17
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp63
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h14
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp10
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp21
11 files changed, 145 insertions, 31 deletions
diff --git a/lldb/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp b/lldb/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp
new file mode 100644
index 00000000000..c7cb3f27f6d
--- /dev/null
+++ b/lldb/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() {}
diff --git a/lldb/lit/SymbolFile/DWARF/find-basic-variable.cpp b/lldb/lit/SymbolFile/DWARF/find-basic-variable.cpp
index 5b677097df2..3ec14ea06ef 100644
--- a/lldb/lit/SymbolFile/DWARF/find-basic-variable.cpp
+++ b/lldb/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:
diff --git a/lldb/lit/SymbolFile/DWARF/find-qualified-variable.cpp b/lldb/lit/SymbolFile/DWARF/find-qualified-variable.cpp
new file mode 100644
index 00000000000..ca1b3184fbe
--- /dev/null
+++ b/lldb/lit/SymbolFile/DWARF/find-qualified-variable.cpp
@@ -0,0 +1,15 @@
+// RUN: clang %s -g -c -o %t --target=x86_64-apple-macosx
+// RUN: lldb-test symbols --name=A::foo --find=variable %t | FileCheck %s
+
+// CHECK: Found 1 variables:
+
+struct A {
+ static int foo;
+};
+int A::foo;
+// NAME-DAG: name = "foo", {{.*}} decl = find-qualified-variable.cpp:[[@LINE-1]]
+
+struct B {
+ static int foo;
+};
+int B::foo;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index 916d3543fb5..984960cc0c4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -13,7 +13,6 @@
#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
-#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Function.h"
@@ -56,19 +55,9 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
return nullptr;
}
-void AppleDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) {
- if (!m_apple_names_up)
- return;
-
- const char *name_cstr = name.GetCString();
- llvm::StringRef basename;
- llvm::StringRef context;
-
- if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
- basename))
- basename = name_cstr;
-
- m_apple_names_up->FindByName(basename, offsets);
+void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
+ if (m_apple_names_up)
+ m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
}
void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
index 486de4a9011..ea133d0e73c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
@@ -33,7 +33,7 @@ public:
void Preload() override {}
- void GetGlobalVariables(ConstString name, DIEArray &offsets) override;
+ void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
void GetGlobalVariables(const RegularExpression &regex,
DIEArray &offsets) override;
void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
index 882fef95b88..934e5981d8c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -25,7 +25,11 @@ public:
virtual void Preload() = 0;
- virtual void GetGlobalVariables(ConstString name, DIEArray &offsets) = 0;
+ /// Finds global variables with the given base name. Any additional filtering
+ /// (e.g., to only retrieve variables from a given context) should be done by
+ /// the consumer.
+ virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0;
+
virtual void GetGlobalVariables(const RegularExpression &regex,
DIEArray &offsets) = 0;
virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index ffd61c2789b..d7d6e5070a0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h"
+#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/Stream.h"
using namespace lldb_private;
using namespace lldb;
@@ -23,11 +25,68 @@ 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));
+ 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 &regex,
+ 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());
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
index a4da6d94f68..bd18797eee6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
+++ b/lldb/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 @@ public:
void Preload() override {}
- void GetGlobalVariables(ConstString name, DIEArray &offsets) override {}
+ void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
void GetGlobalVariables(const RegularExpression &regex,
- 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 @@ public:
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 @@ private:
DWARFDataExtractor m_debug_names_data;
DWARFDataExtractor m_debug_str_data;
- std::unique_ptr<llvm::DWARFDebugNames> m_debug_names_up;
+ using DebugNames = llvm::DWARFDebugNames;
+ std::unique_ptr<DebugNames> 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
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index 9fc8201b57e..ffab5e5eb60 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -345,12 +345,8 @@ void ManualDWARFIndex::IndexUnitImpl(
// entries
if (mangled_cstr && name != mangled_cstr &&
((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
- Mangled mangled(ConstString(mangled_cstr), true);
- set.globals.Insert(mangled.GetMangledName(),
+ set.globals.Insert(ConstString(mangled_cstr),
DIERef(cu_offset, die.GetOffset()));
- ConstString demangled = mangled.GetDemangledName(cu_language);
- if (demangled)
- set.globals.Insert(demangled, DIERef(cu_offset, die.GetOffset()));
}
}
break;
@@ -361,9 +357,9 @@ void ManualDWARFIndex::IndexUnitImpl(
}
}
-void ManualDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) {
+void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
Index();
- m_set.globals.Find(name, offsets);
+ m_set.globals.Find(basename, offsets);
}
void ManualDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
index c5c55b53802..9ce446a5af6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -21,7 +21,7 @@ public:
void Preload() override { Index(); }
- void GetGlobalVariables(ConstString name, DIEArray &offsets) override;
+ void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
void GetGlobalVariables(const RegularExpression &regex,
DIEArray &offsets) override;
void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b9682ed4d49..08d595a9aa7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -27,6 +27,7 @@
#include "lldb/Utility/Timer.h"
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -2024,14 +2025,25 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
+ llvm::StringRef basename;
+ llvm::StringRef context;
+
+ if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(),
+ context, basename))
+ basename = name.GetStringRef();
+
DIEArray die_offsets;
- m_index->GetGlobalVariables(name, die_offsets);
+ m_index->GetGlobalVariables(ConstString(basename), die_offsets);
const size_t num_die_matches = die_offsets.size();
if (num_die_matches) {
SymbolContext sc;
sc.module_sp = m_obj_file->GetModule();
assert(sc.module_sp);
+ // Loop invariant: Variables up to this index have been checked for context
+ // matches.
+ uint32_t pruned_idx = original_size;
+
bool done = false;
for (size_t i = 0; i < num_die_matches && !done; ++i) {
const DIERef &die_ref = die_offsets[i];
@@ -2062,6 +2074,13 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false,
&variables);
+ while (pruned_idx < variables.GetSize()) {
+ VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
+ if (var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
+ ++pruned_idx;
+ else
+ variables.RemoveVariableAtIndex(pruned_idx);
+ }
if (variables.GetSize() - original_size >= max_matches)
done = true;
OpenPOWER on IntegriCloud