[pdb] Dump Module Symbols to Yaml.

This is the first step towards round-tripping symbol information,
and thusly being able to write symbol information to a PDB.

This patch writes the symbol information for each compiland to
the Yaml when running in pdb2yaml mode.  There's still some loose
ends, such as what to do about relocations (necessary in order to
print linkage names), how to print enums with friendly names, and
how to give the dumper access to the StringTable, but this is a
good first start.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283641 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zachary Turner 2016-10-08 01:12:01 +00:00
parent b57fbc72a0
commit 2ce5ded6d2
15 changed files with 705 additions and 36 deletions

View File

@ -524,7 +524,7 @@ enum class RegisterId : uint16_t {
};
/// These values correspond to the THUNK_ORDINAL enumeration.
enum class ThunkOrdinal {
enum class ThunkOrdinal : uint8_t {
Standard,
ThisAdjustor,
Vcall,

View File

@ -32,6 +32,8 @@ public:
Error reload();
uint32_t signature() const { return Signature; }
iterator_range<codeview::CVSymbolArray::Iterator>
symbols(bool *HadError) const;
@ -43,6 +45,8 @@ public:
private:
const ModInfo &Mod;
uint32_t Signature;
std::unique_ptr<msf::MappedBlockStream> Stream;
codeview::CVSymbolArray SymbolsSubstream;

View File

@ -38,8 +38,7 @@ Error ModStream::reload() {
ReadableStreamRef S;
uint32_t SymbolSubstreamSig = 0;
if (auto EC = Reader.readInteger(SymbolSubstreamSig))
if (auto EC = Reader.readInteger(Signature))
return EC;
if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
return EC;

View File

@ -0,0 +1,186 @@
; RUN: llvm-pdbdump pdb2yaml -dbi-module-syms %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: Modi:
YAML: Signature: 4
YAML: Records:
YAML: - Kind: S_OBJNAME
YAML: ObjNameSym:
YAML: Signature: 0
YAML: ObjectName: 'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj'
YAML: - Kind: S_COMPILE3
YAML: Compile3Sym:
YAML: Flags: 8193
YAML: Machine: 7
YAML: FrontendMajor: 18
YAML: FrontendMinor: 0
YAML: FrontendBuild: 31101
YAML: FrontendQFE: 0
YAML: BackendMajor: 18
YAML: BackendMinor: 0
YAML: BackendBuild: 31101
YAML: BackendQFE: 0
YAML: Version: 'Microsoft (R) Optimizing Compiler'
YAML: - Kind: S_GPROC32
YAML: ProcSym:
YAML: PtrParent: 0
YAML: PtrEnd: 196
YAML: PtrNext: 0
YAML: CodeSize: 10
YAML: DbgStart: 3
YAML: DbgEnd: 8
YAML: FunctionType: 4097
YAML: Segment: 1
YAML: Flags: 1
YAML: DisplayName: main
YAML: - Kind: S_FRAMEPROC
YAML: FrameProcSym:
YAML: TotalFrameBytes: 0
YAML: PaddingFrameBytes: 0
YAML: OffsetToPadding: 0
YAML: BytesOfCalleeSavedRegisters: 0
YAML: OffsetOfExceptionHandler: 0
YAML: SectionIdOfExceptionHandler: 0
YAML: Flags: 1212928
YAML: - Kind: S_END
YAML: ScopeEndSym:
YAML: - Kind: S_BUILDINFO
YAML: BuildInfoSym:
YAML: BuildId: 4110
YAML: - Module: '* Linker *'
YAML: ObjFile: ''
YAML: Modi:
YAML: Signature: 4
YAML: Records:
YAML: - Kind: S_OBJNAME
YAML: ObjNameSym:
YAML: Signature: 0
YAML: ObjectName: '* Linker *'
YAML: - Kind: S_COMPILE3
YAML: Compile3Sym:
YAML: Flags: 7
YAML: Machine: 3
YAML: FrontendMajor: 0
YAML: FrontendMinor: 0
YAML: FrontendBuild: 0
YAML: FrontendQFE: 0
YAML: BackendMajor: 12
YAML: BackendMinor: 0
YAML: BackendBuild: 31101
YAML: BackendQFE: 0
YAML: Version: 'Microsoft (R) LINK'
YAML: - Kind: S_ENVBLOCK
YAML: EnvBlockSym:
YAML: Reserved: 0
YAML: Entries:
YAML: - cwd
YAML: - 'd:\src\llvm\test\DebugInfo\PDB\Inputs'
YAML: - exe
YAML: - 'C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\link.exe'
YAML: - pdb
YAML: - 'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.pdb'
YAML: - Kind: S_TRAMPOLINE
YAML: TrampolineSym:
YAML: Type: 0
YAML: Size: 5
YAML: ThunkOff: 5
YAML: TargetOff: 16
YAML: ThunkSection: 1
YAML: TargetSection: 1
YAML: - Kind: S_SECTION
YAML: SectionSym:
YAML: SectionNumber: 1
YAML: Alignment: 12
YAML: Reserved: 0
YAML: Rva: 4096
YAML: Length: 4122
YAML: Characteristics: 1610612768
YAML: Name: .text
YAML: - Kind: S_COFFGROUP
YAML: CoffGroupSym:
YAML: Size: 4122
YAML: Characteristics: 1610612768
YAML: Offset: 0
YAML: Segment: 1
YAML: Name: '.text$mn'
YAML: - Kind: S_SECTION
YAML: SectionSym:
YAML: SectionNumber: 2
YAML: Alignment: 12
YAML: Reserved: 0
YAML: Rva: 12288
YAML: Length: 690
YAML: Characteristics: 1073741888
YAML: Name: .rdata
YAML: - Kind: S_COFFGROUP
YAML: CoffGroupSym:
YAML: Size: 323
YAML: Characteristics: 1073741888
YAML: Offset: 0
YAML: Segment: 2
YAML: Name: .rdata
YAML: - Kind: S_COFFGROUP
YAML: CoffGroupSym:
YAML: Size: 0
YAML: Characteristics: 1073741888
YAML: Offset: 323
YAML: Segment: 2
YAML: Name: .edata
YAML: - Kind: S_COFFGROUP
YAML: CoffGroupSym:
YAML: Size: 366
YAML: Characteristics: 1073741888
YAML: Offset: 324
YAML: Segment: 2
YAML: Name: '.rdata$debug'
YAML: - Kind: S_SECTION
YAML: SectionSym:
YAML: SectionNumber: 3
YAML: Alignment: 12
YAML: Reserved: 0
YAML: Rva: 16384
YAML: Length: 4
YAML: Characteristics: 3221225536
YAML: Name: .data
YAML: - Kind: S_COFFGROUP
YAML: CoffGroupSym:
YAML: Size: 4
YAML: Characteristics: 3221225600
YAML: Offset: 0
YAML: Segment: 3
YAML: Name: .bss
YAML: - Kind: S_SECTION
YAML: SectionSym:
YAML: SectionNumber: 4
YAML: Alignment: 12
YAML: Reserved: 0
YAML: Rva: 20480
YAML: Length: 8
YAML: Characteristics: 1107296320
YAML: Name: .reloc
YAML: ...

View File

@ -10,7 +10,8 @@ add_llvm_tool(llvm-pdbdump
llvm-pdbdump.cpp
BuiltinDumper.cpp
ClassDefinitionDumper.cpp
CodeViewYaml.cpp
YamlSymbolDumper.cpp
YamlTypeDumper.cpp
CompilandDumper.cpp
EnumDumper.cpp
ExternalSymbolDumper.cpp

View File

@ -9,10 +9,14 @@
#include "PdbYaml.h"
#include "CodeViewYaml.h"
#include "YamlSerializationContext.h"
#include "YamlSymbolDumper.h"
#include "YamlTypeDumper.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeSerializationVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
@ -30,6 +34,7 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
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::PdbSymbolRecord)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
@ -205,10 +210,33 @@ void MappingTraits<NamedStreamMapping>::mapping(IO &IO,
IO.mapRequired("StreamNum", Obj.StreamNumber);
}
void MappingTraits<PdbSymbolRecord>::mapping(IO &IO, PdbSymbolRecord &Obj) {
codeview::SymbolVisitorCallbackPipeline Pipeline;
codeview::SymbolDeserializer Deserializer(nullptr);
codeview::yaml::YamlSymbolDumper Dumper(IO);
if (IO.outputting()) {
// For PDB to Yaml, deserialize into a high level record type, then dump it.
Pipeline.addCallbackToPipeline(Deserializer);
Pipeline.addCallbackToPipeline(Dumper);
} else {
return;
}
codeview::CVSymbolVisitor Visitor(Pipeline);
consumeError(Visitor.visitSymbolRecord(Obj.Record));
}
void MappingTraits<PdbModiStream>::mapping(IO &IO, PdbModiStream &Obj) {
IO.mapRequired("Signature", Obj.Signature);
IO.mapRequired("Records", Obj.Symbols);
}
void MappingTraits<PdbDbiModuleInfo>::mapping(IO &IO, PdbDbiModuleInfo &Obj) {
IO.mapRequired("Module", Obj.Mod);
IO.mapRequired("ObjFile", Obj.Obj);
IO.mapOptional("SourceFiles", Obj.SourceFiles);
IO.mapOptional("Modi", Obj.Modi);
}
void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::

View File

@ -13,6 +13,8 @@
#include "OutputStyle.h"
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
@ -53,10 +55,20 @@ struct PdbInfoStream {
std::vector<NamedStreamMapping> NamedStreams;
};
struct PdbSymbolRecord {
codeview::CVSymbol Record;
};
struct PdbModiStream {
uint32_t Signature;
std::vector<PdbSymbolRecord> Symbols;
};
struct PdbDbiModuleInfo {
StringRef Obj;
StringRef Mod;
std::vector<StringRef> SourceFiles;
Optional<PdbModiStream> Modi;
};
struct PdbDbiStream {
@ -138,6 +150,14 @@ template <> struct MappingTraits<pdb::yaml::NamedStreamMapping> {
static void mapping(IO &IO, pdb::yaml::NamedStreamMapping &Obj);
};
template <> struct MappingTraits<pdb::yaml::PdbSymbolRecord> {
static void mapping(IO &IO, pdb::yaml::PdbSymbolRecord &Obj);
};
template <> struct MappingTraits<pdb::yaml::PdbModiStream> {
static void mapping(IO &IO, pdb::yaml::PdbModiStream &Obj);
};
template <> struct MappingTraits<pdb::yaml::PdbDbiModuleInfo> {
static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj);
};

View File

@ -12,8 +12,10 @@
#include "PdbYaml.h"
#include "llvm-pdbdump.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
@ -27,6 +29,8 @@ YAMLOutputStyle::YAMLOutputStyle(PDBFile &File)
Error YAMLOutputStyle::dump() {
if (opts::pdb2yaml::StreamDirectory)
opts::pdb2yaml::StreamMetadata = true;
if (opts::pdb2yaml::DbiModuleSyms)
opts::pdb2yaml::DbiModuleInfo = true;
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
opts::pdb2yaml::DbiModuleInfo = true;
if (opts::pdb2yaml::DbiModuleInfo)
@ -152,6 +156,25 @@ Error YAMLOutputStyle::dumpDbiStream() {
DMI.Obj = MI.Info.getObjFileName();
if (opts::pdb2yaml::DbiModuleSourceFileInfo)
DMI.SourceFiles = MI.SourceFiles;
if (opts::pdb2yaml::DbiModuleSyms &&
MI.Info.getModuleStreamIndex() != kInvalidStreamIndex) {
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();
bool HadError = false;
for (auto &Sym : ModS.symbols(&HadError)) {
pdb::yaml::PdbSymbolRecord Record{Sym};
DMI.Modi->Symbols.push_back(Record);
}
}
Obj.DbiStream->ModInfos.push_back(DMI);
}
}

View File

@ -10,8 +10,8 @@
#ifndef LLVM_TOOLS_LLVMPDBDUMP_YAMLSERIALIZATIONCONTEXT_H
#define LLVM_TOOLS_LLVMPDBDUMP_YAMLSERIALIZATIONCONTEXT_H
#include "CodeViewYaml.h"
#include "PdbYaml.h"
#include "YamlTypeDumper.h"
#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
#include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"

View File

@ -0,0 +1,322 @@
//===- YamlSymbolDumper.cpp ----------------------------------- *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "YamlSymbolDumper.h"
#include "PdbYaml.h"
#include "YamlTypeDumper.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::codeview::yaml;
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord)
LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(CVType)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiFieldListRecord)
namespace llvm {
namespace yaml {
void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
SymbolKind &Value) {
auto SymbolNames = getSymbolTypeNames();
for (const auto &E : SymbolNames)
io.enumCase(Value, E.Name.str().c_str(), E.Value);
}
template <> struct ScalarEnumerationTraits<ThunkOrdinal> {
void enumeration(IO &io, ThunkOrdinal Ord) {}
};
void MappingTraits<ScopeEndSym>::mapping(IO &IO, ScopeEndSym &Obj) {}
void MappingTraits<Thunk32Sym>::mapping(IO &IO, Thunk32Sym &Thunk) {
IO.mapRequired("Parent", Thunk.Header.Parent);
IO.mapRequired("End", Thunk.Header.End);
IO.mapRequired("Next", Thunk.Header.Next);
IO.mapRequired("Off", Thunk.Header.Off);
IO.mapRequired("Seg", Thunk.Header.Seg);
IO.mapRequired("Len", Thunk.Header.Len);
IO.mapRequired("Ordinal", Thunk.Header.Ord);
}
void MappingTraits<TrampolineSym>::mapping(IO &IO, TrampolineSym &Tramp) {
IO.mapRequired("Type", Tramp.Header.Type);
IO.mapRequired("Size", Tramp.Header.Size);
IO.mapRequired("ThunkOff", Tramp.Header.ThunkOff);
IO.mapRequired("TargetOff", Tramp.Header.TargetOff);
IO.mapRequired("ThunkSection", Tramp.Header.ThunkSection);
IO.mapRequired("TargetSection", Tramp.Header.TargetSection);
}
void MappingTraits<SectionSym>::mapping(IO &IO, SectionSym &Section) {
IO.mapRequired("SectionNumber", Section.Header.SectionNumber);
IO.mapRequired("Alignment", Section.Header.Alignment);
IO.mapRequired("Reserved", Section.Header.Reserved);
IO.mapRequired("Rva", Section.Header.Rva);
IO.mapRequired("Length", Section.Header.Length);
IO.mapRequired("Characteristics", Section.Header.Characteristics);
IO.mapRequired("Name", Section.Name);
}
void MappingTraits<CoffGroupSym>::mapping(IO &IO, CoffGroupSym &CoffGroup) {
IO.mapRequired("Size", CoffGroup.Header.Size);
IO.mapRequired("Characteristics", CoffGroup.Header.Characteristics);
IO.mapRequired("Offset", CoffGroup.Header.Offset);
IO.mapRequired("Segment", CoffGroup.Header.Segment);
IO.mapRequired("Name", CoffGroup.Name);
}
void MappingTraits<ExportSym>::mapping(IO &IO, ExportSym &Export) {
IO.mapRequired("Ordinal", Export.Header.Ordinal);
IO.mapRequired("Flags", Export.Header.Flags);
IO.mapRequired("Name", Export.Name);
}
void MappingTraits<ProcSym>::mapping(IO &IO, ProcSym &Proc) {
// TODO: Print the linkage name
IO.mapRequired("PtrParent", Proc.Header.PtrParent);
IO.mapRequired("PtrEnd", Proc.Header.PtrEnd);
IO.mapRequired("PtrNext", Proc.Header.PtrNext);
IO.mapRequired("CodeSize", Proc.Header.CodeSize);
IO.mapRequired("DbgStart", Proc.Header.DbgStart);
IO.mapRequired("DbgEnd", Proc.Header.DbgEnd);
IO.mapRequired("FunctionType", Proc.Header.FunctionType);
IO.mapRequired("Segment", Proc.Header.Segment);
IO.mapRequired("Flags", Proc.Header.Flags);
IO.mapRequired("DisplayName", Proc.Name);
}
void MappingTraits<RegisterSym>::mapping(IO &IO, RegisterSym &Register) {
IO.mapRequired("Type", Register.Header.Index);
IO.mapRequired("Seg", Register.Header.Register);
IO.mapRequired("Name", Register.Name);
}
void MappingTraits<PublicSym32>::mapping(IO &IO, PublicSym32 &Public) {
IO.mapRequired("Type", Public.Header.Index);
IO.mapRequired("Seg", Public.Header.Seg);
IO.mapRequired("Off", Public.Header.Off);
IO.mapRequired("Name", Public.Name);
}
void MappingTraits<ProcRefSym>::mapping(IO &IO, ProcRefSym &ProcRef) {
IO.mapRequired("SumName", ProcRef.Header.SumName);
IO.mapRequired("SymOffset", ProcRef.Header.SymOffset);
IO.mapRequired("Mod", ProcRef.Header.Mod);
IO.mapRequired("Name", ProcRef.Name);
}
void MappingTraits<EnvBlockSym>::mapping(IO &IO, EnvBlockSym &EnvBlock) {
IO.mapRequired("Reserved", EnvBlock.Header.Reserved);
IO.mapRequired("Entries", EnvBlock.Fields);
}
void MappingTraits<InlineSiteSym>::mapping(IO &IO, InlineSiteSym &InlineSite) {
IO.mapRequired("PtrParent", InlineSite.Header.PtrParent);
IO.mapRequired("PtrEnd", InlineSite.Header.PtrEnd);
IO.mapRequired("Inlinee", InlineSite.Header.Inlinee);
// TODO: The binary annotations
}
void MappingTraits<LocalSym>::mapping(IO &IO, LocalSym &Local) {
IO.mapRequired("Type", Local.Header.Type);
IO.mapRequired("Flags", Local.Header.Flags);
IO.mapRequired("VarName", Local.Name);
}
void MappingTraits<DefRangeSym>::mapping(IO &IO, DefRangeSym &Obj) {
// TODO: Print the subfields
}
void MappingTraits<DefRangeSubfieldSym>::mapping(IO &IO,
DefRangeSubfieldSym &Obj) {
// TODO: Print the subfields
}
void MappingTraits<DefRangeRegisterSym>::mapping(IO &IO,
DefRangeRegisterSym &Obj) {
// TODO: Print the subfields
}
void MappingTraits<DefRangeFramePointerRelSym>::mapping(
IO &IO, DefRangeFramePointerRelSym &Obj) {
// TODO: Print the subfields
}
void MappingTraits<DefRangeSubfieldRegisterSym>::mapping(
IO &IO, DefRangeSubfieldRegisterSym &Obj) {
// TODO: Print the subfields
}
void MappingTraits<DefRangeFramePointerRelFullScopeSym>::mapping(
IO &IO, DefRangeFramePointerRelFullScopeSym &Obj) {
// TODO: Print the subfields
}
void MappingTraits<DefRangeRegisterRelSym>::mapping(
IO &IO, DefRangeRegisterRelSym &Obj) {
// TODO: Print the subfields
}
void MappingTraits<BlockSym>::mapping(IO &IO, BlockSym &Block) {
// TODO: Print the linkage name
IO.mapRequired("PtrParent", Block.Header.PtrParent);
IO.mapRequired("PtrEnd", Block.Header.PtrEnd);
IO.mapRequired("CodeSize", Block.Header.CodeSize);
IO.mapRequired("Segment", Block.Header.Segment);
IO.mapRequired("BlockName", Block.Name);
}
void MappingTraits<LabelSym>::mapping(IO &IO, LabelSym &Label) {
// TODO: Print the linkage name
IO.mapRequired("Segment", Label.Header.Segment);
IO.mapRequired("Flags", Label.Header.Flags);
IO.mapRequired("Flags", Label.Header.Flags);
IO.mapRequired("DisplayName", Label.Name);
}
void MappingTraits<ObjNameSym>::mapping(IO &IO, ObjNameSym &ObjName) {
IO.mapRequired("Signature", ObjName.Header.Signature);
IO.mapRequired("ObjectName", ObjName.Name);
}
void MappingTraits<Compile2Sym>::mapping(IO &IO, Compile2Sym &Compile2) {
IO.mapRequired("Flags", Compile2.Header.flags);
IO.mapRequired("Machine", Compile2.Header.Machine);
IO.mapRequired("FrontendMajor", Compile2.Header.VersionFrontendMajor);
IO.mapRequired("FrontendMinor", Compile2.Header.VersionFrontendMinor);
IO.mapRequired("FrontendBuild", Compile2.Header.VersionFrontendBuild);
IO.mapRequired("BackendMajor", Compile2.Header.VersionBackendMajor);
IO.mapRequired("BackendMinor", Compile2.Header.VersionBackendMinor);
IO.mapRequired("BackendBuild", Compile2.Header.VersionBackendBuild);
IO.mapRequired("Version", Compile2.Version);
}
void MappingTraits<Compile3Sym>::mapping(IO &IO, Compile3Sym &Compile3) {
IO.mapRequired("Flags", Compile3.Header.flags);
IO.mapRequired("Machine", Compile3.Header.Machine);
IO.mapRequired("FrontendMajor", Compile3.Header.VersionFrontendMajor);
IO.mapRequired("FrontendMinor", Compile3.Header.VersionFrontendMinor);
IO.mapRequired("FrontendBuild", Compile3.Header.VersionFrontendBuild);
IO.mapRequired("FrontendQFE", Compile3.Header.VersionFrontendQFE);
IO.mapRequired("BackendMajor", Compile3.Header.VersionBackendMajor);
IO.mapRequired("BackendMinor", Compile3.Header.VersionBackendMinor);
IO.mapRequired("BackendBuild", Compile3.Header.VersionBackendBuild);
IO.mapRequired("BackendQFE", Compile3.Header.VersionBackendQFE);
IO.mapRequired("Version", Compile3.Version);
}
void MappingTraits<FrameProcSym>::mapping(IO &IO, FrameProcSym &FrameProc) {
IO.mapRequired("TotalFrameBytes", FrameProc.Header.TotalFrameBytes);
IO.mapRequired("PaddingFrameBytes", FrameProc.Header.PaddingFrameBytes);
IO.mapRequired("OffsetToPadding", FrameProc.Header.OffsetToPadding);
IO.mapRequired("BytesOfCalleeSavedRegisters",
FrameProc.Header.BytesOfCalleeSavedRegisters);
IO.mapRequired("OffsetOfExceptionHandler",
FrameProc.Header.OffsetOfExceptionHandler);
IO.mapRequired("SectionIdOfExceptionHandler",
FrameProc.Header.SectionIdOfExceptionHandler);
IO.mapRequired("Flags", FrameProc.Header.Flags);
}
void MappingTraits<CallSiteInfoSym>::mapping(IO &IO,
CallSiteInfoSym &CallSiteInfo) {
// TODO: Map Linkage Name
IO.mapRequired("Segment", CallSiteInfo.Header.Segment);
IO.mapRequired("Reserved", CallSiteInfo.Header.Reserved);
IO.mapRequired("Type", CallSiteInfo.Header.Type);
}
void MappingTraits<FileStaticSym>::mapping(IO &IO, FileStaticSym &FileStatic) {
IO.mapRequired("Index", FileStatic.Header.Index);
IO.mapRequired("ModFilenameOffset", FileStatic.Header.ModFilenameOffset);
IO.mapRequired("Flags", FileStatic.Header.Flags);
IO.mapRequired("Name", FileStatic.Name);
}
void MappingTraits<HeapAllocationSiteSym>::mapping(
IO &IO, HeapAllocationSiteSym &HeapAllocSite) {
// TODO: Map Linkage Name
IO.mapRequired("Segment", HeapAllocSite.Header.Segment);
IO.mapRequired("CallInstructionSize",
HeapAllocSite.Header.CallInstructionSize);
IO.mapRequired("Type", HeapAllocSite.Header.Type);
}
void MappingTraits<FrameCookieSym>::mapping(IO &IO,
FrameCookieSym &FrameCookie) {
// TODO: Map Linkage Name
IO.mapRequired("Register", FrameCookie.Header.Register);
IO.mapRequired("CookieKind", FrameCookie.Header.CookieKind);
IO.mapRequired("Flags", FrameCookie.Header.Flags);
}
void MappingTraits<CallerSym>::mapping(IO &IO, CallerSym &Caller) {
// TODO: Correctly handle the ArrayRef in here.
std::vector<TypeIndex> Indices(Caller.Indices);
IO.mapRequired("FuncID", Indices);
}
void MappingTraits<UDTSym>::mapping(IO &IO, UDTSym &UDT) {
IO.mapRequired("Type", UDT.Header.Type);
IO.mapRequired("UDTName", UDT.Name);
}
void MappingTraits<BuildInfoSym>::mapping(IO &IO, BuildInfoSym &BuildInfo) {
IO.mapRequired("BuildId", BuildInfo.Header.BuildId);
}
void MappingTraits<BPRelativeSym>::mapping(IO &IO, BPRelativeSym &BPRel) {
IO.mapRequired("Offset", BPRel.Header.Offset);
IO.mapRequired("Type", BPRel.Header.Type);
IO.mapRequired("VarName", BPRel.Name);
}
void MappingTraits<RegRelativeSym>::mapping(IO &IO, RegRelativeSym &RegRel) {
IO.mapRequired("Offset", RegRel.Header.Offset);
IO.mapRequired("Type", RegRel.Header.Type);
IO.mapRequired("Register", RegRel.Header.Register);
IO.mapRequired("VarName", RegRel.Name);
}
void MappingTraits<ConstantSym>::mapping(IO &IO, ConstantSym &Constant) {
IO.mapRequired("Type", Constant.Header.Type);
IO.mapRequired("Value", Constant.Value);
IO.mapRequired("Name", Constant.Name);
}
void MappingTraits<DataSym>::mapping(IO &IO, DataSym &Data) {
// TODO: Map linkage name
IO.mapRequired("Type", Data.Header.Type);
IO.mapRequired("DisplayName", Data.Name);
}
void MappingTraits<ThreadLocalDataSym>::mapping(IO &IO,
ThreadLocalDataSym &Data) {
// TODO: Map linkage name
IO.mapRequired("Type", Data.Header.Type);
IO.mapRequired("DisplayName", Data.Name);
}
}
}
Error llvm::codeview::yaml::YamlSymbolDumper::visitSymbolBegin(CVSymbol &CVR) {
YamlIO.mapRequired("Kind", CVR.Type);
return Error::success();
}

