summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/CodeView
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView')
-rw-r--r--llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp87
-rw-r--r--llvm/lib/DebugInfo/CodeView/EnumTables.cpp10
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp68
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDumper.cpp48
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeRecord.cpp9
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp14
6 files changed, 92 insertions, 144 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index 23e42e1468f..1b96b0cb947 100644
--- a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -15,52 +15,6 @@
using namespace llvm;
using namespace llvm::codeview;
-template <typename T>
-static Error takeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
- if (Data.size() < sizeof(*Res))
- return llvm::make_error<CodeViewError>(cv_error_code::insufficient_buffer);
- Res = reinterpret_cast<const T *>(Data.data());
- Data = Data.drop_front(sizeof(*Res));
- return Error::success();
-}
-
-template <typename T>
-static Expected<CVType> deserializeMemberRecord(ArrayRef<uint8_t> &Data,
- TypeLeafKind Kind) {
- ArrayRef<uint8_t> OldData = Data;
- TypeRecordKind RK = static_cast<TypeRecordKind>(Kind);
- auto ExpectedRecord = T::deserialize(RK, Data);
- if (!ExpectedRecord)
- return ExpectedRecord.takeError();
- assert(Data.size() < OldData.size());
- if (auto EC = skipPadding(Data))
- return std::move(EC);
-
- CVType CVR;
- CVR.Type = Kind;
- CVR.Length = OldData.size() - Data.size();
- CVR.Data = OldData.slice(0, CVR.Length);
- CVR.RawData = CVR.Data;
- return CVR;
-}
-
-static Error skipPadding(ArrayRef<uint8_t> &Data) {
- if (Data.empty())
- return Error::success();
- uint8_t Leaf = Data.front();
- if (Leaf < LF_PAD0)
- return Error::success();
- // Leaf is greater than 0xf0. We should advance by the number of bytes in
- // the low 4 bits.
- unsigned BytesToAdvance = Leaf & 0x0F;
- if (Data.size() < BytesToAdvance) {
- return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid padding bytes!");
- }
- Data = Data.drop_front(BytesToAdvance);
- return Error::success();
-}
-
CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
: Callbacks(Callbacks) {}
@@ -91,10 +45,7 @@ Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
TYPE_RECORD(EnumVal, EnumVal, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- TYPE_RECORD(EnumName, EnumVal, Name)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
- MEMBER_RECORD(EnumName, EnumVal, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
}
@@ -112,39 +63,3 @@ Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
}
return Error::success();
}
-
-Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {
- while (!Data.empty()) {
- const support::ulittle16_t *LeafValue;
- if (auto EC = takeObject(Data, LeafValue))
- return std::move(EC);
-
- TypeLeafKind Leaf = static_cast<TypeLeafKind>(uint16_t(*LeafValue));
- CVType Record;
- switch (Leaf) {
- default:
- // Field list records do not describe their own length, so we cannot
- // continue parsing past a type that we don't know how to deserialize.
- return llvm::make_error<CodeViewError>(
- cv_error_code::unknown_member_record);
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- case EnumName: { \
- auto ExpectedRecord = deserializeMemberRecord<Name##Record>(Data, Leaf); \
- if (!ExpectedRecord) \
- return ExpectedRecord.takeError(); \
- auto &Record = *ExpectedRecord; \
- if (auto EC = Callbacks.visitTypeBegin(Record)) \
- return EC; \
- if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \
- return EC; \
- if (auto EC = Callbacks.visitTypeEnd(Record)) \
- return EC; \
- break; \
- }
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
- MEMBER_RECORD(EnumVal, EnumVal, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
- }
- }
- return Error::success();
-}
diff --git a/llvm/lib/DebugInfo/CodeView/EnumTables.cpp b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
index 0e20bcb27ec..d59271b2367 100644
--- a/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -24,12 +24,6 @@ static const EnumEntry<SymbolKind> SymbolTypeNames[] = {
#undef CV_SYMBOL
};
-static const EnumEntry<TypeLeafKind> TypeLeafNames[] = {
-#define CV_TYPE(name, val) {#name, name},
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
-#undef CV_TYPE
-};
-
static const EnumEntry<uint16_t> RegisterNames[] = {
CV_ENUM_CLASS_ENT(RegisterId, Unknown),
CV_ENUM_CLASS_ENT(RegisterId, VFrame),
@@ -330,10 +324,6 @@ ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames() {
return makeArrayRef(SymbolTypeNames);
}
-ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() {
- return makeArrayRef(TypeLeafNames);
-}
-
ArrayRef<EnumEntry<uint16_t>> getRegisterNames() {
return makeArrayRef(RegisterNames);
}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp b/llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp
index 41aaa3c55b6..3593458565f 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp
@@ -11,3 +11,71 @@
using namespace llvm;
using namespace llvm::codeview;
+
+template <typename T>
+static Error takeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
+ if (Data.size() < sizeof(*Res))
+ return llvm::make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ Res = reinterpret_cast<const T *>(Data.data());
+ Data = Data.drop_front(sizeof(*Res));
+ return Error::success();
+}
+
+Error TypeDeserializer::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ FieldListRecord &Record) {
+ ArrayRef<uint8_t> FieldListRecordData = CVR.Data;
+ auto ExpectedRecord = FieldListRecord::deserialize(TypeRecordKind::FieldList,
+ FieldListRecordData);
+ if (!ExpectedRecord)
+ return ExpectedRecord.takeError();
+
+ Record = *ExpectedRecord;
+ ArrayRef<uint8_t> MemberData = Record.getFieldListData();
+
+ while (!MemberData.empty()) {
+ const ulittle16_t *LeafPtr;
+ if (auto EC = takeObject(MemberData, LeafPtr))
+ return EC;
+ TypeLeafKind Leaf = TypeLeafKind(unsigned(*LeafPtr));
+ switch (Leaf) {
+ default:
+ // Field list records do not describe their own length, so we cannot
+ // continue parsing past a type that we don't know how to deserialize.
+ if (auto EC = Recipient.visitUnknownMember(CVR))
+ return EC;
+ return llvm::make_error<CodeViewError>(
+ cv_error_code::unknown_member_record);
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ case EnumName: { \
+ TypeRecordKind RK = static_cast<TypeRecordKind>(Leaf); \
+ Name##Record Member(RK); \
+ if (auto EC = visitKnownMember(MemberData, Leaf, Member)) \
+ return EC; \
+ break; \
+ }
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
+ MEMBER_RECORD(EnumVal, EnumVal, AliasName)
+#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+ }
+ if (auto EC = skipPadding(MemberData))
+ return EC;
+ }
+ return Error::success();
+}
+
+Error TypeDeserializer::skipPadding(ArrayRef<uint8_t> &Data) {
+ if (Data.empty())
+ return Error::success();
+ uint8_t Leaf = Data.front();
+ if (Leaf < LF_PAD0)
+ return Error::success();
+ // Leaf is greater than 0xf0. We should advance by the number of bytes in
+ // the low 4 bits.
+ unsigned BytesToAdvance = Leaf & 0x0F;
+ if (Data.size() < BytesToAdvance) {
+ return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid padding bytes!");
+ }
+ Data = Data.drop_front(BytesToAdvance);
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp b/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
index 3f409762398..e1ec5ce9802 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
@@ -206,38 +206,21 @@ Error CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
// Reset Name to the empty string. If the visitor sets it, we know it.
Name = "";
- W->startLine() << getLeafTypeName(Record.Type);
- if (!IsInFieldList) {
- // If this is a field list member, don't record its type index because it
- // doesn't have one. Only the outer field list has a type index.
- W->getOStream() << " (" << HexNumber(getNextTypeIndex()) << ")";
- }
- W->getOStream() << " {\n";
+ W->startLine() << getLeafTypeName(Record.Type) << " ("
+ << HexNumber(getNextTypeIndex()) << ") {\n";
W->indent();
W->printEnum("TypeLeafKind", unsigned(Record.Type),
makeArrayRef(LeafTypeNames));
- if (Record.Type == LF_FIELDLIST) {
- // Record that we're in a field list so that members do not get assigned
- // type indices.
- assert(!IsInFieldList);
- IsInFieldList = true;
- }
return Error::success();
}
Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
- if (Record.Type == LF_FIELDLIST) {
- assert(IsInFieldList);
- IsInFieldList = false;
- }
+ if (Record.Type == LF_FIELDLIST)
+ Name = "<field list>";
- if (!IsInFieldList) {
- // Record every type that is not a field list member, even if Name is empty.
- // CVUDTNames is indexed by type index, and must have one entry for every
- // type. Field list members are not recorded, and are only referenced by
- // their containing field list record.
- recordType(Name);
- }
+ // Always record some name for every type, even if Name is empty. CVUDTNames
+ // is indexed by type index, and must have one entry for every type.
+ recordType(Name);
if (PrintRecordBytes)
W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));
@@ -249,12 +232,6 @@ Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
FieldListRecord &FieldList) {
- TypeDeserializer Deserializer(*this);
- CVTypeVisitor Visitor(Deserializer);
- if (auto EC = Visitor.visitFieldListMemberStream(FieldList.Data))
- return EC;
-
- Name = "<field list>";
return Error::success();
}
@@ -573,6 +550,7 @@ Error CVTypeDumper::visitUnknownMember(const CVRecord<TypeLeafKind> &Record) {
}
Error CVTypeDumper::visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
+ DictScope S(*W, "UnknownType");
W->printEnum("Kind", uint16_t(Record.Type), makeArrayRef(LeafTypeNames));
W->printNumber("Length", uint32_t(Record.Data.size()));
return Error::success();
@@ -580,6 +558,7 @@ Error CVTypeDumper::visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
NestedTypeRecord &Nested) {
+ DictScope S(*W, "NestedType");
printTypeIndex("Type", Nested.getNestedType());
W->printString("Name", Nested.getName());
Name = Nested.getName();
@@ -588,6 +567,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
OneMethodRecord &Method) {
+ DictScope S(*W, "OneMethod");
MethodKind K = Method.getKind();
printMemberAttributes(Method.getAccess(), K, Method.getOptions());
printTypeIndex("Type", Method.getType());
@@ -601,6 +581,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
OverloadedMethodRecord &Method) {
+ DictScope S(*W, "OverloadedMethod");
W->printHex("MethodCount", Method.getNumOverloads());
printTypeIndex("MethodListIndex", Method.getMethodList());
W->printString("Name", Method.getName());
@@ -610,6 +591,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
DataMemberRecord &Field) {
+ DictScope S(*W, "DataMember");
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
printTypeIndex("Type", Field.getType());
@@ -621,6 +603,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
StaticDataMemberRecord &Field) {
+ DictScope S(*W, "StaticDataMember");
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
printTypeIndex("Type", Field.getType());
@@ -631,12 +614,14 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
VFPtrRecord &VFTable) {
+ DictScope S(*W, "VFPtr");
printTypeIndex("Type", VFTable.getType());
return Error::success();
}
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
EnumeratorRecord &Enum) {
+ DictScope S(*W, "Enumerator");
printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
W->printNumber("EnumValue", Enum.getValue());
@@ -647,6 +632,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
BaseClassRecord &Base) {
+ DictScope S(*W, "BaseClass");
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
printTypeIndex("BaseType", Base.getBaseType());
@@ -656,6 +642,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
VirtualBaseClassRecord &Base) {
+ DictScope S(*W, "VirtualBaseClass");
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
printTypeIndex("BaseType", Base.getBaseType());
@@ -667,6 +654,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
ListContinuationRecord &Cont) {
+ DictScope S(*W, "ListContinuation");
printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
return Error::success();
}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp
index 47aa04fe76a..e630be87345 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp
@@ -8,9 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -117,9 +116,7 @@ NestedTypeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
Expected<FieldListRecord>
FieldListRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
- auto FieldListData = Data;
- Data = ArrayRef<uint8_t>();
- return FieldListRecord(FieldListData);
+ return FieldListRecord(Data);
}
Expected<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,
@@ -451,7 +448,7 @@ bool PointerRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
bool Success = true;
Success &= remapIndex(IndexMap, ReferentType);
if (isPointerToMember())
- Success &= MemberInfo->remapTypeIndices(IndexMap);
+ Success &= MemberInfo.remapTypeIndices(IndexMap);
return Success;
}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 968aa06cdd2..58c8c3fecb4 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -84,11 +84,6 @@ private:
Error visitKnownRecordImpl(FieldListRecord &Record) {
// Don't do anything, this will get written in the call to visitTypeEnd().
- TypeDeserializer Deserializer(*this);
- CVTypeVisitor Visitor(Deserializer);
-
- if (auto EC = Visitor.visitFieldListMemberStream(Record.Data))
- return std::move(EC);
return Error::success();
}
@@ -107,7 +102,6 @@ private:
TypeTableBuilder &DestStream;
- bool IsInFieldList{false};
size_t BeginIndexMapSize = 0;
/// Map from source type index to destination type index. Indexed by source
@@ -118,10 +112,7 @@ private:
} // end anonymous namespace
Error TypeStreamMerger::visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) {
- if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
- assert(!IsInFieldList);
- IsInFieldList = true;
- } else
+ if (Rec.Type != TypeLeafKind::LF_FIELDLIST)
BeginIndexMapSize = IndexMap.size();
return Error::success();
}
@@ -130,8 +121,7 @@ Error TypeStreamMerger::visitTypeEnd(const CVRecord<TypeLeafKind> &Rec) {
if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
IndexMap.push_back(DestStream.writeFieldList(FieldBuilder));
FieldBuilder.reset();
- IsInFieldList = false;
- } else if (!IsInFieldList) {
+ } else {
assert(IndexMap.size() == BeginIndexMapSize + 1);
}
return Error::success();
OpenPOWER on IntegriCloud