summaryrefslogtreecommitdiff
path: root/include
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 /include
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
Diffstat (limited to 'include')
-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
6 files changed, 290 insertions, 18 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