[llvm] r270511 - Make a symbol visitor and use it to dump CV symbols.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Mon May 23 16:41:13 PDT 2016


Author: zturner
Date: Mon May 23 18:41:13 2016
New Revision: 270511

URL: http://llvm.org/viewvc/llvm-project?rev=270511&view=rev
Log:
Make a symbol visitor and use it to dump CV symbols.

Differential Revision: http://reviews.llvm.org/D20534
Reviewed By: rnk

Added:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
    llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
    llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def?rev=270511&r1=270510&r2=270511&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def Mon May 23 18:41:13 2016
@@ -30,7 +30,6 @@ CV_SYMBOL(S_REGISTER_16t  , 0x0002)
 CV_SYMBOL(S_CONSTANT_16t  , 0x0003)
 CV_SYMBOL(S_UDT_16t       , 0x0004)
 CV_SYMBOL(S_SSEARCH       , 0x0005)
-CV_SYMBOL(S_END           , 0x0006)
 CV_SYMBOL(S_SKIP          , 0x0007)
 CV_SYMBOL(S_CVRESERVE     , 0x0008)
 CV_SYMBOL(S_OBJNAME_ST    , 0x0009)
@@ -179,12 +178,6 @@ CV_SYMBOL(S_GPROCMIPS_ID   , 0x1149)
 CV_SYMBOL(S_LPROCIA64_ID   , 0x114a)
 CV_SYMBOL(S_GPROCIA64_ID   , 0x114b)
 
-// Inlined call site delimiters.
-CV_SYMBOL(S_INLINESITE_END , 0x114e)
-
-// Procedure info end delimiter.
-CV_SYMBOL(S_PROC_ID_END    , 0x114f)
-
 CV_SYMBOL(S_DEFRANGE_HLSL  , 0x1150)
 CV_SYMBOL(S_GDATA_HLSL     , 0x1151)
 CV_SYMBOL(S_LDATA_HLSL     , 0x1152)
