[llvm] r327428 - [PDB] Support dumping injected sources via the DIA reader.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 13 10:46:06 PDT 2018


Author: zturner
Date: Tue Mar 13 10:46:06 2018
New Revision: 327428

URL: http://llvm.org/viewvc/llvm-project?rev=327428&view=rev
Log:
[PDB] Support dumping injected sources via the DIA reader.

Injected sources are basically a way to add actual source file content
to your PDB. Presumably you could use this for shipping your source code
with your debug information, but in practice I can only find this being
used for embedding natvis files inside of PDBs.

In order to effectively test LLVM's natvis file injection, we need a way
to dump the injected sources of a PDB in a way that is authoritative
(i.e. based on Microsoft's understanding of the PDB format, and not
LLVM's). To this end, I've added support for dumping injected sources
via DIA. I made a PDB file that used the /natvis option to generate a
test case.

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

Added:
    llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h
    llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h
    llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h
    llvm/trunk/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h
    llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp
    llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp
    llvm/trunk/test/tools/llvm-pdbdump/Inputs/InjectedSource.pdb   (with props)
    llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h
    llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
    llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp

Added: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h?rev=327428&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h Tue Mar 13 10:46:06 2018
@@ -0,0 +1,40 @@
+//==- DIAEnumInjectedSources.h - DIA Injected Sources Enumerator -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_DIA_DIAENUMINJECTEDSOURCES_H
+#define LLVM_DEBUGINFO_PDB_DIA_DIAENUMINJECTEDSOURCES_H
+
+#include "DIASupport.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
+
+namespace llvm {
+namespace pdb {
+class DIASession;
+
+class DIAEnumInjectedSources : public IPDBEnumChildren<IPDBInjectedSource> {
+public:
+  explicit DIAEnumInjectedSources(
+      const DIASession &PDBSession,
+      CComPtr<IDiaEnumInjectedSources> DiaEnumerator);
+
+  uint32_t getChildCount() const override;
+  ChildTypePtr getChildAtIndex(uint32_t Index) const override;
+  ChildTypePtr getNext() override;
+  void reset() override;
+  DIAEnumInjectedSources *clone() const override;
+
+private:
+  const DIASession &Session;
+  CComPtr<IDiaEnumInjectedSources> Enumerator;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_DIA_DIAENUMINJECTEDSOURCES_H

Added: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h?rev=327428&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h Tue Mar 13 10:46:06 2018
@@ -0,0 +1,40 @@
+//===- DIAInjectedSource.h - DIA impl for IPDBInjectedSource ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_DIA_DIAINJECTEDSOURCE_H
+#define LLVM_DEBUGINFO_PDB_DIA_DIAINJECTEDSOURCE_H
+
+#include "DIASupport.h"
+#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
+
+namespace llvm {
+namespace pdb {
+class DIASession;
+
+class DIAInjectedSource : public IPDBInjectedSource {
+public:
+  explicit DIAInjectedSource(const DIASession &Session,
+                             CComPtr<IDiaInjectedSource> DiaSourceFile);
+
+  uint32_t getCrc32() const override;
+  uint64_t getCodeByteSize() const override;
+  std::string getFileName() const override;
+  std::string getObjectFileName() const override;
+  std::string getVirtualFileName() const override;
+  PDB_SourceCompression getCompression() const override;
+  std::string getCode() const override;
+
+private:
+  const DIASession &Session;
+  CComPtr<IDiaInjectedSource> SourceFile;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_DIA_DIAINJECTEDSOURCE_H

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=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h Tue Mar 13 10:46:06 2018
@@ -65,6 +65,9 @@ public:
   std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const override;
 
   std::unique_ptr<IPDBEnumTables> getEnumTables() const override;
+
+  std::unique_ptr<IPDBEnumInjectedSources> getInjectedSources() const override;
+
 private:
   CComPtr<IDiaSession> Session;
 };

Added: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h?rev=327428&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h Tue Mar 13 10:46:06 2018
@@ -0,0 +1,31 @@
+//===- DIAUtils.h - Utility functions for working with DIA ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_DIA_DIAUTILS_H
+#define LLVM_DEBUGINFO_PDB_DIA_DIAUTILS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/ConvertUTF.h"
+
+template <typename Obj>
+std::string invokeBstrMethod(Obj &Object,
+                             HRESULT (__stdcall Obj::*Func)(BSTR *)) {
+  CComBSTR Str16;
+  HRESULT Result = (Object.*Func)(&Str16);
+  if (S_OK != Result)
+    return std::string();
+
+  std::string Str8;
+  llvm::ArrayRef<char> StrBytes(reinterpret_cast<char *>(Str16.m_str),
+                                Str16.ByteLength());
+  llvm::convertUTF16ToUTF8String(StrBytes, Str8);
+  return Str8;
+}
+
+#endif // LLVM_DEBUGINFO_PDB_DIA_DIAUTILS_H

Added: llvm/trunk/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h?rev=327428&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h Tue Mar 13 10:46:06 2018
@@ -0,0 +1,42 @@
+//===- IPDBInjectedSource.h - base class for PDB injected file --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H
+#define LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H
+
+#include "PDBTypes.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+class raw_ostream;
+
+namespace pdb {
+
+/// IPDBInjectedSource defines an interface used to represent source files
+/// which were injected directly into the PDB file during the compilation
+/// process.  This is used, for example, to add natvis files to a PDB, but
+/// in theory could be used to add arbitrary source code.
+class IPDBInjectedSource {
+public:
+  virtual ~IPDBInjectedSource();
+
+  virtual uint32_t getCrc32() const = 0;
+  virtual uint64_t getCodeByteSize() const = 0;
+  virtual std::string getFileName() const = 0;
+  virtual std::string getObjectFileName() const = 0;
+  virtual std::string getVirtualFileName() const = 0;
+  virtual PDB_SourceCompression getCompression() const = 0;
+  virtual std::string getCode() const = 0;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H

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=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h Tue Mar 13 10:46:06 2018
@@ -69,6 +69,9 @@ public:
   virtual std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const = 0;
 
   virtual std::unique_ptr<IPDBEnumTables> getEnumTables() const = 0;
+
+  virtual std::unique_ptr<IPDBEnumInjectedSources>
+  getInjectedSources() const = 0;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h?rev=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h Tue Mar 13 10:46:06 2018
@@ -85,6 +85,8 @@ public:
 
   std::unique_ptr<IPDBEnumTables> getEnumTables() const override;
 
+  std::unique_ptr<IPDBEnumInjectedSources> getInjectedSources() const override;
+
   PDBFile &getPDBFile() { return *Pdb; }
   const PDBFile &getPDBFile() const { return *Pdb; }
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h?rev=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h Tue Mar 13 10:46:06 2018
@@ -34,6 +34,8 @@ raw_ostream &operator<<(raw_ostream &OS,
 raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
 raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
 raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine);
+raw_ostream &operator<<(raw_ostream &OS,
+                        const PDB_SourceCompression &Compression);
 
 raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
 raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version);

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=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h Tue Mar 13 10:46:06 2018
@@ -23,6 +23,7 @@ namespace llvm {
 namespace pdb {
 
 class IPDBDataStream;
+class IPDBInjectedSource;
 class IPDBLineNumber;
 class IPDBSourceFile;
 class IPDBTable;
@@ -65,6 +66,7 @@ using IPDBEnumSourceFiles = IPDBEnumChil
 using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>;
 using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>;
 using IPDBEnumTables = IPDBEnumChildren<IPDBTable>;
+using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>;
 
 /// Specifies which PDB reader implementation is to be used.  Only a value
 /// of PDB_ReaderType::DIA is currently supported, but Native is in the works.
@@ -133,6 +135,13 @@ enum class PDB_Machine {
   WceMipsV2 = 0x169
 };
 
+enum class PDB_SourceCompression {
+  None,
+  RunLengthEncoded,
+  Huffman,
+  LZ,
+};
+
 /// These values correspond to the CV_call_e enumeration, and are documented
 /// at the following locations:
 ///   https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx

Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Tue Mar 13 10:46:06 2018
@@ -14,11 +14,13 @@ if(LLVM_ENABLE_DIA_SDK)
   add_pdb_impl_folder(DIA
     DIA/DIADataStream.cpp
     DIA/DIAEnumDebugStreams.cpp
+    DIA/DIAEnumInjectedSources.cpp
     DIA/DIAEnumLineNumbers.cpp
     DIA/DIAEnumSourceFiles.cpp
     DIA/DIAEnumSymbols.cpp
     DIA/DIAEnumTables.cpp
     DIA/DIAError.cpp
+    DIA/DIAInjectedSource.cpp
     DIA/DIALineNumber.cpp
     DIA/DIARawSymbol.cpp
     DIA/DIASession.cpp

Added: llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp?rev=327428&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp Tue Mar 13 10:46:06 2018
@@ -0,0 +1,54 @@
+//==- DIAEnumSourceFiles.cpp - DIA Source File Enumerator impl ---*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+DIAEnumInjectedSources::DIAEnumInjectedSources(
+    const DIASession &PDBSession,
+    CComPtr<IDiaEnumInjectedSources> DiaEnumerator)
+    : Session(PDBSession), Enumerator(DiaEnumerator) {}
+
+uint32_t DIAEnumInjectedSources::getChildCount() const {
+  LONG Count = 0;
+  return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
+}
+
+std::unique_ptr<IPDBInjectedSource>
+DIAEnumInjectedSources::getChildAtIndex(uint32_t Index) const {
+  CComPtr<IDiaInjectedSource> Item;
+  if (S_OK != Enumerator->Item(Index, &Item))
+    return nullptr;
+
+  return std::unique_ptr<IPDBInjectedSource>(
+      new DIAInjectedSource(Session, Item));
+}
+
+std::unique_ptr<IPDBInjectedSource> DIAEnumInjectedSources::getNext() {
+  CComPtr<IDiaInjectedSource> Item;
+  ULONG NumFetched = 0;
+  if (S_OK != Enumerator->Next(1, &Item, &NumFetched))
+    return nullptr;
+
+  return std::unique_ptr<IPDBInjectedSource>(
+      new DIAInjectedSource(Session, Item));
+}
+
+void DIAEnumInjectedSources::reset() { Enumerator->Reset(); }
+
+DIAEnumInjectedSources *DIAEnumInjectedSources::clone() const {
+  CComPtr<IDiaEnumInjectedSources> EnumeratorClone;
+  if (S_OK != Enumerator->Clone(&EnumeratorClone))
+    return nullptr;
+  return new DIAEnumInjectedSources(Session, EnumeratorClone);
+}

Added: llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp?rev=327428&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp Tue Mar 13 10:46:06 2018
@@ -0,0 +1,64 @@
+//===- DIAInjectedSource.cpp - DIA impl for IPDBInjectedSource --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+DIAInjectedSource::DIAInjectedSource(const DIASession &Session,
+                                     CComPtr<IDiaInjectedSource> DiaSourceFile)
+    : Session(Session), SourceFile(DiaSourceFile) {}
+
+uint32_t DIAInjectedSource::getCrc32() const {
+  DWORD Crc;
+  return (S_OK == SourceFile->get_crc(&Crc)) ? Crc : 0;
+}
+
+uint64_t DIAInjectedSource::getCodeByteSize() const {
+  ULONGLONG Size;
+  return (S_OK == SourceFile->get_length(&Size)) ? Size : 0;
+}
+
+std::string DIAInjectedSource::getFileName() const {
+  return invokeBstrMethod(*SourceFile, &IDiaInjectedSource::get_filename);
+}
+
+std::string DIAInjectedSource::getObjectFileName() const {
+  return invokeBstrMethod(*SourceFile, &IDiaInjectedSource::get_objectFilename);
+}
+
+std::string DIAInjectedSource::getVirtualFileName() const {
+  return invokeBstrMethod(*SourceFile,
+                          &IDiaInjectedSource::get_virtualFilename);
+}
+
+PDB_SourceCompression DIAInjectedSource::getCompression() const {
+  DWORD Compression = 0;
+  if (S_OK != SourceFile->get_sourceCompression(&Compression))
+    return PDB_SourceCompression::None;
+  return static_cast<PDB_SourceCompression>(Compression);
+}
+
+std::string DIAInjectedSource::getCode() const {
+  DWORD DataSize;
+  if (S_OK != SourceFile->get_source(0, &DataSize, nullptr))
+    return "";
+
+  std::vector<uint8_t> Buffer(DataSize);
+  if (S_OK != SourceFile->get_source(DataSize, &DataSize, Buffer.data()))
+    return "";
+  assert(Buffer.size() == DataSize);
+  return std::string(reinterpret_cast<const char *>(Buffer.data()),
+                     Buffer.size());
+}

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=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp Tue Mar 13 10:46:06 2018
@@ -9,6 +9,7 @@
 #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumTables.h"
@@ -310,3 +311,31 @@ std::unique_ptr<IPDBEnumTables> DIASessi
 
   return llvm::make_unique<DIAEnumTables>(DiaEnumerator);
 }
+
+static CComPtr<IDiaEnumInjectedSources>
+getEnumInjectedSources(IDiaSession &Session) {
+  CComPtr<IDiaEnumInjectedSources> EIS;
+  CComPtr<IDiaEnumTables> ET;
+  CComPtr<IDiaTable> Table;
+  ULONG Count = 0;
+
+  if (Session.getEnumTables(&ET) != S_OK)
+    return nullptr;
+
+  while (ET->Next(1, &Table, &Count) == S_OK && Count == 1) {
+    // There is only one table that matches the given iid
+    if (S_OK ==
+        Table->QueryInterface(__uuidof(IDiaEnumInjectedSources), (void **)&EIS))
+      break;
+    Table.Release();
+  }
+  return EIS;
+}
+std::unique_ptr<IPDBEnumInjectedSources>
+DIASession::getInjectedSources() const {
+  CComPtr<IDiaEnumInjectedSources> Files = getEnumInjectedSources(*Session);
+  if (!Files)
+    return nullptr;
+
+  return llvm::make_unique<DIAEnumInjectedSources>(*this, Files);
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp?rev=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp Tue Mar 13 10:46:06 2018
@@ -249,3 +249,8 @@ std::unique_ptr<IPDBEnumDataStreams> Nat
 std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
   return nullptr;
 }
+
+std::unique_ptr<IPDBEnumInjectedSources>
+NativeSession::getInjectedSources() const {
+  return nullptr;
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp?rev=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp Tue Mar 13 10:46:06 2018
@@ -254,6 +254,18 @@ raw_ostream &llvm::pdb::operator<<(raw_o
   return OS;
 }
 
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+                                   const PDB_SourceCompression &Compression) {
+  switch (Compression) {
+    CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, None, OS)
+    CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, Huffman, OS)
+    CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, LZ, OS)
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_SourceCompression, RunLengthEncoded, "RLE",
+                               OS)
+  }
+  return OS;
+}
+
 raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const Variant &Value) {
   switch (Value.Type) {
     case PDB_VariantType::Bool:

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp?rev=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp Tue Mar 13 10:46:06 2018
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/PDB/IPDBDataStream.h"
+#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
 #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
 #include "llvm/DebugInfo/PDB/IPDBSession.h"
@@ -29,3 +30,5 @@ IPDBRawSymbol::~IPDBRawSymbol() = defaul
 IPDBLineNumber::~IPDBLineNumber() = default;
 
 IPDBTable::~IPDBTable() = default;
+
+IPDBInjectedSource::~IPDBInjectedSource() = default;

Added: llvm/trunk/test/tools/llvm-pdbdump/Inputs/InjectedSource.pdb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/Inputs/InjectedSource.pdb?rev=327428&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-pdbdump/Inputs/InjectedSource.pdb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test?rev=327428&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test (added)
+++ llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test Tue Mar 13 10:46:06 2018
@@ -0,0 +1,16 @@
+; RUN: llvm-pdbutil pretty -injected-sources -injected-source-content \
+; RUN:   %p/Inputs/InjectedSource.pdb | FileCheck %s
+; RUN: llvm-pdbutil pretty -injected-sources -injected-source-content \
+; RUN:   %p/Inputs/ClassLayoutTest.pdb | FileCheck --check-prefix=NEGATIVE %s
+
+; CHECK:      ---INJECTED SOURCES---
+; CHECK-NEXT: d:\sandbox\natvistest\natvistest\test.natvis (220 bytes): obj=<null>, vname=d:\sandbox\natvistest\natvistest\test.natvis, crc=2374979362, compression=None
+; CHECK-NEXT: <?xml version="1.0" encoding="utf-8"?>
+; CHECK-NEXT: <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+; CHECK-NEXT:   <Type Name="Foo">
+; CHECK-NEXT:     <DisplayString>This is a test</DisplayString>
+; CHECK-NEXT:   </Type>
+; CHECK-NEXT: </AutoVisualizer>
+
+; NEGATIVE:      ---INJECTED SOURCES---
+; NEGATIVE-NEXT: There are no injected sources.

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=327428&r1=327427&r2=327428&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Tue Mar 13 10:46:06 2018
@@ -45,6 +45,7 @@
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/PDB/GenericError.h"
 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
 #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
 #include "llvm/DebugInfo/PDB/IPDBSession.h"
 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
@@ -147,6 +148,14 @@ cl::list<std::string> InputFilenames(cl:
                                      cl::desc("<input PDB files>"),
                                      cl::OneOrMore, cl::sub(PrettySubcommand));
 
+cl::opt<bool> InjectedSources("injected-sources",
+                              cl::desc("Display injected sources"),
+                              cl::cat(OtherOptions), cl::sub(PrettySubcommand));
+cl::opt<bool> ShowInjectedSourceContent(
+    "injected-source-content",
+    cl::desc("When displaying an injected source, display the file content"),
+    cl::cat(OtherOptions), cl::sub(PrettySubcommand));
+
 cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"),
                          cl::cat(TypeCategory), cl::sub(PrettySubcommand));
 cl::opt<bool> Symbols("module-syms",
@@ -840,6 +849,62 @@ bool opts::pretty::compareDataSymbols(
   return getTypeLength(*F1) > getTypeLength(*F2);
 }
 
+static std::string stringOr(std::string Str, std::string IfEmpty) {
+  return (Str.empty()) ? IfEmpty : Str;
+}
+
+static void dumpInjectedSources(LinePrinter &Printer, IPDBSession &Session) {
+  auto Sources = Session.getInjectedSources();
+  if (0 == Sources->getChildCount()) {
+    Printer.printLine("There are no injected sources.");
+    return;
+  }
+
+  while (auto IS = Sources->getNext()) {
+    Printer.NewLine();
+    std::string File = stringOr(IS->getFileName(), "<null>");
+    uint64_t Size = IS->getCodeByteSize();
+    std::string Obj = stringOr(IS->getObjectFileName(), "<null>");
+    std::string VFName = stringOr(IS->getVirtualFileName(), "<null>");
+    uint32_t CRC = IS->getCrc32();
+
+    std::string CompressionStr;
+    llvm::raw_string_ostream Stream(CompressionStr);
+    Stream << IS->getCompression();
+    WithColor(Printer, PDB_ColorItem::Path).get() << File;
+    Printer << " (";
+    WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Size;
+    Printer << " bytes): ";
+    WithColor(Printer, PDB_ColorItem::Keyword).get() << "obj";
+    Printer << "=";
+    WithColor(Printer, PDB_ColorItem::Path).get() << Obj;
+    Printer << ", ";
+    WithColor(Printer, PDB_ColorItem::Keyword).get() << "vname";
+    Printer << "=";
+    WithColor(Printer, PDB_ColorItem::Path).get() << VFName;
+    Printer << ", ";
+    WithColor(Printer, PDB_ColorItem::Keyword).get() << "crc";
+    Printer << "=";
+    WithColor(Printer, PDB_ColorItem::LiteralValue).get() << CRC;
+    Printer << ", ";
+    WithColor(Printer, PDB_ColorItem::Keyword).get() << "compression";
+    Printer << "=";
+    WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Stream.str();
+
+    if (!opts::pretty::ShowInjectedSourceContent)
+      continue;
+
+    // Set the indent level to 0 when printing file content.
+    int Indent = Printer.getIndentLevel();
+    Printer.Unindent(Indent);
+
+    Printer.printLine(IS->getCode());
+
+    // Re-indent back to the original level.
+    Printer.Indent(Indent);
+  }
+}
+
 static void dumpPretty(StringRef Path) {
   std::unique_ptr<IPDBSession> Session;
 
@@ -989,6 +1054,19 @@ static void dumpPretty(StringRef Path) {
   if (opts::pretty::Lines) {
     Printer.NewLine();
   }
+  if (opts::pretty::InjectedSources) {
+    Printer.NewLine();
+    WithColor(Printer, PDB_ColorItem::SectionHeader).get()
+        << "---INJECTED SOURCES---";
+    AutoIndent Indent1(Printer);
+
+    if (ReaderType == PDB_ReaderType::Native)
+      Printer.printLine(
+          "Injected sources are not supported with the native reader.");
+    else
+      dumpInjectedSources(Printer, *Session);
+  }
+
   outs().flush();
 }
 




More information about the llvm-commits mailing list