aleksandr.urakov created this revision.
aleksandr.urakov added reviewers: zturner, asmith, labath.
aleksandr.urakov added a project: LLDB.
Herald added a subscriber: lldb-commits.

This patch adds possibility of searching a public symbol with name and type in 
a symbol file, not only in a symtab. It is helpful when working with PE, 
because PE's symtabs contain only imported / exported symbols only. Such a 
search is required for e.g. evaluation of an expression that calls some 
function of the debuggee.

A few weeks ago on `lldb-dev` there was a discussion of this, it is called 
`Symtab for PECOFF`.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D53368

Files:
  include/lldb/Symbol/SymbolFile.h
  include/lldb/Symbol/SymbolVendor.h
  include/lldb/lldb-forward.h
  source/Core/Module.cpp
  source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
  source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
  source/Symbol/SymbolFile.cpp
  source/Symbol/SymbolVendor.cpp
  unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp

Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
===================================================================
--- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
+++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
@@ -615,3 +615,20 @@
   EXPECT_EQ(0u, num_results);
   EXPECT_EQ(0u, results.GetSize());
 }
+
+TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) {
+  FileSpec fspec(m_pdb_test_exe.c_str(), false);
+  ArchSpec aspec("i686-pc-windows");
+  lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);
+
+  SymbolContextList sc_list;
+  EXPECT_EQ(1u,
+            module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"),
+                                               lldb::eSymbolTypeAny, sc_list));
+  EXPECT_EQ(1u, sc_list.GetSize());
+
+  SymbolContext sc;
+  EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));
+  EXPECT_STREQ("int foo(int)",
+               sc.GetFunctionName(Mangled::ePreferDemangled).AsCString());
+}
Index: source/Symbol/SymbolVendor.cpp
===================================================================
--- source/Symbol/SymbolVendor.cpp
+++ source/Symbol/SymbolVendor.cpp
@@ -314,6 +314,18 @@
   return 0;
 }
 
+size_t SymbolVendor::FindPublicSymbols(const ConstString &name,
+                                       lldb::SymbolType type, bool append,
+                                       SymbolContextList &sc_list) {
+  ModuleSP module_sp(GetModule());
+  if (module_sp) {
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+    if (m_sym_file_ap.get())
+      return m_sym_file_ap->FindPublicSymbols(name, type, append, sc_list);
+  }
+  return 0;
+}
+
 size_t SymbolVendor::FindTypes(
     const SymbolContext &sc, const ConstString &name,
     const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches,
Index: source/Symbol/SymbolFile.cpp
===================================================================
--- source/Symbol/SymbolFile.cpp
+++ source/Symbol/SymbolFile.cpp
@@ -127,6 +127,14 @@
   return 0;
 }
 
+size_t SymbolFile::FindPublicSymbols(const ConstString &name,
+                                     lldb::SymbolType type, bool append,
+                                     SymbolContextList &sc_list) {
+  if (!append)
+    sc_list.Clear();
+  return 0;
+}
+
 void SymbolFile::GetMangledNamesForFunction(
     const std::string &scope_qualified_name,
     std::vector<ConstString> &mangled_names) {
Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
===================================================================
--- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -132,6 +132,10 @@
       const std::string &scope_qualified_name,
       std::vector<lldb_private::ConstString> &mangled_names) override;
 
+  size_t FindPublicSymbols(const lldb_private::ConstString &name,
+                           lldb::SymbolType type, bool append,
+                           lldb_private::SymbolContextList &sc_list) override;
+
   uint32_t
   FindTypes(const lldb_private::SymbolContext &sc,
             const lldb_private::ConstString &name,
@@ -227,9 +231,13 @@
   bool DeclContextMatchesThisSymbolFile(
       const lldb_private::CompilerDeclContext *decl_ctx);
 
+  lldb_private::Symbol *
+  GetPublicSymbol(const llvm::pdb::PDBSymbolPublicSymbol &pub_symbol);
+
   llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
   llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
   llvm::DenseMap<uint32_t, lldb::VariableSP> m_variables;
+  llvm::DenseMap<uint32_t, lldb::SymbolSP> m_public_symbols;
 
   std::vector<lldb::TypeSP> m_builtin_types;
   std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
===================================================================
--- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1339,6 +1339,42 @@
     const std::string &scope_qualified_name,
     std::vector<lldb_private::ConstString> &mangled_names) {}
 
