labath created this revision.
labath added reviewers: clayborg, JDevlieghere.
Herald added a subscriber: aprantl.

This adds the ability to lookup variables to the DWARF v5 index class.
find-basic-variable.cpp test is extended to cover this scenario as well,
and I have added a new test which verifies that the dwarf v5 index class
is indeed used.


https://reviews.llvm.org/D47781

Files:
  lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp
  lit/SymbolFile/DWARF/find-basic-variable.cpp
  source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
  source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h

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 &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 @@
 
   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<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
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<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 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 &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());
+}
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: 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() {}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to