@@ -193,8 +186,6 @@ CV_SYMBOL(S_LOCAL_DPC_GROUPSHARED, 0x115
 CV_SYMBOL(S_DEFRANGE_DPC_PTR_TAG, 0x1157)
 CV_SYMBOL(S_DPC_SYM_TAG_MAP, 0x1158)
 CV_SYMBOL(S_ARMSWITCHTABLE , 0x1159)
-CV_SYMBOL(S_CALLEES        , 0x115a)
-CV_SYMBOL(S_CALLERS        , 0x115b)
 CV_SYMBOL(S_POGODATA       , 0x115c)
 CV_SYMBOL(S_INLINESITE2    , 0x115d)
 CV_SYMBOL(S_MOD_TYPEREF    , 0x115f)
@@ -206,19 +197,24 @@ CV_SYMBOL(S_GDATA_HLSL32_EX, 0x1164)
 CV_SYMBOL(S_LDATA_HLSL32_EX, 0x1165)
 
 // Known symbol types
+SYMBOL_RECORD(S_END					 , 0x0006, ScopeEndSym)
+SYMBOL_RECORD_ALIAS(S_INLINESITE_END , 0x114e, InlineSiteEnd, ScopeEndSym)
+SYMBOL_RECORD_ALIAS(S_PROC_ID_END    , 0x114f, ProcEnd, ScopeEndSym) 
+
 SYMBOL_RECORD(S_LPROC32       , 0x110f, ProcSym)
 SYMBOL_RECORD_ALIAS(S_GPROC32       , 0x1110, GlobalProcSym, ProcSym)
 SYMBOL_RECORD_ALIAS(S_LPROC32_ID     , 0x1146, ProcIdSym, ProcSym)
 SYMBOL_RECORD_ALIAS(S_GPROC32_ID     , 0x1147, GlobalProcIdSym, ProcSym)
 SYMBOL_RECORD_ALIAS(S_LPROC32_DPC    , 0x1155, DPCProcSym, ProcSym)
 SYMBOL_RECORD_ALIAS(S_LPROC32_DPC_ID , 0x1156, DPCProcIdSym, ProcSym)
+
 SYMBOL_RECORD(S_INLINESITE     , 0x114d, InlineSiteSym)
 SYMBOL_RECORD(S_LOCAL         , 0x113e, LocalSym)
 SYMBOL_RECORD(S_DEFRANGE      , 0x113f, DefRangeSym)
 SYMBOL_RECORD(S_DEFRANGE_SUBFIELD, 0x1140, DefRangeSubfieldSym)
 SYMBOL_RECORD(S_DEFRANGE_REGISTER, 0x1141, DefRangeRegisterSym)
-SYMBOL_RECORD(S_DEFRANGE_FRAMEPOINTER_REL, 0x1142, DefRangeSubfieldRegisterSym)
-SYMBOL_RECORD(S_DEFRANGE_SUBFIELD_REGISTER, 0x1143, DefRangeFramePointerRelSym)
+SYMBOL_RECORD(S_DEFRANGE_FRAMEPOINTER_REL, 0x1142, DefRangeFramePointerRelSym)
+SYMBOL_RECORD(S_DEFRANGE_SUBFIELD_REGISTER, 0x1143, DefRangeSubfieldRegisterSym)
 SYMBOL_RECORD(S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE, 0x1144, DefRangeFramePointerRelFullScopeSym)
 SYMBOL_RECORD(S_DEFRANGE_REGISTER_REL, 0x1145, DefRangeRegisterRelSym)
 SYMBOL_RECORD(S_BLOCK32       , 0x1103, BlockSym)
@@ -229,17 +225,25 @@ SYMBOL_RECORD(S_FRAMEPROC     , 0x1012,
 SYMBOL_RECORD(S_CALLSITEINFO  , 0x1139, CallSiteInfoSym)
 SYMBOL_RECORD(S_HEAPALLOCSITE  , 0x115e, HeapAllocationSiteSym)
 SYMBOL_RECORD(S_FRAMECOOKIE   , 0x113a, FrameCookieSym)
+
+SYMBOL_RECORD(S_CALLEES        , 0x115a, CallerSym)
+SYMBOL_RECORD_ALIAS(S_CALLERS        , 0x115b, CalleeSym, CallerSym)
+
 SYMBOL_RECORD(S_UDT           , 0x1108, UDTSym)
 SYMBOL_RECORD_ALIAS(S_COBOLUDT      , 0x1109, CobolUDT, UDTSym)
+
 SYMBOL_RECORD(S_BUILDINFO      , 0x114c, BuildInfoSym)
 SYMBOL_RECORD(S_BPREL32       , 0x110b, BPRelativeSym)
 SYMBOL_RECORD(S_REGREL32      , 0x1111, RegRelativeSym)
+
 SYMBOL_RECORD(S_CONSTANT      , 0x1107, ConstantSym)
 SYMBOL_RECORD_ALIAS(S_MANCONSTANT   , 0x112d, ManagedConstant, ConstantSym)
+
 SYMBOL_RECORD(S_LDATA32       , 0x110c, DataSym)
 SYMBOL_RECORD_ALIAS(S_GDATA32       , 0x110d, GlobalData, DataSym)
 SYMBOL_RECORD_ALIAS(S_LMANDATA      , 0x111c, ManagedLocalData, DataSym)
 SYMBOL_RECORD_ALIAS(S_GMANDATA      , 0x111d, ManagedGlobalData, DataSym)
+
 SYMBOL_RECORD(S_LTHREAD32     , 0x1112, ThreadLocalDataSym)
 SYMBOL_RECORD_ALIAS(S_GTHREAD32     , 0x1113, GlobalTLS, ThreadLocalDataSym)
 

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h?rev=270511&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h Mon May 23 18:41:13 2016
@@ -0,0 +1,103 @@
+//===- CVSymbolVisitor.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_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordIterator.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
+#include "llvm/Support/ErrorOr.h"
+
+namespace llvm {
+namespace codeview {
+
+template <typename Derived> class CVSymbolVisitor {
+public:
+  CVSymbolVisitor(SymbolVisitorDelegate *Delegate) : Delegate(Delegate) {}
+
+  bool hadError() const { return HadError; }
+
+  template <typename T>
+  bool consumeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
+    if (Data.size() < sizeof(*Res)) {
+      HadError = true;
+      return false;
+    }
+    Res = reinterpret_cast<const T *>(Data.data());
+    Data = Data.drop_front(sizeof(*Res));
+    return true;
+  }
+
+/// Actions to take on known symbols. By default, they do nothing. Visit methods
+/// for member records take the FieldData by non-const reference and are
+/// expected to consume the trailing bytes used by the field.
+/// FIXME: Make the visitor interpret the trailing bytes so that clients don't
+/// need to.
+#define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
+  void visit##Name(SymbolRecordKind Kind, Name &Record) {}
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "CVSymbolTypes.def"
+
+  void visitSymbolRecord(const SymbolIterator::Record &Record) {
+    ArrayRef<uint8_t> Data = Record.Data;
+    auto *DerivedThis = static_cast<Derived *>(this);
+    DerivedThis->visitSymbolBegin(Record.Type, Data);
+    uint32_t RecordOffset = Delegate ? Delegate->getRecordOffset(Data) : 0;
+    switch (Record.Type) {
+    default:
+      DerivedThis->visitUnknownSymbol(Record.Type, Data);
+      break;
+#define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
+  case EnumName: {                                                             \
+    SymbolRecordKind RK = static_cast<SymbolRecordKind>(EnumName);             \
+    auto Result = Name::deserialize(RK, RecordOffset, Data);                   \
+    if (Result.getError())                                                     \
+      return parseError();                                                     \
+    DerivedThis->visit##Name(Record.Type, *Result);                            \
+    break;                                                                     \
+  }
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)                \
+  SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
+#include "CVSymbolTypes.def"
+    }
+    DerivedThis->visitSymbolEnd(Record.Type, Record.Data);
+  }
+
+  /// Visits the symbol records in Data. Sets the error flag on parse failures.
+  void visitSymbolStream(ArrayRef<uint8_t> Data) {
+    for (const auto &I : makeSymbolRange(Data, &HadError)) {
+      visitSymbolRecord(I);
+      if (hadError())
+        break;
+    }
+  }
+
+  /// Action to take on unknown symbols. By default, they are ignored.
+  void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data) {}
+
+  /// Paired begin/end actions for all symbols. Receives all record data,
+  /// including the fixed-length record prefix.
+  void visitSymbolBegin(SymbolKind Leaf, ArrayRef<uint8_t> RecordData) {}
+  void visitSymbolEnd(SymbolKind Leaf, ArrayRef<uint8_t> OriginalSymData) {}
+
+  /// Helper for returning from a void function when the stream is corrupted.
+  void parseError() { HadError = true; }
+
+private:
+  SymbolVisitorDelegate *Delegate;
+  /// Whether a symbol stream parsing error was encountered.
+  bool HadError = false;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h?rev=270511&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h Mon May 23 18:41:13 2016
@@ -0,0 +1,37 @@
+//===-- SymbolDumpDelegate.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_DEBUGINFO_CODEVIEW_SYMBOLDUMPDELEGATE_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPDELEGATE_H
+
+#include "SymbolVisitorDelegate.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stdint.h>
+
+namespace llvm {
+
+namespace codeview {
+
+class SymbolDumpDelegate : public SymbolVisitorDelegate {
+public:
+  virtual ~SymbolDumpDelegate() {}
+
+  virtual void printRelocatedField(StringRef Label, uint32_t RelocOffset,
+                                   uint32_t Offset,
+                                   StringRef *RelocSym = nullptr) = 0;
+  virtual void printBinaryBlockWithRelocs(StringRef Label,
+                                          ArrayRef<uint8_t> Block) = 0;
+};
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPDELEGATE_H

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h?rev=270511&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h Mon May 23 18:41:13 2016
@@ -0,0 +1,54 @@
+//===-- SymbolDumper.h - CodeView symbol info dumper ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPER_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+namespace llvm {
+class ScopedPrinter;
+
+namespace codeview {
+class CVTypeDumper;
+
+/// Dumper for CodeView symbol streams found in COFF object files and PDB files.
+class CVSymbolDumper {
+public:
+  CVSymbolDumper(ScopedPrinter &W, CVTypeDumper &CVTD,
+                 std::unique_ptr<SymbolDumpDelegate> ObjDelegate,
+                 bool PrintRecordBytes)
+      : W(W), CVTD(CVTD), ObjDelegate(std::move(ObjDelegate)),
+        PrintRecordBytes(PrintRecordBytes) {}
+
+  /// Dumps one type record.  Returns false if there was a type parsing error,
+  /// and true otherwise.  This should be called in order, since the dumper
+  /// maintains state about previous records which are necessary for cross
+  /// type references.
+  bool dump(const SymbolIterator::Record &Record);
+
+  /// Dumps the type records in Data. Returns false if there was a type stream
+  /// parse error, and true otherwise.
+  bool dump(ArrayRef<uint8_t> Data);
+
+private:
+  ScopedPrinter &W;
+  CVTypeDumper &CVTD;
+  std::unique_ptr<SymbolDumpDelegate> ObjDelegate;
+
+  bool PrintRecordBytes;
+};
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPER_H

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h?rev=270511&r1=270510&r2=270511&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h Mon May 23 18:41:13 2016
@@ -79,6 +79,46 @@ public:
   StringRef Name;
 };
 
+class ScopeEndSym : public SymbolRecord {
+public:
+  ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
+      : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
+
+  static ErrorOr<ScopeEndSym> deserialize(SymbolRecordKind Kind,
+                                          uint32_t RecordOffset,
+                                          ArrayRef<uint8_t> &Data) {
+    return ScopeEndSym(Kind, RecordOffset);
+  }
+  uint32_t RecordOffset;
+};
+
+class CallerSym : public SymbolRecord {
+public:
+  struct Hdr {
+    uint32_t Count;
+  };
+
+  CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *Header,
+            ArrayRef<TypeIndex> Indices)
+      : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*Header),
+        Indices(Indices) {}
+
+  static ErrorOr<CallerSym> deserialize(SymbolRecordKind Kind,
+                                        uint32_t RecordOffset,
+                                        ArrayRef<uint8_t> &Data) {
+    const Hdr *Header;
+    ArrayRef<TypeIndex> Indices;
+
+    CV_DESERIALIZE(Data, Header, CV_ARRAY_FIELD_N(Indices, Header->Count));
+
+    return CallerSym(Kind, RecordOffset, Header, Indices);
+  }
+
+  Hdr Header;
+  uint32_t RecordOffset;
+  ArrayRef<TypeIndex> Indices;
+};
+
 struct BinaryAnnotationIterator {
   struct AnnotationData {
     BinaryAnnotationsOpCode OpCode;
@@ -697,7 +737,7 @@ public:
 };
 
 // S_COMPILE3
-class CompileSym3 : public SymbolRecord {
+class Compile3Sym : public SymbolRecord {
 public:
   struct Hdr {
     ulittle32_t flags; // CompileSym3Flags enum
@@ -714,18 +754,18 @@ public:
     // VersionString: The null-terminated version string follows.
   };
 
-  CompileSym3(uint32_t RecordOffset, const Hdr *H, StringRef Version)
+  Compile3Sym(uint32_t RecordOffset, const Hdr *H, StringRef Version)
       : SymbolRecord(SymbolRecordKind::Compile3Sym), RecordOffset(RecordOffset),
         Header(*H), Version(Version) {}
 
-  static ErrorOr<CompileSym3> deserialize(SymbolRecordKind Kind,
+  static ErrorOr<Compile3Sym> deserialize(SymbolRecordKind Kind,
                                           uint32_t RecordOffset,
                                           ArrayRef<uint8_t> &Data) {
     const Hdr *H = nullptr;
     StringRef Version;
     CV_DESERIALIZE(Data, H, Version);
 
-    return CompileSym3(RecordOffset, H, Version);
+    return Compile3Sym(RecordOffset, H, Version);
   }
 
   uint32_t RecordOffset;
@@ -1060,10 +1100,11 @@ public:
   StringRef Name;
 };
 
-typedef RecordIterator<SymbolRecordKind> SymbolIterator;
+typedef RecordIterator<SymbolKind> SymbolIterator;
 
-inline iterator_range<SymbolIterator> makeSymbolRange(ArrayRef<uint8_t> Data) {
-  return make_range(SymbolIterator(Data, nullptr), SymbolIterator());
+inline iterator_range<SymbolIterator> makeSymbolRange(ArrayRef<uint8_t> Data,
+                                                      bool *HadError) {
+  return make_range(SymbolIterator(Data, HadError), SymbolIterator());
 }
 
 } // namespace codeview

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h?rev=270511&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h Mon May 23 18:41:13 2016
@@ -0,0 +1,33 @@
+//===-- SymbolVisitorDelegate.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_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stdint.h>
+
+namespace llvm {
+
+namespace codeview {
+
+class SymbolVisitorDelegate {
+public:
+  virtual ~SymbolVisitorDelegate() {}
+
+  virtual uint32_t getRecordOffset(ArrayRef<uint8_t> Record) = 0;
+  virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
+  virtual StringRef getStringTable() = 0;
+};
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H

Modified: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=270511&r1=270510&r2=270511&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt Mon May 23 18:41:13 2016
@@ -5,6 +5,7 @@ add_llvm_library(LLVMDebugInfoCodeView
   MemoryTypeTableBuilder.cpp
   MethodListRecordBuilder.cpp
   RecordSerialization.cpp
+  SymbolDumper.cpp
   TypeDumper.cpp
   TypeRecord.cpp
   TypeRecordBuilder.cpp

Added: llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp?rev=270511&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp (added)
+++ llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp Mon May 23 18:41:13 2016
@@ -0,0 +1,670 @@
+//===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- 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/SymbolDumper.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
+#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeDumper.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+#include <system_error>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+static const EnumEntry<SymbolKind> SymbolTypeNames[] = {
+#define CV_SYMBOL(enum, val) {#enum, enum},
+#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+};
+
+namespace {
+#define CV_ENUM_CLASS_ENT(enum_class, enum)                                    \
+  { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
+
+#define CV_ENUM_ENT(ns, enum)                                                  \
+  { #enum, ns::enum }
+
+static const EnumEntry<uint8_t> ProcSymFlagNames[] = {
+    CV_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
+    CV_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
+    CV_ENUM_CLASS_ENT(ProcSymFlags, HasFRET),
+    CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn),
+    CV_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable),
+    CV_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv),
+    CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline),
+    CV_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
+};
+
+static const EnumEntry<uint16_t> LocalFlags[] = {
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
+    CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
+};
+
+static const EnumEntry<uint32_t> FrameCookieKinds[] = {
+    CV_ENUM_CLASS_ENT(FrameCookieKind, Copy),
+    CV_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
+    CV_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
+    CV_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
+};
+
+static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
+    CV_ENUM_ENT(SourceLanguage, C),       CV_ENUM_ENT(SourceLanguage, Cpp),
+    CV_ENUM_ENT(SourceLanguage, Fortran), CV_ENUM_ENT(SourceLanguage, Masm),
+    CV_ENUM_ENT(SourceLanguage, Pascal),  CV_ENUM_ENT(SourceLanguage, Basic),
+    CV_ENUM_ENT(SourceLanguage, Cobol),   CV_ENUM_ENT(SourceLanguage, Link),
+    CV_ENUM_ENT(SourceLanguage, Cvtres),  CV_ENUM_ENT(SourceLanguage, Cvtpgd),
+    CV_ENUM_ENT(SourceLanguage, CSharp),  CV_ENUM_ENT(SourceLanguage, VB),
+    CV_ENUM_ENT(SourceLanguage, ILAsm),   CV_ENUM_ENT(SourceLanguage, Java),
+    CV_ENUM_ENT(SourceLanguage, JScript), CV_ENUM_ENT(SourceLanguage, MSIL),
+    CV_ENUM_ENT(SourceLanguage, HLSL),
+};
+
+static const EnumEntry<uint32_t> CompileSym3FlagNames[] = {
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, EC),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
+    CV_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
+};
+
+static const EnumEntry<unsigned> CPUTypeNames[] = {
+    CV_ENUM_CLASS_ENT(CPUType, Intel8080),
+    CV_ENUM_CLASS_ENT(CPUType, Intel8086),
+    CV_ENUM_CLASS_ENT(CPUType, Intel80286),
+    CV_ENUM_CLASS_ENT(CPUType, Intel80386),
+    CV_ENUM_CLASS_ENT(CPUType, Intel80486),
+    CV_ENUM_CLASS_ENT(CPUType, Pentium),
+    CV_ENUM_CLASS_ENT(CPUType, PentiumPro),
+    CV_ENUM_CLASS_ENT(CPUType, Pentium3),
+    CV_ENUM_CLASS_ENT(CPUType, MIPS),
+    CV_ENUM_CLASS_ENT(CPUType, MIPS16),
+    CV_ENUM_CLASS_ENT(CPUType, MIPS32),
+    CV_ENUM_CLASS_ENT(CPUType, MIPS64),
+    CV_ENUM_CLASS_ENT(CPUType, MIPSI),
+    CV_ENUM_CLASS_ENT(CPUType, MIPSII),
+    CV_ENUM_CLASS_ENT(CPUType, MIPSIII),
+    CV_ENUM_CLASS_ENT(CPUType, MIPSIV),
+    CV_ENUM_CLASS_ENT(CPUType, MIPSV),
+    CV_ENUM_CLASS_ENT(CPUType, M68000),
+    CV_ENUM_CLASS_ENT(CPUType, M68010),
+    CV_ENUM_CLASS_ENT(CPUType, M68020),
+    CV_ENUM_CLASS_ENT(CPUType, M68030),
+    CV_ENUM_CLASS_ENT(CPUType, M68040),
+    CV_ENUM_CLASS_ENT(CPUType, Alpha),
+    CV_ENUM_CLASS_ENT(CPUType, Alpha21164),
+    CV_ENUM_CLASS_ENT(CPUType, Alpha21164A),
+    CV_ENUM_CLASS_ENT(CPUType, Alpha21264),
+    CV_ENUM_CLASS_ENT(CPUType, Alpha21364),
+    CV_ENUM_CLASS_ENT(CPUType, PPC601),
+    CV_ENUM_CLASS_ENT(CPUType, PPC603),
+    CV_ENUM_CLASS_ENT(CPUType, PPC604),
+    CV_ENUM_CLASS_ENT(CPUType, PPC620),
+    CV_ENUM_CLASS_ENT(CPUType, PPCFP),
+    CV_ENUM_CLASS_ENT(CPUType, PPCBE),
+    CV_ENUM_CLASS_ENT(CPUType, SH3),
+    CV_ENUM_CLASS_ENT(CPUType, SH3E),
+    CV_ENUM_CLASS_ENT(CPUType, SH3DSP),
+    CV_ENUM_CLASS_ENT(CPUType, SH4),
+    CV_ENUM_CLASS_ENT(CPUType, SHMedia),
+    CV_ENUM_CLASS_ENT(CPUType, ARM3),
+    CV_ENUM_CLASS_ENT(CPUType, ARM4),
+    CV_ENUM_CLASS_ENT(CPUType, ARM4T),
+    CV_ENUM_CLASS_ENT(CPUType, ARM5),
+    CV_ENUM_CLASS_ENT(CPUType, ARM5T),
+    CV_ENUM_CLASS_ENT(CPUType, ARM6),
+    CV_ENUM_CLASS_ENT(CPUType, ARM_XMAC),
+    CV_ENUM_CLASS_ENT(CPUType, ARM_WMMX),
+    CV_ENUM_CLASS_ENT(CPUType, ARM7),
+    CV_ENUM_CLASS_ENT(CPUType, Omni),
+    CV_ENUM_CLASS_ENT(CPUType, Ia64),
+    CV_ENUM_CLASS_ENT(CPUType, Ia64_2),
+    CV_ENUM_CLASS_ENT(CPUType, CEE),
+    CV_ENUM_CLASS_ENT(CPUType, AM33),
+    CV_ENUM_CLASS_ENT(CPUType, M32R),
+    CV_ENUM_CLASS_ENT(CPUType, TriCore),
+    CV_ENUM_CLASS_ENT(CPUType, X64),
+    CV_ENUM_CLASS_ENT(CPUType, EBC),
+    CV_ENUM_CLASS_ENT(CPUType, Thumb),
+    CV_ENUM_CLASS_ENT(CPUType, ARMNT),
+    CV_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
+};
+
+static const EnumEntry<uint32_t> FrameProcSymFlags[] = {
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasStructuredExceptionHandling),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, AsynchronousExceptionHandling),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, NoStackOrderingForSecurityChecks),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
+    CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
+};
+
+/// Use this private dumper implementation to keep implementation details about
+/// the visitor out of SymbolDumper.h.
+class CVSymbolDumperImpl : public CVSymbolVisitor<CVSymbolDumperImpl> {
+public:
+  CVSymbolDumperImpl(CVSymbolDumper &CVSD, CVTypeDumper &CVTD,
+                     SymbolDumpDelegate *ObjDelegate, ScopedPrinter &W,
+                     bool PrintRecordBytes)
+      : CVSymbolVisitor(ObjDelegate), CVSD(CVSD), CVTD(CVTD),
+        ObjDelegate(ObjDelegate), W(W), PrintRecordBytes(PrintRecordBytes),
+        InFunctionScope(false) {}
+
+/// CVSymbolVisitor overrides.
+#define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
+  void visit##Name(SymbolKind Kind, Name &Record);
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
+
+  void visitSymbolBegin(SymbolKind Kind, ArrayRef<uint8_t> Data);
+  void visitSymbolEnd(SymbolKind Kind, ArrayRef<uint8_t> OriginalSymData);
+  void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data);
+
+private:
+  void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
+                                   uint32_t RelocationOffset);
+  void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
+
+  CVSymbolDumper &CVSD;
+  CVTypeDumper &CVTD;
+  SymbolDumpDelegate *ObjDelegate;
+  ScopedPrinter &W;
+
+  bool PrintRecordBytes;
+  bool InFunctionScope;
+};
+}
+
+void CVSymbolDumperImpl::printLocalVariableAddrRange(
+    const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
+  DictScope S(W, "LocalVariableAddrRange");
+  if (ObjDelegate)
+    ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
+                                     Range.OffsetStart);
+  W.printHex("ISectStart", Range.ISectStart);
+  W.printHex("Range", Range.Range);
+}
+
+void CVSymbolDumperImpl::printLocalVariableAddrGap(
+    ArrayRef<LocalVariableAddrGap> Gaps) {
+  for (auto &Gap : Gaps) {
+    ListScope S(W, "LocalVariableAddrGap");
+    W.printHex("GapStartOffset", Gap.GapStartOffset);
+    W.printHex("Range", Gap.Range);
+  }
+}
+
+void CVSymbolDumperImpl::visitSymbolBegin(SymbolKind Kind,
+                                          ArrayRef<uint8_t> Data) {}
+
+void CVSymbolDumperImpl::visitSymbolEnd(SymbolKind Kind,
+                                        ArrayRef<uint8_t> OriginalSymData) {
+  if (PrintRecordBytes && ObjDelegate)
+    ObjDelegate->printBinaryBlockWithRelocs("SymData", OriginalSymData);
+}
+
+void CVSymbolDumperImpl::visitBlockSym(SymbolKind Kind, BlockSym &Block) {
+  DictScope S(W, "BlockStart");
+
+  StringRef LinkageName;
+  W.printHex("PtrParent", Block.Header.PtrParent);
+  W.printHex("PtrEnd", Block.Header.PtrEnd);
+  W.printHex("CodeSize", Block.Header.CodeSize);
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
+                                     Block.Header.CodeOffset, &LinkageName);
+  }
+  W.printHex("Segment", Block.Header.Segment);
+  W.printString("BlockName", Block.Name);
+  W.printString("LinkageName", LinkageName);
+}
+
+void CVSymbolDumperImpl::visitBPRelativeSym(SymbolKind Kind,
+                                            BPRelativeSym &BPRel) {
+  DictScope S(W, "BPRelativeSym");
+
+  W.printNumber("Offset", BPRel.Header.Offset);
+  CVTD.printTypeIndex("Type", BPRel.Header.Type);
+  W.printString("VarName", BPRel.Name);
+}
+
+void CVSymbolDumperImpl::visitBuildInfoSym(SymbolKind Kind,
+                                           BuildInfoSym &BuildInfo) {
+  DictScope S(W, "BuildInfo");
+
+  W.printNumber("BuildId", BuildInfo.Header.BuildId);
+}
+
+void CVSymbolDumperImpl::visitCallSiteInfoSym(SymbolKind Kind,
+                                              CallSiteInfoSym &CallSiteInfo) {
+  DictScope S(W, "CallSiteInfo");
+
+  StringRef LinkageName;
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField(
+        "CodeOffset", CallSiteInfo.getRelocationOffset(),
+        CallSiteInfo.Header.CodeOffset, &LinkageName);
+  }
+  W.printHex("Segment", CallSiteInfo.Header.Segment);
+  W.printHex("Reserved", CallSiteInfo.Header.Reserved);
+  CVTD.printTypeIndex("Type", CallSiteInfo.Header.Type);
+  if (!LinkageName.empty())
+    W.printString("LinkageName", LinkageName);
+}
+
+void CVSymbolDumperImpl::visitCompile3Sym(SymbolKind Kind,
+                                          Compile3Sym &Compile3) {
+  DictScope S(W, "CompilerFlags");
+
+  W.printEnum("Language", Compile3.Header.getLanguage(),
+              makeArrayRef(SourceLanguages));
+  W.printFlags("Flags", Compile3.Header.flags & ~0xff,
+               makeArrayRef(CompileSym3FlagNames));
+  W.printEnum("Machine", unsigned(Compile3.Header.Machine),
+              makeArrayRef(CPUTypeNames));
+  std::string FrontendVersion;
+  {
+    raw_string_ostream Out(FrontendVersion);
+    Out << Compile3.Header.VersionFrontendMajor << '.'
+        << Compile3.Header.VersionFrontendMinor << '.'
+        << Compile3.Header.VersionFrontendBuild << '.'
+        << Compile3.Header.VersionFrontendQFE;
+  }
+  std::string BackendVersion;
+  {
+    raw_string_ostream Out(BackendVersion);
+    Out << Compile3.Header.VersionBackendMajor << '.'
+        << Compile3.Header.VersionBackendMinor << '.'
+        << Compile3.Header.VersionBackendBuild << '.'
+        << Compile3.Header.VersionBackendQFE;
+  }
+  W.printString("FrontendVersion", FrontendVersion);
+  W.printString("BackendVersion", BackendVersion);
+  W.printString("VersionName", Compile3.Version);
+}
+
+void CVSymbolDumperImpl::visitConstantSym(SymbolKind Kind,
+                                          ConstantSym &Constant) {
+  DictScope S(W, "Constant");
+
+  CVTD.printTypeIndex("Type", Constant.Header.Type);
+  W.printNumber("Value", Constant.Value);
+  W.printString("Name", Constant.Name);
+}
+
+void CVSymbolDumperImpl::visitDataSym(SymbolKind Kind, DataSym &Data) {
+  DictScope S(W, "DataSym");
+
+  StringRef LinkageName;
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
+                                     Data.Header.DataOffset, &LinkageName);
+  }
+  CVTD.printTypeIndex("Type", Data.Header.Type);
+  W.printString("DisplayName", Data.Name);
+  if (!LinkageName.empty())
+    W.printString("LinkageName", LinkageName);
+}
+
+void CVSymbolDumperImpl::visitDefRangeFramePointerRelFullScopeSym(
+    SymbolKind Kind,
+    DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
+  DictScope S(W, "DefRangeFramePointerRelFullScope");
+  W.printNumber("Offset", DefRangeFramePointerRelFullScope.Header.Offset);
+}
+
+void CVSymbolDumperImpl::visitDefRangeFramePointerRelSym(
+    SymbolKind Kind, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
+  DictScope S(W, "DefRangeFramePointerRel");
+
+  W.printNumber("Offset", DefRangeFramePointerRel.Header.Offset);
+  printLocalVariableAddrRange(DefRangeFramePointerRel.Header.Range,
+                              DefRangeFramePointerRel.getRelocationOffset());
+  printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
+}
+
+void CVSymbolDumperImpl::visitDefRangeRegisterRelSym(
+    SymbolKind Kind, DefRangeRegisterRelSym &DefRangeRegisterRel) {
+  DictScope S(W, "DefRangeRegisterRel");
+
+  W.printNumber("BaseRegister", DefRangeRegisterRel.Header.BaseRegister);
+  W.printBoolean("HasSpilledUDTMember",
+                 DefRangeRegisterRel.hasSpilledUDTMember());
+  W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
+  W.printNumber("BasePointerOffset",
+                DefRangeRegisterRel.Header.BasePointerOffset);
+  printLocalVariableAddrRange(DefRangeRegisterRel.Header.Range,
+                              DefRangeRegisterRel.getRelocationOffset());
+  printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
+}
+
+void CVSymbolDumperImpl::visitDefRangeRegisterSym(
+    SymbolKind Kind, DefRangeRegisterSym &DefRangeRegister) {
+  DictScope S(W, "DefRangeRegister");
+
+  W.printNumber("Register", DefRangeRegister.Header.Register);
+  W.printNumber("MayHaveNoName", DefRangeRegister.Header.MayHaveNoName);
+  printLocalVariableAddrRange(DefRangeRegister.Header.Range,
+                              DefRangeRegister.getRelocationOffset());
+  printLocalVariableAddrGap(DefRangeRegister.Gaps);
+}
+
+void CVSymbolDumperImpl::visitDefRangeSubfieldRegisterSym(
+    SymbolKind Kind, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
+  DictScope S(W, "DefRangeSubfieldRegister");
+
+  W.printNumber("Register", DefRangeSubfieldRegister.Header.Register);
+  W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Header.MayHaveNoName);
+  W.printNumber("OffsetInParent",
+                DefRangeSubfieldRegister.Header.OffsetInParent);
+  printLocalVariableAddrRange(DefRangeSubfieldRegister.Header.Range,
+                              DefRangeSubfieldRegister.getRelocationOffset());
+  printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
+}
+
+void CVSymbolDumperImpl::visitDefRangeSubfieldSym(
+    SymbolKind Kind, DefRangeSubfieldSym &DefRangeSubfield) {
+  DictScope S(W, "DefRangeSubfield");
+
+  if (ObjDelegate) {
+    StringRef StringTable = ObjDelegate->getStringTable();
+    if (!StringTable.empty()) {
+      W.printString("Program",
+                    StringTable.drop_front(DefRangeSubfield.Header.Program)
+                        .split('\0')
+                        .first);
+    }
+  }
+  W.printNumber("OffsetInParent", DefRangeSubfield.Header.OffsetInParent);
+  printLocalVariableAddrRange(DefRangeSubfield.Header.Range,
+                              DefRangeSubfield.getRelocationOffset());
+  printLocalVariableAddrGap(DefRangeSubfield.Gaps);
+}
+
+void CVSymbolDumperImpl::visitDefRangeSym(SymbolKind Kind,
+                                          DefRangeSym &DefRange) {
+  DictScope S(W, "DefRange");
+
+  if (ObjDelegate) {
+    StringRef StringTable = ObjDelegate->getStringTable();
+    if (!StringTable.empty()) {
+      W.printString(
+          "Program",
+          StringTable.drop_front(DefRange.Header.Program).split('\0').first);
+    }
+  }
+  printLocalVariableAddrRange(DefRange.Header.Range,
+                              DefRange.getRelocationOffset());
+  printLocalVariableAddrGap(DefRange.Gaps);
+}
+
+void CVSymbolDumperImpl::visitFrameCookieSym(SymbolKind Kind,
+                                             FrameCookieSym &FrameCookie) {
+  DictScope S(W, "FrameCookie");
+
+  StringRef LinkageName;
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField(
+        "CodeOffset", FrameCookie.getRelocationOffset(),
+        FrameCookie.Header.CodeOffset, &LinkageName);
+  }
+  W.printHex("Register", FrameCookie.Header.Register);
+  W.printEnum("CookieKind", uint16_t(FrameCookie.Header.CookieKind),
+              makeArrayRef(FrameCookieKinds));
+}
+
+void CVSymbolDumperImpl::visitFrameProcSym(SymbolKind Kind,
+                                           FrameProcSym &FrameProc) {
+  DictScope S(W, "FrameProc");
+
+  W.printHex("TotalFrameBytes", FrameProc.Header.TotalFrameBytes);
+  W.printHex("PaddingFrameBytes", FrameProc.Header.PaddingFrameBytes);
+  W.printHex("OffsetToPadding", FrameProc.Header.OffsetToPadding);
+  W.printHex("BytesOfCalleeSavedRegisters",
+             FrameProc.Header.BytesOfCalleeSavedRegisters);
+  W.printHex("OffsetOfExceptionHandler",
+             FrameProc.Header.OffsetOfExceptionHandler);
+  W.printHex("SectionIdOfExceptionHandler",
+             FrameProc.Header.SectionIdOfExceptionHandler);
+  W.printFlags("Flags", FrameProc.Header.Flags,
+               makeArrayRef(FrameProcSymFlags));
+}
+
+void CVSymbolDumperImpl::visitHeapAllocationSiteSym(
+    SymbolKind Kind, HeapAllocationSiteSym &HeapAllocSite) {
+  DictScope S(W, "HeapAllocationSite");
+
+  StringRef LinkageName;
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField(
+        "CodeOffset", HeapAllocSite.getRelocationOffset(),
+        HeapAllocSite.Header.CodeOffset, &LinkageName);
+  }
+  W.printHex("Segment", HeapAllocSite.Header.Segment);
+  W.printHex("CallInstructionSize", HeapAllocSite.Header.CallInstructionSize);
+  CVTD.printTypeIndex("Type", HeapAllocSite.Header.Type);
+  if (!LinkageName.empty())
+    W.printString("LinkageName", LinkageName);
+}
+
+void CVSymbolDumperImpl::visitInlineSiteSym(SymbolKind Kind,
+                                            InlineSiteSym &InlineSite) {
+  DictScope S(W, "InlineSite");
+
+  W.printHex("PtrParent", InlineSite.Header.PtrParent);
+  W.printHex("PtrEnd", InlineSite.Header.PtrEnd);
+  CVTD.printTypeIndex("Inlinee", InlineSite.Header.Inlinee);
+
+  ListScope BinaryAnnotations(W, "BinaryAnnotations");
+  for (auto &Annotation : InlineSite.annotations()) {
+    switch (Annotation.OpCode) {
+    case BinaryAnnotationsOpCode::Invalid:
+      return parseError();
+    case BinaryAnnotationsOpCode::CodeOffset:
+    case BinaryAnnotationsOpCode::ChangeCodeOffset:
+    case BinaryAnnotationsOpCode::ChangeCodeLength:
+      W.printHex(Annotation.Name, Annotation.U1);
+      break;
+    case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
+    case BinaryAnnotationsOpCode::ChangeLineEndDelta:
+    case BinaryAnnotationsOpCode::ChangeRangeKind:
+    case BinaryAnnotationsOpCode::ChangeColumnStart:
+    case BinaryAnnotationsOpCode::ChangeColumnEnd:
+      W.printNumber(Annotation.Name, Annotation.U1);
+      break;
+    case BinaryAnnotationsOpCode::ChangeLineOffset:
+    case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
+      W.printNumber(Annotation.Name, Annotation.S1);
+      break;
+    case BinaryAnnotationsOpCode::ChangeFile:
+      if (ObjDelegate) {
+        W.printHex("ChangeFile",
+                   ObjDelegate->getFileNameForFileOffset(Annotation.U1),
+                   Annotation.U1);
+      } else {
+        W.printHex("ChangeFile", Annotation.U1);
+      }
+
+      break;
+    case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
+      W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
+                    << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
+                    << "}\n";
+      break;
+    }
+    case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
+      W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
+                    << W.hex(Annotation.U2)
+                    << ", Length: " << W.hex(Annotation.U1) << "}\n";
+      break;
+    }
+    }
+  }
+}
+
+void CVSymbolDumperImpl::visitLabelSym(SymbolKind Kind, LabelSym &Label) {
+  DictScope S(W, "Label");
+
+  StringRef LinkageName;
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
+                                     Label.Header.CodeOffset, &LinkageName);
+  }
+  W.printHex("Segment", Label.Header.Segment);
+  W.printHex("Flags", Label.Header.Flags);
+  W.printFlags("Flags", Label.Header.Flags, makeArrayRef(ProcSymFlagNames));
+  W.printString("DisplayName", Label.Name);
+  if (!LinkageName.empty())
+    W.printString("LinkageName", LinkageName);
+}
+
+void CVSymbolDumperImpl::visitLocalSym(SymbolKind Kind, LocalSym &Local) {
+  DictScope S(W, "Local");
+
+  CVTD.printTypeIndex("Type", Local.Header.Type);
+  W.printFlags("Flags", uint16_t(Local.Header.Flags), makeArrayRef(LocalFlags));
+  W.printString("VarName", Local.Name);
+}
+
+void CVSymbolDumperImpl::visitObjNameSym(SymbolKind Kind, ObjNameSym &ObjName) {
+  DictScope S(W, "ObjectName");
+
+  W.printHex("Signature", ObjName.Header.Signature);
+  W.printString("ObjectName", ObjName.Name);
+}
+
+void CVSymbolDumperImpl::visitProcSym(SymbolKind Kind, ProcSym &Proc) {
+  DictScope S(W, "ProcStart");
+
+  if (InFunctionScope)
+    return parseError();
+
+  InFunctionScope = true;
+
+  StringRef LinkageName;
+  W.printHex("PtrParent", Proc.Header.PtrParent);
+  W.printHex("PtrEnd", Proc.Header.PtrEnd);
+  W.printHex("PtrNext", Proc.Header.PtrNext);
+  W.printHex("CodeSize", Proc.Header.CodeSize);
+  W.printHex("DbgStart", Proc.Header.DbgStart);
+  W.printHex("DbgEnd", Proc.Header.DbgEnd);
+  CVTD.printTypeIndex("FunctionType", Proc.Header.FunctionType);
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
+                                     Proc.Header.CodeOffset, &LinkageName);
+  }
+  W.printHex("Segment", Proc.Header.Segment);
+  W.printFlags("Flags", static_cast<uint8_t>(Proc.Header.Flags),
+               makeArrayRef(ProcSymFlagNames));
+  W.printString("DisplayName", Proc.Name);
+  if (!LinkageName.empty())
+    W.printString("LinkageName", LinkageName);
+}
+
+void CVSymbolDumperImpl::visitScopeEndSym(SymbolKind Kind,
+                                          ScopeEndSym &ScopeEnd) {
+  if (Kind == SymbolKind::S_END)
+    W.startLine() << "BlockEnd\n";
+  else if (Kind == SymbolKind::S_PROC_ID_END)
+    W.startLine() << "ProcEnd\n";
+  else if (Kind == SymbolKind::S_INLINESITE_END)
+    DictScope S(W, "InlineSiteEnd");
+
+  InFunctionScope = false;
+}
+
+void CVSymbolDumperImpl::visitCallerSym(SymbolKind Kind, CallerSym &Caller) {
+  ListScope S(W, Kind == S_CALLEES ? "Callees" : "Callers");
+  for (auto FuncID : Caller.Indices)
+    CVTD.printTypeIndex("FuncID", FuncID);
+}
+
+void CVSymbolDumperImpl::visitRegRelativeSym(SymbolKind Kind,
+                                             RegRelativeSym &RegRel) {
+  DictScope S(W, "RegRelativeSym");
+
+  W.printHex("Offset", RegRel.Header.Offset);
+  CVTD.printTypeIndex("Type", RegRel.Header.Type);
+  W.printHex("Register", RegRel.Header.Register);
+  W.printString("VarName", RegRel.Name);
+}
+
+void CVSymbolDumperImpl::visitThreadLocalDataSym(SymbolKind Kind,
+                                                 ThreadLocalDataSym &Data) {
+  DictScope S(W, "ThreadLocalDataSym");
+
+  StringRef LinkageName;
+  if (ObjDelegate) {
+    ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
+                                     Data.Header.DataOffset, &LinkageName);
+  }
+  CVTD.printTypeIndex("Type", Data.Header.Type);
+  W.printString("DisplayName", Data.Name);
+  if (!LinkageName.empty())
+    W.printString("LinkageName", LinkageName);
+}
+
+void CVSymbolDumperImpl::visitUDTSym(SymbolKind Kind, UDTSym &UDT) {
+  DictScope S(W, "UDT");
+  CVTD.printTypeIndex("Type", UDT.Header.Type);
+  W.printString("UDTName", UDT.Name);
+}
+
+void CVSymbolDumperImpl::visitUnknownSymbol(SymbolKind Kind,
+                                            ArrayRef<uint8_t> Data) {
+  DictScope S(W, "UnknownSym");
+  W.printHex("Kind", unsigned(Kind));
+  W.printHex("Size", Data.size());
+}
+
+bool CVSymbolDumper::dump(const SymbolIterator::Record &Record) {
+  CVSymbolDumperImpl Dumper(*this, CVTD, ObjDelegate.get(), W,
+                            PrintRecordBytes);
+  Dumper.visitSymbolRecord(Record);
+  return !Dumper.hadError();
+}
+
+bool CVSymbolDumper::dump(ArrayRef<uint8_t> Data) {
+  CVSymbolDumperImpl Dumper(*this, CVTD, ObjDelegate.get(), W,
+                            PrintRecordBytes);
+  Dumper.visitSymbolStream(Data);
+  return !Dumper.hadError();
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp?rev=270511&r1=270510&r2=270511&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp Mon May 23 18:41:13 2016
@@ -51,5 +51,5 @@ Error ModStream::reload() {
 }
 
 iterator_range<codeview::SymbolIterator> ModStream::symbols() const {
-  return codeview::makeSymbolRange(SymbolsSubstream.data().slice(4));
+  return codeview::makeSymbolRange(SymbolsSubstream.data().slice(4), nullptr);
 }

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=270511&r1=270510&r2=270511&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Mon May 23 18:41:13 2016
@@ -24,8 +24,10 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
 #include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
+#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeDumper.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
@@ -58,6 +60,7 @@ namespace {
 
 class COFFDumper : public ObjDumper {
 public:
+  friend class COFFObjectDumpDelegate;
   COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer)
       : ObjDumper(Writer), Obj(Obj),
         CVTD(Writer, opts::CodeViewSubsectionBytes) {}
@@ -96,10 +99,6 @@ private:
     // Forward to CVTypeDumper for simplicity.
     CVTD.printTypeIndex(FieldName, TI);
   }
-  void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
-                                   const coff_section *Sec,
-                                   uint32_t RelocationOffset);
-  void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
 
   void printCodeViewSymbolsSubsection(StringRef Subsection,
                                       const SectionRef &Section,
@@ -148,6 +147,45 @@ private:
   CVTypeDumper CVTD;
 };
 
