summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-05-23 18:49:06 +0000
committerZachary Turner <zturner@google.com>2016-05-23 18:49:06 +0000
commitdc38d33d03ff4ba40c28aa03f95da6b5f24ff58b (patch)
treefc7a17c10bbf37cf194d13ab57d50ac82adfe804
parent50c861b595ffb962bd97f8bd1bdab5d6bcaee5cb (diff)
[codeview] Refactor symbol records to use same pattern as types.
This will pave the way to introduce a full fledged symbol visitor similar to how we have a type visitor, thus allowing the same dumping code to be used in llvm-readobj and llvm-pdbdump. Differential Revision: http://reviews.llvm.org/D20384 Reviewed By: rnk git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270475 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/DebugInfo/CodeView/RecordSerialization.h33
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h1087
-rw-r--r--lib/CodeGen/AsmPrinter/CodeViewDebug.cpp22
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp599
4 files changed, 1315 insertions, 426 deletions
diff --git a/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/include/llvm/DebugInfo/CodeView/RecordSerialization.h
index bdb61484801..d4eb5754bad 100644
--- a/include/llvm/DebugInfo/CodeView/RecordSerialization.h
+++ b/include/llvm/DebugInfo/CodeView/RecordSerialization.h
@@ -114,8 +114,8 @@ template <typename T, typename U> struct serialize_array_impl {
U Func;
};
-template <typename T> struct serialize_array_tail_impl {
- serialize_array_tail_impl(std::vector<T> &Item) : Item(Item) {}
+template <typename T> struct serialize_vector_tail_impl {
+ serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
T Field;
@@ -131,6 +131,18 @@ template <typename T> struct serialize_array_tail_impl {
std::vector<T> &Item;
};
+template <typename T> struct serialize_arrayref_tail_impl {
+ serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
+
+ std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ uint32_t Count = Data.size() / sizeof(T);
+ Item = ArrayRef<T>(reinterpret_cast<const T *>(Data.begin()), Count);
+ return std::error_code();
+ }
+
+ ArrayRef<T> &Item;
+};
+
template <typename T> struct serialize_numeric_impl {
serialize_numeric_impl(T &Item) : Item(Item) {}
@@ -147,8 +159,13 @@ serialize_array_impl<T, U> serialize_array(ArrayRef<T> &Item, U Func) {
}
template <typename T>
-serialize_array_tail_impl<T> serialize_array_tail(std::vector<T> &Item) {
- return serialize_array_tail_impl<T>(Item);
+serialize_vector_tail_impl<T> serialize_array_tail(std::vector<T> &Item) {
+ return serialize_vector_tail_impl<T>(Item);
+}
+
+template <typename T>
+serialize_arrayref_tail_impl<T> serialize_array_tail(ArrayRef<T> &Item) {
+ return serialize_arrayref_tail_impl<T>(Item);
}
template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
@@ -185,7 +202,13 @@ std::error_code consume(ArrayRef<uint8_t> &Data,
template <typename T>
std::error_code consume(ArrayRef<uint8_t> &Data,
- const serialize_array_tail_impl<T> &Item) {
+ const serialize_vector_tail_impl<T> &Item) {
+ return Item.deserialize(Data);
+}
+
+template <typename T>
+std::error_code consume(ArrayRef<uint8_t> &Data,
+ const serialize_arrayref_tail_impl<T> &Item) {
return Item.deserialize(Data);
}
diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index d31c3f6174b..2fa616c2a81 100644
--- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -10,10 +10,14 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordIterator.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
@@ -22,35 +26,300 @@ using llvm::support::ulittle16_t;
using llvm::support::ulittle32_t;
using llvm::support::little32_t;
+class SymbolRecord {
+protected:
+ explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
+
+public:
+ SymbolRecordKind getKind() const { return Kind; }
+
+private:
+ SymbolRecordKind Kind;
+};
+
// S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
// S_LPROC32_DPC_ID
-struct ProcSym {
- ulittle32_t PtrParent;
- ulittle32_t PtrEnd;
- ulittle32_t PtrNext;
- ulittle32_t CodeSize;
- ulittle32_t DbgStart;
- ulittle32_t DbgEnd;
- TypeIndex FunctionType;
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- uint8_t Flags; // ProcSymFlags enum
- // Name: The null-terminated name follows.
+class ProcSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ ulittle32_t PtrNext;
+ ulittle32_t CodeSize;
+ ulittle32_t DbgStart;
+ ulittle32_t DbgEnd;
+ TypeIndex FunctionType;
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ uint8_t Flags; // ProcSymFlags enum
+ // Name: The null-terminated name follows.
+ };
+
+ ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
+ StringRef Name)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
+ }
+
+ static ErrorOr<ProcSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ProcSym(Kind, RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+struct BinaryAnnotationIterator {
+ struct AnnotationData {
+ BinaryAnnotationsOpCode OpCode;
+ StringRef Name;
+ uint32_t U1;
+ uint32_t U2;
+ int32_t S1;
+ };
+
+ BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
+ BinaryAnnotationIterator() {}
+ BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
+ : Data(Other.Data) {}
+
+ bool operator==(BinaryAnnotationIterator Other) const {
+ return Data == Other.Data;
+ }
+
+ bool operator!=(BinaryAnnotationIterator Other) const {
+ return !(*this == Other);
+ }
+
+ BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
+ Data = Other.Data;
+ return *this;
+ }
+
+ BinaryAnnotationIterator &operator++() {
+ if (!ParseCurrentAnnotation()) {
+ *this = BinaryAnnotationIterator();
+ return *this;
+ }
+ Data = Next;
+ Next = ArrayRef<uint8_t>();
+ Current.reset();
+ return *this;
+ }
+
+ BinaryAnnotationIterator operator++(int) {
+ BinaryAnnotationIterator Orig(*this);
+ ++(*this);
+ return Orig;
+ }
+
+ const AnnotationData &operator*() {
+ ParseCurrentAnnotation();
+ return Current.getValue();
+ }
+
+private:
+ static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t FirstByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if ((FirstByte & 0x80) == 0x00)
+ return FirstByte;
+
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t SecondByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if ((FirstByte & 0xC0) == 0x80)
+ return ((FirstByte & 0x3F) << 8) | SecondByte;
+
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t ThirdByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t FourthByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if ((FirstByte & 0xE0) == 0xC0)
+ return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
+ (ThirdByte << 8) | FourthByte;
+
+ return -1;
+ };
+
+ static int32_t DecodeSignedOperand(uint32_t Operand) {
+ if (Operand & 1)
+ return -(Operand >> 1);
+ return Operand >> 1;
+ };
+
+ static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
+ return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
+ };
+
+ bool ParseCurrentAnnotation() {
+ if (Current.hasValue())
+ return true;
+
+ Next = Data;
+ uint32_t Op = GetCompressedAnnotation(Next);
+ AnnotationData Result;
+ Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
+ switch (Result.OpCode) {
+ case BinaryAnnotationsOpCode::Invalid:
+ Result.Name = "Invalid";
+ Next = ArrayRef<uint8_t>();
+ break;
+ case BinaryAnnotationsOpCode::CodeOffset:
+ Result.Name = "CodeOffset";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
+ Result.Name = "ChangeCodeOffsetBase";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ Result.Name = "ChangeCodeOffset";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ Result.Name = "ChangeCodeLength";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeFile:
+ Result.Name = "ChangeFile";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineEndDelta:
+ Result.Name = "ChangeLineEndDelta";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeRangeKind:
+ Result.Name = "ChangeRangeKind";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeColumnStart:
+ Result.Name = "ChangeColumnStart";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeColumnEnd:
+ Result.Name = "ChangeColumnEnd";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
+ Result.Name = "ChangeLineOffset";
+ Result.S1 = DecodeSignedOperand(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
+ Result.Name = "ChangeColumnEndDelta";
+ Result.S1 = DecodeSignedOperand(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
+ Result.Name = "ChangeCodeOffsetAndLineOffset";
+ uint32_t Annotation = GetCompressedAnnotation(Next);
+ Result.S1 = DecodeSignedOperand(Annotation >> 4);
+ Result.U1 = Annotation & 0xf;
+ break;
+ }
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
+ Result.Name = "ChangeCodeLengthAndCodeOffset";
+ Result.U1 = GetCompressedAnnotation(Next);
+ Result.U2 = GetCompressedAnnotation(Next);
+ break;
+ }
+ }
+ Current = Result;
+ return true;
+ }
+
+ Optional<AnnotationData> Current;
+ ArrayRef<uint8_t> Data;
+ ArrayRef<uint8_t> Next;
};
// S_INLINESITE
-struct InlineSiteSym {
- ulittle32_t PtrParent;
- ulittle32_t PtrEnd;
- TypeIndex Inlinee;
- // BinaryAnnotations
+class InlineSiteSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ TypeIndex Inlinee;
+ // BinaryAnnotations
+ };
+
+ InlineSiteSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<uint8_t> Annotations)
+ : SymbolRecord(SymbolRecordKind::InlineSiteSym),
+ RecordOffset(RecordOffset), Header(*H), Annotations(Annotations) {}
+
+ static ErrorOr<InlineSiteSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<uint8_t> Annotations;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Annotations));
+
+ return InlineSiteSym(RecordOffset, H, Annotations);
+ }
+
+ llvm::iterator_range<BinaryAnnotationIterator> annotations() const {
+ return llvm::make_range(BinaryAnnotationIterator(Annotations),
+ BinaryAnnotationIterator());
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+
+private:
+ ArrayRef<uint8_t> Annotations;
};
// S_LOCAL
-struct LocalSym {
- TypeIndex Type;
- ulittle16_t Flags; // LocalSymFlags enum
- // Name: The null-terminated name follows.
+class LocalSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ ulittle16_t Flags; // LocalSymFlags enum
+ // Name: The null-terminated name follows.
+ };
+
+ LocalSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<LocalSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return LocalSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
struct LocalVariableAddrRange {
@@ -67,182 +336,728 @@ struct LocalVariableAddrGap {
enum : uint16_t { MaxDefRange = 0xf000 };
// S_DEFRANGE
-struct DefRangeSym {
- ulittle32_t Program;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
+class DefRangeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Program;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSym), RecordOffset(RecordOffset),
+ Header(*H), Gaps(Gaps) {}
+
+ static ErrorOr<DefRangeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_SUBFIELD
-struct DefRangeSubfieldSym {
- ulittle32_t Program;
- ulittle16_t OffsetInParent;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
+class DefRangeSubfieldSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Program;
+ ulittle16_t OffsetInParent;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+ DefRangeSubfieldSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ static ErrorOr<DefRangeSubfieldSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeSubfieldSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_REGISTER
-struct DefRangeRegisterSym {
- ulittle16_t Register;
- ulittle16_t MayHaveNoName;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
+class DefRangeRegisterSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t Register;
+ ulittle16_t MayHaveNoName;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeRegisterSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ DefRangeRegisterSym(uint16_t Register, uint16_t MayHaveNoName,
+ uint32_t OffsetStart, uint16_t ISectStart, uint16_t Range,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym), RecordOffset(0),
+ Gaps(Gaps) {
+ Header.Register = Register;
+ Header.MayHaveNoName = MayHaveNoName;
+ Header.Range.OffsetStart = OffsetStart;
+ Header.Range.ISectStart = ISectStart;
+ Header.Range.Range = Range;
+ }
+
+ static ErrorOr<DefRangeRegisterSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeRegisterSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_SUBFIELD_REGISTER
-struct DefRangeSubfieldRegisterSym {
- ulittle16_t Register; // Register to which the variable is relative
- ulittle16_t MayHaveNoName;
- ulittle32_t OffsetInParent;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
+class DefRangeSubfieldRegisterSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t Register; // Register to which the variable is relative
+ ulittle16_t MayHaveNoName;
+ ulittle32_t OffsetInParent;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeSubfieldRegisterSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ DefRangeSubfieldRegisterSym(uint16_t Register, uint16_t MayHaveNoName,
+ uint32_t OffsetInParent,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
+ RecordOffset(0), Gaps(Gaps) {
+ Header.Register = Register;
+ Header.MayHaveNoName = MayHaveNoName;
+ Header.OffsetInParent = OffsetInParent;
+ }
+
+ static ErrorOr<DefRangeSubfieldRegisterSym>
+ deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeSubfieldRegisterSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_FRAMEPOINTER_REL
-struct DefRangeFramePointerRelSym {
- little32_t Offset; // Offset from the frame pointer register
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
-};
+class DefRangeFramePointerRelSym : public SymbolRecord {
+public:
+ struct Hdr {
+ little32_t Offset; // Offset from the frame pointer register
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
-// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
-struct DefRangeFramePointerRelFullScopeSym {
- little32_t Offset; // Offset from the frame pointer register
+ DefRangeFramePointerRelSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ static ErrorOr<DefRangeFramePointerRelSym>
+ deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeFramePointerRelSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
};
// S_DEFRANGE_REGISTER_REL
-struct DefRangeRegisterRelSym {
- ulittle16_t BaseRegister;
- ulittle16_t Flags;
- little32_t BasePointerOffset;
- LocalVariableAddrRange Range;
- // LocalVariableAddrGap Gaps[];
-
- bool hasSpilledUDTMember() const { return Flags & 1; }
- uint16_t offsetInParent() const { return Flags >> 4; }
+class DefRangeRegisterRelSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t BaseRegister;
+ ulittle16_t Flags;
+ little32_t BasePointerOffset;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeRegisterRelSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ DefRangeRegisterRelSym(uint16_t BaseRegister, uint16_t Flags,
+ int32_t BasePointerOffset, uint32_t OffsetStart,
+ uint16_t ISectStart, uint16_t Range,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym), RecordOffset(0),
+ Gaps(Gaps) {
+ Header.BaseRegister = BaseRegister;
+ Header.Flags = Flags;
+ Header.BasePointerOffset = BasePointerOffset;
+ Header.Range.OffsetStart = OffsetStart;
+ Header.Range.ISectStart = ISectStart;
+ Header.Range.Range = Range;
+ }
+
+ static ErrorOr<DefRangeRegisterRelSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeRegisterRelSym(RecordOffset, H, Gaps);
+ }
+
+ bool hasSpilledUDTMember() const { return Header.Flags & 1; }
+ uint16_t offsetInParent() const { return Header.Flags >> 4; }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+};
+
+// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
+class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ little32_t Offset; // Offset from the frame pointer register
+ };
+
+ DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<DefRangeFramePointerRelFullScopeSym>
+ deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return DefRangeFramePointerRelFullScopeSym(RecordOffset, H);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
};
// S_BLOCK32
-struct BlockSym {
- ulittle32_t PtrParent;
- ulittle32_t PtrEnd;
- ulittle32_t CodeSize;
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- // Name: The null-terminated name follows.
+class BlockSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ ulittle32_t CodeSize;
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+ };
+
+ BlockSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<BlockSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return BlockSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
// S_LABEL32
-struct LabelSym {
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- uint8_t Flags; // CV_PROCFLAGS
- // Name: The null-terminated name follows.
+class LabelSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ uint8_t Flags; // CV_PROCFLAGS
+ // Name: The null-terminated name follows.
+ };
+
+ LabelSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<LabelSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return LabelSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
// S_OBJNAME
-struct ObjNameSym {
- ulittle32_t Signature;
- // Name: The null-terminated name follows.
+class ObjNameSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Signature;
+ // Name: The null-terminated name follows.
+ };
+
+ ObjNameSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<ObjNameSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ObjNameSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
// S_COMPILE3
-struct CompileSym3 {
- ulittle32_t flags; // CompileSym3Flags enum
- uint8_t getLanguage() const { return flags & 0xff; }
- ulittle16_t Machine; // CPUType
- ulittle16_t VersionFrontendMajor;
- ulittle16_t VersionFrontendMinor;
- ulittle16_t VersionFrontendBuild;
- ulittle16_t VersionFrontendQFE;
- ulittle16_t VersionBackendMajor;
- ulittle16_t VersionBackendMinor;
- ulittle16_t VersionBackendBuild;
- ulittle16_t VersionBackendQFE;
- // VersionString: The null-terminated version string follows.
+class CompileSym3 : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t flags; // CompileSym3Flags enum
+ uint8_t getLanguage() const { return flags & 0xff; }
+ ulittle16_t Machine; // CPUType
+ ulittle16_t VersionFrontendMajor;
+ ulittle16_t VersionFrontendMinor;
+ ulittle16_t VersionFrontendBuild;
+ ulittle16_t VersionFrontendQFE;
+ ulittle16_t VersionBackendMajor;
+ ulittle16_t VersionBackendMinor;
+ ulittle16_t VersionBackendBuild;
+ ulittle16_t VersionBackendQFE;
+ // VersionString: The null-terminated version string follows.
+ };
+
+ CompileSym3(uint32_t RecordOffset, const Hdr *H, StringRef Version)
+ : SymbolRecord(SymbolRecordKind::Compile3Sym), RecordOffset(RecordOffset),
+ Header(*H), Version(Version) {}
+
+ static ErrorOr<CompileSym3> 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);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Version;
};
// S_FRAMEPROC
-struct FrameProcSym {
- ulittle32_t TotalFrameBytes;
- ulittle32_t PaddingFrameBytes;
- ulittle32_t OffsetToPadding;
- ulittle32_t BytesOfCalleeSavedRegisters;
- ulittle32_t OffsetOfExceptionHandler;
- ulittle16_t SectionIdOfExceptionHandler;
- ulittle32_t Flags;
+class FrameProcSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t TotalFrameBytes;
+ ulittle32_t PaddingFrameBytes;
+ ulittle32_t OffsetToPadding;
+ ulittle32_t BytesOfCalleeSavedRegisters;
+ ulittle32_t OffsetOfExceptionHandler;
+ ulittle16_t SectionIdOfExceptionHandler;
+ ulittle32_t Flags;
+ };
+
+ FrameProcSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::FrameProcSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<FrameProcSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return FrameProcSym(RecordOffset, H);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
};
// S_CALLSITEINFO
-struct CallSiteInfoSym {
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- ulittle16_t Reserved;
- TypeIndex Type;
+class CallSiteInfoSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ ulittle16_t Reserved;
+ TypeIndex Type;
+ };
+
+ CallSiteInfoSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::CallSiteInfoSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<CallSiteInfoSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return CallSiteInfoSym(RecordOffset, H);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
};
// S_HEAPALLOCSITE
-struct HeapAllocationSiteSym {
- ulittle32_t CodeOffset;
- ulittle16_t Segment;
- ulittle16_t CallInstructionSize;
- TypeIndex Type;
+class HeapAllocationSiteSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ ulittle16_t CallInstructionSize;
+ TypeIndex Type;
+ };
+
+ HeapAllocationSiteSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<HeapAllocationSiteSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return HeapAllocationSiteSym(RecordOffset, H);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
};
// S_FRAMECOOKIE
-struct FrameCookieSym {
- ulittle32_t CodeOffset;
- ulittle16_t Register;
- ulittle32_t CookieKind;
+class FrameCookieSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Register;
+ ulittle32_t CookieKind;
+ };
+
+ FrameCookieSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::FrameCookieSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<FrameCookieSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return FrameCookieSym(RecordOffset, H);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
};
// S_UDT, S_COBOLUDT
-struct UDTSym {
- TypeIndex Type; // Type of the UDT
- // Name: The null-terminated name follows.
+class UDTSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type; // Type of the UDT
+ // Name: The null-terminated name follows.
+ };
+
+ UDTSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::UDTSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<UDTSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return UDTSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
// S_BUILDINFO
-struct BuildInfoSym {
- ulittle32_t BuildId;
+class BuildInfoSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t BuildId;
+ };
+
+ BuildInfoSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::BuildInfoSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<BuildInfoSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return BuildInfoSym(RecordOffset, H);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
};
// S_BPREL32
-struct BPRelativeSym {
- little32_t Offset; // Offset from the base pointer register
- TypeIndex Type; // Type of the variable
- // Name: The null-terminated name follows.
+class BPRelativeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ little32_t Offset; // Offset from the base pointer register
+ TypeIndex Type; // Type of the variable
+ // Name: The null-terminated name follows.
+ };
+
+ BPRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::BPRelativeSym),
+ RecordOffset(RecordOffset), Header(*H), Name(Name) {}
+
+ static ErrorOr<BPRelativeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return BPRelativeSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
// S_REGREL32
-struct RegRelativeSym {
- ulittle32_t Offset; // Offset from the register
- TypeIndex Type; // Type of the variable
- ulittle16_t Register; // Register to which the variable is relative
- // Name: The null-terminated name follows.
+class RegRelativeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Offset; // Offset from the register
+ TypeIndex Type; // Type of the variable
+ ulittle16_t Register; // Register to which the variable is relative
+ // Name: The null-terminated name follows.
+ };
+
+ RegRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::RegRelativeSym),
+ RecordOffset(RecordOffset), Header(*H), Name(Name) {}
+
+ static ErrorOr<RegRelativeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return RegRelativeSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
// S_CONSTANT, S_MANCONSTANT
-struct ConstantSym {
- TypeIndex Type;
- // Value: The value of the constant.
- // Name: The null-terminated name follows.
+class ConstantSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ // Value: The value of the constant.
+ // Name: The null-terminated name follows.
+ };
+
+ ConstantSym(uint32_t RecordOffset, const Hdr *H, const APSInt &Value,
+ StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ConstantSym), RecordOffset(RecordOffset),
+ Header(*H), Value(Value), Name(Name) {}
+
+ static ErrorOr<ConstantSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ APSInt Value;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Value, Name);
+
+ return ConstantSym(RecordOffset, H, Value, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ APSInt Value;
+ StringRef Name;
};
// S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
-struct DataSym {
- TypeIndex Type;
- ulittle32_t DataOffset;
- ulittle16_t Segment;
- // Name: The null-terminated name follows.
+class DataSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ ulittle32_t DataOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+ };
+
+ DataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<DataSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return DataSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, DataOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
// S_LTHREAD32, S_GTHREAD32
-struct ThreadLocalDataSym {
- TypeIndex Type;
- ulittle32_t DataOffset;
- ulittle16_t Segment;
- // Name: The null-terminated name follows.
+class ThreadLocalDataSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ ulittle32_t DataOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+ };
+
+ ThreadLocalDataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
+ RecordOffset(RecordOffset), Header(*H), Name(Name) {}
+
+ static ErrorOr<ThreadLocalDataSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ThreadLocalDataSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, DataOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
};
typedef RecordIterator<SymbolRecordKind> SymbolIterator;
diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index b5c796a01bd..06ac58333bc 100644
--- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -734,25 +734,25 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
continue;
if (DefRange.InMemory) {
- DefRangeRegisterRelSym Sym{};
+ DefRangeRegisterRelSym Sym(DefRange.CVRegister, 0, DefRange.DataOffset, 0,
+ 0, 0, ArrayRef<LocalVariableAddrGap>());
ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL);
- Sym.BaseRegister = DefRange.CVRegister;
- Sym.Flags = 0; // Unclear what matters here.
- Sym.BasePointerOffset = DefRange.DataOffset;
BytePrefix +=
StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind));
- BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),
- sizeof(Sym) - sizeof(LocalVariableAddrRange));
+ BytePrefix +=
+ StringRef(reinterpret_cast<const char *>(&Sym.Header),
+ sizeof(Sym.Header) - sizeof(LocalVariableAddrRange));
} else {
assert(DefRange.DataOffset == 0 && "unexpected offset into register");
- DefRangeRegisterSym Sym{};
+ // Unclear what matters here.
+ DefRangeRegisterSym Sym(DefRange.CVRegister, 0, 0, 0, 0,
+ ArrayRef<LocalVariableAddrGap>());
ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER);
- Sym.Register = DefRange.CVRegister;
- Sym.MayHaveNoName = 0; // Unclear what matters here.
BytePrefix +=
StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind));
- BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym),
- sizeof(Sym) - sizeof(LocalVariableAddrRange));
+ BytePrefix +=
+ StringRef(reinterpret_cast<const char *>(&Sym.Header),
+ sizeof(Sym.Header) - sizeof(LocalVariableAddrRange));
}
OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);
}
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index c39dcf349f8..9e7362233e2 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -98,8 +98,8 @@ private:
}
void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
const coff_section *Sec,
- StringRef SectionContents);
- void printLocalVariableAddrGap(StringRef &SymData);
+ uint32_t RelocationOffset);
+ void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
void printCodeViewSymbolsSubsection(StringRef Subsection,
const SectionRef &Section,
@@ -110,6 +110,10 @@ private:
void printCodeViewInlineeLines(StringRef Subsection);
void printRelocatedField(StringRef Label, const coff_section *Sec,
+ uint32_t RelocOffset, uint32_t Offset,
+ StringRef *RelocSym = nullptr);
+
+ void printRelocatedField(StringRef Label, const coff_section *Sec,
StringRef SectionContents, const ulittle32_t *Field,
StringRef *RelocSym = nullptr);
@@ -208,6 +212,17 @@ std::error_code COFFDumper::resolveSymbolName(const coff_section *Section,
}
void COFFDumper::printRelocatedField(StringRef Label, const coff_section *Sec,
+ uint32_t RelocOffset, uint32_t Offset,
+ StringRef *RelocSym) {
+ StringRef SymStorage;
+ StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;
+ if (!resolveSymbolName(Sec, RelocOffset, Symbol))
+ W.printSymbolOffset(Label, Symbol, Offset);
+ else
+ W.printHex(Label, RelocOffset);
+}
+
+void COFFDumper::printRelocatedField(StringRef Label, const coff_section *Sec,
StringRef SectionContents,
const ulittle32_t *Field,
StringRef *RelocSym) {
@@ -1011,6 +1026,7 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
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) {
@@ -1021,26 +1037,31 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
case S_LPROC32_DPC:
case S_LPROC32_DPC_ID: {
DictScope S(W, "ProcStart");
- const ProcSym *Proc;
- error(consumeObject(SymData, Proc));
+ 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;
- StringRef DisplayName = SymData.split('\0').first;
- W.printHex("PtrParent", Proc->PtrParent);
- W.printHex("PtrEnd", Proc->PtrEnd);
- W.printHex("PtrNext", Proc->PtrNext);
- W.printHex("CodeSize", Proc->CodeSize);
- W.printHex("DbgStart", Proc->DbgStart);
- W.printHex("DbgEnd", Proc->DbgEnd);
- printTypeIndex("FunctionType", Proc->FunctionType);
- printRelocatedField("CodeOffset", Sec, SectionContents, &Proc->CodeOffset,
- &LinkageName);
- W.printHex("Segment", Proc->Segment);
- W.printFlags("Flags", Proc->Flags, makeArrayRef(ProcSymFlagNames));
- W.printString("DisplayName", DisplayName);
+ 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;
}
@@ -1053,18 +1074,21 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
case S_BLOCK32: {
DictScope S(W, "BlockStart");
- const BlockSym *Block;
- error(consumeObject(SymData, Block));
+ 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 BlockName = SymData.split('\0').first;
StringRef LinkageName;
- W.printHex("PtrParent", Block->PtrParent);
- W.printHex("PtrEnd", Block->PtrEnd);
- W.printHex("CodeSize", Block->CodeSize);
- printRelocatedField("CodeOffset", Sec, SectionContents,
- &Block->CodeOffset, &LinkageName);
- W.printHex("Segment", Block->Segment);
- W.printString("BlockName", BlockName);
+ 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;
}
@@ -1077,131 +1101,73 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
case S_LABEL32: {
DictScope S(W, "Label");
- const LabelSym *Label;
- error(consumeObject(SymData, 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 DisplayName = SymData.split('\0').first;
StringRef LinkageName;
- printRelocatedField("CodeOffset", Sec, SectionContents,
- &Label->CodeOffset, &LinkageName);
- W.printHex("Segment", Label->Segment);
- W.printHex("Flags", Label->Flags);
- W.printFlags("Flags", Label->Flags, makeArrayRef(ProcSymFlagNames));
- W.printString("DisplayName", DisplayName);
+ 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");
- const InlineSiteSym *InlineSite;
- error(consumeObject(SymData, InlineSite));
- W.printHex("PtrParent", InlineSite->PtrParent);
- W.printHex("PtrEnd", InlineSite->PtrEnd);
- printTypeIndex("Inlinee", InlineSite->Inlinee);
-
- auto GetCompressedAnnotation = [&]() -> uint32_t {
- if (SymData.empty())
- return -1;
-
- uint8_t FirstByte = SymData.front();
- SymData = SymData.drop_front();
-
- if ((FirstByte & 0x80) == 0x00)
- return FirstByte;
-
- if (SymData.empty())
- return -1;
-
- uint8_t SecondByte = SymData.front();
- SymData = SymData.drop_front();
-
- if ((FirstByte & 0xC0) == 0x80)
- return ((FirstByte & 0x3F) << 8) | SecondByte;
-
- if (SymData.empty())
- return -1;
-
- uint8_t ThirdByte = SymData.front();
- SymData = SymData.drop_front();
-
- if (SymData.empty())
- return -1;
-
- uint8_t FourthByte = SymData.front();
- SymData = SymData.drop_front();
+ 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();
- if ((FirstByte & 0xE0) == 0xC0)
- return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
- (ThirdByte << 8) | FourthByte;
-
- return -1;
- };
- auto DecodeSignedOperand = [](uint32_t Operand) -> int32_t {
- if (Operand & 1)
- return -(Operand >> 1);
- return Operand >> 1;
- };
+ W.printHex("PtrParent", InlineSite.Header.PtrParent);
+ W.printHex("PtrEnd", InlineSite.Header.PtrEnd);
+ printTypeIndex("Inlinee", InlineSite.Header.Inlinee);
ListScope BinaryAnnotations(W, "BinaryAnnotations");
- while (!SymData.empty()) {
- auto OpCode =
- static_cast<BinaryAnnotationsOpCode>(GetCompressedAnnotation());
- switch (OpCode) {
+ for (auto &Annotation : InlineSite.annotations()) {
+ switch (Annotation.OpCode) {
case BinaryAnnotationsOpCode::Invalid:
return error(object_error::parse_failed);
case BinaryAnnotationsOpCode::CodeOffset:
- W.printHex("CodeOffset", GetCompressedAnnotation());
- break;
- case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
- W.printNumber("ChangeCodeOffsetBase", GetCompressedAnnotation());
- break;
case BinaryAnnotationsOpCode::ChangeCodeOffset:
- W.printHex("ChangeCodeOffset", GetCompressedAnnotation());
- break;
case BinaryAnnotationsOpCode::ChangeCodeLength:
- W.printHex("ChangeCodeLength", GetCompressedAnnotation());
- break;
- case BinaryAnnotationsOpCode::ChangeFile:
- printFileNameForOffset("ChangeFile", GetCompressedAnnotation());
- break;
- case BinaryAnnotationsOpCode::ChangeLineOffset:
- W.printNumber("ChangeLineOffset",
- DecodeSignedOperand(GetCompressedAnnotation()));
+ W.printHex(Annotation.Name, Annotation.U1);
break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
case BinaryAnnotationsOpCode::ChangeLineEndDelta:
- W.printNumber("ChangeLineEndDelta", GetCompressedAnnotation());
- break;
case BinaryAnnotationsOpCode::ChangeRangeKind:
- W.printNumber("ChangeRangeKind", GetCompressedAnnotation());
- break;
case BinaryAnnotationsOpCode::ChangeColumnStart:
- W.printNumber("ChangeColumnStart", GetCompressedAnnotation());
+ case BinaryAnnotationsOpCode::ChangeColumnEnd:
+ W.printNumber(Annotation.Name, Annotation.U1);
break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
- W.printNumber("ChangeColumnEndDelta",
- DecodeSignedOperand(GetCompressedAnnotation()));
+ W.printNumber(Annotation.Name, Annotation.S1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeFile:
+ printFileNameForOffset("ChangeFile", Annotation.U1);
break;
case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
- uint32_t Annotation = GetCompressedAnnotation();
- int32_t LineOffset = DecodeSignedOperand(Annotation >> 4);
- uint32_t CodeOffset = Annotation & 0xf;
W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
- << W.hex(CodeOffset) << ", LineOffset: " << LineOffset
- << "}\n";
+ << W.hex(Annotation.U1)
+ << ", LineOffset: " << Annotation.S1 << "}\n";
break;
}
case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
- uint32_t Length = GetCompressedAnnotation();
- uint32_t CodeOffset = GetCompressedAnnotation();
W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
- << W.hex(CodeOffset) << ", Length: " << W.hex(Length)
- << "}\n";
+ << W.hex(Annotation.U2)
+ << ", Length: " << W.hex(Annotation.U1) << "}\n";
break;
}
- case BinaryAnnotationsOpCode::ChangeColumnEnd:
- W.printNumber("ChangeColumnEnd", GetCompressedAnnotation());
- break;
}
}
break;
@@ -1227,140 +1193,192 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
case S_LOCAL: {
DictScope S(W, "Local");
- const LocalSym *Local;
- error(consumeObject(SymData, Local));
- printTypeIndex("Type", Local->Type);
- W.printFlags("Flags", uint16_t(Local->Flags), makeArrayRef(LocalFlags));
- StringRef VarName = SymData.split('\0').first;
- W.printString("VarName", VarName);
+ 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");
- const DefRangeSym *DefRange;
- error(consumeObject(SymData, 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->Program).split('\0').first);
- printLocalVariableAddrRange(DefRange->Range, Sec, SectionContents);
- printLocalVariableAddrGap(SymData);
+ 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");
- const DefRangeSubfieldSym *DefRangeSubfield;
- error(consumeObject(SymData, 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->Program)
+ CVStringTable.drop_front(DefRangeSubfield.Header.Program)
.split('\0')
.first);
- W.printNumber("OffsetInParent", DefRangeSubfield->OffsetInParent);
- printLocalVariableAddrRange(DefRangeSubfield->Range, Sec,
- SectionContents);
- printLocalVariableAddrGap(SymData);
+ 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");
- const DefRangeRegisterSym *DefRangeRegister;
- error(consumeObject(SymData, DefRangeRegister));
- W.printNumber("Register", DefRangeRegister->Register);
- W.printNumber("MayHaveNoName", DefRangeRegister->MayHaveNoName);
- printLocalVariableAddrRange(DefRangeRegister->Range, Sec,
- SectionContents);
- printLocalVariableAddrGap(SymData);
+ 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");
- const DefRangeSubfieldRegisterSym *DefRangeSubfieldRegisterSym;
- error(consumeObject(SymData, DefRangeSubfieldRegisterSym));
- W.printNumber("Register", DefRangeSubfieldRegisterSym->Register);
+ 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",
- DefRangeSubfieldRegisterSym->MayHaveNoName);
+ DefRangeSubfieldRegister.Header.MayHaveNoName);
W.printNumber("OffsetInParent",
- DefRangeSubfieldRegisterSym->OffsetInParent);
- printLocalVariableAddrRange(DefRangeSubfieldRegisterSym->Range, Sec,
- SectionContents);
- printLocalVariableAddrGap(SymData);
+ DefRangeSubfieldRegister.Header.OffsetInParent);
+ printLocalVariableAddrRange(
+ DefRangeSubfieldRegister.Header.Range, Sec,
+ DefRangeSubfieldRegister.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
break;
}
case S_DEFRANGE_FRAMEPOINTER_REL: {
DictScope S(W, "DefRangeFramePointerRel");
- const DefRangeFramePointerRelSym *DefRangeFramePointerRel;
- error(consumeObject(SymData, DefRangeFramePointerRel));
- W.printNumber("Offset", DefRangeFramePointerRel->Offset);
- printLocalVariableAddrRange(DefRangeFramePointerRel->Range, Sec,
- SectionContents);
- printLocalVariableAddrGap(SymData);
+ 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");
- const DefRangeFramePointerRelFullScopeSym
- *DefRangeFramePointerRelFullScope;
- error(consumeObject(SymData, DefRangeFramePointerRelFullScope));
- W.printNumber("Offset", DefRangeFramePointerRelFullScope->Offset);
+ 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");
- const DefRangeRegisterRelSym *DefRangeRegisterRel;
- error(consumeObject(SymData, DefRangeRegisterRel));
- W.printNumber("BaseRegister", DefRangeRegisterRel->BaseRegister);
+ 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());
+ DefRangeRegisterRel.hasSpilledUDTMember());
+ W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
W.printNumber("BasePointerOffset",
- DefRangeRegisterRel->BasePointerOffset);
- printLocalVariableAddrRange(DefRangeRegisterRel->Range, Sec,
- SectionContents);
- printLocalVariableAddrGap(SymData);
+ DefRangeRegisterRel.Header.BasePointerOffset);
+ printLocalVariableAddrRange(DefRangeRegisterRel.Header.Range, Sec,
+ DefRangeRegisterRel.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
break;
}
case S_CALLSITEINFO: {
DictScope S(W, "CallSiteInfo");
- const CallSiteInfoSym *CallSiteInfo;
- error(consumeObject(SymData, 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, SectionContents,
- &CallSiteInfo->CodeOffset, &LinkageName);
- W.printHex("Segment", CallSiteInfo->Segment);
- W.printHex("Reserved", CallSiteInfo->Reserved);
- printTypeIndex("Type", CallSiteInfo->Type);
+ 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");
- const HeapAllocationSiteSym *HeapAllocationSite;
- error(consumeObject(SymData, 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, SectionContents,
- &HeapAllocationSite->CodeOffset, &LinkageName);
- W.printHex("Segment", HeapAllocationSite->Segment);
+ printRelocatedField("CodeOffset", Sec,
+ HeapAllocSite.getRelocationOffset(),
+ HeapAllocSite.Header.CodeOffset, &LinkageName);
+ W.printHex("Segment", HeapAllocSite.Header.Segment);
W.printHex("CallInstructionSize",
- HeapAllocationSite->CallInstructionSize);
- printTypeIndex("Type", HeapAllocationSite->Type);
+ HeapAllocSite.Header.CallInstructionSize);
+ printTypeIndex("Type", HeapAllocSite.Header.Type);
W.printString("LinkageName", LinkageName);
break;
}
case S_FRAMECOOKIE: {
DictScope S(W, "FrameCookie");
- const FrameCookieSym *FrameCookie;
- error(consumeObject(SymData, 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, SectionContents,
- &FrameCookie->CodeOffset, &LinkageName);
- W.printHex("Register", FrameCookie->Register);
- W.printEnum("CookieKind", uint16_t(FrameCookie->CookieKind),
+ 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;
}
@@ -1370,15 +1388,18 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
case S_LMANDATA:
case S_GMANDATA: {
DictScope S(W, "DataSym");
- const DataSym *Data;
- error(consumeObject(SymData, Data));
+ 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 DisplayName = SymData.split('\0').first;
StringRef LinkageName;
- printRelocatedField("DataOffset", Sec, SectionContents, &Data->DataOffset,
- &LinkageName);
- printTypeIndex("Type", Data->Type);
- W.printString("DisplayName", DisplayName);
+ printRelocatedField("DataOffset", Sec, Data.getRelocationOffset(),
+ Data.Header.DataOffset, &LinkageName);
+ printTypeIndex("Type", Data.Header.Type);
+ W.printString("DisplayName", Data.Name);
W.printString("LinkageName", LinkageName);
break;
}
@@ -1386,130 +1407,161 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
case S_LTHREAD32:
case S_GTHREAD32: {
DictScope S(W, "ThreadLocalDataSym");
- const ThreadLocalDataSym *Data;
- error(consumeObject(SymData, Data));
+ 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 DisplayName = SymData.split('\0').first;
StringRef LinkageName;
- printRelocatedField("DataOffset", Sec, SectionContents, &Data->DataOffset,
- &LinkageName);
- printTypeIndex("Type", Data->Type);
- W.printString("DisplayName", DisplayName);
+ 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");
- const ObjNameSym *ObjName;
- error(consumeObject(SymData, ObjName));
- W.printHex("Signature", ObjName->Signature);
- StringRef ObjectName = SymData.split('\0').first;
- W.printString("ObjectName", 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");
- const CompileSym3 *CompFlags;
- error(consumeObject(SymData, CompFlags));
- W.printEnum("Language", CompFlags->getLanguage(),
+ 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", CompFlags->flags & ~0xff,
+ W.printFlags("Flags", Compile3.Header.flags & ~0xff,
makeArrayRef(CompileSym3FlagNames));
- W.printEnum("Machine", unsigned(CompFlags->Machine),
+ W.printEnum("Machine", unsigned(Compile3.Header.Machine),
makeArrayRef(CPUTypeNames));
std::string FrontendVersion;
{
raw_string_ostream Out(FrontendVersion);
- Out << CompFlags->VersionFrontendMajor << '.'
- << CompFlags->VersionFrontendMinor << '.'
- << CompFlags->VersionFrontendBuild << '.'
- << CompFlags->VersionFrontendQFE;
+ Out << Compile3.Header.VersionFrontendMajor << '.'
+ << Compile3.Header.VersionFrontendMinor << '.'
+ << Compile3.Header.VersionFrontendBuild << '.'
+ << Compile3.Header.VersionFrontendQFE;
}
std::string BackendVersion;
{
raw_string_ostream Out(BackendVersion);
- Out << CompFlags->VersionBackendMajor << '.'
- << CompFlags->VersionBackendMinor << '.'
- << CompFlags->VersionBackendBuild << '.'
- << CompFlags->VersionBackendQFE;
+ Out << Compile3.Header.VersionBackendMajor << '.'
+ << Compile3.Header.VersionBackendMinor << '.'
+ << Compile3.Header.VersionBackendBuild << '.'
+ << Compile3.Header.VersionBackendQFE;
}
W.printString("FrontendVersion", FrontendVersion);
W.printString("BackendVersion", BackendVersion);
- StringRef VersionName = SymData.split('\0').first;
- W.printString("VersionName", VersionName);
+ W.printString("VersionName", Compile3.Version);
break;
}
case S_FRAMEPROC: {
DictScope S(W, "FrameProc");
- const FrameProcSym *FrameProc;
- error(consumeObject(SymData, FrameProc));
- W.printHex("TotalFrameBytes", FrameProc->TotalFrameBytes);
- W.printHex("PaddingFrameBytes", FrameProc->PaddingFrameBytes);
- W.printHex("OffsetToPadding", FrameProc->OffsetToPadding);
- W.printHex("BytesOfCalleeSavedRegisters", FrameProc->BytesOfCalleeSavedRegisters);
- W.printHex("OffsetOfExceptionHandler", FrameProc->OffsetOfExceptionHandler);
- W.printHex("SectionIdOfExceptionHandler", FrameProc->SectionIdOfExceptionHandler);
- W.printFlags("Flags", FrameProc->Flags, makeArrayRef(FrameProcSymFlags));
+ 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");
- const UDTSym *UDT;
- error(consumeObject(SymData, UDT));
- printTypeIndex("Type", UDT->Type);
- StringRef UDTName = SymData.split('\0').first;
- W.printString("UDTName", UDTName);
+ 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");
- const BPRelativeSym *BPRel;
- error(consumeObject(SymData, BPRel));
- W.printNumber("Offset", BPRel->Offset);
- printTypeIndex("Type", BPRel->Type);
- StringRef VarName = SymData.split('\0').first;
- W.printString("VarName", VarName);
+ 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");
- const RegRelativeSym *RegRel;
- error(consumeObject(SymData, RegRel));
- W.printHex("Offset", RegRel->Offset);
- printTypeIndex("Type", RegRel->Type);
- W.printHex("Register", RegRel->Register);
- StringRef VarName = SymData.split('\0').first;
- W.printString("VarName", VarName);
+ 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");
- const BuildInfoSym *BuildInfo;
- error(consumeObject(SymData, BuildInfo));
- W.printNumber("BuildId", BuildInfo->BuildId);
+ 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");
- const ConstantSym *Constant;
- error(consumeObject(SymData, Constant));
- printTypeIndex("Type", Constant->Type);
- APSInt Value;
- if (consume(SymData, Value))
- error(object_error::parse_failed);
- W.printNumber("Value", Value);
- StringRef Name = SymData.split('\0').first;
- W.printString("Name", Name);
+ 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;
}
@@ -1583,20 +1635,19 @@ void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
void COFFDumper::printLocalVariableAddrRange(
const LocalVariableAddrRange &Range, const coff_section *Sec,
- StringRef SectionContents) {
+ uint32_t RelocationOffset) {
DictScope S(W, "LocalVariableAddrRange");
- printRelocatedField("OffsetStart", Sec, SectionContents, &Range.OffsetStart);
+ printRelocatedField("OffsetStart", Sec, RelocationOffset, Range.OffsetStart);
W.printHex("ISectStart", Range.ISectStart);
W.printHex("Range", Range.Range);
}
-void COFFDumper::printLocalVariableAddrGap(StringRef &SymData) {
- while (!SymData.empty()) {
- const LocalVariableAddrGap *Gap;
- error(consumeObject(SymData, Gap));
+void COFFDumper::printLocalVariableAddrGap(
+ ArrayRef<LocalVariableAddrGap> Gaps) {
+ for (auto &Gap : Gaps) {
ListScope S(W, "LocalVariableAddrGap");
- W.printHex("GapStartOffset", Gap->GapStartOffset);
- W.printHex("Range", Gap->Range);
+ W.printHex("GapStartOffset", Gap.GapStartOffset);
+ W.printHex("Range", Gap.Range);
}
}