diff options
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView')
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp | 87 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/EnumTables.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp | 68 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/TypeDumper.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/TypeRecord.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp | 14 |
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(); |