forked from OSchip/llvm-project
[llvm-pdbdump] Dump File / Line Info to YAML.
We were already parsing and dumping this to the human readable format, but not to the YAML format. This does so, in preparation for reading it in and reconstructing the line information from YAML. llvm-svn: 301357
This commit is contained in:
parent
e46b4498b8
commit
ee3b9c2558
|
@ -546,7 +546,7 @@ enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland };
|
||||||
// These values correspond to the CV_SourceChksum_t enumeration.
|
// These values correspond to the CV_SourceChksum_t enumeration.
|
||||||
enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
|
enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
|
||||||
|
|
||||||
enum LineFlags : uint32_t {
|
enum LineFlags : uint16_t {
|
||||||
HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
|
HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
BinaryStreamReader Reader(Stream);
|
BinaryStreamReader Reader(Stream);
|
||||||
if (auto EC = Reader.readObject(BlockHeader))
|
if (auto EC = Reader.readObject(BlockHeader))
|
||||||
return EC;
|
return EC;
|
||||||
bool HasColumn = Header->Flags & LineFlags::HaveColumns;
|
bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns);
|
||||||
uint32_t LineInfoSize =
|
uint32_t LineInfoSize =
|
||||||
BlockHeader->NumLines *
|
BlockHeader->NumLines *
|
||||||
(sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
|
(sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
|
||||||
|
|
|
@ -40,6 +40,8 @@ public:
|
||||||
iterator_range<codeview::ModuleSubstreamArray::Iterator>
|
iterator_range<codeview::ModuleSubstreamArray::Iterator>
|
||||||
lines(bool *HadError) const;
|
lines(bool *HadError) const;
|
||||||
|
|
||||||
|
bool hasLineInfo() const;
|
||||||
|
|
||||||
Error commit();
|
Error commit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -606,7 +606,7 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void bitSetCase(T &Val, const char* Str, const T ConstVal) {
|
void bitSetCase(T &Val, const char* Str, const T ConstVal) {
|
||||||
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
|
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
|
||||||
Val = Val | ConstVal;
|
Val = static_cast<T>(Val | ConstVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,7 +614,7 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
|
void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
|
||||||
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
|
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
|
||||||
Val = Val | ConstVal;
|
Val = static_cast<T>(Val | ConstVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,4 +82,8 @@ ModStream::lines(bool *HadError) const {
|
||||||
return make_range(LineInfo.begin(HadError), LineInfo.end());
|
return make_range(LineInfo.begin(HadError), LineInfo.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ModStream::hasLineInfo() const {
|
||||||
|
return C13LinesSubstream.getLength() > 0 || LinesSubstream.getLength() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
Error ModStream::commit() { return Error::success(); }
|
Error ModStream::commit() { return Error::success(); }
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
; RUN: llvm-pdbdump pdb2yaml -dbi-module-lines %p/Inputs/empty.pdb \
|
||||||
|
; RUN: | FileCheck -check-prefix=YAML %s
|
||||||
|
|
||||||
|
|
||||||
|
YAML: ---
|
||||||
|
YAML: MSF:
|
||||||
|
YAML: SuperBlock:
|
||||||
|
YAML: BlockSize: 4096
|
||||||
|
YAML: FreeBlockMap: 2
|
||||||
|
YAML: NumBlocks: 25
|
||||||
|
YAML: NumDirectoryBytes: 136
|
||||||
|
YAML: Unknown1: 0
|
||||||
|
YAML: BlockMapAddr: 24
|
||||||
|
YAML: NumDirectoryBlocks: 1
|
||||||
|
YAML: DirectoryBlocks: [ 23 ]
|
||||||
|
YAML: NumStreams: 0
|
||||||
|
YAML: FileSize: 102400
|
||||||
|
YAML: DbiStream:
|
||||||
|
YAML: VerHeader: V70
|
||||||
|
YAML: Age: 1
|
||||||
|
YAML: BuildNumber: 35840
|
||||||
|
YAML: PdbDllVersion: 31101
|
||||||
|
YAML: PdbDllRbld: 0
|
||||||
|
YAML: Flags: 1
|
||||||
|
YAML: MachineType: x86
|
||||||
|
YAML: Modules:
|
||||||
|
YAML: - Module: 'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj'
|
||||||
|
YAML: ObjFile: 'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj'
|
||||||
|
YAML: SourceFiles:
|
||||||
|
YAML: - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
|
||||||
|
YAML: LineInfo:
|
||||||
|
YAML: Lines:
|
||||||
|
YAML: CodeSize: 10
|
||||||
|
YAML: Flags: [ ]
|
||||||
|
YAML: RelocOffset: 16
|
||||||
|
YAML: RelocSegment: 1
|
||||||
|
YAML: LineInfo:
|
||||||
|
YAML: - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
|
||||||
|
YAML: Lines:
|
||||||
|
YAML: - Offset: 0
|
||||||
|
YAML: LineStart: 5
|
||||||
|
YAML: IsStatement: true
|
||||||
|
YAML: EndDelta: 5
|
||||||
|
YAML: - Offset: 3
|
||||||
|
YAML: LineStart: 6
|
||||||
|
YAML: IsStatement: true
|
||||||
|
YAML: EndDelta: 6
|
||||||
|
YAML: - Offset: 8
|
||||||
|
YAML: LineStart: 7
|
||||||
|
YAML: IsStatement: true
|
||||||
|
YAML: EndDelta: 7
|
||||||
|
YAML: Columns:
|
||||||
|
YAML: Checksums:
|
||||||
|
YAML: - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
|
||||||
|
YAML: Kind: MD5
|
||||||
|
YAML: Checksum: A0A5BD0D3ECD93FC29D19DE826FBF4BC
|
||||||
|
YAML: - Module: '* Linker *'
|
||||||
|
YAML: ObjFile: ''
|
||||||
|
YAML: ...
|
|
@ -13,6 +13,7 @@
|
||||||
#include "YamlSymbolDumper.h"
|
#include "YamlSymbolDumper.h"
|
||||||
#include "YamlTypeDumper.h"
|
#include "YamlTypeDumper.h"
|
||||||
|
|
||||||
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
|
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
|
||||||
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
|
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
|
||||||
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
|
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
|
||||||
|
@ -35,6 +36,10 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceFileChecksumEntry)
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineEntry)
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceColumnEntry)
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineBlock)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSymbolRecord)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSymbolRecord)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord)
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
|
||||||
|
@ -145,9 +150,40 @@ template <> struct ScalarEnumerationTraits<llvm::pdb::PdbRaw_FeatureSig> {
|
||||||
io.enumCase(Features, "VC140", PdbRaw_FeatureSig::VC140);
|
io.enumCase(Features, "VC140", PdbRaw_FeatureSig::VC140);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> struct ScalarEnumerationTraits<llvm::codeview::FileChecksumKind> {
|
||||||
|
static void enumeration(IO &io, llvm::codeview::FileChecksumKind &Kind) {
|
||||||
|
io.enumCase(Kind, "None", llvm::codeview::FileChecksumKind::None);
|
||||||
|
io.enumCase(Kind, "MD5", llvm::codeview::FileChecksumKind::MD5);
|
||||||
|
io.enumCase(Kind, "SHA1", llvm::codeview::FileChecksumKind::SHA1);
|
||||||
|
io.enumCase(Kind, "SHA256", llvm::codeview::FileChecksumKind::SHA256);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct ScalarBitSetTraits<llvm::codeview::LineFlags> {
|
||||||
|
static void bitset(IO &io, llvm::codeview::LineFlags &Flags) {
|
||||||
|
io.bitSetCase(Flags, "HasColumnInfo",
|
||||||
|
llvm::codeview::LineFlags::HaveColumns);
|
||||||
|
io.enumFallback<Hex16>(Flags);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
|
||||||
|
void *ctx, raw_ostream &Out) {
|
||||||
|
StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
|
||||||
|
Value.Bytes.size());
|
||||||
|
Out << toHex(Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
|
||||||
|
HexFormattedString &Value) {
|
||||||
|
std::string H = fromHex(Scalar);
|
||||||
|
Value.Bytes.assign(H.begin(), H.end());
|
||||||
|
return StringRef();
|
||||||
|
}
|
||||||
|
|
||||||
void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
|
void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
|
||||||
// Create a single serialization context that will be passed through the
|
// Create a single serialization context that will be passed through the
|
||||||
// entire process of serializing / deserializing a Tpi Stream. This is
|
// entire process of serializing / deserializing a Tpi Stream. This is
|
||||||
|
@ -255,9 +291,65 @@ void MappingContextTraits<PdbDbiModuleInfo, pdb::yaml::SerializationContext>::ma
|
||||||
IO.mapRequired("Module", Obj.Mod);
|
IO.mapRequired("Module", Obj.Mod);
|
||||||
IO.mapOptional("ObjFile", Obj.Obj, Obj.Mod);
|
IO.mapOptional("ObjFile", Obj.Obj, Obj.Mod);
|
||||||
IO.mapOptional("SourceFiles", Obj.SourceFiles);
|
IO.mapOptional("SourceFiles", Obj.SourceFiles);
|
||||||
|
IO.mapOptionalWithContext("LineInfo", Obj.FileLineInfo, Context);
|
||||||
IO.mapOptionalWithContext("Modi", Obj.Modi, Context);
|
IO.mapOptionalWithContext("Modi", Obj.Modi, Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MappingContextTraits<pdb::yaml::PdbSourceLineEntry,
|
||||||
|
pdb::yaml::SerializationContext>::
|
||||||
|
mapping(IO &IO, PdbSourceLineEntry &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context) {
|
||||||
|
IO.mapRequired("Offset", Obj.Offset);
|
||||||
|
IO.mapRequired("LineStart", Obj.LineStart);
|
||||||
|
IO.mapRequired("IsStatement", Obj.IsStatement);
|
||||||
|
IO.mapRequired("EndDelta", Obj.EndDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingContextTraits<pdb::yaml::PdbSourceColumnEntry,
|
||||||
|
pdb::yaml::SerializationContext>::
|
||||||
|
mapping(IO &IO, PdbSourceColumnEntry &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context) {
|
||||||
|
IO.mapRequired("StartColumn", Obj.StartColumn);
|
||||||
|
IO.mapRequired("EndColumn", Obj.EndColumn);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MappingContextTraits<pdb::yaml::PdbSourceLineBlock,
|
||||||
|
pdb::yaml::SerializationContext>::
|
||||||
|
mapping(IO &IO, PdbSourceLineBlock &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context) {
|
||||||
|
IO.mapRequired("FileName", Obj.FileName);
|
||||||
|
IO.mapRequired("Lines", Obj.Lines, Context);
|
||||||
|
IO.mapRequired("Columns", Obj.Columns, Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MappingContextTraits<pdb::yaml::PdbSourceFileChecksumEntry,
|
||||||
|
pdb::yaml::SerializationContext>::
|
||||||
|
mapping(IO &IO, PdbSourceFileChecksumEntry &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context) {
|
||||||
|
IO.mapRequired("FileName", Obj.FileName);
|
||||||
|
IO.mapRequired("Kind", Obj.Kind);
|
||||||
|
IO.mapRequired("Checksum", Obj.ChecksumBytes);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MappingContextTraits<pdb::yaml::PdbSourceLineInfo,
|
||||||
|
pdb::yaml::SerializationContext>::
|
||||||
|
mapping(IO &IO, PdbSourceLineInfo &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context) {
|
||||||
|
IO.mapRequired("CodeSize", Obj.CodeSize);
|
||||||
|
IO.mapRequired("Flags", Obj.Flags);
|
||||||
|
IO.mapRequired("RelocOffset", Obj.RelocOffset);
|
||||||
|
IO.mapRequired("RelocSegment", Obj.RelocSegment);
|
||||||
|
IO.mapRequired("LineInfo", Obj.LineInfo, Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MappingContextTraits<pdb::yaml::PdbSourceFileInfo,
|
||||||
|
pdb::yaml::SerializationContext>::
|
||||||
|
mapping(IO &IO, PdbSourceFileInfo &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context) {
|
||||||
|
IO.mapOptionalWithContext("Lines", Obj.Lines, Context);
|
||||||
|
IO.mapOptionalWithContext("Checksums", Obj.FileChecksums, Context);
|
||||||
|
};
|
||||||
|
|
||||||
void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
|
void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
|
||||||
mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
|
mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
|
||||||
pdb::yaml::SerializationContext &Context) {
|
pdb::yaml::SerializationContext &Context) {
|
||||||
|
|
|
@ -65,10 +65,53 @@ struct PdbModiStream {
|
||||||
std::vector<PdbSymbolRecord> Symbols;
|
std::vector<PdbSymbolRecord> Symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PdbSourceLineEntry {
|
||||||
|
uint32_t Offset;
|
||||||
|
uint32_t LineStart;
|
||||||
|
uint32_t EndDelta;
|
||||||
|
bool IsStatement;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PdbSourceColumnEntry {
|
||||||
|
uint16_t StartColumn;
|
||||||
|
uint16_t EndColumn;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PdbSourceLineBlock {
|
||||||
|
StringRef FileName;
|
||||||
|
std::vector<PdbSourceLineEntry> Lines;
|
||||||
|
std::vector<PdbSourceColumnEntry> Columns;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HexFormattedString {
|
||||||
|
std::vector<uint8_t> Bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PdbSourceFileChecksumEntry {
|
||||||
|
StringRef FileName;
|
||||||
|
codeview::FileChecksumKind Kind;
|
||||||
|
HexFormattedString ChecksumBytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PdbSourceLineInfo {
|
||||||
|
uint32_t RelocOffset;
|
||||||
|
uint32_t RelocSegment;
|
||||||
|
codeview::LineFlags Flags;
|
||||||
|
uint32_t CodeSize;
|
||||||
|
|
||||||
|
std::vector<PdbSourceLineBlock> LineInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PdbSourceFileInfo {
|
||||||
|
PdbSourceLineInfo Lines;
|
||||||
|
std::vector<PdbSourceFileChecksumEntry> FileChecksums;
|
||||||
|
};
|
||||||
|
|
||||||
struct PdbDbiModuleInfo {
|
struct PdbDbiModuleInfo {
|
||||||
StringRef Obj;
|
StringRef Obj;
|
||||||
StringRef Mod;
|
StringRef Mod;
|
||||||
std::vector<StringRef> SourceFiles;
|
std::vector<StringRef> SourceFiles;
|
||||||
|
Optional<PdbSourceFileInfo> FileLineInfo;
|
||||||
Optional<PdbModiStream> Modi;
|
Optional<PdbModiStream> Modi;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,6 +208,56 @@ template <> struct MappingContextTraits<pdb::yaml::PdbDbiModuleInfo, pdb::yaml::
|
||||||
static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context);
|
static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MappingContextTraits<pdb::yaml::PdbSourceLineEntry,
|
||||||
|
pdb::yaml::SerializationContext> {
|
||||||
|
static void mapping(IO &IO, pdb::yaml::PdbSourceLineEntry &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MappingContextTraits<pdb::yaml::PdbSourceColumnEntry,
|
||||||
|
pdb::yaml::SerializationContext> {
|
||||||
|
static void mapping(IO &IO, pdb::yaml::PdbSourceColumnEntry &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MappingContextTraits<pdb::yaml::PdbSourceLineBlock,
|
||||||
|
pdb::yaml::SerializationContext> {
|
||||||
|
static void mapping(IO &IO, pdb::yaml::PdbSourceLineBlock &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MappingContextTraits<pdb::yaml::PdbSourceFileChecksumEntry,
|
||||||
|
pdb::yaml::SerializationContext> {
|
||||||
|
static void mapping(IO &IO, pdb::yaml::PdbSourceFileChecksumEntry &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct ScalarTraits<pdb::yaml::HexFormattedString> {
|
||||||
|
static void output(const pdb::yaml::HexFormattedString &Value, void *ctx,
|
||||||
|
llvm::raw_ostream &Out);
|
||||||
|
static StringRef input(StringRef Scalar, void *ctxt,
|
||||||
|
pdb::yaml::HexFormattedString &Value);
|
||||||
|
static bool mustQuote(StringRef) { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MappingContextTraits<pdb::yaml::PdbSourceLineInfo,
|
||||||
|
pdb::yaml::SerializationContext> {
|
||||||
|
static void mapping(IO &IO, pdb::yaml::PdbSourceLineInfo &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MappingContextTraits<pdb::yaml::PdbSourceFileInfo,
|
||||||
|
pdb::yaml::SerializationContext> {
|
||||||
|
static void mapping(IO &IO, pdb::yaml::PdbSourceFileInfo &Obj,
|
||||||
|
pdb::yaml::SerializationContext &Context);
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct MappingContextTraits<pdb::yaml::PdbTpiRecord,
|
struct MappingContextTraits<pdb::yaml::PdbTpiRecord,
|
||||||
pdb::yaml::SerializationContext> {
|
pdb::yaml::SerializationContext> {
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include "PdbYaml.h"
|
#include "PdbYaml.h"
|
||||||
#include "llvm-pdbdump.h"
|
#include "llvm-pdbdump.h"
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/CodeView/Line.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h"
|
||||||
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
|
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
|
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
|
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
|
||||||
|
@ -33,8 +36,13 @@ Error YAMLOutputStyle::dump() {
|
||||||
opts::pdb2yaml::StreamMetadata = true;
|
opts::pdb2yaml::StreamMetadata = true;
|
||||||
if (opts::pdb2yaml::DbiModuleSyms)
|
if (opts::pdb2yaml::DbiModuleSyms)
|
||||||
opts::pdb2yaml::DbiModuleInfo = true;
|
opts::pdb2yaml::DbiModuleInfo = true;
|
||||||
|
|
||||||
|
if (opts::pdb2yaml::DbiModuleSourceLineInfo)
|
||||||
|
opts::pdb2yaml::DbiModuleSourceFileInfo = true;
|
||||||
|
|
||||||
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
|
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
|
||||||
opts::pdb2yaml::DbiModuleInfo = true;
|
opts::pdb2yaml::DbiModuleInfo = true;
|
||||||
|
|
||||||
if (opts::pdb2yaml::DbiModuleInfo)
|
if (opts::pdb2yaml::DbiModuleInfo)
|
||||||
opts::pdb2yaml::DbiStream = true;
|
opts::pdb2yaml::DbiStream = true;
|
||||||
|
|
||||||
|
@ -66,6 +74,112 @@ Error YAMLOutputStyle::dump() {
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class C13SubstreamVisitor : public codeview::IModuleSubstreamVisitor {
|
||||||
|
public:
|
||||||
|
C13SubstreamVisitor(llvm::pdb::yaml::PdbSourceFileInfo &Info, PDBFile &F)
|
||||||
|
: Info(Info), F(F) {}
|
||||||
|
|
||||||
|
Error visitUnknown(codeview::ModuleSubstreamKind Kind,
|
||||||
|
BinaryStreamRef Stream) override {
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error
|
||||||
|
visitFileChecksums(BinaryStreamRef Data,
|
||||||
|
const codeview::FileChecksumArray &Checksums) override {
|
||||||
|
for (const auto &C : Checksums) {
|
||||||
|
llvm::pdb::yaml::PdbSourceFileChecksumEntry Entry;
|
||||||
|
if (auto Result = getGlobalString(C.FileNameOffset))
|
||||||
|
Entry.FileName = *Result;
|
||||||
|
else
|
||||||
|
return Result.takeError();
|
||||||
|
|
||||||
|
Entry.Kind = C.Kind;
|
||||||
|
Entry.ChecksumBytes.Bytes = C.Checksum;
|
||||||
|
Info.FileChecksums.push_back(Entry);
|
||||||
|
}
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error visitLines(BinaryStreamRef Data,
|
||||||
|
const codeview::LineSubstreamHeader *Header,
|
||||||
|
const codeview::LineInfoArray &Lines) override {
|
||||||
|
|
||||||
|
Info.Lines.CodeSize = Header->CodeSize;
|
||||||
|
Info.Lines.Flags =
|
||||||
|
static_cast<codeview::LineFlags>(uint16_t(Header->Flags));
|
||||||
|
Info.Lines.RelocOffset = Header->RelocOffset;
|
||||||
|
Info.Lines.RelocSegment = Header->RelocSegment;
|
||||||
|
|
||||||
|
for (const auto &L : Lines) {
|
||||||
|
llvm::pdb::yaml::PdbSourceLineBlock Block;
|
||||||
|
|
||||||
|
if (auto Result = getDbiFileName(L.NameIndex))
|
||||||
|
Block.FileName = *Result;
|
||||||
|
else
|
||||||
|
return Result.takeError();
|
||||||
|
|
||||||
|
for (const auto &N : L.LineNumbers) {
|
||||||
|
llvm::pdb::yaml::PdbSourceLineEntry Line;
|
||||||
|
Line.Offset = N.Offset;
|
||||||
|
codeview::LineInfo LI(N.Flags);
|
||||||
|
Line.LineStart = LI.getStartLine();
|
||||||
|
Line.EndDelta = LI.getEndLine();
|
||||||
|
Line.IsStatement = LI.isStatement();
|
||||||
|
Block.Lines.push_back(Line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Info.Lines.Flags & codeview::LineFlags::HaveColumns) {
|
||||||
|
for (const auto &C : L.Columns) {
|
||||||
|
llvm::pdb::yaml::PdbSourceColumnEntry Column;
|
||||||
|
Column.StartColumn = C.StartColumn;
|
||||||
|
Column.EndColumn = C.EndColumn;
|
||||||
|
Block.Columns.push_back(Column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info.Lines.LineInfo.push_back(Block);
|
||||||
|
}
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Expected<StringRef> getGlobalString(uint32_t Offset) {
|
||||||
|
auto ST = F.getStringTable();
|
||||||
|
if (!ST)
|
||||||
|
return ST.takeError();
|
||||||
|
|
||||||
|
return ST->getStringForID(Offset);
|
||||||
|
}
|
||||||
|
Expected<StringRef> getDbiFileName(uint32_t Offset) {
|
||||||
|
auto DS = F.getPDBDbiStream();
|
||||||
|
if (!DS)
|
||||||
|
return DS.takeError();
|
||||||
|
return DS->getFileNameForIndex(Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::pdb::yaml::PdbSourceFileInfo &Info;
|
||||||
|
PDBFile &F;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Expected<Optional<llvm::pdb::yaml::PdbSourceFileInfo>>
|
||||||
|
YAMLOutputStyle::getFileLineInfo(const pdb::ModStream &ModS) {
|
||||||
|
if (!ModS.hasLineInfo())
|
||||||
|
return None;
|
||||||
|
|
||||||
|
yaml::PdbSourceFileInfo Info;
|
||||||
|
bool Error = false;
|
||||||
|
C13SubstreamVisitor Visitor(Info, File);
|
||||||
|
for (auto &Substream : ModS.lines(&Error)) {
|
||||||
|
if (auto E = codeview::visitModuleSubstream(Substream, Visitor))
|
||||||
|
return std::move(E);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Info;
|
||||||
|
}
|
||||||
|
|
||||||
Error YAMLOutputStyle::dumpFileHeaders() {
|
Error YAMLOutputStyle::dumpFileHeaders() {
|
||||||
if (opts::pdb2yaml::NoFileHeaders)
|
if (opts::pdb2yaml::NoFileHeaders)
|
||||||
return Error::success();
|
return Error::success();
|
||||||
|
@ -175,16 +289,24 @@ Error YAMLOutputStyle::dumpDbiStream() {
|
||||||
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
|
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
|
||||||
DMI.SourceFiles = MI.SourceFiles;
|
DMI.SourceFiles = MI.SourceFiles;
|
||||||
|
|
||||||
|
auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
|
||||||
|
File.getMsfLayout(), File.getMsfBuffer(),
|
||||||
|
MI.Info.getModuleStreamIndex());
|
||||||
|
|
||||||
|
pdb::ModStream ModS(MI.Info, std::move(ModStreamData));
|
||||||
|
if (auto EC = ModS.reload())
|
||||||
|
return EC;
|
||||||
|
|
||||||
|
if (opts::pdb2yaml::DbiModuleSourceLineInfo) {
|
||||||
|
auto ExpectedInfo = getFileLineInfo(ModS);
|
||||||
|
if (!ExpectedInfo)
|
||||||
|
return ExpectedInfo.takeError();
|
||||||
|
DMI.FileLineInfo = *ExpectedInfo;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts::pdb2yaml::DbiModuleSyms &&
|
if (opts::pdb2yaml::DbiModuleSyms &&
|
||||||
MI.Info.getModuleStreamIndex() != kInvalidStreamIndex) {
|
MI.Info.getModuleStreamIndex() != kInvalidStreamIndex) {
|
||||||
DMI.Modi.emplace();
|
DMI.Modi.emplace();
|
||||||
auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
|
|
||||||
File.getMsfLayout(), File.getMsfBuffer(),
|
|
||||||
MI.Info.getModuleStreamIndex());
|
|
||||||
|
|
||||||
pdb::ModStream ModS(MI.Info, std::move(ModStreamData));
|
|
||||||
if (auto EC = ModS.reload())
|
|
||||||
return EC;
|
|
||||||
|
|
||||||
DMI.Modi->Signature = ModS.signature();
|
DMI.Modi->Signature = ModS.signature();
|
||||||
bool HadError = false;
|
bool HadError = false;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace pdb {
|
namespace pdb {
|
||||||
|
class ModStream;
|
||||||
|
|
||||||
class YAMLOutputStyle : public OutputStyle {
|
class YAMLOutputStyle : public OutputStyle {
|
||||||
public:
|
public:
|
||||||
YAMLOutputStyle(PDBFile &File);
|
YAMLOutputStyle(PDBFile &File);
|
||||||
|
@ -26,6 +28,9 @@ public:
|
||||||
Error dump() override;
|
Error dump() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Expected<Optional<llvm::pdb::yaml::PdbSourceFileInfo>>
|
||||||
|
getFileLineInfo(const pdb::ModStream &ModS);
|
||||||
|
|
||||||
Error dumpStringTable();
|
Error dumpStringTable();
|
||||||
Error dumpFileHeaders();
|
Error dumpFileHeaders();
|
||||||
Error dumpStreamMetadata();
|
Error dumpStreamMetadata();
|
||||||
|
|
|
@ -375,9 +375,15 @@ cl::opt<bool> DbiModuleSyms(
|
||||||
cl::opt<bool> DbiModuleSourceFileInfo(
|
cl::opt<bool> DbiModuleSourceFileInfo(
|
||||||
"dbi-module-source-info",
|
"dbi-module-source-info",
|
||||||
cl::desc(
|
cl::desc(
|
||||||
"Dump DBI Module Source File Information (implies -dbi-module-info"),
|
"Dump DBI Module Source File Information (implies -dbi-module-info)"),
|
||||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||||
|
|
||||||
|
cl::opt<bool>
|
||||||
|
DbiModuleSourceLineInfo("dbi-module-lines",
|
||||||
|
cl::desc("Dump DBI Module Source Line Information "
|
||||||
|
"(implies -dbi-module-source-info)"),
|
||||||
|
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||||
|
|
||||||
cl::opt<bool> TpiStream("tpi-stream",
|
cl::opt<bool> TpiStream("tpi-stream",
|
||||||
cl::desc("Dump the TPI Stream (Stream 3)"),
|
cl::desc("Dump the TPI Stream (Stream 3)"),
|
||||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||||
|
|
|
@ -66,6 +66,7 @@ extern llvm::cl::opt<bool> DumpIpiRecords;
|
||||||
extern llvm::cl::opt<bool> DumpIpiRecordBytes;
|
extern llvm::cl::opt<bool> DumpIpiRecordBytes;
|
||||||
extern llvm::cl::opt<bool> DumpModules;
|
extern llvm::cl::opt<bool> DumpModules;
|
||||||
extern llvm::cl::opt<bool> DumpModuleFiles;
|
extern llvm::cl::opt<bool> DumpModuleFiles;
|
||||||
|
extern llvm::cl::opt<bool> DumpModuleLines;
|
||||||
extern llvm::cl::opt<bool> DumpModuleSyms;
|
extern llvm::cl::opt<bool> DumpModuleSyms;
|
||||||
extern llvm::cl::opt<bool> DumpPublics;
|
extern llvm::cl::opt<bool> DumpPublics;
|
||||||
extern llvm::cl::opt<bool> DumpSectionContribs;
|
extern llvm::cl::opt<bool> DumpSectionContribs;
|
||||||
|
@ -92,6 +93,7 @@ extern llvm::cl::opt<bool> DbiStream;
|
||||||
extern llvm::cl::opt<bool> DbiModuleInfo;
|
extern llvm::cl::opt<bool> DbiModuleInfo;
|
||||||
extern llvm::cl::opt<bool> DbiModuleSyms;
|
extern llvm::cl::opt<bool> DbiModuleSyms;
|
||||||
extern llvm::cl::opt<bool> DbiModuleSourceFileInfo;
|
extern llvm::cl::opt<bool> DbiModuleSourceFileInfo;
|
||||||
|
extern llvm::cl::opt<bool> DbiModuleSourceLineInfo;
|
||||||
extern llvm::cl::opt<bool> TpiStream;
|
extern llvm::cl::opt<bool> TpiStream;
|
||||||
extern llvm::cl::opt<bool> IpiStream;
|
extern llvm::cl::opt<bool> IpiStream;
|
||||||
extern llvm::cl::list<std::string> InputFilename;
|
extern llvm::cl::list<std::string> InputFilename;
|
||||||
|
|
Loading…
Reference in New Issue