[llvm] r235237 - [PDB] Support executables and source/line info.

Zachary Turner zturner at google.com
Fri Apr 17 15:40:36 PDT 2015


Author: zturner
Date: Fri Apr 17 17:40:36 2015
New Revision: 235237

URL: http://llvm.org/viewvc/llvm-project?rev=235237&view=rev
Log:
[PDB] Support executables and source/line info.

Previously DebugInfoPDB could only load data for a PDB given a
path to the PDB.  It could not open an EXE and find the matching
PDB and verify it matched, etc.  This patch adds support for that
so that we can simply load debug information for a PDB directly.

Additionally, this patch extends DebugInfoPDB to support getting
source and line information for symbols.

Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h
    llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDB.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
    llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDB.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
    llvm/trunk/unittests/DebugInfo/PDB/PDBApiTest.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h Fri Apr 17 17:40:36 2015
@@ -21,12 +21,19 @@ public:
 
   static PDB_ErrorCode createFromPdb(StringRef Path,
                                      std::unique_ptr<IPDBSession> &Session);
+  static PDB_ErrorCode createFromExe(StringRef Path,
+                                     std::unique_ptr<IPDBSession> &Session);
 
   uint64_t getLoadAddress() const override;
   void setLoadAddress(uint64_t Address) override;
   std::unique_ptr<PDBSymbolExe> getGlobalScope() const override;
   std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
 
+  std::unique_ptr<PDBSymbol>
+  findSymbolByAddress(uint64_t Address) const override;
+  std::unique_ptr<IPDBEnumLineNumbers>
+  findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
+
   std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override;
   std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
       const PDBSymbolCompiland &Compiland) const override;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h Fri Apr 17 17:40:36 2015
@@ -43,6 +43,11 @@ public:
     return std::unique_ptr<T>(ConcreteSymbol);
   }
 
+  virtual std::unique_ptr<PDBSymbol>
+  findSymbolByAddress(uint64_t Address) const = 0;
+  virtual std::unique_ptr<IPDBEnumLineNumbers>
+  findLineNumbersByAddress(uint64_t Address, uint32_t Length) const = 0;
+
   virtual std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const = 0;
   virtual std::unique_ptr<IPDBEnumSourceFiles>
   getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const = 0;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDB.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDB.h?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDB.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDB.h Fri Apr 17 17:40:36 2015
@@ -16,8 +16,11 @@
 namespace llvm {
 class StringRef;
 
-PDB_ErrorCode createPDBReader(PDB_ReaderType Type, StringRef Path,
-                              std::unique_ptr<IPDBSession> &Session);
+PDB_ErrorCode loadDataForPDB(PDB_ReaderType Type, StringRef Path,
+                             std::unique_ptr<IPDBSession> &Session);
+
+PDB_ErrorCode loadDataForEXE(PDB_ReaderType Type, StringRef Path,
+                             std::unique_ptr<IPDBSession> &Session);
 }
 
 #endif

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h Fri Apr 17 17:40:36 2015
@@ -21,6 +21,7 @@ class PDBSymbol;
 
 class IPDBDataStream;
 template <class T> class IPDBEnumChildren;
+class IPDBLineNumber;
 class IPDBRawSymbol;
 class IPDBSession;
 class IPDBSourceFile;
@@ -28,6 +29,7 @@ class IPDBSourceFile;
 typedef IPDBEnumChildren<PDBSymbol> IPDBEnumSymbols;
 typedef IPDBEnumChildren<IPDBSourceFile> IPDBEnumSourceFiles;
 typedef IPDBEnumChildren<IPDBDataStream> IPDBEnumDataStreams;
+typedef IPDBEnumChildren<IPDBLineNumber> IPDBEnumLineNumbers;
 
 class PDBSymbolExe;
 class PDBSymbolCompiland;
