From: Zachary Turner Date: Thu, 20 Oct 2016 18:31:19 +0000 (+0000) Subject: [CodeView] Refactor serialization to use StreamInterface. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4d49eb9fa0bb4ddc87329192ca24ffebedd05e1b;p=platform%2Fupstream%2Fllvm.git [CodeView] Refactor serialization to use StreamInterface. This was all using ArrayRef<>s before which presents a problem when you want to serialize to or deserialize from an actual PDB stream. An ArrayRef<> is really just a special case of what can be handled with StreamInterface though (e.g. by using a ByteStream), so changing this to use StreamInterface allows us to plug in a PDB stream and get all the record serialization and deserialization for free on a MappedBlockStream. Subsequent patches will try to remove TypeTableBuilder and TypeRecordBuilder in favor of class that operate on Streams as well, which should allow us to completely merge the reading and writing codepaths for both types and symbols. Differential Revision: https://reviews.llvm.org/D25831 llvm-svn: 284762 --- diff --git a/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h index 77e74ff..d1b0363 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ b/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -30,6 +30,7 @@ public: Error visitTypeStream(const CVTypeArray &Types); Error visitFieldListMemberStream(ArrayRef FieldList); + Error visitFieldListMemberStream(msf::StreamReader Reader); private: /// The interface to the class that gets notified of each visitation. diff --git a/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h index 8b24086..a670bb4 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h +++ b/llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h @@ -15,6 +15,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/MSF/StreamReader.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include @@ -40,53 +41,40 @@ struct RecordPrefix { StringRef getBytesAsCharacters(ArrayRef LeafData); StringRef getBytesAsCString(ArrayRef LeafData); -/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if -/// there are not enough bytes remaining. Reinterprets the consumed bytes as a -/// T object and points 'Res' at them. -template -inline Error consumeObject(U &Data, const T *&Res) { - if (Data.size() < sizeof(*Res)) - return make_error( - cv_error_code::insufficient_buffer, - "Insufficient bytes for expected object type"); - Res = reinterpret_cast(Data.data()); - Data = Data.drop_front(sizeof(*Res)); - return Error::success(); -} - -inline Error consume(ArrayRef &Data) { return Error::success(); } +inline Error consume(msf::StreamReader &Reader) { return Error::success(); } /// Decodes a numeric "leaf" value. These are integer literals encountered in /// the type stream. If the value is positive and less than LF_NUMERIC (1 << /// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR /// that indicates the bitwidth and sign of the numeric data. -Error consume(ArrayRef &Data, APSInt &Num); -Error consume(StringRef &Data, APSInt &Num); +Error consume(msf::StreamReader &Reader, APSInt &Num); /// Decodes a numeric leaf value that is known to be a particular type. -Error consume_numeric(ArrayRef &Data, uint64_t &Value); +Error consume_numeric(msf::StreamReader &Reader, uint64_t &Value); /// Decodes signed and unsigned fixed-length integers. -Error consume(ArrayRef &Data, uint32_t &Item); -Error consume(StringRef &Data, uint32_t &Item); -Error consume(ArrayRef &Data, int32_t &Item); +Error consume(msf::StreamReader &Reader, uint32_t &Item); +Error consume(msf::StreamReader &Reader, int32_t &Item); /// Decodes a null terminated string. -Error consume(ArrayRef &Data, StringRef &Item); +Error consume(msf::StreamReader &Reader, StringRef &Item); + +Error consume(StringRef &Data, APSInt &Num); +Error consume(StringRef &Data, uint32_t &Item); /// Decodes an arbitrary object whose layout matches that of the underlying /// byte sequence, and returns a pointer to the object. -template Error consume(ArrayRef &Data, T *&Item) { - return consumeObject(Data, Item); +template Error consume(msf::StreamReader &Reader, T *&Item) { + return Reader.readObject(Item); } template struct serialize_conditional_impl { serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {} - Error deserialize(ArrayRef &Data) const { + Error deserialize(msf::StreamReader &Reader) const { if (!Func()) return Error::success(); - return consume(Data, Item); + return consume(Reader, Item); } T &Item; @@ -101,26 +89,8 @@ serialize_conditional_impl serialize_conditional(T &Item, U Func) { template struct serialize_array_impl { serialize_array_impl(ArrayRef &Item, U Func) : Item(Item), Func(Func) {} - Error deserialize(ArrayRef &Data) const { - uint32_t N = Func(); - if (N == 0) - return Error::success(); - - uint32_t Size = sizeof(T) * N; - - if (Size / sizeof(T) != N) - return make_error( - cv_error_code::corrupt_record, - "Array length is not a multiple of sizeof(T)"); - - if (Data.size() < Size) - return make_error( - cv_error_code::corrupt_record, - "Array does not contain enough data for all elements"); - - Item = ArrayRef(reinterpret_cast(Data.data()), N); - Data = Data.drop_front(Size); - return Error::success(); + Error deserialize(msf::StreamReader &Reader) const { + return Reader.readArray(Item, Func()); } ArrayRef &Item; @@ -130,11 +100,11 @@ template struct serialize_array_impl { template struct serialize_vector_tail_impl { serialize_vector_tail_impl(std::vector &Item) : Item(Item) {} - Error deserialize(ArrayRef &Data) const { + Error deserialize(msf::StreamReader &Reader) const { T Field; // Stop when we run out of bytes or we hit record padding bytes. - while (!Data.empty() && Data.front() < LF_PAD0) { - if (auto EC = consume(Data, Field)) + while (!Reader.empty() && Reader.peek() < LF_PAD0) { + if (auto EC = consume(Reader, Field)) return EC; Item.push_back(Field); } @@ -148,24 +118,18 @@ struct serialize_null_term_string_array_impl { serialize_null_term_string_array_impl(std::vector &Item) : Item(Item) {} - Error deserialize(ArrayRef &Data) const { - if (Data.empty()) + Error deserialize(msf::StreamReader &Reader) const { + if (Reader.empty()) return make_error(cv_error_code::insufficient_buffer, "Null terminated string is empty!"); - StringRef Field; - // Stop when we run out of bytes or we hit record padding bytes. - while (Data.front() != 0) { - if (auto EC = consume(Data, Field)) + while (Reader.peek() != 0) { + StringRef Field; + if (auto EC = Reader.readZeroString(Field)) return EC; Item.push_back(Field); - if (Data.empty()) - return make_error( - cv_error_code::insufficient_buffer, - "Null terminated string has no null terminator!"); } - Data = Data.drop_front(1); - return Error::success(); + return Reader.skip(1); } std::vector &Item; @@ -174,10 +138,9 @@ struct serialize_null_term_string_array_impl { template struct serialize_arrayref_tail_impl { serialize_arrayref_tail_impl(ArrayRef &Item) : Item(Item) {} - Error deserialize(ArrayRef &Data) const { - uint32_t Count = Data.size() / sizeof(T); - Item = ArrayRef(reinterpret_cast(Data.begin()), Count); - return Error::success(); + Error deserialize(msf::StreamReader &Reader) const { + uint32_t Count = Reader.bytesRemaining() / sizeof(T); + return Reader.readArray(Item, Count); } ArrayRef &Item; @@ -186,8 +149,8 @@ template struct serialize_arrayref_tail_impl { template struct serialize_numeric_impl { serialize_numeric_impl(T &Item) : Item(Item) {} - Error deserialize(ArrayRef &Data) const { - return consume_numeric(Data, Item); + Error deserialize(msf::StreamReader &Reader) const { + return consume_numeric(Reader, Item); } T &Item; @@ -238,43 +201,45 @@ template serialize_numeric_impl serialize_numeric(T &Item) { #define CV_NUMERIC_FIELD(I) serialize_numeric(I) template -Error consume(ArrayRef &Data, +Error consume(msf::StreamReader &Reader, const serialize_conditional_impl &Item) { - return Item.deserialize(Data); + return Item.deserialize(Reader); } template -Error consume(ArrayRef &Data, const serialize_array_impl &Item) { - return Item.deserialize(Data); +Error consume(msf::StreamReader &Reader, + const serialize_array_impl &Item) { + return Item.deserialize(Reader); } -inline Error consume(ArrayRef &Data, +inline Error consume(msf::StreamReader &Reader, const serialize_null_term_string_array_impl &Item) { - return Item.deserialize(Data); + return Item.deserialize(Reader); } template -Error consume(ArrayRef &Data, +Error consume(msf::StreamReader &Reader, const serialize_vector_tail_impl &Item) { - return Item.deserialize(Data); + return Item.deserialize(Reader); } template -Error consume(ArrayRef &Data, +Error consume(msf::StreamReader &Reader, const serialize_arrayref_tail_impl &Item) { - return Item.deserialize(Data); + return Item.deserialize(Reader); } template -Error consume(ArrayRef &Data, const serialize_numeric_impl &Item) { - return Item.deserialize(Data); +Error consume(msf::StreamReader &Reader, + const serialize_numeric_impl &Item) { + return Item.deserialize(Reader); } template -Error consume(ArrayRef &Data, T &&X, U &&Y, Args &&... Rest) { - if (auto EC = consume(Data, X)) +Error consume(msf::StreamReader &Reader, T &&X, U &&Y, Args &&... Rest) { + if (auto EC = consume(Reader, X)) return EC; - return consume(Data, Y, std::forward(Rest)...); + return consume(Reader, Y, std::forward(Rest)...); } #define CV_DESERIALIZE(...) \ diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h index 24e8c61..3ccc2db 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h +++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h @@ -14,6 +14,8 @@ #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h" +#include "llvm/DebugInfo/MSF/ByteStream.h" +#include "llvm/DebugInfo/MSF/StreamReader.h" #include "llvm/Support/Error.h" namespace llvm { @@ -33,11 +35,11 @@ public: protected: template - Error deserializeRecord(ArrayRef &Data, SymbolKind Kind, + Error deserializeRecord(msf::StreamReader &Reader, SymbolKind Kind, T &Record) const { - uint32_t RecordOffset = Delegate ? Delegate->getRecordOffset(Data) : 0; + uint32_t RecordOffset = Delegate ? Delegate->getRecordOffset(Reader) : 0; SymbolRecordKind RK = static_cast(Kind); - auto ExpectedRecord = T::deserialize(RK, RecordOffset, Data); + auto ExpectedRecord = T::deserialize(RK, RecordOffset, Reader); if (!ExpectedRecord) return ExpectedRecord.takeError(); Record = std::move(*ExpectedRecord); @@ -47,8 +49,9 @@ protected: private: template Error defaultVisitKnownRecord(CVSymbol &CVR, T &Record) { - ArrayRef RD = CVR.content(); - if (auto EC = deserializeRecord(RD, CVR.Type, Record)) + msf::ByteStream S(CVR.content()); + msf::StreamReader SR(S); + if (auto EC = deserializeRecord(SR, CVR.Type, Record)) return EC; return Error::success(); } diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 4eecda0..117c63b 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -64,10 +64,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return ProcSym(Kind, RecordOffset, H, Name); } @@ -104,12 +104,12 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; ArrayRef VariantData; - CV_DESERIALIZE(Data, H, Name, CV_ARRAY_FIELD_TAIL(VariantData)); + CV_DESERIALIZE(Reader, H, Name, CV_ARRAY_FIELD_TAIL(VariantData)); return Thunk32Sym(Kind, RecordOffset, H, Name, VariantData); } @@ -138,10 +138,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; - CV_DESERIALIZE(Data, H); + CV_DESERIALIZE(Reader, H); return TrampolineSym(Kind, RecordOffset, H); } @@ -171,11 +171,11 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return SectionSym(Kind, RecordOffset, H, Name); } @@ -204,11 +204,11 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return CoffGroupSym(Kind, RecordOffset, H, Name); } @@ -226,7 +226,7 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { return ScopeEndSym(Kind, RecordOffset); } uint32_t RecordOffset; @@ -246,11 +246,11 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *Header; ArrayRef Indices; - CV_DESERIALIZE(Data, Header, CV_ARRAY_FIELD_N(Indices, Header->Count)); + CV_DESERIALIZE(Reader, Header, CV_ARRAY_FIELD_N(Indices, Header->Count)); return CallerSym(Kind, RecordOffset, Header, Indices); } @@ -456,10 +456,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; ArrayRef Annotations; - CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Annotations)); + CV_DESERIALIZE(Reader, H, CV_ARRAY_FIELD_TAIL(Annotations)); return InlineSiteSym(RecordOffset, H, Annotations); } @@ -493,10 +493,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return PublicSym32(RecordOffset, H, Name); } @@ -522,10 +522,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return RegisterSym(RecordOffset, H, Name); } @@ -552,10 +552,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return ProcRefSym(RecordOffset, H, Name); } @@ -581,10 +581,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return LocalSym(RecordOffset, H, Name); } @@ -624,10 +624,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; ArrayRef Gaps; - CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); + CV_DESERIALIZE(Reader, H, CV_ARRAY_FIELD_TAIL(Gaps)); return DefRangeSym(RecordOffset, H, Gaps); } @@ -658,10 +658,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; ArrayRef Gaps; - CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); + CV_DESERIALIZE(Reader, H, CV_ARRAY_FIELD_TAIL(Gaps)); return DefRangeSubfieldSym(RecordOffset, H, Gaps); } @@ -702,10 +702,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; ArrayRef Gaps; - CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); + CV_DESERIALIZE(Reader, H, CV_ARRAY_FIELD_TAIL(Gaps)); return DefRangeRegisterSym(RecordOffset, H, Gaps); } @@ -750,10 +750,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; ArrayRef Gaps; - CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); + CV_DESERIALIZE(Reader, H, CV_ARRAY_FIELD_TAIL(Gaps)); return DefRangeSubfieldRegisterSym(RecordOffset, H, Gaps); } @@ -785,10 +785,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; ArrayRef Gaps; - CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); + CV_DESERIALIZE(Reader, H, CV_ARRAY_FIELD_TAIL(Gaps)); return DefRangeFramePointerRelSym(RecordOffset, H, Gaps); } @@ -830,12 +830,12 @@ public: Header.Range = {}; } - static Expected deserialize(SymbolRecordKind Kind, - uint32_t RecordOffset, - ArrayRef &Data) { + static Expected + deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, + msf::StreamReader &Reader) { const Hdr *H = nullptr; ArrayRef Gaps; - CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); + CV_DESERIALIZE(Reader, H, CV_ARRAY_FIELD_TAIL(Gaps)); return DefRangeRegisterRelSym(RecordOffset, H, Gaps); } @@ -876,9 +876,9 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; - CV_DESERIALIZE(Data, H); + CV_DESERIALIZE(Reader, H); return DefRangeFramePointerRelFullScopeSym(RecordOffset, H); } @@ -906,10 +906,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return BlockSym(RecordOffset, H, Name); } @@ -940,10 +940,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return LabelSym(RecordOffset, H, Name); } @@ -972,10 +972,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return ObjNameSym(RecordOffset, H, Name); } @@ -1001,10 +1001,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; std::vector Fields; - CV_DESERIALIZE(Data, H, CV_STRING_ARRAY_NULL_TERM(Fields)); + CV_DESERIALIZE(Reader, H, CV_STRING_ARRAY_NULL_TERM(Fields)); return EnvBlockSym(RecordOffset, H, Fields); } @@ -1030,10 +1030,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return ExportSym(RecordOffset, H, Name); } @@ -1060,10 +1060,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return FileStaticSym(RecordOffset, H, Name); } @@ -1097,10 +1097,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Version; - CV_DESERIALIZE(Data, H, Version); + CV_DESERIALIZE(Reader, H, Version); return Compile2Sym(RecordOffset, H, Version); } @@ -1135,10 +1135,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Version; - CV_DESERIALIZE(Data, H, Version); + CV_DESERIALIZE(Reader, H, Version); return Compile3Sym(RecordOffset, H, Version); } @@ -1168,9 +1168,9 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; - CV_DESERIALIZE(Data, H); + CV_DESERIALIZE(Reader, H); return FrameProcSym(RecordOffset, H); } @@ -1196,9 +1196,9 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; - CV_DESERIALIZE(Data, H); + CV_DESERIALIZE(Reader, H); return CallSiteInfoSym(RecordOffset, H); } @@ -1226,11 +1226,11 @@ public: : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym), RecordOffset(RecordOffset), Header(*H) {} - static Expected deserialize(SymbolRecordKind Kind, - uint32_t RecordOffset, - ArrayRef &Data) { + static Expected + deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, + msf::StreamReader &Reader) { const Hdr *H = nullptr; - CV_DESERIALIZE(Data, H); + CV_DESERIALIZE(Reader, H); return HeapAllocationSiteSym(RecordOffset, H); } @@ -1260,9 +1260,9 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; - CV_DESERIALIZE(Data, H); + CV_DESERIALIZE(Reader, H); return FrameCookieSym(RecordOffset, H); } @@ -1290,10 +1290,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return UDTSym(RecordOffset, H, Name); } @@ -1317,9 +1317,9 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; - CV_DESERIALIZE(Data, H); + CV_DESERIALIZE(Reader, H); return BuildInfoSym(RecordOffset, H); } @@ -1344,10 +1344,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return BPRelativeSym(RecordOffset, H, Name); } @@ -1374,10 +1374,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return RegRelativeSym(RecordOffset, H, Name); } @@ -1404,11 +1404,11 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; APSInt Value; StringRef Name; - CV_DESERIALIZE(Data, H, Value, Name); + CV_DESERIALIZE(Reader, H, Value, Name); return ConstantSym(RecordOffset, H, Value, Name); } @@ -1436,10 +1436,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return DataSym(RecordOffset, H, Name); } @@ -1470,10 +1470,10 @@ public: static Expected deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Hdr *H = nullptr; StringRef Name; - CV_DESERIALIZE(Data, H, Name); + CV_DESERIALIZE(Reader, H, Name); return ThreadLocalDataSym(RecordOffset, H, Name); } diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h index a496516..f4449ba 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h +++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h @@ -17,13 +17,17 @@ namespace llvm { +namespace msf { +class StreamReader; +} + namespace codeview { class SymbolVisitorDelegate { public: virtual ~SymbolVisitorDelegate() {} - virtual uint32_t getRecordOffset(ArrayRef Record) = 0; + virtual uint32_t getRecordOffset(msf::StreamReader Reader) = 0; virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0; virtual StringRef getStringTable() = 0; }; diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h index bf5c825..eb73ce0 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ b/llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -11,6 +11,8 @@ #define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/DebugInfo/Msf/ByteStream.h" +#include "llvm/DebugInfo/Msf/StreamReader.h" #include "llvm/Support/Error.h" namespace llvm { @@ -32,12 +34,11 @@ public: #include "TypeRecords.def" protected: - template - Error deserializeRecord(ArrayRef &Data, TypeLeafKind Kind, + Error deserializeRecord(msf::StreamReader &Reader, TypeLeafKind Kind, T &Record) const { TypeRecordKind RK = static_cast(Kind); - auto ExpectedRecord = T::deserialize(RK, Data); + auto ExpectedRecord = T::deserialize(RK, Reader); if (!ExpectedRecord) return ExpectedRecord.takeError(); Record = std::move(*ExpectedRecord); @@ -46,15 +47,17 @@ protected: private: template Error defaultVisitKnownRecord(CVType &CVR, T &Record) { - ArrayRef RD = CVR.content(); - if (auto EC = deserializeRecord(RD, CVR.Type, Record)) + msf::ByteStream S(CVR.content()); + msf::StreamReader SR(S); + if (auto EC = deserializeRecord(SR, CVR.Type, Record)) return EC; return Error::success(); } template Error defaultVisitKnownMember(CVMemberRecord &CVMR, T &Record) { - ArrayRef RD = CVMR.Data; - if (auto EC = deserializeRecord(RD, CVMR.Kind, Record)) + msf::ByteStream S(CVMR.Data); + msf::StreamReader SR(S); + if (auto EC = deserializeRecord(SR, CVMR.Kind, Record)) return EC; return Error::success(); } diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h index 16800d9..35f0775d 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -22,6 +22,11 @@ #include namespace llvm { + +namespace msf { +class StreamReader; +} + namespace codeview { using llvm::support::little32_t; @@ -92,7 +97,7 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(ArrayRef &Data); + static Expected deserialize(msf::StreamReader &Reader); TypeIndex getContainingType() const { return ContainingType; } PointerToMemberRepresentation getRepresentation() const { @@ -134,7 +139,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getModifiedType() const { return ModifiedType; } ModifierOptions getModifiers() const { return Modifiers; } @@ -165,7 +170,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); static uint32_t getLayoutSize() { return 2 + sizeof(Layout); } @@ -211,7 +216,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getReturnType() const { return ReturnType; } TypeIndex getClassType() const { return ClassType; } @@ -258,7 +263,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getClassType() const { return ClassType; } TypeIndex getFunctionType() const { return FunctionType; } StringRef getName() const { return Name; } @@ -287,7 +292,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); ArrayRef getIndices() const { return StringIndices; } @@ -333,7 +338,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getReferentType() const { return ReferentType; } PointerKind getPointerKind() const { return PtrKind; } @@ -410,7 +415,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getNestedType() const { return Type; } StringRef getName() const { return Name; } @@ -438,7 +443,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap) { return false; } static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); ArrayRef Data; }; @@ -457,7 +462,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getElementType() const { return ElementType; } TypeIndex getIndexType() const { return IndexType; } @@ -526,7 +531,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); HfaKind getHfa() const { return Hfa; } WindowsRTClassKind getWinRTKind() const { return WinRTKind; } @@ -568,7 +573,7 @@ struct UnionRecord : public TagRecord { Hfa(Hfa), Size(Size) {} static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); HfaKind getHfa() const { return Hfa; } uint64_t getSize() const { return Size; } @@ -605,7 +610,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getUnderlyingType() const { return UnderlyingType; } TypeIndex UnderlyingType; @@ -638,7 +643,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getType() const { return Type; } uint8_t getBitOffset() const { return BitOffset; } @@ -670,7 +675,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); ArrayRef getSlots() const { if (!SlotsRef.empty()) @@ -705,7 +710,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); StringRef getGuid() const { return Guid; } @@ -736,7 +741,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getId() const { return Id; } @@ -764,7 +769,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getParentScope() const { return ParentScope; } @@ -797,7 +802,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } @@ -826,10 +831,10 @@ public: bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + static Expected + deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); + CV_DESERIALIZE(Reader, L); return UdtModSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber, L->Module); @@ -867,7 +872,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); ArrayRef getArgs() const { return ArgIndices; } SmallVector ArgIndices; @@ -901,7 +906,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getCompleteClass() const { return CompleteClass; } TypeIndex getOverriddenVTable() const { return OverriddenVFTable; } @@ -947,7 +952,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getType() const { return Type; } MethodKind getKind() const { return Kind; } @@ -990,7 +995,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected - deserialize(TypeRecordKind Kind, ArrayRef &Data); + deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); ArrayRef getMethods() const { return Methods; } std::vector Methods; @@ -1020,8 +1025,8 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + static Expected + deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); uint16_t getNumOverloads() const { return NumOverloads; } TypeIndex getMethodList() const { return MethodList; } @@ -1053,7 +1058,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); MemberAccess getAccess() const { return Access; } TypeIndex getType() const { return Type; } @@ -1086,8 +1091,8 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + static Expected + deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); MemberAccess getAccess() const { return Access; } TypeIndex getType() const { return Type; } @@ -1118,7 +1123,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); MemberAccess getAccess() const { return Access; } APSInt getValue() const { return Value; } @@ -1148,7 +1153,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); TypeIndex getType() const { return Type; } TypeIndex Type; @@ -1173,7 +1178,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + msf::StreamReader &Reader); MemberAccess getAccess() const { return Access; } TypeIndex getBaseType() const { return Type; } @@ -1204,8 +1209,8 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + static Expected + deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); MemberAccess getAccess() const { return Access; } TypeIndex getBaseType() const { return BaseType; } @@ -1241,8 +1246,8 @@ public: bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - ArrayRef &Data); + static Expected + deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); TypeIndex ContinuationIndex; private: diff --git a/llvm/include/llvm/DebugInfo/MSF/ByteStream.h b/llvm/include/llvm/DebugInfo/MSF/ByteStream.h index 737693a..34361ef 100644 --- a/llvm/include/llvm/DebugInfo/MSF/ByteStream.h +++ b/llvm/include/llvm/DebugInfo/MSF/ByteStream.h @@ -28,6 +28,8 @@ class ByteStream : public ReadableStream { public: ByteStream() {} explicit ByteStream(ArrayRef Data) : Data(Data) {} + explicit ByteStream(StringRef Data) + : Data(Data.bytes_begin(), Data.bytes_end()) {} Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const override { diff --git a/llvm/include/llvm/DebugInfo/MSF/StreamReader.h b/llvm/include/llvm/DebugInfo/MSF/StreamReader.h index 5c971e0..fc2ca78 100644 --- a/llvm/include/llvm/DebugInfo/MSF/StreamReader.h +++ b/llvm/include/llvm/DebugInfo/MSF/StreamReader.h @@ -29,8 +29,14 @@ public: Error readLongestContiguousChunk(ArrayRef &Buffer); Error readBytes(ArrayRef &Buffer, uint32_t Size); + Error readInteger(uint8_t &Dest); Error readInteger(uint16_t &Dest); Error readInteger(uint32_t &Dest); + Error readInteger(uint64_t &Dest); + Error readInteger(int8_t &Dest); + Error readInteger(int16_t &Dest); + Error readInteger(int32_t &Dest); + Error readInteger(int64_t &Dest); Error readZeroString(StringRef &Dest); Error readFixedString(StringRef &Dest, uint32_t Length); Error readStreamRef(ReadableStreamRef &Ref); @@ -101,6 +107,10 @@ public: uint32_t getLength() const { return Stream.getLength(); } uint32_t bytesRemaining() const { return getLength() - getOffset(); } + Error skip(uint32_t Amount); + + uint8_t peek() const; + private: ReadableStreamRef Stream; uint32_t Offset; diff --git a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp index deefa8d..2dee898 100644 --- a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp +++ b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp @@ -15,47 +15,38 @@ using namespace llvm; using namespace llvm::codeview; -template -static Error takeObject(ArrayRef &Data, const T *&Res) { - if (Data.size() < sizeof(*Res)) - return llvm::make_error(cv_error_code::insufficient_buffer); - Res = reinterpret_cast(Data.data()); - Data = Data.drop_front(sizeof(*Res)); - return Error::success(); -} - -static Error skipPadding(ArrayRef &Data) { - if (Data.empty()) +static Error skipPadding(msf::StreamReader &Reader) { + if (Reader.empty()) return Error::success(); - uint8_t Leaf = Data.front(); + + uint8_t Leaf = Reader.peek(); 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(cv_error_code::corrupt_record, - "Invalid padding bytes!"); - } - Data = Data.drop_front(BytesToAdvance); - return Error::success(); + return Reader.skip(BytesToAdvance); } template -static Expected deserializeMemberRecord(ArrayRef &Data, - TypeLeafKind Kind) { - ArrayRef OldData = Data; +static Expected +deserializeMemberRecord(msf::StreamReader &Reader, TypeLeafKind Kind) { + msf::StreamReader OldReader = Reader; TypeRecordKind RK = static_cast(Kind); - auto ExpectedRecord = T::deserialize(RK, Data); + auto ExpectedRecord = T::deserialize(RK, Reader); if (!ExpectedRecord) return ExpectedRecord.takeError(); - assert(Data.size() < OldData.size()); - if (auto EC = skipPadding(Data)) + assert(Reader.bytesRemaining() < OldReader.bytesRemaining()); + if (auto EC = skipPadding(Reader)) return std::move(EC); CVMemberRecord CVMR; CVMR.Kind = Kind; - CVMR.Data = OldData.drop_back(Data.size()); + + uint32_t RecordLength = OldReader.bytesRemaining() - Reader.bytesRemaining(); + if (auto EC = OldReader.readBytes(CVMR.Data, RecordLength)) + return std::move(EC); + return CVMR; } @@ -147,9 +138,9 @@ Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) { } template -static Error visitKnownMember(ArrayRef &Data, TypeLeafKind Leaf, +static Error visitKnownMember(msf::StreamReader &Reader, TypeLeafKind Leaf, TypeVisitorCallbacks &Callbacks) { - auto ExpectedRecord = deserializeMemberRecord(Data, Leaf); + auto ExpectedRecord = deserializeMemberRecord(Reader, Leaf); if (!ExpectedRecord) return ExpectedRecord.takeError(); CVMemberRecord &Record = *ExpectedRecord; @@ -162,13 +153,12 @@ static Error visitKnownMember(ArrayRef &Data, TypeLeafKind Leaf, return Error::success(); } -Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef Data) { - while (!Data.empty()) { - const support::ulittle16_t *LeafValue; - if (auto EC = takeObject(Data, LeafValue)) +Error CVTypeVisitor::visitFieldListMemberStream(msf::StreamReader Reader) { + TypeLeafKind Leaf; + while (!Reader.empty()) { + if (auto EC = Reader.readEnum(Leaf)) return EC; - TypeLeafKind Leaf = static_cast(uint16_t(*LeafValue)); CVType Record; switch (Leaf) { default: @@ -178,7 +168,7 @@ Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef Data) { cv_error_code::unknown_member_record); #define MEMBER_RECORD(EnumName, EnumVal, Name) \ case EnumName: { \ - if (auto EC = visitKnownMember(Data, Leaf, Callbacks)) \ + if (auto EC = visitKnownMember(Reader, Leaf, Callbacks)) \ return EC; \ break; \ } @@ -189,3 +179,9 @@ Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef Data) { } return Error::success(); } + +Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef Data) { + msf::ByteStream S(Data); + msf::StreamReader SR(S); + return visitFieldListMemberStream(SR); +} diff --git a/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp b/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp index 9386d29..6f29caa 100644 --- a/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp +++ b/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/APSInt.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/MSF/ByteStream.h" using namespace llvm; using namespace llvm::codeview; @@ -32,114 +33,88 @@ StringRef llvm::codeview::getBytesAsCString(ArrayRef LeafData) { return getBytesAsCharacters(LeafData).split('\0').first; } -Error llvm::codeview::consume(ArrayRef &Data, APSInt &Num) { +Error llvm::codeview::consume(msf::StreamReader &Reader, APSInt &Num) { // Used to avoid overload ambiguity on APInt construtor. bool FalseVal = false; - if (Data.size() < 2) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an APSInt"); - uint16_t Short = *reinterpret_cast(Data.data()); - Data = Data.drop_front(2); + uint16_t Short; + if (auto EC = Reader.readInteger(Short)) + return EC; + if (Short < LF_NUMERIC) { Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false), /*isUnsigned=*/true); return Error::success(); } + switch (Short) { - case LF_CHAR: - if (Data.size() < 1) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an LF_CHAR"); - Num = APSInt(APInt(/*numBits=*/8, - *reinterpret_cast(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(1); + case LF_CHAR: { + int8_t N; + if (auto EC = Reader.readInteger(N)) + return EC; + Num = APSInt(APInt(8, N, true), false); return Error::success(); - case LF_SHORT: - if (Data.size() < 2) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an LF_SHORT"); - Num = APSInt(APInt(/*numBits=*/16, - *reinterpret_cast(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(2); + } + case LF_SHORT: { + int16_t N; + if (auto EC = Reader.readInteger(N)) + return EC; + Num = APSInt(APInt(16, N, true), false); return Error::success(); - case LF_USHORT: - if (Data.size() < 2) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an LF_USHORT"); - Num = APSInt(APInt(/*numBits=*/16, - *reinterpret_cast(Data.data()), - /*isSigned=*/false), - /*isUnsigned=*/true); - Data = Data.drop_front(2); + } + case LF_USHORT: { + uint16_t N; + if (auto EC = Reader.readInteger(N)) + return EC; + Num = APSInt(APInt(16, N, false), true); return Error::success(); - case LF_LONG: - if (Data.size() < 4) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an LF_LONG"); - Num = APSInt(APInt(/*numBits=*/32, - *reinterpret_cast(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(4); + } + case LF_LONG: { + int32_t N; + if (auto EC = Reader.readInteger(N)) + return EC; + Num = APSInt(APInt(32, N, true), false); return Error::success(); - case LF_ULONG: - if (Data.size() < 4) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an LF_ULONG"); - Num = APSInt(APInt(/*numBits=*/32, - *reinterpret_cast(Data.data()), - /*isSigned=*/FalseVal), - /*isUnsigned=*/true); - Data = Data.drop_front(4); + } + case LF_ULONG: { + uint32_t N; + if (auto EC = Reader.readInteger(N)) + return EC; + Num = APSInt(APInt(32, N, FalseVal), true); return Error::success(); - case LF_QUADWORD: - if (Data.size() < 8) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an LF_QUADWORD"); - Num = APSInt(APInt(/*numBits=*/64, - *reinterpret_cast(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(8); + } + case LF_QUADWORD: { + int64_t N; + if (auto EC = Reader.readInteger(N)) + return EC; + Num = APSInt(APInt(64, N, true), false); return Error::success(); - case LF_UQUADWORD: - if (Data.size() < 8) - return make_error( - cv_error_code::insufficient_buffer, - "Buffer does not contain enough data for an LF_UQUADWORD"); - Num = APSInt(APInt(/*numBits=*/64, - *reinterpret_cast(Data.data()), - /*isSigned=*/false), - /*isUnsigned=*/true); - Data = Data.drop_front(8); + } + case LF_UQUADWORD: { + uint64_t N; + if (auto EC = Reader.readInteger(N)) + return EC; + Num = APSInt(APInt(64, N, false), true); return Error::success(); } + } return make_error(cv_error_code::corrupt_record, "Buffer contains invalid APSInt type"); } Error llvm::codeview::consume(StringRef &Data, APSInt &Num) { ArrayRef Bytes(Data.bytes_begin(), Data.bytes_end()); - auto EC = consume(Bytes, Num); - Data = StringRef(reinterpret_cast(Bytes.data()), Bytes.size()); + msf::ByteStream S(Bytes); + msf::StreamReader SR(S); + auto EC = consume(SR, Num); + Data = Data.take_back(SR.bytesRemaining()); return EC; } /// Decode a numeric leaf value that is known to be a uint64_t. -Error llvm::codeview::consume_numeric(ArrayRef &Data, uint64_t &Num) { +Error llvm::codeview::consume_numeric(msf::StreamReader &Reader, + uint64_t &Num) { APSInt N; - if (auto EC = consume(Data, N)) + if (auto EC = consume(Reader, N)) return EC; if (N.isSigned() || !N.isIntN(64)) return make_error(cv_error_code::corrupt_record, @@ -148,41 +123,27 @@ Error llvm::codeview::consume_numeric(ArrayRef &Data, uint64_t &Num) { return Error::success(); } -Error llvm::codeview::consume(ArrayRef &Data, uint32_t &Item) { - const support::ulittle32_t *IntPtr; - if (auto EC = consumeObject(Data, IntPtr)) - return EC; - Item = *IntPtr; - return Error::success(); +Error llvm::codeview::consume(msf::StreamReader &Reader, uint32_t &Item) { + return Reader.readInteger(Item); } Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) { ArrayRef Bytes(Data.bytes_begin(), Data.bytes_end()); - auto EC = consume(Bytes, Item); - Data = StringRef(reinterpret_cast(Bytes.data()), Bytes.size()); + msf::ByteStream S(Bytes); + msf::StreamReader SR(S); + auto EC = consume(SR, Item); + Data = Data.take_back(SR.bytesRemaining()); return EC; } -Error llvm::codeview::consume(ArrayRef &Data, int32_t &Item) { - const support::little32_t *IntPtr; - if (auto EC = consumeObject(Data, IntPtr)) - return EC; - Item = *IntPtr; - return Error::success(); +Error llvm::codeview::consume(msf::StreamReader &Reader, int32_t &Item) { + return Reader.readInteger(Item); } -Error llvm::codeview::consume(ArrayRef &Data, StringRef &Item) { - if (Data.empty()) +Error llvm::codeview::consume(msf::StreamReader &Reader, StringRef &Item) { + if (Reader.empty()) return make_error(cv_error_code::corrupt_record, "Null terminated string buffer is empty!"); - StringRef Rest; - std::tie(Item, Rest) = getBytesAsCharacters(Data).split('\0'); - // We expect this to be null terminated. If it was not, it is an error. - if (Data.size() == Item.size()) - return make_error(cv_error_code::corrupt_record, - "Expected null terminator!"); - - Data = ArrayRef(Rest.bytes_begin(), Rest.bytes_end()); - return Error::success(); + return Reader.readZeroString(Item); } diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp index 47aa04f..a7a1bb9 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp @@ -11,6 +11,7 @@ #include "llvm/DebugInfo/CodeView/RecordSerialization.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/MSF/ByteStream.h" +#include "llvm/DebugInfo/MSF/StreamReader.h" using namespace llvm; using namespace llvm::codeview; @@ -20,9 +21,9 @@ using namespace llvm::codeview; //===----------------------------------------------------------------------===// Expected -MemberPointerInfo::deserialize(ArrayRef &Data) { +MemberPointerInfo::deserialize(msf::StreamReader &Reader) { const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) + if (auto EC = Reader.readObject(L)) return std::move(EC); TypeIndex T = L->ClassType; @@ -32,10 +33,10 @@ MemberPointerInfo::deserialize(ArrayRef &Data) { return MemberPointerInfo(T, PMR); } -Expected ModifierRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { +Expected +ModifierRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) + if (auto EC = Reader.readObject(L)) return std::move(EC); TypeIndex M = L->ModifiedType; @@ -45,9 +46,9 @@ Expected ModifierRecord::deserialize(TypeRecordKind Kind, } Expected -ProcedureRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +ProcedureRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) + if (auto EC = Reader.readObject(L)) return std::move(EC); return ProcedureRecord(L->ReturnType, L->CallConv, L->Options, L->NumParameters, L->ArgListType); @@ -55,24 +56,25 @@ ProcedureRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { Expected MemberFunctionRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); + CV_DESERIALIZE(Reader, L); return MemberFunctionRecord(L->ReturnType, L->ClassType, L->ThisType, L->CallConv, L->Options, L->NumParameters, L->ArgListType, L->ThisAdjustment); } Expected -MemberFuncIdRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +MemberFuncIdRecord::deserialize(TypeRecordKind Kind, + msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; - CV_DESERIALIZE(Data, L, Name); + CV_DESERIALIZE(Reader, L, Name); return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name); } Expected ArgListRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList) return make_error( cv_error_code::corrupt_record, @@ -80,14 +82,14 @@ Expected ArgListRecord::deserialize(TypeRecordKind Kind, const Layout *L = nullptr; ArrayRef Indices; - CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); + CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); return ArgListRecord(Kind, Indices); } Expected PointerRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) + if (auto EC = Reader.readObject(L)) return std::move(EC); PointerKind PtrKind = L->getPtrKind(); @@ -97,7 +99,7 @@ Expected PointerRecord::deserialize(TypeRecordKind Kind, uint8_t Size = L->getPtrSize(); if (L->isPointerToMember()) { - if (auto ExpectedMPI = MemberPointerInfo::deserialize(Data)) + if (auto ExpectedMPI = MemberPointerInfo::deserialize(Reader)) return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size, *ExpectedMPI); else @@ -108,38 +110,39 @@ Expected PointerRecord::deserialize(TypeRecordKind Kind, } Expected -NestedTypeRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +NestedTypeRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; - CV_DESERIALIZE(Data, L, Name); + CV_DESERIALIZE(Reader, L, Name); return NestedTypeRecord(L->Type, Name); } Expected -FieldListRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { - auto FieldListData = Data; - Data = ArrayRef(); - return FieldListRecord(FieldListData); +FieldListRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { + ArrayRef Data; + if (auto EC = Reader.readBytes(Data, Reader.bytesRemaining())) + return std::move(EC); + return FieldListRecord(Data); } Expected ArrayRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; uint64_t Size; StringRef Name; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name); + CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Size), Name); return ArrayRecord(L->ElementType, L->IndexType, Size, Name); } Expected ClassRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { uint64_t Size = 0; StringRef Name; StringRef UniqueName; uint16_t Props; const Layout *L = nullptr; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name, + CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Size), Name, CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); Props = L->Properties; @@ -154,14 +157,14 @@ Expected ClassRecord::deserialize(TypeRecordKind Kind, } Expected UnionRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { uint64_t Size = 0; StringRef Name; StringRef UniqueName; uint16_t Props; const Layout *L = nullptr; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name, + CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Size), Name, CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); Props = L->Properties; @@ -174,11 +177,11 @@ Expected UnionRecord::deserialize(TypeRecordKind Kind, } Expected EnumRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; StringRef UniqueName; - CV_DESERIALIZE(Data, L, Name, + CV_DESERIALIZE(Reader, L, Name, CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); uint16_t P = L->Properties; @@ -187,97 +190,98 @@ Expected EnumRecord::deserialize(TypeRecordKind Kind, UniqueName, L->UnderlyingType); } -Expected BitFieldRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { +Expected +BitFieldRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); + CV_DESERIALIZE(Reader, L); return BitFieldRecord(L->Type, L->BitSize, L->BitOffset); } Expected -VFTableShapeRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +VFTableShapeRecord::deserialize(TypeRecordKind Kind, + msf::StreamReader &Reader) { const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) + if (auto EC = Reader.readObject(L)) return std::move(EC); std::vector Slots; uint16_t Count = L->VFEntryCount; while (Count > 0) { - if (Data.empty()) - return make_error(cv_error_code::corrupt_record, - "VTableShapeRecord contains no entries"); - // Process up to 2 nibbles at a time (if there are at least 2 remaining) - uint8_t Value = Data[0] & 0x0F; + uint8_t Data; + if (auto EC = Reader.readInteger(Data)) + return std::move(EC); + + uint8_t Value = Data & 0x0F; Slots.push_back(static_cast(Value)); if (--Count > 0) { - Value = (Data[0] & 0xF0) >> 4; + Value = (Data & 0xF0) >> 4; Slots.push_back(static_cast(Value)); --Count; } - Data = Data.slice(1); } return VFTableShapeRecord(Slots); } Expected -TypeServer2Record::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +TypeServer2Record::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; - CV_DESERIALIZE(Data, L, Name); + CV_DESERIALIZE(Reader, L, Name); return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name); } -Expected StringIdRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { +Expected +StringIdRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; - CV_DESERIALIZE(Data, L, Name); + CV_DESERIALIZE(Reader, L, Name); return StringIdRecord(L->id, Name); } Expected FuncIdRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; - CV_DESERIALIZE(Data, L, Name); + CV_DESERIALIZE(Reader, L, Name); return FuncIdRecord(L->ParentScope, L->FunctionType, Name); } Expected -UdtSourceLineRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +UdtSourceLineRecord::deserialize(TypeRecordKind Kind, + msf::StreamReader &Reader) { const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); + CV_DESERIALIZE(Reader, L); return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber); } Expected -BuildInfoRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +BuildInfoRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; ArrayRef Indices; - CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); + CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); return BuildInfoRecord(Indices); } Expected VFTableRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; std::vector Names; - CV_DESERIALIZE(Data, L, Name, CV_ARRAY_FIELD_TAIL(Names)); + CV_DESERIALIZE(Reader, L, Name, CV_ARRAY_FIELD_TAIL(Names)); return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset, Name, Names); } Expected -OneMethodRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +OneMethodRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; int32_t VFTableOffset = -1; - CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD(VFTableOffset, - L->Attrs.isIntroducedVirtual()), + CV_DESERIALIZE(Reader, L, CV_CONDITIONAL_FIELD( + VFTableOffset, L->Attrs.isIntroducedVirtual()), Name); MethodOptions Options = L->Attrs.getFlags(); @@ -294,13 +298,14 @@ OneMethodRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { Expected MethodOverloadListRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { std::vector Methods; - while (!Data.empty()) { + while (!Reader.empty()) { const Layout *L = nullptr; int32_t VFTableOffset = -1; - CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD( - VFTableOffset, L->Attrs.isIntroducedVirtual())); + CV_DESERIALIZE( + Reader, L, + CV_CONDITIONAL_FIELD(VFTableOffset, L->Attrs.isIntroducedVirtual())); MethodOptions Options = L->Attrs.getFlags(); MethodKind MethKind = L->Attrs.getMethodKind(); @@ -320,72 +325,72 @@ MethodOverloadListRecord::deserialize(TypeRecordKind Kind, Expected OverloadedMethodRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; - CV_DESERIALIZE(Data, L, Name); + CV_DESERIALIZE(Reader, L, Name); return OverloadedMethodRecord(L->MethodCount, L->MethList, Name); } Expected -DataMemberRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +DataMemberRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; uint64_t Offset; StringRef Name; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), Name); + CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset), Name); return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name); } Expected StaticDataMemberRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; StringRef Name; - CV_DESERIALIZE(Data, L, Name); + CV_DESERIALIZE(Reader, L, Name); return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name); } Expected -EnumeratorRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +EnumeratorRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; APSInt Value; StringRef Name; - CV_DESERIALIZE(Data, L, Value, Name); + CV_DESERIALIZE(Reader, L, Value, Name); return EnumeratorRecord(L->Attrs.getAccess(), Value, Name); } Expected VFPtrRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) + if (auto EC = Reader.readObject(L)) return std::move(EC); return VFPtrRecord(L->Type); } Expected -BaseClassRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { +BaseClassRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { const Layout *L = nullptr; uint64_t Offset; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset)); + CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset)); return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset); } Expected VirtualBaseClassRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; uint64_t Offset; uint64_t Index; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), CV_NUMERIC_FIELD(Index)); + CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset), CV_NUMERIC_FIELD(Index)); return VirtualBaseClassRecord(L->Attrs.getAccess(), L->BaseType, L->VBPtrType, Offset, Index); } Expected ListContinuationRecord::deserialize(TypeRecordKind Kind, - ArrayRef &Data) { + msf::StreamReader &Reader) { const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); + CV_DESERIALIZE(Reader, L); return ListContinuationRecord(L->ContinuationIndex); } diff --git a/llvm/lib/DebugInfo/MSF/StreamReader.cpp b/llvm/lib/DebugInfo/MSF/StreamReader.cpp index eb3d3e8..b85fd14 100644 --- a/llvm/lib/DebugInfo/MSF/StreamReader.cpp +++ b/llvm/lib/DebugInfo/MSF/StreamReader.cpp @@ -31,6 +31,14 @@ Error StreamReader::readBytes(ArrayRef &Buffer, uint32_t Size) { return Error::success(); } +Error StreamReader::readInteger(uint8_t &Dest) { + const uint8_t *P; + if (auto EC = readObject(P)) + return EC; + Dest = *P; + return Error::success(); +} + Error StreamReader::readInteger(uint16_t &Dest) { const support::ulittle16_t *P; if (auto EC = readObject(P)) @@ -47,6 +55,46 @@ Error StreamReader::readInteger(uint32_t &Dest) { return Error::success(); } +Error StreamReader::readInteger(uint64_t &Dest) { + const support::ulittle64_t *P; + if (auto EC = readObject(P)) + return EC; + Dest = *P; + return Error::success(); +} + +Error StreamReader::readInteger(int8_t &Dest) { + const int8_t *P; + if (auto EC = readObject(P)) + return EC; + Dest = *P; + return Error::success(); +} + +Error StreamReader::readInteger(int16_t &Dest) { + const support::little16_t *P; + if (auto EC = readObject(P)) + return EC; + Dest = *P; + return Error::success(); +} + +Error StreamReader::readInteger(int32_t &Dest) { + const support::little32_t *P; + if (auto EC = readObject(P)) + return EC; + Dest = *P; + return Error::success(); +} + +Error StreamReader::readInteger(int64_t &Dest) { + const support::little64_t *P; + if (auto EC = readObject(P)) + return EC; + Dest = *P; + return Error::success(); +} + Error StreamReader::readZeroString(StringRef &Dest) { uint32_t Length = 0; // First compute the length of the string by reading 1 byte at a time. @@ -91,3 +139,18 @@ Error StreamReader::readStreamRef(ReadableStreamRef &Ref, uint32_t Length) { Offset += Length; return Error::success(); } + +Error StreamReader::skip(uint32_t Amount) { + if (Amount > bytesRemaining()) + return make_error(msf_error_code::insufficient_buffer); + Offset += Amount; + return Error::success(); +} + +uint8_t StreamReader::peek() const { + ArrayRef Buffer; + auto EC = Stream.readBytes(Offset, 1, Buffer); + assert(!EC && "Cannot peek an empty buffer!"); + llvm::consumeError(std::move(EC)); + return Buffer[0]; +} diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 2b45d1d..73118eb 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -154,8 +154,13 @@ public: Sec = Obj->getCOFFSection(SR); } - uint32_t getRecordOffset(ArrayRef Record) override { - return Record.data() - SectionContents.bytes_begin(); + uint32_t getRecordOffset(msf::StreamReader Reader) override { + ArrayRef Data; + if (auto EC = Reader.readLongestContiguousChunk(Data)) { + llvm::consumeError(std::move(EC)); + return 0; + } + return Data.data() - SectionContents.bytes_begin(); } void printRelocatedField(StringRef Label, uint32_t RelocOffset, @@ -835,8 +840,10 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, } case ModuleSubstreamKind::FrameData: { // First four bytes is a relocation against the function. + msf::ByteStream S(Contents); + msf::StreamReader SR(S); const uint32_t *CodePtr; - error(consumeObject(Contents, CodePtr)); + error(SR.readObject(CodePtr)); StringRef LinkageName; error(resolveSymbolName(Obj->getCOFFSection(Section), SectionContents, CodePtr, LinkageName)); @@ -844,9 +851,9 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, // To find the active frame description, search this array for the // smallest PC range that includes the current PC. - while (!Contents.empty()) { + while (!SR.empty()) { const FrameData *FD; - error(consumeObject(Contents, FD)); + error(SR.readObject(FD)); if (FD->FrameFunc >= CVStringTable.size()) error(object_error::parse_failed); @@ -974,11 +981,12 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, } void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { - StringRef Data = Subsection; - while (!Data.empty()) { + msf::ByteStream S(Subsection); + msf::StreamReader SR(S); + while (!SR.empty()) { DictScope S(W, "FileChecksum"); const FileChecksum *FC; - error(consumeObject(Data, FC)); + error(SR.readObject(FC)); if (FC->FileNameOffset >= CVStringTable.size()) error(object_error::parse_failed); StringRef Filename = @@ -987,27 +995,30 @@ void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { W.printHex("ChecksumSize", FC->ChecksumSize); W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind), makeArrayRef(FileChecksumKindNames)); - if (FC->ChecksumSize >= Data.size()) + if (FC->ChecksumSize >= SR.bytesRemaining()) error(object_error::parse_failed); - StringRef ChecksumBytes = Data.substr(0, FC->ChecksumSize); + ArrayRef ChecksumBytes; + error(SR.readBytes(ChecksumBytes, FC->ChecksumSize)); W.printBinary("ChecksumBytes", ChecksumBytes); unsigned PaddedSize = alignTo(FC->ChecksumSize + sizeof(FileChecksum), 4) - sizeof(FileChecksum); - if (PaddedSize > Data.size()) + PaddedSize -= ChecksumBytes.size(); + if (PaddedSize > SR.bytesRemaining()) error(object_error::parse_failed); - Data = Data.drop_front(PaddedSize); + error(SR.skip(PaddedSize)); } } void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) { - StringRef Data = Subsection; + msf::ByteStream S(Subsection); + msf::StreamReader SR(S); uint32_t Signature; - error(consume(Data, Signature)); + error(SR.readInteger(Signature)); bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles); - while (!Data.empty()) { + while (!SR.empty()) { const InlineeSourceLine *ISL; - error(consumeObject(Data, ISL)); + error(SR.readObject(ISL)); DictScope S(W, "InlineeSourceLine"); printTypeIndex("Inlinee", ISL->Inlinee); printFileNameForOffset("FileID", ISL->FileID); @@ -1015,12 +1026,12 @@ void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) { if (HasExtraFiles) { uint32_t ExtraFileCount; - error(consume(Data, ExtraFileCount)); + error(SR.readInteger(ExtraFileCount)); W.printNumber("ExtraFileCount", ExtraFileCount); ListScope ExtraFiles(W, "ExtraFiles"); for (unsigned I = 0; I < ExtraFileCount; ++I) { uint32_t FileID; - error(consume(Data, FileID)); + error(SR.readInteger(FileID)); printFileNameForOffset("FileID", FileID); } }