summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-05-23 23:41:13 +0000
committerZachary Turner <zturner@google.com>2016-05-23 23:41:13 +0000
commit24466fcd2c598109ad3c1a511212e2608cb064ba (patch)
tree21714f91a45c86b9042db430f4ff1dfa30beb28d
parentbc88e8bed4fbb14e94e5e1f5b30209c5d5dacdbe (diff)
Make a symbol visitor and use it to dump CV symbols.
Differential Revision: http://reviews.llvm.org/D20534 Reviewed By: rnk git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270511 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/DebugInfo/CodeView/CVSymbolTypes.def26
-rw-r--r--include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h103
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h37
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDumper.h54
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h55
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h33
-rw-r--r--lib/DebugInfo/CodeView/CMakeLists.txt1
-rw-r--r--lib/DebugInfo/CodeView/SymbolDumper.cpp670
-rw-r--r--lib/DebugInfo/PDB/Raw/ModStream.cpp2
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp783
10 files changed, 1013 insertions, 751 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def b/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
index 758771a403a..d3ecca534e1 100644
--- a/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
+++ b/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
@@ -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, 0x1154)
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, FrameProcSym)
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)
diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
new file mode 100644
index 00000000000..fe21ff9956b
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
@@ -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
diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
new file mode 100644
index 00000000000..30b0a40451c
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
@@ -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
diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/include/llvm/DebugInfo/CodeView/SymbolDumper.h
new file mode 100644
index 00000000000..62c5ab3931b
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/SymbolDumper.h
@@ -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
diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index 2fa616c2a81..431fa1bc345 100644
--- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -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
diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
new file mode 100644
index 00000000000..a4965168c3d
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
@@ -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
diff --git a/lib/DebugInfo/CodeView/CMakeLists.txt b/lib/DebugInfo/CodeView/CMakeLists.txt
index ecddfaf9d7b..e0c7119dd91 100644
--- a/lib/DebugInfo/CodeView/CMakeLists.txt
+++ b/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -5,6 +5,7 @@ add_llvm_library(LLVMDebugInfoCodeView
MemoryTypeTableBuilder.cpp
MethodListRecordBuilder.cpp
RecordSerialization.cpp
+ SymbolDumper.cpp
TypeDumper.cpp
TypeRecord.cpp
TypeRecordBuilder.cpp
diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp
new file mode 100644
index 00000000000..3ea4e51dc37
--- /dev/null
+++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -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();
+}
diff --git a/lib/DebugInfo/PDB/Raw/ModStream.cpp b/lib/DebugInfo/PDB/Raw/ModStream.cpp
index 8c435073655..dfc7bfc0f5f 100644
--- a/lib/DebugInfo/PDB/Raw/ModStream.cpp
+++ b/lib/DebugInfo/PDB/Raw/ModStream.cpp
@@ -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);
}
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index 9e7362233e2..49dc5b38ae8 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -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::printBinaryBlockWithRelocs(StringRef Label,
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> SubSectionTypes[] = {
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> ProcSymFlagNames[] = {
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::printCodeViewSymbolSection(StringRef SectionName,
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;
- }
+ ArrayRef<uint8_t> BinaryData(Subsection.bytes_begin(),
+ Subsection.bytes_end());
+ auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj,
+ SectionContents);
- 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;
- }
+ CVSymbolDumper CVSD(W, CVTD, std::move(CODD), opts::CodeViewSubsectionBytes);
- 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();
-
- 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;
- }
-
- 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::printCodeViewInlineeLines(StringRef Subsection) {
}
}
-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())