+size_t
+SymbolFilePDB::FindPublicSymbols(const lldb_private::ConstString &name,
+                                 lldb::SymbolType type, bool append,
+                                 lldb_private::SymbolContextList &sc_list) {
+  if (!append)
+    sc_list.Clear();
+
+  auto results = m_global_scope_up->findChildren(
+      PDB_SymType::PublicSymbol, name.GetStringRef(), NS_Default);
+  if (!results)
+    return 0;
+
+  size_t count = 0;
+  while (auto symbol = results->getNext()) {
+    auto pub_symbol =
+        llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>(symbol.get());
+    if (!pub_symbol)
+      continue;
+
+    auto symbol_ptr = GetPublicSymbol(*pub_symbol);
+    if (!symbol_ptr)
+      continue;
+
+    if (type != eSymbolTypeAny && symbol_ptr->GetType() != type)
+      continue;
+
+    SymbolContext sc;
+    sc.symbol = symbol_ptr;
+    sc_list.Append(sc);
+
+    count++;
+  }
+
+  return count;
+}
+
 uint32_t SymbolFilePDB::FindTypes(
     const lldb_private::SymbolContext &sc,
     const lldb_private::ConstString &name,
@@ -1882,3 +1918,45 @@
 
   return false;
 }
+
+lldb_private::Symbol *SymbolFilePDB::GetPublicSymbol(
+    const llvm::pdb::PDBSymbolPublicSymbol &pub_symbol) {
+  auto it = m_public_symbols.find(pub_symbol.getSymIndexId());
+  if (it != m_public_symbols.end())
+    return it->second.get();
+
+  auto section_list = m_obj_file->GetSectionList();
+  if (!section_list)
+    return nullptr;
+
+  auto section_idx = pub_symbol.getAddressSection() - 1;
+  if (section_idx >= section_list->GetSize())
+    return nullptr;
+
+  auto section = section_list->GetSectionAtIndex(section_idx);
+  if (!section)
+    return nullptr;
+
+  auto size = pub_symbol.getLength();
+
+  auto symbol_sp = std::make_shared<Symbol>(
+      pub_symbol.getSymIndexId(),   // symID
+      pub_symbol.getName().c_str(), // name
+      true,                         // name_is_mangled
+      pub_symbol.isCode() ? eSymbolTypeCode : eSymbolTypeData, // type
+      true,                                                    // external
+      false,                                                   // is_debug
+      false,                                                   // is_trampoline
+      false,                                                   // is_artificial
+      section,                                                 // section_sp
+      pub_symbol.getAddressOffset(),                           // value
+      size,                                                    // size
+      size != 0,                                               // size_is_valid
+      false, // contains_linker_annotations
+      0      // flags
+  );
+
+  m_public_symbols[pub_symbol.getSymIndexId()] = symbol_sp;
+
+  return symbol_sp.get();
+}
Index: source/Core/Module.cpp
===================================================================
--- source/Core/Module.cpp
+++ source/Core/Module.cpp
@@ -1366,6 +1366,8 @@
   const size_t initial_size = sc_list.GetSize();
   SymbolVendor *sym_vendor = GetSymbolVendor();
   if (sym_vendor) {
+    sym_vendor->FindPublicSymbols(name, symbol_type, true, sc_list);
+
     Symtab *symtab = sym_vendor->GetSymtab();
     if (symtab) {
       std::vector<uint32_t> symbol_indexes;
Index: include/lldb/lldb-forward.h
===================================================================
--- include/lldb/lldb-forward.h
+++ include/lldb/lldb-forward.h
@@ -441,6 +441,7 @@
     StructuredDataPluginSP;
 typedef std::weak_ptr<lldb_private::StructuredDataPlugin>
     StructuredDataPluginWP;
+typedef std::shared_ptr<lldb_private::Symbol> SymbolSP;
 typedef std::shared_ptr<lldb_private::SymbolFile> SymbolFileSP;
 typedef std::shared_ptr<lldb_private::SymbolFileType> SymbolFileTypeSP;
 typedef std::weak_ptr<lldb_private::SymbolFileType> SymbolFileTypeWP;
Index: include/lldb/Symbol/SymbolVendor.h
===================================================================
--- include/lldb/Symbol/SymbolVendor.h
+++ include/lldb/Symbol/SymbolVendor.h
@@ -97,6 +97,10 @@
                                bool include_inlines, bool append,
                                SymbolContextList &sc_list);
 
+  virtual size_t FindPublicSymbols(const ConstString &name,
+                                   lldb::SymbolType type, bool append,
+                                   SymbolContextList &sc_list);
+
   virtual size_t
   FindTypes(const SymbolContext &sc, const ConstString &name,
             const CompilerDeclContext *parent_decl_ctx, bool append,
Index: include/lldb/Symbol/SymbolFile.h
===================================================================
--- include/lldb/Symbol/SymbolFile.h
+++ include/lldb/Symbol/SymbolFile.h
@@ -161,6 +161,9 @@
   virtual uint32_t FindFunctions(const RegularExpression &regex,
                                  bool include_inlines, bool append,
                                  SymbolContextList &sc_list);
+  virtual size_t FindPublicSymbols(const ConstString &name,
+                                   lldb::SymbolType type, bool append,
+                                   SymbolContextList &sc_list);
   virtual uint32_t
   FindTypes(const SymbolContext &sc, const ConstString &name,
             const CompilerDeclContext *parent_decl_ctx, bool append,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to