amccarth created this revision.
amccarth added a reviewer: rnk.
amccarth requested review of this revision.

In theory, this adds symbols from the module's PDB file to the symtab.  This 
implementation was modeled after the one in SymbolFilePDB, so it relies on the 
same IPDBSession abstraction as the DIA-based PDB reader. 
 Unfortunately, the native reader implementation of that interface was not 
fully implemented, so the attempt to find the public symbols comes up empty.  
The result is that this patch has no functional change (and thus there are no 
meaningful tests to write).

      

I am currently investigating whether to implement the abstraction or to use the 
lower level native PDB reader interface directly in SymbolFileNativePDB.


https://reviews.llvm.org/D104954

Files:
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp


Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -48,6 +48,8 @@
 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/DebugInfo/PDB/PDB.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/Demangle/MicrosoftDemangle.h"
 #include "llvm/Object/COFF.h"
@@ -307,8 +309,8 @@
   auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
       lldb::eLanguageTypeC_plus_plus);
   if (auto err = ts_or_err.takeError()) {
-    LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
-                   std::move(err), "Failed to initialize");
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+    LLDB_LOG_ERROR(log, std::move(err), "Failed to initialize");
   } else {
     ts_or_err->SetSymbolFile(this);
     auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get());
@@ -905,7 +907,63 @@
   return TranslateLanguage(item->m_compile_opts->getLanguage());
 }
 
-void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
+void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
+  // Currently, we can handle only one symbol for any given address, so we'll
+  // use a `std::set` to keep track of known addresses.
+  std::set<lldb::addr_t> sym_addresses;
+  for (size_t i = 0; i < symtab.GetNumSymbols(); i++) {
+    sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress());
+  }
+
+  std::unique_ptr<IPDBSession> session_up;
+  auto error = llvm::pdb::loadDataForPDB(PDB_ReaderType::Native,
+      GetPDBFile().getFilePath(), session_up);
+  if (error) return;
+  NativeSession *native_session = static_cast<NativeSession 
*>(session_up.get());
+  auto global_scope_up = native_session->getGlobalScope();
+
+  auto results = global_scope_up->findAllChildren<PDBSymbolPublicSymbol>();
+  if (!results)
+    return;
+
+  auto section_list = m_objfile_sp->GetSectionList();
+  if (!section_list)
+    return;
+
+  while (auto pub_symbol = results->getNext()) {
+    auto section_id = pub_symbol->getAddressSection();
+
+    auto section = section_list->FindSectionByID(section_id);
+    if (!section)
+      continue;
+
+    auto offset = pub_symbol->getAddressOffset();
+
+    auto file_addr = section->GetFileAddress() + offset;
+    if (sym_addresses.find(file_addr) != sym_addresses.end())
+      continue;
+    sym_addresses.insert(file_addr);
+
+    auto size = pub_symbol->getLength();
+    symtab.AddSymbol(
+        Symbol(pub_symbol->getSymIndexId(),
+               pub_symbol->getName().c_str(),
+               pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData,
+               /* external */ true,
+               /* is_debug */ false,
+               /* is_trampoline */ false,
+               /* is_artificial */ false,
+               section,
+               offset,
+               size,
+               /* size_is_valid */ size != 0,
+               /* contains_linker_annotations */ false,
+               /* flags */ 0));
+  }
+
+  symtab.CalculateSymbolSizes();
+  symtab.Finalize();
+}
 
 size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());


Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -48,6 +48,8 @@
 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/DebugInfo/PDB/PDB.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/Demangle/MicrosoftDemangle.h"
 #include "llvm/Object/COFF.h"
@@ -307,8 +309,8 @@
   auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
       lldb::eLanguageTypeC_plus_plus);
   if (auto err = ts_or_err.takeError()) {
-    LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
-                   std::move(err), "Failed to initialize");
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+    LLDB_LOG_ERROR(log, std::move(err), "Failed to initialize");
   } else {
     ts_or_err->SetSymbolFile(this);
     auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get());
@@ -905,7 +907,63 @@
   return TranslateLanguage(item->m_compile_opts->getLanguage());
 }
 
-void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
+void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
+  // Currently, we can handle only one symbol for any given address, so we'll
+  // use a `std::set` to keep track of known addresses.
+  std::set<lldb::addr_t> sym_addresses;
+  for (size_t i = 0; i < symtab.GetNumSymbols(); i++) {
+    sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress());
+  }
+
+  std::unique_ptr<IPDBSession> session_up;
+  auto error = llvm::pdb::loadDataForPDB(PDB_ReaderType::Native,
+      GetPDBFile().getFilePath(), session_up);
+  if (error) return;
+  NativeSession *native_session = static_cast<NativeSession *>(session_up.get());
+  auto global_scope_up = native_session->getGlobalScope();
+
+  auto results = global_scope_up->findAllChildren<PDBSymbolPublicSymbol>();
+  if (!results)
+    return;
+
+  auto section_list = m_objfile_sp->GetSectionList();
+  if (!section_list)
+    return;
+
+  while (auto pub_symbol = results->getNext()) {
+    auto section_id = pub_symbol->getAddressSection();
+
+    auto section = section_list->FindSectionByID(section_id);
+    if (!section)
+      continue;
+
+    auto offset = pub_symbol->getAddressOffset();
+
+    auto file_addr = section->GetFileAddress() + offset;
+    if (sym_addresses.find(file_addr) != sym_addresses.end())
+      continue;
+    sym_addresses.insert(file_addr);
+
+    auto size = pub_symbol->getLength();
+    symtab.AddSymbol(
+        Symbol(pub_symbol->getSymIndexId(),
+               pub_symbol->getName().c_str(),
+               pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData,
+               /* external */ true,
+               /* is_debug */ false,
+               /* is_trampoline */ false,
+               /* is_artificial */ false,
+               section,
+               offset,
+               size,
+               /* size_is_valid */ size != 0,
+               /* contains_linker_annotations */ false,
+               /* flags */ 0));
+  }
+
+  symtab.CalculateSymbolSizes();
+  symtab.Finalize();
+}
 
 size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to