[llvm] r297625 - [llvm-pdbdump] Add support for dumping symbols from Yaml -> PDB.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 13 07:57:46 PDT 2017


Author: zturner
Date: Mon Mar 13 09:57:45 2017
New Revision: 297625

URL: http://llvm.org/viewvc/llvm-project?rev=297625&view=rev
Log:
[llvm-pdbdump] Add support for dumping symbols from Yaml -> PDB.

Previously we could round-trip type records from PDB -> Yaml ->
PDB, but for symbols we could only go from PDB -> Yaml.  This
completes the round-tripping for symbols as well.

Added:
    llvm/trunk/lib/DebugInfo/CodeView/SymbolSerializer.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
    llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.h
    llvm/trunk/tools/llvm-pdbdump/YamlSymbolDumper.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h?rev=297625&r1=297624&r2=297625&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolSerializer.h Mon Mar 13 09:57:45 2017
@@ -29,7 +29,10 @@ namespace codeview {
 
 class SymbolSerializer : public SymbolVisitorCallbacks {
   uint32_t RecordStart = 0;
-  BinaryStreamWriter &Writer;
+  BumpPtrAllocator &Storage;
+  std::vector<uint8_t> RecordBuffer;
+  MutableBinaryByteStream Stream;
+  BinaryStreamWriter Writer;
   SymbolRecordMapping Mapping;
   Optional<SymbolKind> CurrentSymbol;
 
@@ -43,40 +46,10 @@ class SymbolSerializer : public SymbolVi
   }
 
 public:
-  explicit SymbolSerializer(BinaryStreamWriter &Writer)
-      : Writer(Writer), Mapping(Writer) {}
+  explicit SymbolSerializer(BumpPtrAllocator &Storage);
 
-  virtual Error visitSymbolBegin(CVSymbol &Record) override {
-    assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
-
-    RecordStart = Writer.getOffset();
-    if (auto EC = writeRecordPrefix(Record.kind()))
-      return EC;
-
-    CurrentSymbol = Record.kind();
-    if (auto EC = Mapping.visitSymbolBegin(Record))
-      return EC;
-
-    return Error::success();
-  }
-
-  virtual Error visitSymbolEnd(CVSymbol &Record) override {
-    assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
-
-    if (auto EC = Mapping.visitSymbolEnd(Record))
-      return EC;
-
-    uint32_t RecordEnd = Writer.getOffset();
-    Writer.setOffset(RecordStart);
-    uint16_t Length = RecordEnd - Writer.getOffset() - 2;
-    if (auto EC = Writer.writeInteger(Length))
-      return EC;
-
-    Writer.setOffset(RecordEnd);
-    CurrentSymbol.reset();
-
-    return Error::success();
-  }
+  virtual Error visitSymbolBegin(CVSymbol &Record) override;
+  virtual Error visitSymbolEnd(CVSymbol &Record) override;
 
 #define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
   virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override {       \

Modified: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=297625&r1=297624&r2=297625&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt Mon Mar 13 09:57:45 2017
@@ -12,6 +12,7 @@ add_llvm_library(LLVMDebugInfoCodeView
   RecordSerialization.cpp
   SymbolRecordMapping.cpp
   SymbolDumper.cpp
+  SymbolSerializer.cpp
   TypeDatabase.cpp
   TypeDatabaseVisitor.cpp
   TypeDumpVisitor.cpp

Added: llvm/trunk/lib/DebugInfo/CodeView/SymbolSerializer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/SymbolSerializer.cpp?rev=297625&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/SymbolSerializer.cpp (added)
+++ llvm/trunk/lib/DebugInfo/CodeView/SymbolSerializer.cpp Mon Mar 13 09:57:45 2017
@@ -0,0 +1,52 @@
+//===- SymbolSerializer.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+SymbolSerializer::SymbolSerializer(BumpPtrAllocator &Allocator)
+  : Storage(Allocator), RecordBuffer(MaxRecordLength), Stream(RecordBuffer, llvm::support::little),
+  Writer(Stream), Mapping(Writer) { }
+
+Error SymbolSerializer::visitSymbolBegin(CVSymbol &Record) {
+  assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
+
+  Writer.setOffset(0);
+
+  if (auto EC = writeRecordPrefix(Record.kind()))
+    return EC;
+
+  CurrentSymbol = Record.kind();
+  if (auto EC = Mapping.visitSymbolBegin(Record))
+    return EC;
+
+  return Error::success();
+}
+
+Error SymbolSerializer::visitSymbolEnd(CVSymbol &Record) {
+  assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
+
+  if (auto EC = Mapping.visitSymbolEnd(Record))
+    return EC;
+
+  uint32_t RecordEnd = Writer.getOffset();
+  uint16_t Length = RecordEnd - 2;
+  Writer.setOffset(0);
+  if (auto EC = Writer.writeInteger(Length))
+    return EC;
+
+  uint8_t *StableStorage = Storage.Allocate<uint8_t>(RecordEnd);
+  ::memcpy(StableStorage, &RecordBuffer[0], RecordEnd);
+  Record.RecordData = ArrayRef<uint8_t>(StableStorage, RecordEnd);
+  CurrentSymbol.reset();
+
+  return Error::success();
+}

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp?rev=297625&r1=297624&r2=297625&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp Mon Mar 13 09:57:45 2017
@@ -16,6 +16,7 @@
 #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeSerializer.h"
@@ -137,14 +138,23 @@ template <> struct ScalarEnumerationTrai
 }
 
 void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
+  // Create a single serialization context that will be passed through the
+  // entire process of serializing / deserializing a Tpi Stream.  This is
+  // especially important when we are going from Pdb -> Yaml because we need
+  // to maintain state in a TypeTableBuilder across mappings, and at the end of
+  // the entire process, we need to have one TypeTableBuilder that has every
+  // record.
+  pdb::yaml::SerializationContext Context(IO, Obj.Allocator);
+
+
   IO.mapOptional("MSF", Obj.Headers);
   IO.mapOptional("StreamSizes", Obj.StreamSizes);
   IO.mapOptional("StreamMap", Obj.StreamMap);
   IO.mapOptional("StringTable", Obj.StringTable);
   IO.mapOptional("PdbStream", Obj.PdbStream);
-  IO.mapOptional("DbiStream", Obj.DbiStream);
-  IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Obj.Allocator);
-  IO.mapOptionalWithContext("IpiStream", Obj.IpiStream, Obj.Allocator);
+  IO.mapOptionalWithContext("DbiStream", Obj.DbiStream, Context);
+  IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Context);
+  IO.mapOptionalWithContext("IpiStream", Obj.IpiStream, Context);
 }
 
 void MappingTraits<MSFHeaders>::mapping(IO &IO, MSFHeaders &Obj) {
@@ -179,7 +189,7 @@ void MappingTraits<PdbInfoStream>::mappi
   IO.mapRequired("Version", Obj.Version);
 }
 
