[Lldb-commits] [lldb] r334273 - DebugNamesDWARFIndex: Implement GetFunctions method

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 8 02:10:31 PDT 2018


Author: labath
Date: Fri Jun  8 02:10:31 2018
New Revision: 334273

URL: http://llvm.org/viewvc/llvm-project?rev=334273&view=rev
Log:
DebugNamesDWARFIndex: Implement GetFunctions method

Summary:
This patch implements the non-regex variant of GetFunctions. To share
more code with the Apple implementation, I've extracted the common
filtering code from that class into a utility function on the DWARFIndex
base class.

The new implementation also searching the accelerator table multiple
times -- previously it could happen that the apple table would return
the same die more than once if one specified multiple search flags in
name_type_mask. This way, I separate table iteration from filtering, and
so we can be sure each die is inserted at most once.

Reviewers: clayborg, JDevlieghere

Subscribers: aprantl, lldb-commits

Differential Revision: https://reviews.llvm.org/D47881

Modified:
    lldb/trunk/lit/SymbolFile/DWARF/find-basic-function.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DIERef.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h

Modified: lldb/trunk/lit/SymbolFile/DWARF/find-basic-function.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/find-basic-function.cpp?rev=334273&r1=334272&r2=334273&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/find-basic-function.cpp (original)
+++ lldb/trunk/lit/SymbolFile/DWARF/find-basic-function.cpp Fri Jun  8 02:10:31 2018
@@ -29,6 +29,22 @@
 // RUN: lldb-test symbols --name=not_there --find=function %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=function --function-flags=base %t | \
+// RUN:   FileCheck --check-prefix=BASE %s
+// RUN: lldb-test symbols --name=foo --find=function --function-flags=method %t | \
+// RUN:   FileCheck --check-prefix=METHOD %s
+// RUN: lldb-test symbols --name=foo --find=function --function-flags=full %t | \
+// RUN:   FileCheck --check-prefix=FULL %s
+// RUN: lldb-test symbols --name=_Z3fooi --find=function --function-flags=full %t | \
+// RUN:   FileCheck --check-prefix=FULL-MANGLED %s
+// RUN: lldb-test symbols --name=foo --context=context --find=function --function-flags=base %t | \
+// RUN:   FileCheck --check-prefix=CONTEXT %s
+// RUN: lldb-test symbols --name=not_there --find=function %t | \
+// RUN:   FileCheck --check-prefix=EMPTY %s
+
 // BASE: Found 4 functions:
 // BASE-DAG: name = "foo()", mangled = "_Z3foov"
 // BASE-DAG: name = "foo(int)", mangled = "_Z3fooi"

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp?rev=334273&r1=334272&r2=334273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp Fri Jun  8 02:10:31 2018
@@ -13,7 +13,6 @@
 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
 
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/Function.h"
 
@@ -135,74 +134,15 @@ void AppleDWARFIndex::GetNamespaces(Cons
     m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
 }
 
