From 9cba8e4a60765983e2e197598efaaac50a3daa8d Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Mon, 6 Jun 2016 20:37:05 +0000 Subject: [PATCH] [llvm-pdbdump] Dump MSF headers to YAML. This is the simplest possible patch to get some kind of YAML output. All it dumps is the MSF header fields so that in theory an empty MSF file could be reconstructed. Reviewed By: ruiu, majnemer Differential Revision: http://reviews.llvm.org/D20971 llvm-svn: 271939 --- test/DebugInfo/PDB/pdbdump-yaml.test | 17 ++++ tools/llvm-pdbdump/CMakeLists.txt | 2 + tools/llvm-pdbdump/LLVMOutputStyle.cpp | 1 + tools/llvm-pdbdump/LLVMOutputStyle.h | 2 + tools/llvm-pdbdump/OutputStyle.h | 2 + tools/llvm-pdbdump/PdbYaml.cpp | 35 +++++++ tools/llvm-pdbdump/PdbYaml.h | 57 +++++++++++ tools/llvm-pdbdump/YAMLOutputStyle.cpp | 126 +++++++++++++++++++++++++ tools/llvm-pdbdump/YAMLOutputStyle.h | 51 ++++++++++ tools/llvm-pdbdump/llvm-pdbdump.cpp | 4 + 10 files changed, 297 insertions(+) create mode 100644 test/DebugInfo/PDB/pdbdump-yaml.test create mode 100644 tools/llvm-pdbdump/PdbYaml.cpp create mode 100644 tools/llvm-pdbdump/PdbYaml.h create mode 100644 tools/llvm-pdbdump/YAMLOutputStyle.cpp create mode 100644 tools/llvm-pdbdump/YAMLOutputStyle.h diff --git a/test/DebugInfo/PDB/pdbdump-yaml.test b/test/DebugInfo/PDB/pdbdump-yaml.test new file mode 100644 index 00000000000..419be6b361c --- /dev/null +++ b/test/DebugInfo/PDB/pdbdump-yaml.test @@ -0,0 +1,17 @@ +; RUN: llvm-pdbdump -raw-headers -raw-output-style=YAML %p/Inputs/empty.pdb \ +; RUN: | FileCheck -check-prefix=YAML %s + +; YAML: --- +; YAML-NEXT: MSF: +; YAML-NEXT: BlockSize: 4096 +; YAML-NEXT: Unknown0: 2 +; YAML-NEXT: NumBlocks: 25 +; YAML-NEXT: NumDirectoryBytes: 136 +; YAML-NEXT: Unknown1: 0 +; YAML-NEXT: BlockMapAddr: 24 +; YAML-NEXT: NumDirectoryBlocks: 1 +; YAML-NEXT: BlockMapOffset: 98304 +; YAML-NEXT: DirectoryBlocks: +; YAML-NEXT: - 23 +; YAML-NEXT: NumStreams: 17 +; YAML-NEXT: ... diff --git a/tools/llvm-pdbdump/CMakeLists.txt b/tools/llvm-pdbdump/CMakeLists.txt index 22d52003c77..f725edfaf3d 100644 --- a/tools/llvm-pdbdump/CMakeLists.txt +++ b/tools/llvm-pdbdump/CMakeLists.txt @@ -15,9 +15,11 @@ add_llvm_tool(llvm-pdbdump FunctionDumper.cpp LinePrinter.cpp LLVMOutputStyle.cpp + PdbYaml.cpp TypeDumper.cpp TypedefDumper.cpp VariableDumper.cpp + YAMLOutputStyle.cpp ) if(LLVM_USE_SANITIZE_COVERAGE) diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/tools/llvm-pdbdump/LLVMOutputStyle.cpp index 1707454df66..75e87afeb74 100644 --- a/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -694,3 +694,4 @@ Error LLVMOutputStyle::dumpFpoStream() { } return Error::success(); } +void LLVMOutputStyle::flush() { P.flush(); } diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.h b/tools/llvm-pdbdump/LLVMOutputStyle.h index 0c601c9b9b1..9fcfb6e986e 100644 --- a/tools/llvm-pdbdump/LLVMOutputStyle.h +++ b/tools/llvm-pdbdump/LLVMOutputStyle.h @@ -35,6 +35,8 @@ public: Error dumpSectionHeaders() override; Error dumpFpoStream() override; + void flush() override; + private: PDBFile &File; ScopedPrinter P; diff --git a/tools/llvm-pdbdump/OutputStyle.h b/tools/llvm-pdbdump/OutputStyle.h index c42f7d21002..34dd0965b89 100644 --- a/tools/llvm-pdbdump/OutputStyle.h +++ b/tools/llvm-pdbdump/OutputStyle.h @@ -32,6 +32,8 @@ public: virtual Error dumpPublicsStream() = 0; virtual Error dumpSectionHeaders() = 0; virtual Error dumpFpoStream() = 0; + + virtual void flush() = 0; }; } } diff --git a/tools/llvm-pdbdump/PdbYaml.cpp b/tools/llvm-pdbdump/PdbYaml.cpp new file mode 100644 index 00000000000..23e756654af --- /dev/null +++ b/tools/llvm-pdbdump/PdbYaml.cpp @@ -0,0 +1,35 @@ +//===- PdbYAML.cpp -------------------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PdbYaml.h" + +#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" + +using namespace llvm; +using namespace llvm::pdb; +using namespace llvm::pdb::yaml; + +void llvm::yaml::MappingTraits::mapping( + IO &IO, pdb::yaml::MsfHeaders &Obj) { + IO.mapRequired("BlockSize", Obj.BlockSize); + IO.mapRequired("Unknown0", Obj.Unknown0); + IO.mapRequired("NumBlocks", Obj.BlockCount); + IO.mapRequired("NumDirectoryBytes", Obj.NumDirectoryBytes); + IO.mapRequired("Unknown1", Obj.Unknown1); + IO.mapRequired("BlockMapAddr", Obj.BlockMapIndex); + IO.mapRequired("NumDirectoryBlocks", Obj.NumDirectoryBlocks); + IO.mapRequired("BlockMapOffset", Obj.BlockMapOffset); + IO.mapRequired("DirectoryBlocks", Obj.DirectoryBlocks); + IO.mapRequired("NumStreams", Obj.NumStreams); +} + +void llvm::yaml::MappingTraits::mapping( + IO &IO, pdb::yaml::PdbObject &Obj) { + IO.mapOptional("MSF", Obj.Headers); +} diff --git a/tools/llvm-pdbdump/PdbYaml.h b/tools/llvm-pdbdump/PdbYaml.h new file mode 100644 index 00000000000..a623dde2c49 --- /dev/null +++ b/tools/llvm-pdbdump/PdbYaml.h @@ -0,0 +1,57 @@ +//===- PdbYAML.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_PDBYAML_H +#define LLVM_TOOLS_LLVMPDBDUMP_PDBYAML_H + +#include "OutputStyle.h" + +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/YAMLTraits.h" + +#include + +namespace llvm { +namespace pdb { +class PDBFile; + +namespace yaml { +struct MsfHeaders { + uint32_t BlockSize; + uint32_t Unknown0; + uint32_t BlockCount; + uint32_t NumDirectoryBytes; + uint32_t Unknown1; + uint32_t BlockMapIndex; + uint32_t NumDirectoryBlocks; + uint32_t BlockMapOffset; + std::vector DirectoryBlocks; + uint32_t NumStreams; +}; + +struct PdbObject { + Optional Headers; +}; +} +} + +namespace yaml { +template <> struct MappingTraits { + static void mapping(IO &IO, pdb::yaml::MsfHeaders &Obj); +}; +template <> struct MappingTraits { + static void mapping(IO &IO, pdb::yaml::PdbObject &Obj); +}; +} +} + +LLVM_YAML_IS_SEQUENCE_VECTOR(uint32_t) + +#endif // LLVM_TOOLS_LLVMPDBDUMP_PDBYAML_H diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/tools/llvm-pdbdump/YAMLOutputStyle.cpp new file mode 100644 index 00000000000..a06a22d93ed --- /dev/null +++ b/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -0,0 +1,126 @@ +//===- YAMLOutputStyle.cpp ------------------------------------ *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "YAMLOutputStyle.h" + +#include "PdbYaml.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" + +using namespace llvm; +using namespace llvm::pdb; + +YAMLOutputStyle::YAMLOutputStyle(PDBFile &File) : File(File), Out(outs()) {} + +Error YAMLOutputStyle::dumpFileHeaders() { + if (!opts::DumpHeaders) + return Error::success(); + + yaml::MsfHeaders Headers; + Headers.BlockCount = File.getBlockCount(); + Headers.BlockMapIndex = File.getBlockMapIndex(); + Headers.BlockMapOffset = File.getBlockMapOffset(); + Headers.BlockSize = File.getBlockSize(); + auto Blocks = File.getDirectoryBlockArray(); + Headers.DirectoryBlocks.assign(Blocks.begin(), Blocks.end()); + Headers.NumDirectoryBlocks = File.getNumDirectoryBlocks(); + Headers.NumDirectoryBytes = File.getNumDirectoryBytes(); + Headers.NumStreams = File.getNumStreams(); + Headers.Unknown0 = File.getUnknown0(); + Headers.Unknown1 = File.getUnknown1(); + + Obj.Headers.emplace(Headers); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpStreamSummary() { + if (!opts::DumpStreamSummary) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpStreamBlocks() { + if (!opts::DumpStreamBlocks) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpStreamData() { + uint32_t StreamCount = File.getNumStreams(); + StringRef DumpStreamStr = opts::DumpStreamDataIdx; + uint32_t DumpStreamNum; + if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) || + DumpStreamNum >= StreamCount) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpInfoStream() { + if (!opts::DumpHeaders) + return Error::success(); + return Error::success(); +} + +Error YAMLOutputStyle::dumpNamedStream() { + if (opts::DumpStreamDataName.empty()) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpTpiStream(uint32_t StreamIdx) { + return Error::success(); +} + +Error YAMLOutputStyle::dumpDbiStream() { return Error::success(); } + +Error YAMLOutputStyle::dumpSectionContribs() { + if (!opts::DumpSectionContribs) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpSectionMap() { + if (!opts::DumpSectionMap) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpPublicsStream() { + if (!opts::DumpPublics) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpSectionHeaders() { + if (!opts::DumpSectionHeaders) + return Error::success(); + + return Error::success(); +} + +Error YAMLOutputStyle::dumpFpoStream() { + if (!opts::DumpFpo) + return Error::success(); + + return Error::success(); +} + +void YAMLOutputStyle::flush() { + Out << Obj; + outs().flush(); +} diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.h b/tools/llvm-pdbdump/YAMLOutputStyle.h new file mode 100644 index 00000000000..cbd1817773c --- /dev/null +++ b/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -0,0 +1,51 @@ +//===- YAMLOutputStyle.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_YAMLOUTPUTSTYLE_H +#define LLVM_TOOLS_LLVMPDBDUMP_YAMLOUTPUTSTYLE_H + +#include "OutputStyle.h" +#include "PdbYaml.h" + +#include "llvm/DebugInfo/CodeView/TypeDumper.h" +#include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/YAMLTraits.h" + +namespace llvm { +namespace pdb { +class YAMLOutputStyle : public OutputStyle { +public: + YAMLOutputStyle(PDBFile &File); + + Error dumpFileHeaders() override; + Error dumpStreamSummary() override; + Error dumpStreamBlocks() override; + Error dumpStreamData() override; + Error dumpInfoStream() override; + Error dumpNamedStream() override; + Error dumpTpiStream(uint32_t StreamIdx) override; + Error dumpDbiStream() override; + Error dumpSectionContribs() override; + Error dumpSectionMap() override; + Error dumpPublicsStream() override; + Error dumpSectionHeaders() override; + Error dumpFpoStream() override; + + void flush() override; + +private: + PDBFile &File; + llvm::yaml::Output Out; + + yaml::PdbObject Obj; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_TOOLS_LLVMPDBDUMP_YAMLOUTPUTSTYLE_H diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index b798929ace8..7d4ba6471f1 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -22,6 +22,7 @@ #include "OutputStyle.h" #include "TypeDumper.h" #include "VariableDumper.h" +#include "YAMLOutputStyle.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" @@ -211,6 +212,8 @@ static Error dumpStructure(RawSession &RS) { std::unique_ptr O; if (opts::RawOutputStyle == opts::OutputStyleTy::LLVM) O = llvm::make_unique(File); + else if (opts::RawOutputStyle == opts::OutputStyleTy::YAML) + O = llvm::make_unique(File); else return make_error(raw_error_code::feature_unsupported, "Requested output style unsupported"); @@ -256,6 +259,7 @@ static Error dumpStructure(RawSession &RS) { if (auto EC = O->dumpFpoStream()) return EC; + O->flush(); return Error::success(); }