@@ -426,7 +428,8 @@ enum class PDB_ErrorCode {
   InvalidParameter,
   AlreadyLoaded,
   UnknownError,
-  NoMemory
+  NoMemory,
+  DebugInfoMismatch
 };
 
 struct VersionInfo {

Modified: llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp Fri Apr 17 17:40:36 2015
@@ -9,6 +9,7 @@
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
 #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
 #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
@@ -64,6 +65,50 @@ PDB_ErrorCode DIASession::createFromPdb(
   return PDB_ErrorCode::Success;
 }
 
+PDB_ErrorCode DIASession::createFromExe(StringRef Path,
+                                        std::unique_ptr<IPDBSession> &Session) {
+  CComPtr<IDiaDataSource> DiaDataSource;
+  CComPtr<IDiaSession> DiaSession;
+
+  // We assume that CoInitializeEx has already been called by the executable.
+  HRESULT Result = ::CoCreateInstance(
+      CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
+      reinterpret_cast<LPVOID *>(&DiaDataSource));
+  if (FAILED(Result))
+    return PDB_ErrorCode::NoPdbImpl;
+
+  llvm::SmallVector<UTF16, 128> Path16;
+  if (!llvm::convertUTF8ToUTF16String(Path, Path16))
+    return PDB_ErrorCode::InvalidPath;
+
+  const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());
+  if (FAILED(Result =
+                 DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) {
+    if (Result == E_PDB_NOT_FOUND)
+      return PDB_ErrorCode::InvalidPath;
+    else if (Result == E_PDB_FORMAT)
+      return PDB_ErrorCode::InvalidFileFormat;
+    else if (Result == E_PDB_INVALID_SIG || Result == E_PDB_INVALID_AGE)
+      return PDB_ErrorCode::DebugInfoMismatch;
+    else if (Result == E_INVALIDARG)
+      return PDB_ErrorCode::InvalidParameter;
+    else if (Result == E_UNEXPECTED)
+      return PDB_ErrorCode::AlreadyLoaded;
+    else
+      return PDB_ErrorCode::UnknownError;
+  }
+
+  if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) {
+    if (Result == E_OUTOFMEMORY)
+      return PDB_ErrorCode::NoMemory;
+    else
+      return PDB_ErrorCode::UnknownError;
+  }
+
+  Session.reset(new DIASession(DiaSession));
+  return PDB_ErrorCode::Success;
+}
+
 uint64_t DIASession::getLoadAddress() const {
   uint64_t LoadAddress;
   bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
@@ -95,6 +140,24 @@ std::unique_ptr<PDBSymbol> DIASession::g
   return PDBSymbol::create(*this, std::move(RawSymbol));
 }
 
+std::unique_ptr<PDBSymbol>
+DIASession::findSymbolByAddress(uint64_t Address) const {
+  CComPtr<IDiaSymbol> Symbol;
+  if (S_OK != Session->findSymbolByVA(Address, SymTagNull, &Symbol))
+    return nullptr;
+  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
+  return PDBSymbol::create(*this, std::move(RawSymbol));
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const {
+  CComPtr<IDiaEnumLineNumbers> LineNumbers;
+  if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers))
+    return nullptr;
+
+  return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+}
+
 std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const {
   CComPtr<IDiaEnumSourceFiles> Files;
   if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))

Modified: llvm/trunk/lib/DebugInfo/PDB/PDB.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDB.cpp?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDB.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDB.cpp Fri Apr 17 17:40:36 2015
@@ -20,11 +20,20 @@
 
 using namespace llvm;
 
-PDB_ErrorCode llvm::createPDBReader(PDB_ReaderType Type, StringRef Path,
-                                    std::unique_ptr<IPDBSession> &Session) {
+PDB_ErrorCode llvm::loadDataForPDB(PDB_ReaderType Type, StringRef Path,
+                                   std::unique_ptr<IPDBSession> &Session) {
   // Create the correct concrete instance type based on the value of Type.
 #if HAVE_DIA_SDK
   return DIASession::createFromPdb(Path, Session);
 #endif
   return PDB_ErrorCode::NoPdbImpl;
 }
+
+PDB_ErrorCode llvm::loadDataForEXE(PDB_ReaderType Type, StringRef Path,
+                                   std::unique_ptr<IPDBSession> &Session) {
+// Create the correct concrete instance type based on the value of Type.
+#if HAVE_DIA_SDK
+  return DIASession::createFromExe(Path, Session);
+#endif
+  return PDB_ErrorCode::NoPdbImpl;
+}

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri Apr 17 17:40:36 2015
@@ -101,7 +101,7 @@ cl::opt<bool> NoEnumDefs("no-enum-defini
 static void dumpInput(StringRef Path) {
   std::unique_ptr<IPDBSession> Session;
   PDB_ErrorCode Error =
-      llvm::createPDBReader(PDB_ReaderType::DIA, Path, Session);
+      llvm::loadDataForPDB(PDB_ReaderType::DIA, Path, Session);
   switch (Error) {
   case PDB_ErrorCode::Success:
     break;

Modified: llvm/trunk/unittests/DebugInfo/PDB/PDBApiTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/PDBApiTest.cpp?rev=235237&r1=235236&r2=235237&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/PDBApiTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/PDBApiTest.cpp Fri Apr 17 17:40:36 2015
@@ -72,6 +72,16 @@ class MockSession : public IPDBSession {
   getSourceFileById(uint32_t SymbolId) const override {
     return nullptr;
   }
+
+  std::unique_ptr<PDBSymbol>
+  findSymbolByAddress(uint64_t Address) const override {
+    return nullptr;
+  }
+  std::unique_ptr<IPDBEnumLineNumbers>
+  findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override {
+    return nullptr;
+  }
+
   std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override {
     return nullptr;
   }





More information about the llvm-commits mailing list