-static bool KeepFunctionDIE(DWARFDIE die, uint32_t name_type_mask) {
-  bool looking_for_methods = name_type_mask & eFunctionNameTypeMethod;
-  bool looking_for_functions = name_type_mask & eFunctionNameTypeBase;
-  if (looking_for_methods && looking_for_functions)
-    return true;
-  return looking_for_methods == die.IsMethod();
-}
-
 void AppleDWARFIndex::GetFunctions(ConstString name, DWARFDebugInfo &info,
                                    const CompilerDeclContext &parent_decl_ctx,
                                    uint32_t name_type_mask,
                                    std::vector<DWARFDIE> &dies) {
-  if (name_type_mask & eFunctionNameTypeFull) {
-    // If they asked for the full name, match what they typed.  At some
-    // point we may want to canonicalize this (strip double spaces, etc.
-    // For now, we just add all the dies that we find by exact match.
-    DIEArray offsets;
-    m_apple_names_up->FindByName(name.GetStringRef(), offsets);
-    for (const DIERef &die_ref: offsets) {
-      DWARFDIE die = info.GetDIE(die_ref);
-      if (!die) {
-        ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef());
-        continue;
-      }
-      if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
-        dies.push_back(die);
-    }
-  }
-  if (name_type_mask & eFunctionNameTypeSelector &&
-      !parent_decl_ctx.IsValid()) {
-    DIEArray offsets;
-    m_apple_names_up->FindByName(name.GetStringRef(), offsets);
-
-    // Now make sure these are actually ObjC methods.  In this case we can
-    // simply look up the name, and if it is an ObjC method name, we're
-    // good.
-    for (const DIERef &die_ref: offsets) {
-      DWARFDIE die = info.GetDIE(die_ref);
-      if (!die) {
-        ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef());
-        continue;
-      }
-      const char *die_name = die.GetName();
-      if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
-        dies.push_back(die);
-    }
-  }
-  if (((name_type_mask & eFunctionNameTypeMethod) &&
-       !parent_decl_ctx.IsValid()) ||
-      name_type_mask & eFunctionNameTypeBase) {
-    // The apple_names table stores just the "base name" of C++ methods in
-    // the table.  So we have to extract the base name, look that up, and
-    // if there is any other information in the name we were passed in we
-    // have to post-filter based on that.
-
-    DIEArray offsets;
-    m_apple_names_up->FindByName(name.GetStringRef(), offsets);
-
-    for (const DIERef &die_ref: offsets) {
-      DWARFDIE die = info.GetDIE(die_ref);
-      if (!die) {
-        ReportInvalidDIEOffset(die_ref.die_offset, name.GetStringRef());
-        continue;
-      }
-      if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die) &&
-          KeepFunctionDIE(die, name_type_mask))
-        dies.push_back(die);
-    }
+  DIEArray offsets;
+  m_apple_names_up->FindByName(name.GetStringRef(), offsets);
+  for (const DIERef &die_ref : offsets) {
+    ProcessFunctionDIE(name.GetStringRef(), die_ref, info, parent_decl_ctx,
+                       name_type_mask, dies);
   }
 }
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DIERef.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DIERef.h?rev=334273&r1=334272&r2=334273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DIERef.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DIERef.h Fri Jun  8 02:10:31 2018
@@ -45,6 +45,10 @@ struct DIERef {
 
   bool operator<(const DIERef &ref) { return die_offset < ref.die_offset; }
 
+  explicit operator bool() const {
+    return cu_offset != DW_INVALID_OFFSET || die_offset != DW_INVALID_OFFSET;
+  }
+
   dw_offset_t cu_offset = DW_INVALID_OFFSET;
   dw_offset_t die_offset = DW_INVALID_OFFSET;
 };

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp?rev=334273&r1=334272&r2=334273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp Fri Jun  8 02:10:31 2018
@@ -11,7 +11,58 @@
 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
 
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
+
 using namespace lldb_private;
 using namespace lldb;
 
 DWARFIndex::~DWARFIndex() = default;