+class COFFObjectDumpDelegate : public SymbolDumpDelegate {
+public:
+  COFFObjectDumpDelegate(COFFDumper &CD, const SectionRef &SR,
+                         const COFFObjectFile *Obj, StringRef SectionContents)
+      : CD(CD), SR(SR), Obj(Obj), SectionContents(SectionContents) {
+    Sec = Obj->getCOFFSection(SR);
+  }
+
+  uint32_t getRecordOffset(ArrayRef<uint8_t> Record) override {
+    return Record.data() - SectionContents.bytes_begin();
+  }
+
+  void printRelocatedField(StringRef Label, uint32_t RelocOffset,
+                           uint32_t Offset, StringRef *RelocSym) override {
+    CD.printRelocatedField(Label, Sec, RelocOffset, Offset, RelocSym);
+  }
+
+  void printBinaryBlockWithRelocs(StringRef Label,
+                                  ArrayRef<uint8_t> Block) override {
+    StringRef SBlock(reinterpret_cast<const char *>(Block.data()),
+                     Block.size());
+    if (opts::CodeViewSubsectionBytes)
+      CD.printBinaryBlockWithRelocs(Label, SR, SectionContents, SBlock);
+  }
+
+  StringRef getFileNameForFileOffset(uint32_t FileOffset) override {
+    return CD.getFileNameForFileOffset(FileOffset);
+  }
+
+  StringRef getStringTable() override { return CD.CVStringTable; }
+
+private:
+  COFFDumper &CD;
+  const SectionRef &SR;
+  const COFFObjectFile *Obj;
+  const coff_section *Sec;
+  StringRef SectionContents;
+};
+
 } // end namespace
 
 namespace llvm {
@@ -246,6 +284,7 @@ void COFFDumper::printBinaryBlockWithRel
   uint64_t OffsetStart = Block.data() - SectionContents.data();
   uint64_t OffsetEnd = OffsetStart + Block.size();
 
+  W.flush();
   cacheRelocations();
   ListScope D(W, "BlockRelocations");
   const coff_section *Section = Obj->getCOFFSection(Sec);
@@ -440,41 +479,6 @@ WeakExternalCharacteristics[] = {
   { "Alias"    , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS     }
 };
 
-static const EnumEntry<uint32_t> CompileSym3FlagNames[] = {
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, EC),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
-    LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
-};
-
-static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, C),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cpp),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Fortran),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Masm),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Pascal),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Basic),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cobol),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Link),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cvtres),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cvtpgd),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, CSharp),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, VB),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, ILAsm),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, Java),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, JScript),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, MSIL),
-    LLVM_READOBJ_ENUM_ENT(SourceLanguage, HLSL),
-};
-
 static const EnumEntry<uint32_t> SubSectionTypes[] = {
   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Symbols),
   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Lines),
