mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:29:58 +00:00
[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
This commit is contained in:
parent
30167650e0
commit
1882229246
40
include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h
Normal file
40
include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h
Normal file
@ -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
|
40
include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h
Normal file
40
include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h
Normal file
@ -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
|
@ -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;
|
||||
};
|
||||
|
31
include/llvm/DebugInfo/PDB/DIA/DIAUtils.h
Normal file
31
include/llvm/DebugInfo/PDB/DIA/DIAUtils.h
Normal file
@ -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
|
42
include/llvm/DebugInfo/PDB/IPDBInjectedSource.h
Normal file
42
include/llvm/DebugInfo/PDB/IPDBInjectedSource.h
Normal file
@ -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
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -34,6 +34,8 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag);
|
||||
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);
|
||||
|
@ -23,6 +23,7 @@ namespace llvm {
|
||||
namespace pdb {
|
||||
|
||||
class IPDBDataStream;
|
||||
class IPDBInjectedSource;
|
||||
class IPDBLineNumber;
|
||||
class IPDBSourceFile;
|
||||
class IPDBTable;
|
||||
@ -65,6 +66,7 @@ using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>;
|
||||
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
|
||||
|
@ -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
|
||||
|
54
lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp
Normal file
54
lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp
Normal file
@ -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);
|
||||
}
|
64
lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp
Normal file
64
lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp
Normal file
@ -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());
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -249,3 +249,8 @@ std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
|
||||
std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<IPDBEnumInjectedSources>
|
||||
NativeSession::getInjectedSources() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -254,6 +254,18 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
|
||||
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:
|
||||
|
@ -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() = default;
|
||||
IPDBLineNumber::~IPDBLineNumber() = default;
|
||||
|
||||
IPDBTable::~IPDBTable() = default;
|
||||
|
||||
IPDBInjectedSource::~IPDBInjectedSource() = default;
|
||||
|
BIN
test/tools/llvm-pdbdump/Inputs/InjectedSource.pdb
Normal file
BIN
test/tools/llvm-pdbdump/Inputs/InjectedSource.pdb
Normal file
Binary file not shown.
16
test/tools/llvm-pdbdump/injected-sources.test
Normal file
16
test/tools/llvm-pdbdump/injected-sources.test
Normal file
@ -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.
|
@ -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::Positional,
|
||||
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user