From: Zachary Turner Date: Sat, 8 Oct 2016 01:12:01 +0000 (+0000) Subject: [pdb] Dump Module Symbols to Yaml. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ce5ded6d2e277c76262ddbbb7b5334aa7b1683b;p=llvm [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 --- diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index 9db217e12f1..4cf04e66cfe 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -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, diff --git a/include/llvm/DebugInfo/PDB/Raw/ModStream.h b/include/llvm/DebugInfo/PDB/Raw/ModStream.h index f5296e08169..d5e7a6830d8 100644 --- a/include/llvm/DebugInfo/PDB/Raw/ModStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/ModStream.h @@ -32,6 +32,8 @@ public: Error reload(); + uint32_t signature() const { return Signature; } + iterator_range symbols(bool *HadError) const; @@ -43,6 +45,8 @@ public: private: const ModInfo &Mod; + uint32_t Signature; + std::unique_ptr Stream; codeview::CVSymbolArray SymbolsSubstream; diff --git a/lib/DebugInfo/PDB/Raw/ModStream.cpp b/lib/DebugInfo/PDB/Raw/ModStream.cpp index 3810b29dba1..527ca6bbea5 100644 --- a/lib/DebugInfo/PDB/Raw/ModStream.cpp +++ b/lib/DebugInfo/PDB/Raw/ModStream.cpp @@ -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; diff --git a/test/DebugInfo/PDB/pdb-yaml-symbols.test b/test/DebugInfo/PDB/pdb-yaml-symbols.test new file mode 100644 index 00000000000..9b6872d5eca --- /dev/null +++ b/test/DebugInfo/PDB/pdb-yaml-symbols.test @@ -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: ... \ No newline at end of file diff --git a/tools/llvm-pdbdump/CMakeLists.txt b/tools/llvm-pdbdump/CMakeLists.txt index 701fcda4194..d929313903d 100644 --- a/tools/llvm-pdbdump/CMakeLists.txt +++ b/tools/llvm-pdbdump/CMakeLists.txt @@ -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 diff --git a/tools/llvm-pdbdump/PdbYaml.cpp b/tools/llvm-pdbdump/PdbYaml.cpp index fd1016b4ce5..3d0e8237609 100644 --- a/tools/llvm-pdbdump/PdbYaml.cpp +++ b/tools/llvm-pdbdump/PdbYaml.cpp @@ -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::mapping(IO &IO, IO.mapRequired("StreamNum", Obj.StreamNumber); } +void MappingTraits::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::mapping(IO &IO, PdbModiStream &Obj) { + IO.mapRequired("Signature", Obj.Signature); + IO.mapRequired("Records", Obj.Symbols); +} + void MappingTraits::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:: diff --git a/tools/llvm-pdbdump/PdbYaml.h b/tools/llvm-pdbdump/PdbYaml.h index ffa194df214..398186f16d7 100644 --- a/tools/llvm-pdbdump/PdbYaml.h +++ b/tools/llvm-pdbdump/PdbYaml.h @@ -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 NamedStreams; }; +struct PdbSymbolRecord { + codeview::CVSymbol Record; +}; + +struct PdbModiStream { + uint32_t Signature; + std::vector Symbols; +}; + struct PdbDbiModuleInfo { StringRef Obj; StringRef Mod; std::vector SourceFiles; + Optional Modi; }; struct PdbDbiStream { @@ -138,6 +150,14 @@ template <> struct MappingTraits { static void mapping(IO &IO, pdb::yaml::NamedStreamMapping &Obj); }; +template <> struct MappingTraits { + static void mapping(IO &IO, pdb::yaml::PdbSymbolRecord &Obj); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, pdb::yaml::PdbModiStream &Obj); +}; + template <> struct MappingTraits { static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj); }; diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/tools/llvm-pdbdump/YAMLOutputStyle.cpp index ee1875c6b67..3f2733d701a 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.cpp +++ b/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -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); } } diff --git a/tools/llvm-pdbdump/YamlSerializationContext.h b/tools/llvm-pdbdump/YamlSerializationContext.h index e7fa168ad65..3456b15f8de 100644 --- a/tools/llvm-pdbdump/YamlSerializationContext.h +++ b/tools/llvm-pdbdump/YamlSerializationContext.h @@ -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" diff --git a/tools/llvm-pdbdump/YamlSymbolDumper.cpp b/tools/llvm-pdbdump/YamlSymbolDumper.cpp new file mode 100644 index 00000000000..c2df26f7cd2 --- /dev/null +++ b/tools/llvm-pdbdump/YamlSymbolDumper.cpp @@ -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::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 { + void enumeration(IO &io, ThunkOrdinal Ord) {} +}; + +void MappingTraits::mapping(IO &IO, ScopeEndSym &Obj) {} + +void MappingTraits::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::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::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::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::mapping(IO &IO, ExportSym &Export) { + IO.mapRequired("Ordinal", Export.Header.Ordinal); + IO.mapRequired("Flags", Export.Header.Flags); + IO.mapRequired("Name", Export.Name); +} + +void MappingTraits::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::mapping(IO &IO, RegisterSym &Register) { + IO.mapRequired("Type", Register.Header.Index); + IO.mapRequired("Seg", Register.Header.Register); + IO.mapRequired("Name", Register.Name); +} + +void MappingTraits::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::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::mapping(IO &IO, EnvBlockSym &EnvBlock) { + IO.mapRequired("Reserved", EnvBlock.Header.Reserved); + IO.mapRequired("Entries", EnvBlock.Fields); +} + +void MappingTraits::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::mapping(IO &IO, LocalSym &Local) { + IO.mapRequired("Type", Local.Header.Type); + IO.mapRequired("Flags", Local.Header.Flags); + IO.mapRequired("VarName", Local.Name); +} + +void MappingTraits::mapping(IO &IO, DefRangeSym &Obj) { + // TODO: Print the subfields +} + +void MappingTraits::mapping(IO &IO, + DefRangeSubfieldSym &Obj) { + // TODO: Print the subfields +} + +void MappingTraits::mapping(IO &IO, + DefRangeRegisterSym &Obj) { + // TODO: Print the subfields +} + +void MappingTraits::mapping( + IO &IO, DefRangeFramePointerRelSym &Obj) { + // TODO: Print the subfields +} + +void MappingTraits::mapping( + IO &IO, DefRangeSubfieldRegisterSym &Obj) { + // TODO: Print the subfields +} + +void MappingTraits::mapping( + IO &IO, DefRangeFramePointerRelFullScopeSym &Obj) { + // TODO: Print the subfields +} + +void MappingTraits::mapping( + IO &IO, DefRangeRegisterRelSym &Obj) { + // TODO: Print the subfields +} + +void MappingTraits::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::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::mapping(IO &IO, ObjNameSym &ObjName) { + IO.mapRequired("Signature", ObjName.Header.Signature); + IO.mapRequired("ObjectName", ObjName.Name); +} + +void MappingTraits::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::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::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::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::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::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::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::mapping(IO &IO, CallerSym &Caller) { + // TODO: Correctly handle the ArrayRef in here. + std::vector Indices(Caller.Indices); + IO.mapRequired("FuncID", Indices); +} + +void MappingTraits::mapping(IO &IO, UDTSym &UDT) { + IO.mapRequired("Type", UDT.Header.Type); + IO.mapRequired("UDTName", UDT.Name); +} + +void MappingTraits::mapping(IO &IO, BuildInfoSym &BuildInfo) { + IO.mapRequired("BuildId", BuildInfo.Header.BuildId); +} + +void MappingTraits::mapping(IO &IO, BPRelativeSym &BPRel) { + IO.mapRequired("Offset", BPRel.Header.Offset); + IO.mapRequired("Type", BPRel.Header.Type); + IO.mapRequired("VarName", BPRel.Name); +} + +void MappingTraits::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::mapping(IO &IO, ConstantSym &Constant) { + IO.mapRequired("Type", Constant.Header.Type); + IO.mapRequired("Value", Constant.Value); + IO.mapRequired("Name", Constant.Name); +} + +void MappingTraits::mapping(IO &IO, DataSym &Data) { + // TODO: Map linkage name + IO.mapRequired("Type", Data.Header.Type); + IO.mapRequired("DisplayName", Data.Name); +} + +void MappingTraits::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(); +} diff --git a/tools/llvm-pdbdump/YamlSymbolDumper.h b/tools/llvm-pdbdump/YamlSymbolDumper.h new file mode 100644 index 00000000000..61e63f96719 --- /dev/null +++ b/tools/llvm-pdbdump/YamlSymbolDumper.h @@ -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 + void visitKnownRecordImpl(const char *Name, CVSymbol &Type, T &Record) { + YamlIO.mapRequired(Name, Record); + } + + llvm::yaml::IO &YamlIO; +}; +} +} +} + +namespace llvm { +namespace yaml { +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, codeview::SymbolKind &Value); +}; + +#define SYMBOL_RECORD(EnumName, EnumVal, Name) \ + template <> struct MappingTraits { \ + static void mapping(IO &IO, codeview::Name &Obj); \ + }; +#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" +} +} + +#endif diff --git a/tools/llvm-pdbdump/CodeViewYaml.cpp b/tools/llvm-pdbdump/YamlTypeDumper.cpp similarity index 95% rename from tools/llvm-pdbdump/CodeViewYaml.cpp rename to tools/llvm-pdbdump/YamlTypeDumper.cpp index 78a7aefa96f..d20e26d18d2 100644 --- a/tools/llvm-pdbdump/CodeViewYaml.cpp +++ b/tools/llvm-pdbdump/YamlTypeDumper.cpp @@ -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 { } }; -template <> struct ScalarTraits { - 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::output(const APSInt &S, void *, + llvm::raw_ostream &OS) { + S.print(OS, true); +} +StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, APSInt &S) { + S = APSInt(Scalar); + return ""; +} - static bool mustQuote(StringRef Scalar) { return false; } -}; +bool ScalarTraits::mustQuote(StringRef Scalar) { return false; } void MappingContextTraits::mapping( IO &IO, CVType &Record, pdb::yaml::SerializationContext &Context) { @@ -501,21 +500,22 @@ void MappingTraits::mapping( IO.mapRequired("ContinuationIndex", Cont.ContinuationIndex); } -template <> struct ScalarTraits { - 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::input(Scalar, Ctx, I); - if (!Result.empty()) - return Result; - S = TypeIndex(I); - return ""; - } - static bool mustQuote(StringRef Scalar) { return false; } -}; +void ScalarTraits::output(const codeview::TypeIndex &S, + void *, llvm::raw_ostream &OS) { + OS << S.getIndex(); +} +StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, + codeview::TypeIndex &S) { + uint32_t I; + StringRef Result = ScalarTraits::input(Scalar, Ctx, I); + if (!Result.empty()) + return Result; + S = TypeIndex(I); + return ""; +} +bool ScalarTraits::mustQuote(StringRef Scalar) { + return false; +} void ScalarEnumerationTraits::enumeration(IO &io, TypeLeafKind &Value) { diff --git a/tools/llvm-pdbdump/CodeViewYaml.h b/tools/llvm-pdbdump/YamlTypeDumper.h similarity index 83% rename from tools/llvm-pdbdump/CodeViewYaml.h rename to tools/llvm-pdbdump/YamlTypeDumper.h index 484f002c411..75b37b041f0 100644 --- a/tools/llvm-pdbdump/CodeViewYaml.h +++ b/tools/llvm-pdbdump/YamlTypeDumper.h @@ -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 { + 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 { + 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 { static void mapping(IO &IO, codeview::MemberPointerInfo &Obj); }; diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 14c6f40b50f..a6dd56048ce 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -280,6 +280,11 @@ cl::opt cl::desc("Dump DBI Module Information (implies -dbi-stream)"), cl::sub(PdbToYamlSubcommand), cl::init(false)); +cl::opt DbiModuleSyms( + "dbi-module-syms", + cl::desc("Dump DBI Module Information (implies -dbi-module-info)"), + cl::sub(PdbToYamlSubcommand), cl::init(false)); + cl::opt DbiModuleSourceFileInfo( "dbi-module-source-info", cl::desc( diff --git a/tools/llvm-pdbdump/llvm-pdbdump.h b/tools/llvm-pdbdump/llvm-pdbdump.h index 8f05ca7356e..72423d7e8c7 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/tools/llvm-pdbdump/llvm-pdbdump.h @@ -71,6 +71,7 @@ extern llvm::cl::opt StreamDirectory; extern llvm::cl::opt PdbStream; extern llvm::cl::opt DbiStream; extern llvm::cl::opt DbiModuleInfo; +extern llvm::cl::opt DbiModuleSyms; extern llvm::cl::opt DbiModuleSourceFileInfo; extern llvm::cl::opt TpiStream; extern llvm::cl::opt IpiStream;