View File

@ -0,0 +1,66 @@
//===- YamlSymbolDumper.h ------------------------------------- *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVMPDBDUMP_YAMLSYMBOLDUMPER_H
#define LLVM_TOOLS_LLVMPDBDUMP_YAMLSYMBOLDUMPER_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/Support/YAMLTraits.h"
namespace llvm {
namespace pdb {
namespace yaml {
struct SerializationContext;
}
}
namespace codeview {
namespace yaml {
class YamlSymbolDumper : public SymbolVisitorCallbacks {
public:
YamlSymbolDumper(llvm::yaml::IO &IO) : YamlIO(IO) {}
virtual Error visitSymbolBegin(CVSymbol &Record) override;
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
visitKnownRecordImpl(#Name, CVR, Record); \
return Error::success(); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
private:
template <typename T>
void visitKnownRecordImpl(const char *Name, CVSymbol &Type, T &Record) {
YamlIO.mapRequired(Name, Record);
}
llvm::yaml::IO &YamlIO;
};
}
}
}
namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<codeview::SymbolKind> {
static void enumeration(IO &io, codeview::SymbolKind &Value);
};
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
template <> struct MappingTraits<codeview::Name> { \
static void mapping(IO &IO, codeview::Name &Obj); \
};
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
}
}
#endif