-void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
+void MappingContextTraits<PdbDbiStream, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbDbiStream &Obj, pdb::yaml::SerializationContext &Context) {
   IO.mapRequired("VerHeader", Obj.VerHeader);
   IO.mapRequired("Age", Obj.Age);
   IO.mapRequired("BuildNumber", Obj.BuildNumber);
@@ -187,19 +197,11 @@ void MappingTraits<PdbDbiStream>::mappin
   IO.mapRequired("PdbDllRbld", Obj.PdbDllRbld);
   IO.mapRequired("Flags", Obj.Flags);
   IO.mapRequired("MachineType", Obj.MachineType);
-  IO.mapOptional("Modules", Obj.ModInfos);
+  IO.mapOptionalWithContext("Modules", Obj.ModInfos, Context);
 }
 
-void MappingContextTraits<PdbTpiStream, BumpPtrAllocator>::mapping(
-    IO &IO, pdb::yaml::PdbTpiStream &Obj, BumpPtrAllocator &Allocator) {
-  // Create a single serialization context that will be passed through the
-  // entire process of serializing / deserializing a Tpi Stream.  This is
-  // especially important when we are going from Pdb -> Yaml because we need
-  // to maintain state in a TypeTableBuilder across mappings, and at the end of
-  // the entire process, we need to have one TypeTableBuilder that has every
-  // record.
-  pdb::yaml::SerializationContext Context(IO, Allocator);
-
+void MappingContextTraits<PdbTpiStream, pdb::yaml::SerializationContext>::mapping(
+    IO &IO, pdb::yaml::PdbTpiStream &Obj, pdb::yaml::SerializationContext &Context) {
   IO.mapRequired("Version", Obj.Version);
   IO.mapRequired("Records", Obj.Records, Context);
 }
@@ -210,8 +212,9 @@ void MappingTraits<NamedStreamMapping>::
   IO.mapRequired("StreamNum", Obj.StreamNumber);
 }
 
