diff options
| author | Zachary Turner <zturner@google.com> | 2018-03-13 17:46:06 +0000 | 
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2018-03-13 17:46:06 +0000 | 
| commit | 679aeadda116f1d87ba65fd524f5b901afbeeafb (patch) | |
| tree | c4170a3e925a42daff933862501ae140e4b260be /llvm/lib/DebugInfo/PDB/DIA | |
| parent | e5f72dd5e1b14814c1fbb0a10cbf02222782e5bd (diff) | |
| download | bcm5719-llvm-679aeadda116f1d87ba65fd524f5b901afbeeafb.tar.gz bcm5719-llvm-679aeadda116f1d87ba65fd524f5b901afbeeafb.zip  | |
[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
llvm-svn: 327428
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/DIA')
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp | 54 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp | 64 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp | 29 | 
3 files changed, 147 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp new file mode 100644 index 00000000000..873f4a0a8db --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp @@ -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); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp new file mode 100644 index 00000000000..fbd169524b6 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp @@ -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()); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp index dcf29a56b9d..a6bbf6f9e4f 100644 --- a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp +++ b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp @@ -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> DIASession::getEnumTables() const {    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); +}  | 