View File

@ -1,4 +1,4 @@
//===- PdbYAML.cpp -------------------------------------------- *- C++ --*-===//
//===- YamlTypeDumper.cpp ------------------------------------- *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "CodeViewYaml.h"
#include "YamlTypeDumper.h"
#include "PdbYaml.h"
#include "YamlSerializationContext.h"
@ -260,17 +260,16 @@ template <> struct ScalarBitSetTraits<MethodOptions> {
}
};
template <> struct ScalarTraits<APSInt> {
static void output(const APSInt &S, void *, llvm::raw_ostream &OS) {
S.print(OS, true);
}
static StringRef input(StringRef Scalar, void *Ctx, APSInt &S) {
S = APSInt(Scalar);
return "";
}
void ScalarTraits<APSInt>::output(const APSInt &S, void *,
llvm::raw_ostream &OS) {
S.print(OS, true);
}
StringRef ScalarTraits<APSInt>::input(StringRef Scalar, void *Ctx, APSInt &S) {
S = APSInt(Scalar);
return "";
}
static bool mustQuote(StringRef Scalar) { return false; }
};
bool ScalarTraits<APSInt>::mustQuote(StringRef Scalar) { return false; }
void MappingContextTraits<CVType, pdb::yaml::SerializationContext>::mapping(
IO &IO, CVType &Record, pdb::yaml::SerializationContext &Context) {
@ -501,21 +500,22 @@ void MappingTraits<ListContinuationRecord>::mapping(
IO.mapRequired("ContinuationIndex", Cont.ContinuationIndex);
}
template <> struct ScalarTraits<codeview::TypeIndex> {
static void output(const codeview::TypeIndex &S, void *,
llvm::raw_ostream &OS) {
OS << S.getIndex();
}
static StringRef input(StringRef Scalar, void *Ctx, codeview::TypeIndex &S) {
uint32_t I;
StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I);
if (!Result.empty())
return Result;
S = TypeIndex(I);
return "";
}
static bool mustQuote(StringRef Scalar) { return false; }
};
void ScalarTraits<codeview::TypeIndex>::output(const codeview::TypeIndex &S,
void *, llvm::raw_ostream &OS) {
OS << S.getIndex();
}
StringRef ScalarTraits<codeview::TypeIndex>::input(StringRef Scalar, void *Ctx,
codeview::TypeIndex &S) {
uint32_t I;
StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I);
if (!Result.empty())
return Result;
S = TypeIndex(I);
return "";
}
bool ScalarTraits<codeview::TypeIndex>::mustQuote(StringRef Scalar) {
return false;
}
void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
TypeLeafKind &Value) {

View File

@ -1,4 +1,4 @@
//===- PdbYAML.h ---------------------------------------------- *- C++ --*-===//
//===- YamlTypeDumper.h --------------------------------------- *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVMPDBDUMP_CODEVIEWYAML_H
#define LLVM_TOOLS_LLVMPDBDUMP_CODEVIEWYAML_H
#ifndef LLVM_TOOLS_LLVMPDBDUMP_YAMLTYPEDUMPER_H
#define LLVM_TOOLS_LLVMPDBDUMP_YAMLTYPEDUMPER_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
@ -74,6 +74,20 @@ struct SerializationContext;
namespace llvm {
namespace yaml {
template <> struct ScalarTraits<APSInt> {
static void output(const APSInt &S, void *, llvm::raw_ostream &OS);
static StringRef input(StringRef Scalar, void *Ctx, APSInt &S);
static bool mustQuote(StringRef Scalar);
};
template <> struct ScalarTraits<codeview::TypeIndex> {
static void output(const codeview::TypeIndex &S, void *,
llvm::raw_ostream &OS);
static StringRef input(StringRef Scalar, void *Ctx, codeview::TypeIndex &S);
static bool mustQuote(StringRef Scalar);
};
template <> struct MappingTraits<codeview::MemberPointerInfo> {
static void mapping(IO &IO, codeview::MemberPointerInfo &Obj);
};

View File

@ -280,6 +280,11 @@ cl::opt<bool>
cl::desc("Dump DBI Module Information (implies -dbi-stream)"),
cl::sub(PdbToYamlSubcommand), cl::init(false));
cl::opt<bool> DbiModuleSyms(
"dbi-module-syms",
cl::desc("Dump DBI Module Information (implies -dbi-module-info)"),
cl::sub(PdbToYamlSubcommand), cl::init(false));
cl::opt<bool> DbiModuleSourceFileInfo(
"dbi-module-source-info",
cl::desc(

View File

@ -71,6 +71,7 @@ extern llvm::cl::opt<bool> StreamDirectory;
extern llvm::cl::opt<bool> PdbStream;
extern llvm::cl::opt<bool> DbiStream;
extern llvm::cl::opt<bool> DbiModuleInfo;
extern llvm::cl::opt<bool> DbiModuleSyms;
extern llvm::cl::opt<bool> DbiModuleSourceFileInfo;
extern llvm::cl::opt<bool> TpiStream;
extern llvm::cl::opt<bool> IpiStream;