@@ -491,68 +495,6 @@ static const EnumEntry<uint32_t> SubSect
   LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CoffSymbolRVA),
 };
 
-static const EnumEntry<unsigned> CPUTypeNames[] = {
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel8080),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel8086),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80286),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80386),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80486),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Pentium),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PentiumPro),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Pentium3),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS16),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS32),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS64),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSI),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSII),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSIII),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSIV),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSV),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68000),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68010),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68020),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68030),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68040),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21164),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21164A),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21264),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21364),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC601),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC603),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC604),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC620),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPCFP),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPCBE),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3E),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3DSP),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH4),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SHMedia),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM3),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM4),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM4T),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM5),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM5T),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM6),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM_XMAC),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM_WMMX),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM7),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Omni),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Ia64),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Ia64_2),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, CEE),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, AM33),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M32R),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, TriCore),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, X64),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, EBC),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Thumb),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARMNT),
-  LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
-};
-
 static const EnumEntry<uint8_t> ProcSymFlagNames[] = {
     LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
     LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
@@ -564,59 +506,12 @@ static const EnumEntry<uint8_t> ProcSymF
     LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
 };
 
-static const EnumEntry<uint32_t> FrameProcSymFlags[] = {
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
-                                HasStructuredExceptionHandling),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
-                                AsynchronousExceptionHandling),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
-                                NoStackOrderingForSecurityChecks),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
-                                ProfileGuidedOptimization),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
-};
-
 static const EnumEntry<uint32_t> FrameDataFlags[] = {
     LLVM_READOBJ_ENUM_ENT(FrameData, HasSEH),
     LLVM_READOBJ_ENUM_ENT(FrameData, HasEH),
     LLVM_READOBJ_ENUM_ENT(FrameData, IsFunctionStart),
 };
 