+
+void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
+                                    DWARFDebugInfo &info,
+                                    const CompilerDeclContext &parent_decl_ctx,
+                                    uint32_t name_type_mask,
+                                    std::vector<DWARFDIE> &dies) {
+  DWARFDIE die = info.GetDIE(ref);
+  if (!die) {
+    ReportInvalidDIEOffset(ref.die_offset, name);
+    return;
+  }
+
+  // Exit early if we're searching exclusively for methods or selectors and
+  // we have a context specified (no methods in namespaces).
+  uint32_t looking_for_nonmethods =
+      name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
+  if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
+    return;
+
+  // Otherwise, we need to also check that the context matches. If it does not
+  // match, we do nothing.
+  if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
+    return;
+
+  // In case of a full match, we just insert everything we find.
+  if (name_type_mask & eFunctionNameTypeFull) {
+    dies.push_back(die);
+    return;
+  }
+
+  // If looking for ObjC selectors, we need to also check if the name is a
+  // possible selector.
+  if (name_type_mask & eFunctionNameTypeSelector &&
+      ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) {
+    dies.push_back(die);
+    return;
+  }
+
+  bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
+  bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
+  if (looking_for_methods || looking_for_functions) {
+    // If we're looking for either methods or functions, we definitely want this
+    // die. Otherwise, only keep it if the die type matches what we are
+    // searching for.
+    if ((looking_for_methods && looking_for_functions) ||
+        looking_for_methods == die.IsMethod())
+      dies.push_back(die);
+  }
+}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h?rev=334273&r1=334272&r2=334273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h Fri Jun  8 02:10:31 2018
@@ -11,6 +11,7 @@
 #define LLDB_DWARFINDEX_H
 
 #include "Plugins/SymbolFile/DWARF/DIERef.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
 #include "Plugins/SymbolFile/DWARF/DWARFFormValue.h"
 
 class DWARFDebugInfo;
@@ -53,6 +54,15 @@ public:
 
 protected:
   Module &m_module;
+
+  /// Helper function implementing common logic for processing function dies. If
+  /// the function given by "ref" matches search criteria given by
+  /// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies"
+  /// vector.
+  void ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
+                          DWARFDebugInfo &info,
+                          const CompilerDeclContext &parent_decl_ctx,
+                          uint32_t name_type_mask, std::vector<DWARFDIE> &dies);
 };
 } // namespace lldb_private
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp?rev=334273&r1=334272&r2=334273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp Fri Jun  8 02:10:31 2018
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Stream.h"
 
@@ -44,12 +45,18 @@ DebugNamesDWARFIndex::GetUnits(const Deb
   return result;
 }
 
-void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
-                                  DIEArray &offsets) {
+DIERef DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
   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);
+    return DIERef(*cu_offset, *die_offset);
+  return DIERef();
+}
+
+void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
+                                  DIEArray &offsets) {
+  if (DIERef ref = ToDIERef(entry))
+    offsets.push_back(ref);
 }
 
 void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
@@ -118,6 +125,25 @@ void DebugNamesDWARFIndex::GetNamespaces
   }
 }
 
+void DebugNamesDWARFIndex::GetFunctions(
+    ConstString name, DWARFDebugInfo &info,
+    const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+    std::vector<DWARFDIE> &dies) {
+
+  m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies);
+
+  for (const DebugNames::Entry &entry :
+       m_debug_names_up->equal_range(name.GetStringRef())) {
+    Tag tag = entry.tag();
+    if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
+      continue;
+
+    if (DIERef ref = ToDIERef(entry))
+      ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx,
+                         name_type_mask, dies);
+  }
+}
+
 void DebugNamesDWARFIndex::Dump(Stream &s) {
   m_fallback.Dump(s);
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h?rev=334273&r1=334272&r2=334273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h Fri Jun  8 02:10:31 2018
@@ -38,7 +38,7 @@ public:
   void GetFunctions(ConstString name, DWARFDebugInfo &info,
                     const CompilerDeclContext &parent_decl_ctx,
                     uint32_t name_type_mask,
-                    std::vector<DWARFDIE> &dies) override {}
+                    std::vector<DWARFDIE> &dies) override;
   void GetFunctions(const RegularExpression &regex,
                     DIEArray &offsets) override {}
 
@@ -64,9 +64,11 @@ private:
   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 DIERef ToDIERef(const DebugNames::Entry &entry);
+  static void Append(const DebugNames::Entry &entry, DIEArray &offsets);
+  static void MaybeLogLookupError(llvm::Error error,
+                                  const DebugNames::NameIndex &ni,
+                                  llvm::StringRef name);
 
   static llvm::DenseSet<dw_offset_t> GetUnits(const DebugNames &debug_names);
 };




More information about the lldb-commits mailing list