-void MappingTraits<PdbSymbolRecord>::mapping(IO &IO, PdbSymbolRecord &Obj) {
+void MappingContextTraits<PdbSymbolRecord, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbSymbolRecord &Obj, pdb::yaml::SerializationContext &Context) {
   codeview::SymbolVisitorCallbackPipeline Pipeline;
+  codeview::SymbolSerializer Serializer(Context.Allocator);
   codeview::SymbolDeserializer Deserializer(nullptr);
   codeview::yaml::YamlSymbolDumper Dumper(IO);
 
@@ -220,23 +223,26 @@ void MappingTraits<PdbSymbolRecord>::map
     Pipeline.addCallbackToPipeline(Deserializer);
     Pipeline.addCallbackToPipeline(Dumper);
   } else {
-    return;
+    // For the other way around, dump it into a concrete structure, and then
+    // serialize it into the CVRecord.
+    Pipeline.addCallbackToPipeline(Dumper);
+    Pipeline.addCallbackToPipeline(Serializer);
   }
 
   codeview::CVSymbolVisitor Visitor(Pipeline);
   consumeError(Visitor.visitSymbolRecord(Obj.Record));
 }
 
-void MappingTraits<PdbModiStream>::mapping(IO &IO, PdbModiStream &Obj) {
+void MappingContextTraits<PdbModiStream, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbModiStream &Obj, pdb::yaml::SerializationContext &Context) {
   IO.mapRequired("Signature", Obj.Signature);
-  IO.mapRequired("Records", Obj.Symbols);
+  IO.mapRequired("Records", Obj.Symbols, Context);
 }
 
-void MappingTraits<PdbDbiModuleInfo>::mapping(IO &IO, PdbDbiModuleInfo &Obj) {
+void MappingContextTraits<PdbDbiModuleInfo, pdb::yaml::SerializationContext>::mapping(IO &IO, PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context) {
   IO.mapRequired("Module", Obj.Mod);
   IO.mapRequired("ObjFile", Obj.Obj);
   IO.mapOptional("SourceFiles", Obj.SourceFiles);
-  IO.mapOptional("Modi", Obj.Modi);
+  IO.mapOptionalWithContext("Modi", Obj.Modi, Context);
 }
 
 void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.h?rev=297625&r1=297624&r2=297625&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.h Mon Mar 13 09:57:45 2017
@@ -138,30 +138,30 @@ template <> struct MappingTraits<pdb::ya
   static void mapping(IO &IO, pdb::yaml::PdbInfoStream &Obj);
 };
 
-template <> struct MappingTraits<pdb::yaml::PdbDbiStream> {
-  static void mapping(IO &IO, pdb::yaml::PdbDbiStream &Obj);
+template <> struct MappingContextTraits<pdb::yaml::PdbDbiStream, pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbDbiStream &Obj, pdb::yaml::SerializationContext &Context);
 };
 
 template <>
-struct MappingContextTraits<pdb::yaml::PdbTpiStream, llvm::BumpPtrAllocator> {
+struct MappingContextTraits<pdb::yaml::PdbTpiStream, pdb::yaml::SerializationContext> {
   static void mapping(IO &IO, pdb::yaml::PdbTpiStream &Obj,
-                      llvm::BumpPtrAllocator &Allocator);
+    pdb::yaml::SerializationContext &Context);
 };
 
 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 MappingContextTraits<pdb::yaml::PdbSymbolRecord, pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbSymbolRecord &Obj, pdb::yaml::SerializationContext &Context);
 };
 
-template <> struct MappingTraits<pdb::yaml::PdbModiStream> {
-  static void mapping(IO &IO, pdb::yaml::PdbModiStream &Obj);
+template <> struct MappingContextTraits<pdb::yaml::PdbModiStream, pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbModiStream &Obj, pdb::yaml::SerializationContext &Context);
 };
 
-template <> struct MappingTraits<pdb::yaml::PdbDbiModuleInfo> {
-  static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj);
+template <> struct MappingContextTraits<pdb::yaml::PdbDbiModuleInfo, pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context);
 };
 
 template <>

Modified: llvm/trunk/tools/llvm-pdbdump/YamlSymbolDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YamlSymbolDumper.cpp?rev=297625&r1=297624&r2=297625&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YamlSymbolDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/YamlSymbolDumper.cpp Mon Mar 13 09:57:45 2017
@@ -113,6 +113,7 @@ template <> struct ScalarEnumerationTrai
     for (const auto &E : RegNames) {
       io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
     }
+    io.enumFallback<Hex16>(Reg);
   }
 };
 




More information about the llvm-commits mailing list