-static const EnumEntry<uint16_t> LocalFlags[] = {
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
-    LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
-};
-
-static const EnumEntry<uint32_t> FrameCookieKinds[] = {
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, Copy),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
-    LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
-};
-
 static const EnumEntry<uint8_t> FileChecksumKindNames[] = {
   LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, None),
   LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, MD5),
@@ -1009,574 +904,16 @@ void COFFDumper::printCodeViewSymbolSect
 void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
                                                 const SectionRef &Section,
                                                 StringRef SectionContents) {
-  if (Subsection.size() < sizeof(RecordPrefix))
-    return error(object_error::parse_failed);
-
-  const coff_section *Sec = Obj->getCOFFSection(Section);
-
-  // This holds the remaining data to parse.
-  StringRef Data = Subsection;
-
-  bool InFunctionScope = false;
-  while (!Data.empty()) {
-    const RecordPrefix *Rec;
-    error(consumeObject(Data, Rec));
-
-    StringRef SymData = Data.substr(0, Rec->RecordLen - 2);
-    StringRef OrigSymData = SymData;
-
-    Data = Data.drop_front(Rec->RecordLen - 2);
-    uint32_t RecordOffset = SymData.data() - SectionContents.data();
-
-    SymbolKind Kind = static_cast<SymbolKind>(uint16_t(Rec->RecordKind));
-    switch (Kind) {
-    case S_LPROC32:
-    case S_GPROC32:
-    case S_GPROC32_ID:
-    case S_LPROC32_ID:
-    case S_LPROC32_DPC:
-    case S_LPROC32_DPC_ID: {
-      DictScope S(W, "ProcStart");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto ProcOrError = ProcSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!ProcOrError)
-        error(ProcOrError.getError());
-      auto &Proc = ProcOrError.get();
-
-      if (InFunctionScope)
-        return error(object_error::parse_failed);
-      InFunctionScope = true;
-
-      StringRef LinkageName;
-      W.printHex("PtrParent", Proc.Header.PtrParent);
-      W.printHex("PtrEnd", Proc.Header.PtrEnd);
-      W.printHex("PtrNext", Proc.Header.PtrNext);
-      W.printHex("CodeSize", Proc.Header.CodeSize);
-      W.printHex("DbgStart", Proc.Header.DbgStart);
-      W.printHex("DbgEnd", Proc.Header.DbgEnd);
-      printTypeIndex("FunctionType", Proc.Header.FunctionType);
-      printRelocatedField("CodeOffset", Sec, Proc.getRelocationOffset(),
-                          Proc.Header.CodeOffset, &LinkageName);
-      W.printHex("Segment", Proc.Header.Segment);
-      W.printFlags("Flags", static_cast<uint8_t>(Proc.Header.Flags),
-                   makeArrayRef(ProcSymFlagNames));
-      W.printString("DisplayName", Proc.Name);
-      W.printString("LinkageName", LinkageName);
-      break;
-    }
-
-    case S_PROC_ID_END: {
-      W.startLine() << "ProcEnd\n";
-      InFunctionScope = false;
-      break;
-    }
-
-    case S_BLOCK32: {
-      DictScope S(W, "BlockStart");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto BlockOrError = BlockSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!BlockOrError)
-        error(BlockOrError.getError());
-      auto &Block = BlockOrError.get();
-
-      StringRef LinkageName;
-      W.printHex("PtrParent", Block.Header.PtrParent);
-      W.printHex("PtrEnd", Block.Header.PtrEnd);
-      W.printHex("CodeSize", Block.Header.CodeSize);
-      printRelocatedField("CodeOffset", Sec, Block.getRelocationOffset(),
-                          Block.Header.CodeOffset, &LinkageName);
-      W.printHex("Segment", Block.Header.Segment);
-      W.printString("BlockName", Block.Name);
-      W.printString("LinkageName", LinkageName);
-      break;
-    }
-
-    case S_END: {
-      W.startLine() << "BlockEnd\n";
-      InFunctionScope = false;
-      break;
-    }
-
-    case S_LABEL32: {
-      DictScope S(W, "Label");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto LabelOrError = LabelSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!LabelOrError)
-        error(LabelOrError.getError());
-      auto &Label = LabelOrError.get();
-
-      StringRef LinkageName;
-      printRelocatedField("CodeOffset", Sec, Label.getRelocationOffset(),
-                          Label.Header.CodeOffset, &LinkageName);
-      W.printHex("Segment", Label.Header.Segment);
-      W.printHex("Flags", Label.Header.Flags);
-      W.printFlags("Flags", Label.Header.Flags, makeArrayRef(ProcSymFlagNames));
-      W.printString("DisplayName", Label.Name);
-      W.printString("LinkageName", LinkageName);
-      break;
-    }
-
-    case S_INLINESITE: {
-      DictScope S(W, "InlineSite");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto InlineSiteOrError = InlineSiteSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!InlineSiteOrError)
-        error(InlineSiteOrError.getError());
-      auto &InlineSite = InlineSiteOrError.get();
-
-      W.printHex("PtrParent", InlineSite.Header.PtrParent);
-      W.printHex("PtrEnd", InlineSite.Header.PtrEnd);
-      printTypeIndex("Inlinee", InlineSite.Header.Inlinee);
-
-      ListScope BinaryAnnotations(W, "BinaryAnnotations");
-      for (auto &Annotation : InlineSite.annotations()) {
-        switch (Annotation.OpCode) {
-        case BinaryAnnotationsOpCode::Invalid:
-          return error(object_error::parse_failed);
-        case BinaryAnnotationsOpCode::CodeOffset:
-        case BinaryAnnotationsOpCode::ChangeCodeOffset:
-        case BinaryAnnotationsOpCode::ChangeCodeLength:
-          W.printHex(Annotation.Name, Annotation.U1);
-          break;
-        case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
-        case BinaryAnnotationsOpCode::ChangeLineEndDelta:
-        case BinaryAnnotationsOpCode::ChangeRangeKind:
-        case BinaryAnnotationsOpCode::ChangeColumnStart:
-        case BinaryAnnotationsOpCode::ChangeColumnEnd:
-          W.printNumber(Annotation.Name, Annotation.U1);
-          break;
-        case BinaryAnnotationsOpCode::ChangeLineOffset:
-        case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
-          W.printNumber(Annotation.Name, Annotation.S1);
-          break;
-        case BinaryAnnotationsOpCode::ChangeFile:
-          printFileNameForOffset("ChangeFile", Annotation.U1);
-          break;
-        case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
-          W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
-                        << W.hex(Annotation.U1)
-                        << ", LineOffset: " << Annotation.S1 << "}\n";
-          break;
-        }
-        case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
-          W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
-                        << W.hex(Annotation.U2)
-                        << ", Length: " << W.hex(Annotation.U1) << "}\n";
-          break;
-        }
-        }
-      }
-      break;
-    }
-
-    case S_INLINESITE_END: {
-      DictScope S(W, "InlineSiteEnd");
-      break;
-    }
-
-    case S_CALLERS:
-    case S_CALLEES: {
-      ListScope S(W, Kind == S_CALLEES ? "Callees" : "Callers");
-      uint32_t Count;
-      error(consume(SymData, Count));
-      for (uint32_t I = 0; I < Count; ++I) {
-        const TypeIndex *FuncID;
-        error(consumeObject(SymData, FuncID));
-        printTypeIndex("FuncID", *FuncID);
-      }
-      break;
-    }
-
-    case S_LOCAL: {
-      DictScope S(W, "Local");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto LocalOrError = LocalSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!LocalOrError)
-        error(LocalOrError.getError());
-      auto &Local = LocalOrError.get();
-
-      printTypeIndex("Type", Local.Header.Type);
-      W.printFlags("Flags", uint16_t(Local.Header.Flags),
-                   makeArrayRef(LocalFlags));
-      W.printString("VarName", Local.Name);
-      break;
-    }
-
-    case S_DEFRANGE: {
-      DictScope S(W, "DefRange");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto DefRangeOrError = DefRangeSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!DefRangeOrError)
-        error(DefRangeOrError.getError());
-      auto &DefRange = DefRangeOrError.get();
-
-      W.printString(
-          "Program",
-          CVStringTable.drop_front(DefRange.Header.Program).split('\0').first);
-      printLocalVariableAddrRange(DefRange.Header.Range, Sec,
-                                  DefRange.getRelocationOffset());
-      printLocalVariableAddrGap(DefRange.Gaps);
-      break;
-    }
-    case S_DEFRANGE_SUBFIELD: {
-      DictScope S(W, "DefRangeSubfield");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto DefRangeOrError = DefRangeSubfieldSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!DefRangeOrError)
-        error(DefRangeOrError.getError());
-      auto &DefRangeSubfield = DefRangeOrError.get();
-
-      W.printString("Program",
-                    CVStringTable.drop_front(DefRangeSubfield.Header.Program)
-                        .split('\0')
-                        .first);
-      W.printNumber("OffsetInParent", DefRangeSubfield.Header.OffsetInParent);
-      printLocalVariableAddrRange(DefRangeSubfield.Header.Range, Sec,
-                                  DefRangeSubfield.getRelocationOffset());
-      printLocalVariableAddrGap(DefRangeSubfield.Gaps);
-      break;
-    }
-    case S_DEFRANGE_REGISTER: {
-      DictScope S(W, "DefRangeRegister");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto DefRangeOrError = DefRangeRegisterSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!DefRangeOrError)
-        error(DefRangeOrError.getError());
-      auto &DefRangeRegisterSym = DefRangeOrError.get();
-
-      W.printNumber("Register", DefRangeRegisterSym.Header.Register);
-      W.printNumber("MayHaveNoName", DefRangeRegisterSym.Header.MayHaveNoName);
-      printLocalVariableAddrRange(DefRangeRegisterSym.Header.Range, Sec,
-                                  DefRangeRegisterSym.getRelocationOffset());
-      printLocalVariableAddrGap(DefRangeRegisterSym.Gaps);
-      break;
-    }
-    case S_DEFRANGE_SUBFIELD_REGISTER: {
-      DictScope S(W, "DefRangeSubfieldRegister");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto DefRangeOrError = DefRangeSubfieldRegisterSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!DefRangeOrError)
-        error(DefRangeOrError.getError());
-      auto &DefRangeSubfieldRegister = DefRangeOrError.get();
-      W.printNumber("Register", DefRangeSubfieldRegister.Header.Register);
-      W.printNumber("MayHaveNoName",
-                    DefRangeSubfieldRegister.Header.MayHaveNoName);
-      W.printNumber("OffsetInParent",
-                    DefRangeSubfieldRegister.Header.OffsetInParent);
-      printLocalVariableAddrRange(
-          DefRangeSubfieldRegister.Header.Range, Sec,
-          DefRangeSubfieldRegister.getRelocationOffset());
-      printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
-      break;
-    }
-    case S_DEFRANGE_FRAMEPOINTER_REL: {
-      DictScope S(W, "DefRangeFramePointerRel");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto DefRangeOrError = DefRangeFramePointerRelSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!DefRangeOrError)
-        error(DefRangeOrError.getError());
-      auto &DefRangeFramePointerRel = DefRangeOrError.get();
-      W.printNumber("Offset", DefRangeFramePointerRel.Header.Offset);
-      printLocalVariableAddrRange(
-          DefRangeFramePointerRel.Header.Range, Sec,
-          DefRangeFramePointerRel.getRelocationOffset());
-      printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
-      break;
-    }
-    case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: {
-      DictScope S(W, "DefRangeFramePointerRelFullScope");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto DefRangeOrError = DefRangeFramePointerRelFullScopeSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!DefRangeOrError)
-        error(DefRangeOrError.getError());
-      auto &DefRangeFramePointerRelFullScope = DefRangeOrError.get();
-      W.printNumber("Offset", DefRangeFramePointerRelFullScope.Header.Offset);
-      break;
-    }
-    case S_DEFRANGE_REGISTER_REL: {
-      DictScope S(W, "DefRangeRegisterRel");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto DefRangeOrError = DefRangeRegisterRelSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!DefRangeOrError)
-        error(DefRangeOrError.getError());
-      auto &DefRangeRegisterRel = DefRangeOrError.get();
-
-      W.printNumber("BaseRegister", DefRangeRegisterRel.Header.BaseRegister);
-      W.printBoolean("HasSpilledUDTMember",
-                     DefRangeRegisterRel.hasSpilledUDTMember());
-      W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
-      W.printNumber("BasePointerOffset",
-                    DefRangeRegisterRel.Header.BasePointerOffset);
-      printLocalVariableAddrRange(DefRangeRegisterRel.Header.Range, Sec,
-                                  DefRangeRegisterRel.getRelocationOffset());
-      printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
-      break;
-    }
-
-    case S_CALLSITEINFO: {
-      DictScope S(W, "CallSiteInfo");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto CallSiteOrError = CallSiteInfoSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!CallSiteOrError)
-        error(CallSiteOrError.getError());
-      auto &CallSiteInfo = CallSiteOrError.get();
-
-      StringRef LinkageName;
-      printRelocatedField("CodeOffset", Sec, CallSiteInfo.getRelocationOffset(),
-                          CallSiteInfo.Header.CodeOffset, &LinkageName);
-      W.printHex("Segment", CallSiteInfo.Header.Segment);
-      W.printHex("Reserved", CallSiteInfo.Header.Reserved);
-      printTypeIndex("Type", CallSiteInfo.Header.Type);
-      W.printString("LinkageName", LinkageName);
-      break;
-    }
-
-    case S_HEAPALLOCSITE: {
-      DictScope S(W, "HeapAllocationSite");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto HeapAllocSiteOrError = HeapAllocationSiteSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!HeapAllocSiteOrError)
-        error(HeapAllocSiteOrError.getError());
-      auto &HeapAllocSite = HeapAllocSiteOrError.get();
-
-      StringRef LinkageName;
-      printRelocatedField("CodeOffset", Sec,
-                          HeapAllocSite.getRelocationOffset(),
-                          HeapAllocSite.Header.CodeOffset, &LinkageName);
-      W.printHex("Segment", HeapAllocSite.Header.Segment);
-      W.printHex("CallInstructionSize",
-                 HeapAllocSite.Header.CallInstructionSize);
-      printTypeIndex("Type", HeapAllocSite.Header.Type);
-      W.printString("LinkageName", LinkageName);
-      break;
-    }
-
-    case S_FRAMECOOKIE: {
-      DictScope S(W, "FrameCookie");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto FrameCookieOrError = FrameCookieSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!FrameCookieOrError)
-        error(FrameCookieOrError.getError());
-      auto &FrameCookie = FrameCookieOrError.get();
-
-      StringRef LinkageName;
-      printRelocatedField("CodeOffset", Sec, FrameCookie.getRelocationOffset(),
-                          FrameCookie.Header.CodeOffset, &LinkageName);
-      W.printHex("Register", FrameCookie.Header.Register);
-      W.printEnum("CookieKind", uint16_t(FrameCookie.Header.CookieKind),
-                  makeArrayRef(FrameCookieKinds));
-      break;
-    }
-
-    case S_LDATA32:
-    case S_GDATA32:
-    case S_LMANDATA:
-    case S_GMANDATA: {
-      DictScope S(W, "DataSym");
-      ArrayRef<uint8_t> SymBytes(SymData.bytes_begin(), SymData.bytes_end());
-      auto DataOrError = DataSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, SymBytes);
-      if (!DataOrError)
-        error(DataOrError.getError());
-      auto &Data = DataOrError.get();
-
-      StringRef LinkageName;
-      printRelocatedField("DataOffset", Sec, Data.getRelocationOffset(),
-                          Data.Header.DataOffset, &LinkageName);
-      printTypeIndex("Type", Data.Header.Type);
-      W.printString("DisplayName", Data.Name);
-      W.printString("LinkageName", LinkageName);
-      break;
-    }
-
-    case S_LTHREAD32:
-    case S_GTHREAD32: {
-      DictScope S(W, "ThreadLocalDataSym");
-      ArrayRef<uint8_t> SymBytes(SymData.bytes_begin(), SymData.bytes_end());
-      auto ThreadLocalDataOrError = ThreadLocalDataSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, SymBytes);
-      if (!ThreadLocalDataOrError)
-        error(ThreadLocalDataOrError.getError());
-      auto &Data = ThreadLocalDataOrError.get();
+  ArrayRef<uint8_t> BinaryData(Subsection.bytes_begin(),
+                               Subsection.bytes_end());
+  auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj,
+                                                        SectionContents);
 
-      StringRef LinkageName;
-      printRelocatedField("DataOffset", Sec, Data.getRelocationOffset(),
-                          Data.Header.DataOffset, &LinkageName);
-      printTypeIndex("Type", Data.Header.Type);
-      W.printString("DisplayName", Data.Name);
-      W.printString("LinkageName", LinkageName);
-      break;
-    }
-
-    case S_OBJNAME: {
-      DictScope S(W, "ObjectName");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto ObjNameOrError = ObjNameSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!ObjNameOrError)
-        error(ObjNameOrError.getError());
-      auto &ObjName = ObjNameOrError.get();
-      W.printHex("Signature", ObjName.Header.Signature);
-      W.printString("ObjectName", ObjName.Name);
-      break;
-    }
-
-    case S_COMPILE3: {
-      DictScope S(W, "CompilerFlags");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto Compile3OrError = CompileSym3::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!Compile3OrError)
-        error(Compile3OrError.getError());
-      auto &Compile3 = Compile3OrError.get();
-
-      W.printEnum("Language", Compile3.Header.getLanguage(),
-                  makeArrayRef(SourceLanguages));
-      W.printFlags("Flags", Compile3.Header.flags & ~0xff,
-                   makeArrayRef(CompileSym3FlagNames));
-      W.printEnum("Machine", unsigned(Compile3.Header.Machine),
-                  makeArrayRef(CPUTypeNames));
-      std::string FrontendVersion;
-      {
-        raw_string_ostream Out(FrontendVersion);
-        Out << Compile3.Header.VersionFrontendMajor << '.'
-            << Compile3.Header.VersionFrontendMinor << '.'
-            << Compile3.Header.VersionFrontendBuild << '.'
-            << Compile3.Header.VersionFrontendQFE;
-      }
-      std::string BackendVersion;
-      {
-        raw_string_ostream Out(BackendVersion);
-        Out << Compile3.Header.VersionBackendMajor << '.'
-            << Compile3.Header.VersionBackendMinor << '.'
-            << Compile3.Header.VersionBackendBuild << '.'
-            << Compile3.Header.VersionBackendQFE;
-      }
-      W.printString("FrontendVersion", FrontendVersion);
-      W.printString("BackendVersion", BackendVersion);
-      W.printString("VersionName", Compile3.Version);
-      break;
-    }
-
-    case S_FRAMEPROC: {
-      DictScope S(W, "FrameProc");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto FrameProcOrError = FrameProcSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!FrameProcOrError)
-        error(FrameProcOrError.getError());
-      auto &FrameProc = FrameProcOrError.get();
-      W.printHex("TotalFrameBytes", FrameProc.Header.TotalFrameBytes);
-      W.printHex("PaddingFrameBytes", FrameProc.Header.PaddingFrameBytes);
-      W.printHex("OffsetToPadding", FrameProc.Header.OffsetToPadding);
-      W.printHex("BytesOfCalleeSavedRegisters",
-                 FrameProc.Header.BytesOfCalleeSavedRegisters);
-      W.printHex("OffsetOfExceptionHandler",
-                 FrameProc.Header.OffsetOfExceptionHandler);
-      W.printHex("SectionIdOfExceptionHandler",
-                 FrameProc.Header.SectionIdOfExceptionHandler);
-      W.printFlags("Flags", FrameProc.Header.Flags,
-                   makeArrayRef(FrameProcSymFlags));
-      break;
-    }
-
-    case S_UDT:
-    case S_COBOLUDT: {
-      DictScope S(W, "UDT");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto UdtOrError = UDTSym::deserialize(static_cast<SymbolRecordKind>(Kind),
-                                            RecordOffset, Data);
-      if (!UdtOrError)
-        error(UdtOrError.getError());
-      auto &UDT = UdtOrError.get();
-      printTypeIndex("Type", UDT.Header.Type);
-      W.printString("UDTName", UDT.Name);
-      break;
-    }
-
-    case S_BPREL32: {
-      DictScope S(W, "BPRelativeSym");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto BPRelOrError = BPRelativeSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!BPRelOrError)
-        error(BPRelOrError.getError());
-      auto &BPRel = BPRelOrError.get();
-      W.printNumber("Offset", BPRel.Header.Offset);
-      printTypeIndex("Type", BPRel.Header.Type);
-      W.printString("VarName", BPRel.Name);
-      break;
-    }
-
-    case S_REGREL32: {
-      DictScope S(W, "RegRelativeSym");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto RegRelOrError = RegRelativeSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!RegRelOrError)
-        error(RegRelOrError.getError());
-      auto &RegRel = RegRelOrError.get();
-      W.printHex("Offset", RegRel.Header.Offset);
-      printTypeIndex("Type", RegRel.Header.Type);
-      W.printHex("Register", RegRel.Header.Register);
-      W.printString("VarName", RegRel.Name);
-      break;
-    }
-
-    case S_BUILDINFO: {
-      DictScope S(W, "BuildInfo");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto BuildInfoOrError = BuildInfoSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!BuildInfoOrError)
-        error(BuildInfoOrError.getError());
-      auto &BuildInfo = BuildInfoOrError.get();
-      W.printNumber("BuildId", BuildInfo.Header.BuildId);
-      break;
-    }
-
-    case S_CONSTANT:
-    case S_MANCONSTANT: {
-      DictScope S(W, "Constant");
-      ArrayRef<uint8_t> Data(SymData.bytes_begin(), SymData.bytes_end());
-      auto ConstantOrError = ConstantSym::deserialize(
-          static_cast<SymbolRecordKind>(Kind), RecordOffset, Data);
-      if (!ConstantOrError)
-        error(ConstantOrError.getError());
-      auto &Constant = ConstantOrError.get();
-      printTypeIndex("Type", Constant.Header.Type);
-      W.printNumber("Value", Constant.Value);
-      W.printString("Name", Constant.Name);
-      break;
-    }
+  CVSymbolDumper CVSD(W, CVTD, std::move(CODD), opts::CodeViewSubsectionBytes);
 
-    default: {
-      DictScope S(W, "UnknownSym");
-      W.printHex("Kind", unsigned(Kind));
-      W.printHex("Size", Rec->RecordLen);
-      break;
-    }
-    }
-
-    if (opts::CodeViewSubsectionBytes)
-      printBinaryBlockWithRelocs("SymData", Section, SectionContents,
-                                 OrigSymData);
+  if (!CVSD.dump(BinaryData)) {
     W.flush();
+    error(object_error::parse_failed);
   }
   W.flush();
 }
@@ -1633,24 +970,6 @@ void COFFDumper::printCodeViewInlineeLin
   }
 }
 
-void COFFDumper::printLocalVariableAddrRange(
-    const LocalVariableAddrRange &Range, const coff_section *Sec,
-    uint32_t RelocationOffset) {
-  DictScope S(W, "LocalVariableAddrRange");
-  printRelocatedField("OffsetStart", Sec, RelocationOffset, Range.OffsetStart);
-  W.printHex("ISectStart", Range.ISectStart);
-  W.printHex("Range", Range.Range);
-}
-
-void COFFDumper::printLocalVariableAddrGap(
-    ArrayRef<LocalVariableAddrGap> Gaps) {
-  for (auto &Gap : Gaps) {
-    ListScope S(W, "LocalVariableAddrGap");
-    W.printHex("GapStartOffset", Gap.GapStartOffset);
-    W.printHex("Range", Gap.Range);
-  }
-}
-
 StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) {
   // The file checksum subsection should precede all references to it.
   if (!CVFileChecksumTable.data() || !CVStringTable.data())




More information about the llvm-commits mailing list