llvm.org GIT mirror llvm / f3491b2
[Support] Move Stream library from MSF -> Support. After several smaller patches to get most of the core improvements finished up, this patch is a straight move and header fixup of the source. Differential Revision: https://reviews.llvm.org/D30266 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296810 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 2 years ago
89 changed file(s) with 2335 addition(s) and 2334 deletion(s). Raw diff Collapse all Expand all
1313 #include "llvm/ADT/Optional.h"
1414 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
1515 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
16 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
16 #include "llvm/Support/BinaryStreamReader.h"
17 #include "llvm/Support/BinaryStreamRef.h"
1818 #include "llvm/Support/Endian.h"
1919 #include "llvm/Support/Error.h"
2020 #include
1616 #include "llvm/ADT/StringRef.h"
1717 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
1818 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
19 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
20 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
19 #include "llvm/Support/BinaryStreamReader.h"
20 #include "llvm/Support/BinaryStreamWriter.h"
2121 #include "llvm/Support/Error.h"
2222 #include
2323 #include
1010 #define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
1111
1212 #include "llvm/DebugInfo/CodeView/CodeView.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
13 #include "llvm/Support/BinaryStreamArray.h"
14 #include "llvm/Support/BinaryStreamRef.h"
1515 #include "llvm/Support/Endian.h"
1616 #include "llvm/Support/Error.h"
1717
1414 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
1515 #include "llvm/DebugInfo/CodeView/Line.h"
1616 #include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
18 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
19 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
17 #include "llvm/Support/BinaryStreamArray.h"
18 #include "llvm/Support/BinaryStreamReader.h"
19 #include "llvm/Support/BinaryStreamRef.h"
2020 #include "llvm/Support/Endian.h"
2121 #include "llvm/Support/Error.h"
2222 #include
1414 #include "llvm/ADT/StringRef.h"
1515 #include "llvm/DebugInfo/CodeView/CodeView.h"
1616 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
17 #include "llvm/Support/BinaryStreamReader.h"
1818 #include "llvm/Support/Endian.h"
1919 #include "llvm/Support/Error.h"
2020 #include
1414 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
1515 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
1616 #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
17 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
18 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
17 #include "llvm/Support/BinaryByteStream.h"
18 #include "llvm/Support/BinaryStreamReader.h"
1919 #include "llvm/Support/Error.h"
2020
2121 namespace llvm {
1818 #include "llvm/DebugInfo/CodeView/CodeView.h"
1919 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
2020 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
21 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
21 #include "llvm/Support/BinaryStreamArray.h"
2222 #include "llvm/Support/Endian.h"
2323 #include "llvm/Support/Error.h"
2424 #include
1717 #include "llvm/ADT/StringMap.h"
1818 #include "llvm/ADT/StringRef.h"
1919 #include "llvm/ADT/iterator_range.h"
20 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
21 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
2220 #include "llvm/Support/Allocator.h"
21 #include "llvm/Support/BinaryByteStream.h"
22 #include "llvm/Support/BinaryStreamWriter.h"
2323 #include "llvm/Support/Error.h"
2424
2525 namespace llvm {
1515 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
1616 #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
1717 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
18 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
19 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
18 #include "llvm/Support/BinaryByteStream.h"
19 #include "llvm/Support/BinaryStreamReader.h"
2020 #include "llvm/Support/Error.h"
2121 #include
2222 #include
1717 #include "llvm/DebugInfo/CodeView/CVRecord.h"
1818 #include "llvm/DebugInfo/CodeView/CodeView.h"
1919 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
20 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
20 #include "llvm/Support/BinaryStreamArray.h"
2121 #include "llvm/Support/Endian.h"
2222 #include
2323 #include
1111
1212 #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
1313 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
14 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
15 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
14 #include "llvm/Support/BinaryByteStream.h"
15 #include "llvm/Support/BinaryStreamWriter.h"
1616
1717 #include "llvm/ADT/Optional.h"
1818 #include "llvm/ADT/SmallVector.h"
+0
-192
include/llvm/DebugInfo/MSF/BinaryByteStream.h less more
None //===- BinaryByteStream.h ---------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
7 // A BinaryStream which stores data in a single continguous memory buffer.
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_DEBUGINFO_MSF_BINARYBYTESTREAM_H
11 #define LLVM_DEBUGINFO_MSF_BINARYBYTESTREAM_H
12
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/DebugInfo/MSF/BinaryStream.h"
16 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/FileOutputBuffer.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include
21 #include
22 #include
23 #include
24
25 namespace llvm {
26
27 /// \brief An implementation of BinaryStream which holds its entire data set
28 /// in a single contiguous buffer. BinaryByteStream guarantees that no read
29 /// operation will ever incur a copy. Note that BinaryByteStream does not
30 /// own the underlying buffer.
31 class BinaryByteStream : public BinaryStream {
32 public:
33 BinaryByteStream() = default;
34 BinaryByteStream(ArrayRef Data, llvm::support::endianness Endian)
35 : Endian(Endian), Data(Data) {}
36 BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
37 : Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
38
39 llvm::support::endianness getEndian() const override { return Endian; }
40
41 Error readBytes(uint32_t Offset, uint32_t Size,
42 ArrayRef &Buffer) override {
43 if (auto EC = checkOffset(Offset, Size))
44 return EC;
45 Buffer = Data.slice(Offset, Size);
46 return Error::success();
47 }
48
49 Error readLongestContiguousChunk(uint32_t Offset,
50 ArrayRef &Buffer) override {
51 if (auto EC = checkOffset(Offset, 1))
52 return EC;
53 Buffer = Data.slice(Offset);
54 return Error::success();
55 }
56
57 uint32_t getLength() override { return Data.size(); }
58
59 ArrayRef data() const { return Data; }
60
61 StringRef str() const {
62 const char *CharData = reinterpret_cast(Data.data());
63 return StringRef(CharData, Data.size());
64 }
65
66 protected:
67 llvm::support::endianness Endian;
68 ArrayRef Data;
69 };
70
71 /// \brief An implementation of BinaryStream whose data is backed by an llvm
72 /// MemoryBuffer object. MemoryBufferByteStream owns the MemoryBuffer in
73 /// question. As with BinaryByteStream, reading from a MemoryBufferByteStream
74 /// will never cause a copy.
75 class MemoryBufferByteStream : public BinaryByteStream {
76 public:
77 MemoryBufferByteStream(std::unique_ptr Buffer,
78 llvm::support::endianness Endian)
79 : BinaryByteStream(Buffer->getBuffer(), Endian),
80 MemBuffer(std::move(Buffer)) {}
81
82 std::unique_ptr MemBuffer;
83 };
84
85 /// \brief An implementation of BinaryStream which holds its entire data set
86 /// in a single contiguous buffer. As with BinaryByteStream, the mutable
87 /// version also guarantees that no read operation will ever incur a copy,
88 /// and similarly it does not own the underlying buffer.
89 class MutableBinaryByteStream : public WritableBinaryStream {
90 public:
91 MutableBinaryByteStream() = default;
92 MutableBinaryByteStream(MutableArrayRef Data,
93 llvm::support::endianness Endian)
94 : Data(Data), ImmutableStream(Data, Endian) {}
95
96 llvm::support::endianness getEndian() const override {
97 return ImmutableStream.getEndian();
98 }
99
100 Error readBytes(uint32_t Offset, uint32_t Size,
101 ArrayRef &Buffer) override {
102 return ImmutableStream.readBytes(Offset, Size, Buffer);
103 }
104
105 Error readLongestContiguousChunk(uint32_t Offset,
106 ArrayRef &Buffer) override {
107 return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
108 }
109
110 uint32_t getLength() override { return ImmutableStream.getLength(); }
111
112 Error writeBytes(uint32_t Offset, ArrayRef Buffer) override {
113 if (Buffer.empty())
114 return Error::success();
115
116 if (auto EC = checkOffset(Offset, Buffer.size()))
117 return EC;
118
119 uint8_t *DataPtr = const_cast(Data.data());
120 ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
121 return Error::success();
122 }
123
124 Error commit() override { return Error::success(); }
125
126 MutableArrayRef data() const { return Data; }
127
128 private:
129 MutableArrayRef Data;
130 BinaryByteStream ImmutableStream;
131 };
132
133 /// \brief An implementation of WritableBinaryStream backed by an llvm
134 /// FileOutputBuffer.
135 class FileBufferByteStream : public WritableBinaryStream {
136 private:
137 class StreamImpl : public MutableBinaryByteStream {
138 public:
139 StreamImpl(std::unique_ptr Buffer,
140 llvm::support::endianness Endian)
141 : MutableBinaryByteStream(
142 MutableArrayRef(Buffer->getBufferStart(),
143 Buffer->getBufferEnd()),
144 Endian),
145 FileBuffer(std::move(Buffer)) {}
146
147 Error commit() override {
148 if (FileBuffer->commit())
149 return make_error(
150 stream_error_code::filesystem_error);
151 return Error::success();
152 }
153
154 private:
155 std::unique_ptr FileBuffer;
156 };
157
158 public:
159 FileBufferByteStream(std::unique_ptr Buffer,
160 llvm::support::endianness Endian)
161 : Impl(std::move(Buffer), Endian) {}
162
163 llvm::support::endianness getEndian() const override {
164 return Impl.getEndian();
165 }
166
167 Error readBytes(uint32_t Offset, uint32_t Size,
168 ArrayRef &Buffer) override {
169 return Impl.readBytes(Offset, Size, Buffer);
170 }
171
172 Error readLongestContiguousChunk(uint32_t Offset,
173 ArrayRef &Buffer) override {
174 return Impl.readLongestContiguousChunk(Offset, Buffer);
175 }
176
177 uint32_t getLength() override { return Impl.getLength(); }
178
179 Error writeBytes(uint32_t Offset, ArrayRef Data) override {
180 return Impl.writeBytes(Offset, Data);
181 }
182
183 Error commit() override { return Impl.commit(); }
184
185 private:
186 StreamImpl Impl;
187 };
188
189 } // end namespace llvm
190
191 #endif // LLVM_DEBUGINFO_MSF_BYTESTREAM_H
+0
-95
include/llvm/DebugInfo/MSF/BinaryItemStream.h less more
None //===- BinaryItemStream.h ---------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_BINARYITEMSTREAM_H
10 #define LLVM_DEBUGINFO_MSF_BINARYITEMSTREAM_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/DebugInfo/MSF/BinaryStream.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
15 #include "llvm/Support/Error.h"
16 #include
17 #include
18
19 namespace llvm {
20
21 template struct BinaryItemTraits {
22 static size_t length(const T &Item) = delete;
23 static ArrayRef bytes(const T &Item) = delete;
24 };
25
26 /// BinaryItemStream represents a sequence of objects stored in some kind of
27 /// external container but for which it is useful to view as a stream of
28 /// contiguous bytes. An example of this might be if you have a collection of
29 /// records and you serialize each one into a buffer, and store these serialized
30 /// records in a container. The pointers themselves are not laid out
31 /// contiguously in memory, but we may wish to read from or write to these
32 /// records as if they were.
33 template >
34 class BinaryItemStream : public BinaryStream {
35 public:
36 explicit BinaryItemStream(llvm::support::endianness Endian)
37 : Endian(Endian) {}
38
39 llvm::support::endianness getEndian() const override { return Endian; }
40
41 Error readBytes(uint32_t Offset, uint32_t Size,
42 ArrayRef &Buffer) override {
43 auto ExpectedIndex = translateOffsetIndex(Offset);
44 if (!ExpectedIndex)
45 return ExpectedIndex.takeError();
46 const auto &Item = Items[*ExpectedIndex];
47 if (auto EC = checkOffset(Offset, Size))
48 return EC;
49 if (Size > Traits::length(Item))
50 return make_error(stream_error_code::stream_too_short);
51 Buffer = Traits::bytes(Item).take_front(Size);
52 return Error::success();
53 }
54
55 Error readLongestContiguousChunk(uint32_t Offset,
56 ArrayRef &Buffer) override {
57 auto ExpectedIndex = translateOffsetIndex(Offset);
58 if (!ExpectedIndex)
59 return ExpectedIndex.takeError();
60 Buffer = Traits::bytes(Items[*ExpectedIndex]);
61 return Error::success();
62 }
63
64 void setItems(ArrayRef ItemArray) { Items = ItemArray; }
65
66 uint32_t getLength() override {
67 uint32_t Size = 0;
68 for (const auto &Item : Items)
69 Size += Traits::length(Item);
70 return Size;
71 }
72
73 private:
74 Expected translateOffsetIndex(uint32_t Offset) const {
75 uint32_t CurrentOffset = 0;
76 uint32_t CurrentIndex = 0;
77 for (const auto &Item : Items) {
78 if (CurrentOffset >= Offset)
79 break;
80 CurrentOffset += Traits::length(Item);
81 ++CurrentIndex;
82 }
83 if (CurrentOffset != Offset)
84 return make_error(stream_error_code::stream_too_short);
85 return CurrentIndex;
86 }
87
88 llvm::support::endianness Endian;
89 ArrayRef Items;
90 };
91
92 } // end namespace llvm
93
94 #endif // LLVM_DEBUGINFO_MSF_BINARYITEMSTREAM_H
+0
-78
include/llvm/DebugInfo/MSF/BinaryStream.h less more
None //===- BinaryStream.h - Base interface for a stream of data -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_BINARYSTREAM_H
10 #define LLVM_DEBUGINFO_MSF_BINARYSTREAM_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
14 #include "llvm/Support/Endian.h"
15 #include "llvm/Support/Error.h"
16 #include
17
18 namespace llvm {
19
20 /// \brief An interface for accessing data in a stream-like format, but which
21 /// discourages copying. Instead of specifying a buffer in which to copy
22 /// data on a read, the API returns an ArrayRef to data owned by the stream's
23 /// implementation. Since implementations may not necessarily store data in a
24 /// single contiguous buffer (or even in memory at all), in such cases a it may
25 /// be necessary for an implementation to cache such a buffer so that it can
26 /// return it.
27 class BinaryStream {
28 public:
29 virtual ~BinaryStream() = default;
30
31 virtual llvm::support::endianness getEndian() const = 0;
32
33 /// \brief Given an offset into the stream and a number of bytes, attempt to
34 /// read the bytes and set the output ArrayRef to point to data owned by the
35 /// stream.
36 virtual Error readBytes(uint32_t Offset, uint32_t Size,
37 ArrayRef &Buffer) = 0;
38
39 /// \brief Given an offset into the stream, read as much as possible without
40 /// copying any data.
41 virtual Error readLongestContiguousChunk(uint32_t Offset,
42 ArrayRef &Buffer) = 0;
43
44 /// \brief Return the number of bytes of data in this stream.
45 virtual uint32_t getLength() = 0;
46
47 protected:
48 Error checkOffset(uint32_t Offset, uint32_t DataSize) {
49 if (Offset > getLength())
50 return make_error(stream_error_code::invalid_offset);
51 if (getLength() < DataSize + Offset)
52 return make_error(stream_error_code::stream_too_short);
53 return Error::success();
54 }
55 };
56
57 /// \brief A BinaryStream which can be read from as well as written to. Note
58 /// that writing to a BinaryStream always necessitates copying from the input
59 /// buffer to the stream's backing store. Streams are assumed to be buffered
60 /// so that to be portable it is necessary to call commit() on the stream when
61 /// all data has been written.
62 class WritableBinaryStream : public BinaryStream {
63 public:
64 ~WritableBinaryStream() override = default;
65
66 /// \brief Attempt to write the given bytes into the stream at the desired
67 /// offset. This will always necessitate a copy. Cannot shrink or grow the
68 /// stream, only writes into existing allocated space.
69 virtual Error writeBytes(uint32_t Offset, ArrayRef Data) = 0;
70
71 /// \brief For buffered streams, commits changes to the backing store.
72 virtual Error commit() = 0;
73 };
74
75 } // end namespace llvm
76
77 #endif // LLVM_DEBUGINFO_MSF_BINARYSTREAM_H
+0
-320
include/llvm/DebugInfo/MSF/BinaryStreamArray.h less more
None //===- BinaryStreamArray.h - Array backed by an arbitrary stream *- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_BINARYSTREAMARRAY_H
10 #define LLVM_DEBUGINFO_MSF_BINARYSTREAMARRAY_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/iterator.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
15 #include "llvm/Support/Error.h"
16 #include
17 #include
18
19 /// Lightweight arrays that are backed by an arbitrary BinaryStream. This file
20 /// provides two different array implementations.
21 ///
22 /// VarStreamArray - Arrays of variable length records. The user specifies
23 /// an Extractor type that can extract a record from a given offset and
24 /// return the number of bytes consumed by the record.
25 ///
26 /// FixedStreamArray - Arrays of fixed length records. This is similar in
27 /// spirit to ArrayRef, but since it is backed by a BinaryStream, the
28 /// elements of the array need not be laid out in contiguous memory.
29 namespace llvm {
30
31 /// VarStreamArrayExtractor is intended to be specialized to provide customized
32 /// extraction logic. On input it receives a BinaryStreamRef pointing to the
33 /// beginning of the next record, but where the length of the record is not yet
34 /// known. Upon completion, it should return an appropriate Error instance if
35 /// a record could not be extracted, or if one could be extracted it should
36 /// return success and set Len to the number of bytes this record occupied in
37 /// the underlying stream, and it should fill out the fields of the value type
38 /// Item appropriately to represent the current record.
39 ///
40 /// You can specialize this template for your own custom value types to avoid
41 /// having to specify a second template argument to VarStreamArray (documented
42 /// below).
43 template struct VarStreamArrayExtractor {
44 // Method intentionally deleted. You must provide an explicit specialization
45 // with the following method implemented.
46 Error operator()(BinaryStreamRef Stream, uint32_t &Len,
47 T &Item) const = delete;
48 };
49
50 /// VarStreamArray represents an array of variable length records backed by a
51 /// stream. This could be a contiguous sequence of bytes in memory, it could
52 /// be a file on disk, or it could be a PDB stream where bytes are stored as
53 /// discontiguous blocks in a file. Usually it is desirable to treat arrays
54 /// as contiguous blocks of memory, but doing so with large PDB files, for
55 /// example, could mean allocating huge amounts of memory just to allow
56 /// re-ordering of stream data to be contiguous before iterating over it. By
57 /// abstracting this out, we need not duplicate this memory, and we can
58 /// iterate over arrays in arbitrarily formatted streams. Elements are parsed
59 /// lazily on iteration, so there is no upfront cost associated with building
60 /// or copying a VarStreamArray, no matter how large it may be.
61 ///
62 /// You create a VarStreamArray by specifying a ValueType and an Extractor type.
63 /// If you do not specify an Extractor type, you are expected to specialize
64 /// VarStreamArrayExtractor for your ValueType.
65 ///
66 /// By default an Extractor is default constructed in the class, but in some
67 /// cases you might find it useful for an Extractor to maintain state across
68 /// extractions. In this case you can provide your own Extractor through a
69 /// secondary constructor. The following examples show various ways of
70 /// creating a VarStreamArray.
71 ///
72 /// // Will use VarStreamArrayExtractor as the extractor.
73 /// VarStreamArray MyTypeArray;
74 ///
75 /// // Will use a default-constructed MyExtractor as the extractor.
76 /// VarStreamArray MyTypeArray2;
77 ///
78 /// // Will use the specific instance of MyExtractor provided.
79 /// // MyExtractor need not be default-constructible in this case.
80 /// MyExtractor E(SomeContext);
81 /// VarStreamArray MyTypeArray3(E);
82 ///
83 template class VarStreamArrayIterator;
84
85 template
86 typename Extractor = VarStreamArrayExtractor>
87
88 class VarStreamArray {
89 friend class VarStreamArrayIterator;
90
91 public:
92 typedef VarStreamArrayIterator Iterator;
93
94 VarStreamArray() = default;
95 explicit VarStreamArray(const Extractor &E) : E(E) {}
96
97 explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {}
98 VarStreamArray(BinaryStreamRef Stream, const Extractor &E)
99 : Stream(Stream), E(E) {}
100
101 VarStreamArray(const VarStreamArray &Other)
102 : Stream(Other.Stream), E(Other.E) {}
103
104 Iterator begin(bool *HadError = nullptr) const {
105 return Iterator(*this, E, HadError);
106 }
107
108 Iterator end() const { return Iterator(E); }
109
110 const Extractor &getExtractor() const { return E; }
111
112 BinaryStreamRef getUnderlyingStream() const { return Stream; }
113
114 private:
115 BinaryStreamRef Stream;
116 Extractor E;
117 };
118
119 template
120 class VarStreamArrayIterator
121 : public iterator_facade_base,
122 std::forward_iterator_tag, ValueType> {
123 typedef VarStreamArrayIterator IterType;
124 typedef VarStreamArray ArrayType;
125
126 public:
127 VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
128 bool *HadError = nullptr)
129 : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) {
130 if (IterRef.getLength() == 0)
131 moveToEnd();
132 else {
133 auto EC = Extract(IterRef, ThisLen, ThisValue);
134 if (EC) {
135 consumeError(std::move(EC));
136 markError();
137 }
138 }
139 }
140 VarStreamArrayIterator() = default;
141 explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {}
142 ~VarStreamArrayIterator() = default;
143
144 bool operator==(const IterType &R) const {
145 if (Array && R.Array) {
146 // Both have a valid array, make sure they're same.
147 assert(Array == R.Array);
148 return IterRef == R.IterRef;
149 }
150
151 // Both iterators are at the end.
152 if (!Array && !R.Array)
153 return true;
154
155 // One is not at the end and one is.
156 return false;
157 }
158
159 const ValueType &operator*() const {
160 assert(Array && !HasError);
161 return ThisValue;
162 }
163
164 IterType &operator+=(unsigned N) {
165 for (unsigned I = 0; I < N; ++I) {
166 // We are done with the current record, discard it so that we are
167 // positioned at the next record.
168 IterRef = IterRef.drop_front(ThisLen);
169 if (IterRef.getLength() == 0) {
170 // There is nothing after the current record, we must make this an end
171 // iterator.
172 moveToEnd();
173 } else {
174 // There is some data after the current record.
175 auto EC = Extract(IterRef, ThisLen, ThisValue);
176 if (EC) {
177 consumeError(std::move(EC));
178 markError();
179 } else if (ThisLen == 0) {
180 // An empty record? Make this an end iterator.
181 moveToEnd();
182 }
183 }
184 }
185 return *this;
186 }
187
188 private:
189 void moveToEnd() {
190 Array = nullptr;
191 ThisLen = 0;
192 }
193 void markError() {
194 moveToEnd();
195 HasError = true;
196 if (HadError != nullptr)
197 *HadError = true;
198 }
199
200 ValueType ThisValue;
201 BinaryStreamRef IterRef;
202 const ArrayType *Array{nullptr};
203 uint32_t ThisLen{0};
204 bool HasError{false};
205 bool *HadError{nullptr};
206 Extractor Extract;
207 };
208
209 template class FixedStreamArrayIterator;
210
211 /// FixedStreamArray is similar to VarStreamArray, except with each record
212 /// having a fixed-length. As with VarStreamArray, there is no upfront
213 /// cost associated with building or copying a FixedStreamArray, as the
214 /// memory for each element is not read from the backing stream until that
215 /// element is iterated.
216 template class FixedStreamArray {
217 friend class FixedStreamArrayIterator;
218
219 public:
220 FixedStreamArray() = default;
221 explicit FixedStreamArray(BinaryStreamRef Stream) : Stream(Stream) {
222 assert(Stream.getLength() % sizeof(T) == 0);
223 }
224
225 bool operator==(const FixedStreamArray &Other) const {
226 return Stream == Other.Stream;
227 }
228
229 bool operator!=(const FixedStreamArray &Other) const {
230 return !(*this == Other);
231 }
232
233 FixedStreamArray &operator=(const FixedStreamArray &) = default;
234
235 const T &operator[](uint32_t Index) const {
236 assert(Index < size());
237 uint32_t Off = Index * sizeof(T);
238 ArrayRef Data;
239 if (auto EC = Stream.readBytes(Off, sizeof(T), Data)) {
240 assert(false && "Unexpected failure reading from stream");
241 // This should never happen since we asserted that the stream length was
242 // an exact multiple of the element size.
243 consumeError(std::move(EC));
244 }
245 assert(llvm::alignmentAdjustment(Data.data(), alignof(T)) == 0);
246 return *reinterpret_cast(Data.data());
247 }
248
249 uint32_t size() const { return Stream.getLength() / sizeof(T); }
250
251 bool empty() const { return size() == 0; }
252
253 FixedStreamArrayIterator begin() const {
254 return FixedStreamArrayIterator(*this, 0);
255 }
256
257 FixedStreamArrayIterator end() const {
258 return FixedStreamArrayIterator(*this, size());
259 }
260
261 BinaryStreamRef getUnderlyingStream() const { return Stream; }
262
263 private:
264 BinaryStreamRef Stream;
265 };
266
267 template
268 class FixedStreamArrayIterator
269 : public iterator_facade_base,
270 std::random_access_iterator_tag, T> {
271
272 public:
273 FixedStreamArrayIterator(const FixedStreamArray &Array, uint32_t Index)
274 : Array(Array), Index(Index) {}
275
276 FixedStreamArrayIterator &
277 operator=(const FixedStreamArrayIterator &Other) {
278 Array = Other.Array;
279 Index = Other.Index;
280 return *this;
281 }
282
283 const T &operator*() const { return Array[Index]; }
284
285 bool operator==(const FixedStreamArrayIterator &R) const {
286 assert(Array == R.Array);
287 return (Index == R.Index) && (Array == R.Array);
288 }
289
290 FixedStreamArrayIterator &operator+=(std::ptrdiff_t N) {
291 Index += N;
292 return *this;
293 }
294
295 FixedStreamArrayIterator &operator-=(std::ptrdiff_t N) {
296 assert(Index >= N);
297 Index -= N;
298 return *this;
299 }
300
301 std::ptrdiff_t operator-(const FixedStreamArrayIterator &R) const {
302 assert(Array == R.Array);
303 assert(Index >= R.Index);
304 return Index - R.Index;
305 }
306
307 bool operator<(const FixedStreamArrayIterator &RHS) const {
308 assert(Array == RHS.Array);
309 return Index < RHS.Index;
310 }
311
312 private:
313 FixedStreamArray Array;
314 uint32_t Index;
315 };
316
317 } // namespace llvm
318
319 #endif // LLVM_DEBUGINFO_MSF_BINARYSTREAMARRAY_H
+0
-47
include/llvm/DebugInfo/MSF/BinaryStreamError.h less more
None //===- BinaryStreamError.h - Error extensions for Binary Streams *- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_BINARYSTREAMERROR_H
10 #define LLVM_DEBUGINFO_MSF_BINARYSTREAMERROR_H
11
12 #include "llvm/Support/Error.h"
13
14 #include
15
16 namespace llvm {
17 enum class stream_error_code {
18 unspecified,
19 stream_too_short,
20 invalid_array_size,
21 invalid_offset,
22 filesystem_error
23 };
24
25 /// Base class for errors originating when parsing raw PDB files
26 class BinaryStreamError : public ErrorInfo {
27 public:
28 static char ID;
29 explicit BinaryStreamError(stream_error_code C);
30 explicit BinaryStreamError(StringRef Context);
31 BinaryStreamError(stream_error_code C, StringRef Context);
32
33 void log(raw_ostream &OS) const override;
34 std::error_code convertToErrorCode() const override;
35
36 StringRef getErrorMessage() const;
37
38 stream_error_code getErrorCode() const { return Code; }
39
40 private:
41 std::string ErrMsg;
42 stream_error_code Code;
43 };
44 } // namespace llvm
45
46 #endif // LLVM_DEBUGINFO_MSF_BINARYSTREAMERROR_H
+0
-234
include/llvm/DebugInfo/MSF/BinaryStreamReader.h less more
None //===- BinaryStreamReader.h - Reads objects from a binary stream *- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_BINARYSTREAMREADER_H
10 #define LLVM_DEBUGINFO_MSF_BINARYSTREAMREADER_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
15 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/MathExtras.h"
19 #include "llvm/Support/type_traits.h"
20
21 #include
22 #include
23
24 namespace llvm {
25
26 /// \brief Provides read only access to a subclass of `BinaryStream`. Provides
27 /// bounds checking and helpers for writing certain common data types such as
28 /// null-terminated strings, integers in various flavors of endianness, etc.
29 /// Can be subclassed to provide reading of custom datatypes, although no
30 /// are overridable.
31 class BinaryStreamReader {
32 public:
33 explicit BinaryStreamReader(BinaryStreamRef Stream);
34 virtual ~BinaryStreamReader() {}
35
36 /// Read as much as possible from the underlying string at the current offset
37 /// without invoking a copy, and set \p Buffer to the resulting data slice.
38 /// Updates the stream's offset to point after the newly read data.
39 ///
40 /// \returns a success error code if the data was successfully read, otherwise
41 /// returns an appropriate error code.
42 Error readLongestContiguousChunk(ArrayRef &Buffer);
43
44 /// Read \p Size bytes from the underlying stream at the current offset and
45 /// and set \p Buffer to the resulting data slice. Whether a copy occurs
46 /// depends on the implementation of the underlying stream. Updates the
47 /// stream's offset to point after the newly read data.
48 ///
49 /// \returns a success error code if the data was successfully read, otherwise
50 /// returns an appropriate error code.
51 Error readBytes(ArrayRef &Buffer, uint32_t Size);
52
53 /// Read an integer of the specified endianness into \p Dest and update the
54 /// stream's offset. The data is always copied from the stream's underlying
55 /// buffer into \p Dest. Updates the stream's offset to point after the newly
56 /// read data.
57 ///
58 /// \returns a success error code if the data was successfully read, otherwise
59 /// returns an appropriate error code.
60 template Error readInteger(T &Dest) {
61 static_assert(std::is_integral::value,
62 "Cannot call readInteger with non-integral value!");
63
64 ArrayRef Bytes;
65 if (auto EC = readBytes(Bytes, sizeof(T)))
66 return EC;
67
68 Dest = llvm::support::endian::read(
69 Bytes.data(), Stream.getEndian());
70 return Error::success();
71 }
72
73 /// Similar to readInteger.
74 template Error readEnum(T &Dest) {
75 static_assert(std::is_enum::value,
76 "Cannot call readEnum with non-enum value!");
77 typename std::underlying_type::type N;
78 if (auto EC = readInteger(N))
79 return EC;
80 Dest = static_cast(N);
81 return Error::success();
82 }
83
84 /// Read a null terminated string from \p Dest. Whether a copy occurs depends
85 /// on the implementation of the underlying stream. Updates the stream's
86 /// offset to point after the newly read data.
87 ///
88 /// \returns a success error code if the data was successfully read, otherwise
89 /// returns an appropriate error code.
90 Error readCString(StringRef &Dest);
91
92 /// Read a \p Length byte string into \p Dest. Whether a copy occurs depends
93 /// on the implementation of the underlying stream. Updates the stream's
94 /// offset to point after the newly read data.
95 ///
96 /// \returns a success error code if the data was successfully read, otherwise
97 /// returns an appropriate error code.
98 Error readFixedString(StringRef &Dest, uint32_t Length);
99
100 /// Read the entire remainder of the underlying stream into \p Ref. This is
101 /// equivalent to calling getUnderlyingStream().slice(Offset). Updates the
102 /// stream's offset to point to the end of the stream. Never causes a copy.
103 ///
104 /// \returns a success error code if the data was successfully read, otherwise
105 /// returns an appropriate error code.
106 Error readStreamRef(BinaryStreamRef &Ref);
107
108 /// Read \p Length bytes from the underlying stream into \p Ref. This is
109 /// equivalent to calling getUnderlyingStream().slice(Offset, Length).
110 /// Updates the stream's offset to point after the newly read object. Never
111 /// causes a copy.
112 ///
113 /// \returns a success error code if the data was successfully read, otherwise
114 /// returns an appropriate error code.
115 Error readStreamRef(BinaryStreamRef &Ref, uint32_t Length);
116
117 /// Get a pointer to an object of type T from the underlying stream, as if by
118 /// memcpy, and store the result into \p Dest. It is up to the caller to
119 /// ensure that objects of type T can be safely treated in this manner.
120 /// Updates the stream's offset to point after the newly read object. Whether
121 /// a copy occurs depends upon the implementation of the underlying
122 /// stream.
123 ///
124 /// \returns a success error code if the data was successfully read, otherwise
125 /// returns an appropriate error code.
126 template Error readObject(const T *&Dest) {
127 ArrayRef Buffer;
128 if (auto EC = readBytes(Buffer, sizeof(T)))
129 return EC;
130 Dest = reinterpret_cast(Buffer.data());
131 return Error::success();
132 }
133
134 /// Get a reference to a \p NumElements element array of objects of type T
135 /// from the underlying stream as if by memcpy, and store the resulting array
136 /// slice into \p array. It is up to the caller to ensure that objects of
137 /// type T can be safely treated in this manner. Updates the stream's offset
138 /// to point after the newly read object. Whether a copy occurs depends upon
139 /// the implementation of the underlying stream.
140 ///
141 /// \returns a success error code if the data was successfully read, otherwise
142 /// returns an appropriate error code.
143 template
144 Error readArray(ArrayRef &Array, uint32_t NumElements) {
145 ArrayRef Bytes;
146 if (NumElements == 0) {
147 Array = ArrayRef();
148 return Error::success();
149 }
150
151 if (NumElements > UINT32_MAX / sizeof(T))
152 return make_error(
153 stream_error_code::invalid_array_size);
154
155 if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
156 return EC;
157
158 assert(alignmentAdjustment(Bytes.data(), alignof(T)) == 0 &&
159 "Reading at invalid alignment!");
160
161 Array = ArrayRef(reinterpret_cast(Bytes.data()), NumElements);
162 return Error::success();
163 }
164
165 /// Read a VarStreamArray of size \p Size bytes and store the result into
166 /// \p Array. Updates the stream's offset to point after the newly read
167 /// array. Never causes a copy (although iterating the elements of the
168 /// VarStreamArray may, depending upon the implementation of the underlying
169 /// stream).
170 ///
171 /// \returns a success error code if the data was successfully read, otherwise
172 /// returns an appropriate error code.
173 template
174 Error readArray(VarStreamArray &Array, uint32_t Size) {
175 BinaryStreamRef S;
176 if (auto EC = readStreamRef(S, Size))
177 return EC;
178 Array = VarStreamArray(S, Array.getExtractor());
179 return Error::success();
180 }
181
182 /// Read a FixedStreamArray of \p NumItems elements and store the result into
183 /// \p Array. Updates the stream's offset to point after the newly read
184 /// array. Never causes a copy (although iterating the elements of the
185 /// FixedStreamArray may, depending upon the implementation of the underlying
186 /// stream).
187 ///
188 /// \returns a success error code if the data was successfully read, otherwise
189 /// returns an appropriate error code.
190 template
191 Error readArray(FixedStreamArray &Array, uint32_t NumItems) {
192 if (NumItems == 0) {
193 Array = FixedStreamArray();
194 return Error::success();
195 }
196
197 if (NumItems > UINT32_MAX / sizeof(T))
198 return make_error(
199 stream_error_code::invalid_array_size);
200
201 BinaryStreamRef View;
202 if (auto EC = readStreamRef(View, NumItems * sizeof(T)))
203 return EC;
204
205 Array = FixedStreamArray(View);
206 return Error::success();
207 }
208
209 bool empty() const { return bytesRemaining() == 0; }
210 void setOffset(uint32_t Off) { Offset = Off; }
211 uint32_t getOffset() const { return Offset; }
212 uint32_t getLength() const { return Stream.getLength(); }
213 uint32_t bytesRemaining() const { return getLength() - getOffset(); }
214
215 /// Advance the stream's offset by \p Amount bytes.
216 ///
217 /// \returns a success error code if at least \p Amount bytes remain in the
218 /// stream, otherwise returns an appropriate error code.
219 Error skip(uint32_t Amount);
220
221 /// Examine the next byte of the underlying stream without advancing the
222 /// stream's offset. If the stream is empty the behavior is undefined.
223 ///
224 /// \returns the next byte in the stream.
225 uint8_t peek() const;
226
227 private:
228 BinaryStreamRef Stream;
229 uint32_t Offset;
230 };
231 } // namespace llvm
232
233 #endif // LLVM_DEBUGINFO_MSF_BINARYSTREAMREADER_H
+0
-174
include/llvm/DebugInfo/MSF/BinaryStreamRef.h less more
None //===- BinaryStreamRef.h - A copyable reference to a stream -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_BINARYSTREAMREF_H
10 #define LLVM_DEBUGINFO_MSF_BINARYSTREAMREF_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/DebugInfo/MSF/BinaryStream.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
15 #include "llvm/Support/Error.h"
16 #include
17 #include
18
19 namespace llvm {
20
21 /// Common stuff for mutable and immutable StreamRefs.
22 template class BinaryStreamRefBase {
23 public:
24 BinaryStreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {}
25 BinaryStreamRefBase(StreamType &Stream, uint32_t Offset, uint32_t Length)
26 : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
27
28 llvm::support::endianness getEndian() const { return Stream->getEndian(); }
29
30 uint32_t getLength() const { return Length; }
31 const StreamType *getStream() const { return Stream; }
32
33 /// Return a new BinaryStreamRef with the first \p N elements removed.
34 RefType drop_front(uint32_t N) const {
35 if (!Stream)
36 return RefType();
37
38 N = std::min(N, Length);
39 return RefType(*Stream, ViewOffset + N, Length - N);
40 }
41
42 /// Return a new BinaryStreamRef with only the first \p N elements remaining.
43 RefType keep_front(uint32_t N) const {
44 if (!Stream)
45 return RefType();
46 N = std::min(N, Length);
47 return RefType(*Stream, ViewOffset, N);
48 }
49
50 /// Return a new BinaryStreamRef with the first \p Offset elements removed,
51 /// and retaining exactly \p Len elements.
52 RefType slice(uint32_t Offset, uint32_t Len) const {
53 return drop_front(Offset).keep_front(Len);
54 }
55
56 bool operator==(const RefType &Other) const {
57 if (Stream != Other.Stream)
58 return false;
59 if (ViewOffset != Other.ViewOffset)
60 return false;
61 if (Length != Other.Length)
62 return false;
63 return true;
64 }
65
66 protected:
67 Error checkOffset(uint32_t Offset, uint32_t DataSize) const {
68 if (Offset > getLength())
69 return make_error(stream_error_code::invalid_offset);
70 if (getLength() < DataSize + Offset)
71 return make_error(stream_error_code::stream_too_short);
72 return Error::success();
73 }
74
75 StreamType *Stream;
76 uint32_t ViewOffset;
77 uint32_t Length;
78 };
79
80 /// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It
81 /// provides copy-semantics and read only access to a "window" of the underlying
82 /// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream. That is to
83 /// say, it does not inherit and override the methods of BinaryStream. In
84 /// general, you should not pass around pointers or references to BinaryStreams
85 /// and use inheritance to achieve polymorphism. Instead, you should pass
86 /// around BinaryStreamRefs by value and achieve polymorphism that way.
87 class BinaryStreamRef
88 : public BinaryStreamRefBase {
89 public:
90 BinaryStreamRef() = default;
91 BinaryStreamRef(BinaryStream &Stream)
92 : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {}
93 BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length)
94 : BinaryStreamRefBase(Stream, Offset, Length) {}
95
96 // Use BinaryStreamRef.slice() instead.
97 BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset,
98 uint32_t Length) = delete;
99
100 /// Given an Offset into this StreamRef and a Size, return a reference to a
101 /// buffer owned by the stream.
102 ///
103 /// \returns a success error code if the entire range of data is within the
104 /// bounds of this BinaryStreamRef's view and the implementation could read
105 /// the data, and an appropriate error code otherwise.
106 Error readBytes(uint32_t Offset, uint32_t Size,
107 ArrayRef &Buffer) const {
108 if (auto EC = checkOffset(Offset, Size))
109 return EC;
110
111 return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
112 }
113
114 /// Given an Offset into this BinaryStreamRef, return a reference to the
115 /// largest buffer the stream could support without necessitating a copy.
116 ///
117 /// \returns a success error code if implementation could read the data,
118 /// and an appropriate error code otherwise.
119 Error readLongestContiguousChunk(uint32_t Offset,
120 ArrayRef &Buffer) const {
121 if (auto EC = checkOffset(Offset, 1))
122 return EC;
123
124 if (auto EC =
125 Stream->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
126 return EC;
127 // This StreamRef might refer to a smaller window over a larger stream. In
128 // that case we will have read out more bytes than we should return, because
129 // we should not read past the end of the current view.
130 uint32_t MaxLength = Length - Offset;
131 if (Buffer.size() > MaxLength)
132 Buffer = Buffer.slice(0, MaxLength);
133 return Error::success();
134 }
135 };
136
137 class WritableBinaryStreamRef
138 : public BinaryStreamRefBase
139 WritableBinaryStreamRef> {
140 public:
141 WritableBinaryStreamRef() = default;
142 WritableBinaryStreamRef(WritableBinaryStream &Stream)
143 : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {}
144 WritableBinaryStreamRef(WritableBinaryStream &Stream, uint32_t Offset,
145 uint32_t Length)
146 : BinaryStreamRefBase(Stream, Offset, Length) {}
147
148 // Use WritableBinaryStreamRef.slice() instead.
149 WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint32_t Offset,
150 uint32_t Length) = delete;
151
152 /// Given an Offset into this WritableBinaryStreamRef and some input data,
153 /// writes the data to the underlying stream.
154 ///
155 /// \returns a success error code if the data could fit within the underlying
156 /// stream at the specified location and the implementation could write the
157 /// data, and an appropriate error code otherwise.
158 Error writeBytes(uint32_t Offset, ArrayRef Data) const {
159 if (auto EC = checkOffset(Offset, Data.size()))
160 return EC;
161
162 return Stream->writeBytes(ViewOffset + Offset, Data);
163 }
164
165 operator BinaryStreamRef() { return BinaryStreamRef(*Stream); }
166
167 /// \brief For buffered streams, commits changes to the backing store.
168 Error commit() { return Stream->commit(); }
169 };
170
171 } // end namespace llvm
172
173 #endif // LLVM_DEBUGINFO_MSF_BINARYSTREAMREF_H
+0
-165
include/llvm/DebugInfo/MSF/BinaryStreamWriter.h less more
None //===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- C++-*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_BINARYSTREAMWRITER_H
10 #define LLVM_DEBUGINFO_MSF_BINARYSTREAMWRITER_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
16 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/Error.h"
20 #include
21 #include
22
23 namespace llvm {
24
25 /// \brief Provides write only access to a subclass of `WritableBinaryStream`.
26 /// Provides bounds checking and helpers for writing certain common data types
27 /// such as null-terminated strings, integers in various flavors of endianness,
28 /// etc. Can be subclassed to provide reading and writing of custom datatypes,
29 /// although no methods are overridable.
30 class BinaryStreamWriter {
31 public:
32 BinaryStreamWriter() = default;
33 explicit BinaryStreamWriter(WritableBinaryStreamRef Stream);
34 virtual ~BinaryStreamWriter() {}
35
36 /// Write the bytes specified in \p Buffer to the underlying stream.
37 /// On success, updates the offset so that subsequent writes will occur
38 /// at the next unwritten position.
39 ///
40 /// \returns a success error code if the data was successfully written,
41 /// otherwise returns an appropriate error code.
42 Error writeBytes(ArrayRef Buffer);
43
44 /// Write the the integer \p Value to the underlying stream in the
45 /// specified endianness. On success, updates the offset so that
46 /// subsequent writes occur at the next unwritten position.
47 ///
48 /// \returns a success error code if the data was successfully written,
49 /// otherwise returns an appropriate error code.
50 template Error writeInteger(T Value) {
51 static_assert(std::is_integral::value,
52 "Cannot call writeInteger with non-integral value!");
53 uint8_t Buffer[sizeof(T)];
54 llvm::support::endian::write(
55 Buffer, Value, Stream.getEndian());
56 return writeBytes(Buffer);
57 }
58
59 /// Similar to writeInteger
60 template Error writeEnum(T Num) {
61 static_assert(std::is_enum::value,
62 "Cannot call writeEnum with non-Enum type");
63
64 using U = typename std::underlying_type::type;
65 return writeInteger(static_cast(Num));
66 }
67
68 /// Write the the string \p Str to the underlying stream followed by a null
69 /// terminator. On success, updates the offset so that subsequent writes
70 /// occur at the next unwritten position. \p Str need not be null terminated
71 /// on input.
72 ///
73 /// \returns a success error code if the data was successfully written,
74 /// otherwise returns an appropriate error code.
75 Error writeCString(StringRef Str);
76
77 /// Write the the string \p Str to the underlying stream without a null
78 /// terminator. On success, updates the offset so that subsequent writes
79 /// occur at the next unwritten position.
80 ///
81 /// \returns a success error code if the data was successfully written,
82 /// otherwise returns an appropriate error code.
83 Error writeFixedString(StringRef Str);
84
85 /// Efficiently reads all data from \p Ref, and writes it to this stream.
86 /// This operation will not invoke any copies of the source data, regardless
87 /// of the source stream's implementation.
88 ///
89 /// \returns a success error code if the data was successfully written,
90 /// otherwise returns an appropriate error code.
91 Error writeStreamRef(BinaryStreamRef Ref);
92
93 /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream.
94 /// This operation will not invoke any copies of the source data, regardless
95 /// of the source stream's implementation.
96 ///
97 /// \returns a success error code if the data was successfully written,
98 /// otherwise returns an appropriate error code.
99 Error writeStreamRef(BinaryStreamRef Ref, uint32_t Size);
100
101 /// Writes the object \p Obj to the underlying stream, as if by using memcpy.
102 /// It is up to the caller to ensure that type of \p Obj can be safely copied
103 /// in this fashion, as no checks are made to ensure that this is safe.
104 ///
105 /// \returns a success error code if the data was successfully written,
106 /// otherwise returns an appropriate error code.
107 template Error writeObject(const T &Obj) {
108 static_assert(!std::is_pointer::value,
109 "writeObject should not be used with pointers, to write "
110 "the pointed-to value dereference the pointer before calling "
111 "writeObject");
112 return writeBytes(
113 ArrayRef(reinterpret_cast(&Obj), sizeof(T)));
114 }
115
116 /// Writes an array of objects of type T to the underlying stream, as if by
117 /// using memcpy. It is up to the caller to ensure that type of \p Obj can
118 /// be safely copied in this fashion, as no checks are made to ensure that
119 /// this is safe.
120 ///
121 /// \returns a success error code if the data was successfully written,
122 /// otherwise returns an appropriate error code.
123 template Error writeArray(ArrayRef Array) {
124 if (Array.empty())
125 return Error::success();
126 if (Array.size() > UINT32_MAX / sizeof(T))
127 return make_error(
128 stream_error_code::invalid_array_size);
129
130 return writeBytes(
131 ArrayRef(reinterpret_cast(Array.data()),
132 Array.size() * sizeof(T)));
133 }
134
135 /// Writes all data from the array \p Array to the underlying stream.
136 ///
137 /// \returns a success error code if the data was successfully written,
138 /// otherwise returns an appropriate error code.
139 template
140 Error writeArray(VarStreamArray Array) {
141 return writeStreamRef(Array.getUnderlyingStream());
142 }
143
144 /// Writes all elements from the array \p Array to the underlying stream.
145 ///
146 /// \returns a success error code if the data was successfully written,
147 /// otherwise returns an appropriate error code.
148 template Error writeArray(FixedStreamArray Array) {
149 return writeStreamRef(Array.getUnderlyingStream());
150 }
151
152 void setOffset(uint32_t Off) { Offset = Off; }
153 uint32_t getOffset() const { return Offset; }
154 uint32_t getLength() const { return Stream.getLength(); }
155 uint32_t bytesRemaining() const { return getLength() - getOffset(); }
156
157 protected:
158 WritableBinaryStreamRef Stream;
159 uint32_t Offset = 0;
160 };
161
162 } // end namespace llvm
163
164 #endif // LLVM_DEBUGINFO_MSF_BINARYSTREAMWRITER_H
1313 #include "llvm/ADT/ArrayRef.h"
1414 #include "llvm/ADT/DenseMap.h"
1515 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/DebugInfo/MSF/BinaryStream.h"
17 #include "llvm/DebugInfo/MSF/BinaryStream.h"
18 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
1916 #include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
2017 #include "llvm/Support/Allocator.h"
18 #include "llvm/Support/BinaryStream.h"
19 #include "llvm/Support/BinaryStream.h"
20 #include "llvm/Support/BinaryStreamRef.h"
2121 #include "llvm/Support/Endian.h"
2222 #include "llvm/Support/Error.h"
2323 #include
1010 #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
1111
1212 #include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
15 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
16 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
1713 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1814 #include "llvm/DebugInfo/PDB/Native/ModInfo.h"
1915 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
2016 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
2117 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
2218 #include "llvm/DebugInfo/PDB/PDBTypes.h"
19 #include "llvm/Support/BinaryStreamArray.h"
20 #include "llvm/Support/BinaryStreamArray.h"
21 #include "llvm/Support/BinaryStreamRef.h"
22 #include "llvm/Support/BinaryStreamRef.h"
2323 #include "llvm/Support/Endian.h"
2424 #include "llvm/Support/Error.h"
2525
1313 #include "llvm/ADT/StringSet.h"
1414 #include "llvm/Support/Error.h"
1515
16 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
1816 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1917 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
2018 #include "llvm/DebugInfo/PDB/PDBTypes.h"
19 #include "llvm/Support/BinaryByteStream.h"
20 #include "llvm/Support/BinaryStreamReader.h"
2121 #include "llvm/Support/Endian.h"
2222
2323 namespace llvm {
99 #ifndef LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H
1010 #define LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H
1111
12 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
1312 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1413 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
1514 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
1615 #include "llvm/DebugInfo/PDB/PDBTypes.h"
16 #include "llvm/Support/BinaryStreamArray.h"
1717 #include "llvm/Support/Error.h"
1818
1919 namespace llvm {
1313 #include "llvm/ADT/SparseBitVector.h"
1414 #include "llvm/ADT/StringRef.h"
1515 #include "llvm/ADT/iterator.h"
16 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
18 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
16 #include "llvm/Support/BinaryStreamArray.h"
17 #include "llvm/Support/BinaryStreamReader.h"
18 #include "llvm/Support/BinaryStreamWriter.h"
1919 #include "llvm/Support/Endian.h"
2020 #include "llvm/Support/Error.h"
2121 #include "llvm/Support/MathExtras.h"
1010 #define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
1111
1212 #include "llvm/ADT/StringRef.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
1513 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
14 #include "llvm/Support/BinaryStreamArray.h"
15 #include "llvm/Support/BinaryStreamRef.h"
1616 #include "llvm/Support/Error.h"
1717 #include
1818 #include
1313 #include "llvm/DebugInfo/CodeView/CVRecord.h"
1414 #include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
1515 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
1816 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
17 #include "llvm/Support/BinaryStreamArray.h"
18 #include "llvm/Support/BinaryStreamRef.h"
1919 #include "llvm/Support/Error.h"
2020
2121 namespace llvm {
1010 #define LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H
1111
1212 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
1413 #include "llvm/DebugInfo/MSF/IMSFFile.h"
1514 #include "llvm/DebugInfo/MSF/MSFCommon.h"
1615 #include "llvm/Support/Allocator.h"
16 #include "llvm/Support/BinaryStreamRef.h"
1717 #include "llvm/Support/Endian.h"
1818 #include "llvm/Support/Error.h"
1919 #include "llvm/Support/MathExtras.h"
1010 #define LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H
1111
1212 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
1413 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1514 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
1615 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
1716 #include "llvm/DebugInfo/PDB/PDBTypes.h"
17 #include "llvm/Support/BinaryStreamArray.h"
1818 #include "llvm/Support/Error.h"
1919
2020 namespace llvm {
1111
1212 #include "llvm/ADT/ArrayRef.h"
1313 #include "llvm/ADT/StringRef.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
15 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
14 #include "llvm/Support/BinaryStreamArray.h"
15 #include "llvm/Support/BinaryStreamRef.h"
1616 #include "llvm/Support/Endian.h"
1717 #include "llvm/Support/Error.h"
1818 #include
1414 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
1515 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
1616 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
17 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
1817 #include "llvm/DebugInfo/PDB/Native/RawError.h"
18 #include "llvm/Support/BinaryStreamArray.h"
1919 #include "llvm/Support/Endian.h"
2020 #include "llvm/Support/Error.h"
2121 #include
1010 #define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H
1111
1212 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
1413 #include "llvm/DebugInfo/PDB/Native/HashTable.h"
1514 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
1615 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
1716 #include "llvm/DebugInfo/PDB/PDBTypes.h"
17 #include "llvm/Support/BinaryStreamArray.h"
1818 #include "llvm/Support/raw_ostream.h"
1919
2020 #include "llvm/Support/Error.h"
1111
1212 #include "llvm/ADT/Optional.h"
1313 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
14 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
15 #include "llvm/DebugInfo/MSF/BinaryItemStream.h"
16 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
1714 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
1815 #include "llvm/Support/Allocator.h"
16 #include "llvm/Support/BinaryByteStream.h"
17 #include "llvm/Support/BinaryItemStream.h"
18 #include "llvm/Support/BinaryStreamRef.h"
1919 #include "llvm/Support/Error.h"
2020
2121 #include
0 //===- BinaryByteStream.h ---------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
7 // A BinaryStream which stores data in a single continguous memory buffer.
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_SUPPORT_BINARYBYTESTREAM_H
11 #define LLVM_SUPPORT_BINARYBYTESTREAM_H
12
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/BinaryStream.h"
16 #include "llvm/Support/BinaryStreamError.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/FileOutputBuffer.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include
21 #include
22 #include
23 #include
24
25 namespace llvm {
26
27 /// \brief An implementation of BinaryStream which holds its entire data set
28 /// in a single contiguous buffer. BinaryByteStream guarantees that no read
29 /// operation will ever incur a copy. Note that BinaryByteStream does not
30 /// own the underlying buffer.
31 class BinaryByteStream : public BinaryStream {
32 public:
33 BinaryByteStream() = default;
34 BinaryByteStream(ArrayRef Data, llvm::support::endianness Endian)
35 : Endian(Endian), Data(Data) {}
36 BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
37 : Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
38
39 llvm::support::endianness getEndian() const override { return Endian; }
40
41 Error readBytes(uint32_t Offset, uint32_t Size,
42 ArrayRef &Buffer) override {
43 if (auto EC = checkOffset(Offset, Size))
44 return EC;
45 Buffer = Data.slice(Offset, Size);
46 return Error::success();
47 }
48
49 Error readLongestContiguousChunk(uint32_t Offset,
50 ArrayRef &Buffer) override {
51 if (auto EC = checkOffset(Offset, 1))
52 return EC;
53 Buffer = Data.slice(Offset);
54 return Error::success();
55 }
56
57 uint32_t getLength() override { return Data.size(); }
58
59 ArrayRef data() const { return Data; }
60
61 StringRef str() const {
62 const char *CharData = reinterpret_cast(Data.data());
63 return StringRef(CharData, Data.size());
64 }
65
66 protected:
67 llvm::support::endianness Endian;
68 ArrayRef Data;
69 };
70
71 /// \brief An implementation of BinaryStream whose data is backed by an llvm
72 /// MemoryBuffer object. MemoryBufferByteStream owns the MemoryBuffer in
73 /// question. As with BinaryByteStream, reading from a MemoryBufferByteStream
74 /// will never cause a copy.
75 class MemoryBufferByteStream : public BinaryByteStream {
76 public:
77 MemoryBufferByteStream(std::unique_ptr Buffer,
78 llvm::support::endianness Endian)
79 : BinaryByteStream(Buffer->getBuffer(), Endian),
80 MemBuffer(std::move(Buffer)) {}
81
82 std::unique_ptr MemBuffer;
83 };
84
85 /// \brief An implementation of BinaryStream which holds its entire data set
86 /// in a single contiguous buffer. As with BinaryByteStream, the mutable
87 /// version also guarantees that no read operation will ever incur a copy,
88 /// and similarly it does not own the underlying buffer.
89 class MutableBinaryByteStream : public WritableBinaryStream {
90 public:
91 MutableBinaryByteStream() = default;
92 MutableBinaryByteStream(MutableArrayRef Data,
93 llvm::support::endianness Endian)
94 : Data(Data), ImmutableStream(Data, Endian) {}
95
96 llvm::support::endianness getEndian() const override {
97 return ImmutableStream.getEndian();
98 }
99
100 Error readBytes(uint32_t Offset, uint32_t Size,
101 ArrayRef &Buffer) override {
102 return ImmutableStream.readBytes(Offset, Size, Buffer);
103 }
104
105 Error readLongestContiguousChunk(uint32_t Offset,
106 ArrayRef &Buffer) override {
107 return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
108 }
109
110 uint32_t getLength() override { return ImmutableStream.getLength(); }
111
112 Error writeBytes(uint32_t Offset, ArrayRef Buffer) override {
113 if (Buffer.empty())
114 return Error::success();
115
116 if (auto EC = checkOffset(Offset, Buffer.size()))
117 return EC;
118
119 uint8_t *DataPtr = const_cast(Data.data());
120 ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
121 return Error::success();
122 }
123
124 Error commit() override { return Error::success(); }
125
126 MutableArrayRef data() const { return Data; }
127
128 private:
129 MutableArrayRef Data;
130 BinaryByteStream ImmutableStream;
131 };
132
133 /// \brief An implementation of WritableBinaryStream backed by an llvm
134 /// FileOutputBuffer.
135 class FileBufferByteStream : public WritableBinaryStream {
136 private:
137 class StreamImpl : public MutableBinaryByteStream {
138 public:
139 StreamImpl(std::unique_ptr Buffer,
140 llvm::support::endianness Endian)
141 : MutableBinaryByteStream(
142 MutableArrayRef(Buffer->getBufferStart(),
143 Buffer->getBufferEnd()),
144 Endian),
145 FileBuffer(std::move(Buffer)) {}
146
147 Error commit() override {
148 if (FileBuffer->commit())
149 return make_error(
150 stream_error_code::filesystem_error);
151 return Error::success();
152 }
153
154 private:
155 std::unique_ptr FileBuffer;
156 };
157
158 public:
159 FileBufferByteStream(std::unique_ptr Buffer,
160 llvm::support::endianness Endian)
161 : Impl(std::move(Buffer), Endian) {}
162
163 llvm::support::endianness getEndian() const override {
164 return Impl.getEndian();
165 }
166
167 Error readBytes(uint32_t Offset, uint32_t Size,
168 ArrayRef &Buffer) override {
169 return Impl.readBytes(Offset, Size, Buffer);
170 }
171
172 Error readLongestContiguousChunk(uint32_t Offset,
173 ArrayRef &Buffer) override {
174 return Impl.readLongestContiguousChunk(Offset, Buffer);
175 }
176
177 uint32_t getLength() override { return Impl.getLength(); }
178
179 Error writeBytes(uint32_t Offset, ArrayRef Data) override {
180 return Impl.writeBytes(Offset, Data);
181 }
182
183 Error commit() override { return Impl.commit(); }
184
185 private:
186 StreamImpl Impl;
187 };
188
189 } // end namespace llvm
190
191 #endif // LLVM_SUPPORT_BYTESTREAM_H
0 //===- BinaryItemStream.h ---------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_BINARYITEMSTREAM_H
10 #define LLVM_SUPPORT_BINARYITEMSTREAM_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/Support/BinaryStream.h"
14 #include "llvm/Support/BinaryStreamError.h"
15 #include "llvm/Support/Error.h"
16 #include
17 #include
18
19 namespace llvm {
20
21 template struct BinaryItemTraits {
22 static size_t length(const T &Item) = delete;
23 static ArrayRef bytes(const T &Item) = delete;
24 };
25
26 /// BinaryItemStream represents a sequence of objects stored in some kind of
27 /// external container but for which it is useful to view as a stream of
28 /// contiguous bytes. An example of this might be if you have a collection of
29 /// records and you serialize each one into a buffer, and store these serialized
30 /// records in a container. The pointers themselves are not laid out
31 /// contiguously in memory, but we may wish to read from or write to these
32 /// records as if they were.
33 template >
34 class BinaryItemStream : public BinaryStream {
35 public:
36 explicit BinaryItemStream(llvm::support::endianness Endian)
37 : Endian(Endian) {}
38
39 llvm::support::endianness getEndian() const override { return Endian; }
40
41 Error readBytes(uint32_t Offset, uint32_t Size,
42 ArrayRef &Buffer) override {
43 auto ExpectedIndex = translateOffsetIndex(Offset);
44 if (!ExpectedIndex)
45 return ExpectedIndex.takeError();
46 const auto &Item = Items[*ExpectedIndex];
47 if (auto EC = checkOffset(Offset, Size))
48 return EC;
49 if (Size > Traits::length(Item))
50 return make_error(stream_error_code::stream_too_short);
51 Buffer = Traits::bytes(Item).take_front(Size);
52 return Error::success();
53 }
54
55 Error readLongestContiguousChunk(uint32_t Offset,
56 ArrayRef &Buffer) override {
57 auto ExpectedIndex = translateOffsetIndex(Offset);
58 if (!ExpectedIndex)
59 return ExpectedIndex.takeError();
60 Buffer = Traits::bytes(Items[*ExpectedIndex]);
61 return Error::success();
62 }
63
64 void setItems(ArrayRef ItemArray) { Items = ItemArray; }
65
66 uint32_t getLength() override {
67 uint32_t Size = 0;
68 for (const auto &Item : Items)
69 Size += Traits::length(Item);
70 return Size;
71 }
72
73 private:
74 Expected translateOffsetIndex(uint32_t Offset) const {
75 uint32_t CurrentOffset = 0;
76 uint32_t CurrentIndex = 0;
77 for (const auto &Item : Items) {
78 if (CurrentOffset >= Offset)
79 break;
80 CurrentOffset += Traits::length(Item);
81 ++CurrentIndex;
82 }
83 if (CurrentOffset != Offset)
84 return make_error(stream_error_code::stream_too_short);
85 return CurrentIndex;
86 }
87
88 llvm::support::endianness Endian;
89 ArrayRef Items;
90 };
91
92 } // end namespace llvm
93
94 #endif // LLVM_SUPPORT_BINARYITEMSTREAM_H
0 //===- BinaryStream.h - Base interface for a stream of data -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_BINARYSTREAM_H
10 #define LLVM_SUPPORT_BINARYSTREAM_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/Support/BinaryStreamError.h"
14 #include "llvm/Support/Endian.h"
15 #include "llvm/Support/Error.h"
16 #include
17
18 namespace llvm {
19
20 /// \brief An interface for accessing data in a stream-like format, but which
21 /// discourages copying. Instead of specifying a buffer in which to copy
22 /// data on a read, the API returns an ArrayRef to data owned by the stream's
23 /// implementation. Since implementations may not necessarily store data in a
24 /// single contiguous buffer (or even in memory at all), in such cases a it may
25 /// be necessary for an implementation to cache such a buffer so that it can
26 /// return it.
27 class BinaryStream {
28 public:
29 virtual ~BinaryStream() = default;
30
31 virtual llvm::support::endianness getEndian() const = 0;
32
33 /// \brief Given an offset into the stream and a number of bytes, attempt to
34 /// read the bytes and set the output ArrayRef to point to data owned by the
35 /// stream.
36 virtual Error readBytes(uint32_t Offset, uint32_t Size,
37 ArrayRef &Buffer) = 0;
38
39 /// \brief Given an offset into the stream, read as much as possible without
40 /// copying any data.
41 virtual Error readLongestContiguousChunk(uint32_t Offset,
42 ArrayRef &Buffer) = 0;
43
44 /// \brief Return the number of bytes of data in this stream.
45 virtual uint32_t getLength() = 0;
46
47 protected:
48 Error checkOffset(uint32_t Offset, uint32_t DataSize) {
49 if (Offset > getLength())
50 return make_error(stream_error_code::invalid_offset);
51 if (getLength() < DataSize + Offset)
52 return make_error(stream_error_code::stream_too_short);
53 return Error::success();
54 }
55 };
56
57 /// \brief A BinaryStream which can be read from as well as written to. Note
58 /// that writing to a BinaryStream always necessitates copying from the input
59 /// buffer to the stream's backing store. Streams are assumed to be buffered
60 /// so that to be portable it is necessary to call commit() on the stream when
61 /// all data has been written.
62 class WritableBinaryStream : public BinaryStream {
63 public:
64 ~WritableBinaryStream() override = default;
65
66 /// \brief Attempt to write the given bytes into the stream at the desired
67 /// offset. This will always necessitate a copy. Cannot shrink or grow the
68 /// stream, only writes into existing allocated space.
69 virtual Error writeBytes(uint32_t Offset, ArrayRef Data) = 0;
70
71 /// \brief For buffered streams, commits changes to the backing store.
72 virtual Error commit() = 0;
73 };
74
75 } // end namespace llvm
76
77 #endif // LLVM_SUPPORT_BINARYSTREAM_H
0 //===- BinaryStreamArray.h - Array backed by an arbitrary stream *- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_BINARYSTREAMARRAY_H
10 #define LLVM_SUPPORT_BINARYSTREAMARRAY_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/iterator.h"
14 #include "llvm/Support/BinaryStreamRef.h"
15 #include "llvm/Support/Error.h"
16 #include
17 #include
18
19 /// Lightweight arrays that are backed by an arbitrary BinaryStream. This file
20 /// provides two different array implementations.
21 ///
22 /// VarStreamArray - Arrays of variable length records. The user specifies
23 /// an Extractor type that can extract a record from a given offset and
24 /// return the number of bytes consumed by the record.
25 ///
26 /// FixedStreamArray - Arrays of fixed length records. This is similar in
27 /// spirit to ArrayRef, but since it is backed by a BinaryStream, the
28 /// elements of the array need not be laid out in contiguous memory.
29 namespace llvm {
30
31 /// VarStreamArrayExtractor is intended to be specialized to provide customized
32 /// extraction logic. On input it receives a BinaryStreamRef pointing to the
33 /// beginning of the next record, but where the length of the record is not yet
34 /// known. Upon completion, it should return an appropriate Error instance if
35 /// a record could not be extracted, or if one could be extracted it should
36 /// return success and set Len to the number of bytes this record occupied in
37 /// the underlying stream, and it should fill out the fields of the value type
38 /// Item appropriately to represent the current record.
39 ///
40 /// You can specialize this template for your own custom value types to avoid
41 /// having to specify a second template argument to VarStreamArray (documented
42 /// below).
43 template struct VarStreamArrayExtractor {
44 // Method intentionally deleted. You must provide an explicit specialization
45 // with the following method implemented.
46 Error operator()(BinaryStreamRef Stream, uint32_t &Len,
47 T &Item) const = delete;
48 };
49
50 /// VarStreamArray represents an array of variable length records backed by a
51 /// stream. This could be a contiguous sequence of bytes in memory, it could
52 /// be a file on disk, or it could be a PDB stream where bytes are stored as
53 /// discontiguous blocks in a file. Usually it is desirable to treat arrays
54 /// as contiguous blocks of memory, but doing so with large PDB files, for
55 /// example, could mean allocating huge amounts of memory just to allow
56 /// re-ordering of stream data to be contiguous before iterating over it. By
57 /// abstracting this out, we need not duplicate this memory, and we can
58 /// iterate over arrays in arbitrarily formatted streams. Elements are parsed
59 /// lazily on iteration, so there is no upfront cost associated with building
60 /// or copying a VarStreamArray, no matter how large it may be.
61 ///
62 /// You create a VarStreamArray by specifying a ValueType and an Extractor type.
63 /// If you do not specify an Extractor type, you are expected to specialize
64 /// VarStreamArrayExtractor for your ValueType.
65 ///
66 /// By default an Extractor is default constructed in the class, but in some
67 /// cases you might find it useful for an Extractor to maintain state across
68 /// extractions. In this case you can provide your own Extractor through a
69 /// secondary constructor. The following examples show various ways of
70 /// creating a VarStreamArray.
71 ///
72 /// // Will use VarStreamArrayExtractor as the extractor.
73 /// VarStreamArray MyTypeArray;
74 ///
75 /// // Will use a default-constructed MyExtractor as the extractor.
76 /// VarStreamArray MyTypeArray2;
77 ///
78 /// // Will use the specific instance of MyExtractor provided.
79 /// // MyExtractor need not be default-constructible in this case.
80 /// MyExtractor E(SomeContext);
81 /// VarStreamArray MyTypeArray3(E);
82 ///
83 template class VarStreamArrayIterator;
84
85 template
86 typename Extractor = VarStreamArrayExtractor>
87
88 class VarStreamArray {
89 friend class VarStreamArrayIterator;
90
91 public:
92 typedef VarStreamArrayIterator Iterator;
93
94 VarStreamArray() = default;
95 explicit VarStreamArray(const Extractor &E) : E(E) {}
96
97 explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {}
98 VarStreamArray(BinaryStreamRef Stream, const Extractor &E)
99 : Stream(Stream), E(E) {}
100
101 VarStreamArray(const VarStreamArray &Other)
102 : Stream(Other.Stream), E(Other.E) {}
103
104 Iterator begin(bool *HadError = nullptr) const {
105 return Iterator(*this, E, HadError);
106 }
107
108 Iterator end() const { return Iterator(E); }
109
110 const Extractor &getExtractor() const { return E; }
111
112 BinaryStreamRef getUnderlyingStream() const { return Stream; }
113
114 private:
115 BinaryStreamRef Stream;
116 Extractor E;
117 };
118
119 template
120 class VarStreamArrayIterator
121 : public iterator_facade_base,
122 std::forward_iterator_tag, ValueType> {
123 typedef VarStreamArrayIterator IterType;
124 typedef VarStreamArray ArrayType;
125
126 public:
127 VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
128 bool *HadError = nullptr)
129 : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) {
130 if (IterRef.getLength() == 0)
131 moveToEnd();
132 else {
133 auto EC = Extract(IterRef, ThisLen, ThisValue);
134 if (EC) {
135 consumeError(std::move(EC));
136 markError();
137 }
138 }
139 }
140 VarStreamArrayIterator() = default;
141 explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {}
142 ~VarStreamArrayIterator() = default;
143
144 bool operator==(const IterType &R) const {
145 if (Array && R.Array) {
146 // Both have a valid array, make sure they're same.
147 assert(Array == R.Array);
148 return IterRef == R.IterRef;
149 }
150
151 // Both iterators are at the end.
152 if (!Array && !R.Array)
153 return true;
154
155 // One is not at the end and one is.
156 return false;
157 }
158
159 const ValueType &operator*() const {
160 assert(Array && !HasError);
161 return ThisValue;
162 }
163
164 IterType &operator+=(unsigned N) {
165 for (unsigned I = 0; I < N; ++I) {
166 // We are done with the current record, discard it so that we are
167 // positioned at the next record.
168 IterRef = IterRef.drop_front(ThisLen);
169 if (IterRef.getLength() == 0) {
170 // There is nothing after the current record, we must make this an end
171 // iterator.
172 moveToEnd();
173 } else {
174 // There is some data after the current record.
175 auto EC = Extract(IterRef, ThisLen, ThisValue);
176 if (EC) {
177 consumeError(std::move(EC));
178 markError();
179 } else if (ThisLen == 0) {
180 // An empty record? Make this an end iterator.
181 moveToEnd();
182 }
183 }
184 }
185 return *this;
186 }
187
188 private:
189 void moveToEnd() {
190 Array = nullptr;
191 ThisLen = 0;
192 }
193 void markError() {
194 moveToEnd();
195 HasError = true;
196 if (HadError != nullptr)
197 *HadError = true;
198 }
199
200 ValueType ThisValue;
201 BinaryStreamRef IterRef;
202 const ArrayType *Array{nullptr};
203 uint32_t ThisLen{0};
204 bool HasError{false};
205 bool *HadError{nullptr};
206 Extractor Extract;
207 };
208
209 template class FixedStreamArrayIterator;
210
211 /// FixedStreamArray is similar to VarStreamArray, except with each record
212 /// having a fixed-length. As with VarStreamArray, there is no upfront
213 /// cost associated with building or copying a FixedStreamArray, as the
214 /// memory for each element is not read from the backing stream until that
215 /// element is iterated.
216 template class FixedStreamArray {
217 friend class FixedStreamArrayIterator;
218
219 public:
220 FixedStreamArray() = default;
221 explicit FixedStreamArray(BinaryStreamRef Stream) : Stream(Stream) {
222 assert(Stream.getLength() % sizeof(T) == 0);
223 }
224
225 bool operator==(const FixedStreamArray &Other) const {
226 return Stream == Other.Stream;
227 }
228
229 bool operator!=(const FixedStreamArray &Other) const {
230 return !(*this == Other);
231 }
232
233 FixedStreamArray &operator=(const FixedStreamArray &) = default;
234
235 const T &operator[](uint32_t Index) const {
236 assert(Index < size());
237 uint32_t Off = Index * sizeof(T);
238 ArrayRef Data;
239 if (auto EC = Stream.readBytes(Off, sizeof(T), Data)) {
240 assert(false && "Unexpected failure reading from stream");
241 // This should never happen since we asserted that the stream length was
242 // an exact multiple of the element size.
243 consumeError(std::move(EC));
244 }
245 assert(llvm::alignmentAdjustment(Data.data(), alignof(T)) == 0);
246 return *reinterpret_cast(Data.data());
247 }
248
249 uint32_t size() const { return Stream.getLength() / sizeof(T); }
250
251 bool empty() const { return size() == 0; }
252
253 FixedStreamArrayIterator begin() const {
254 return FixedStreamArrayIterator(*this, 0);
255 }
256
257 FixedStreamArrayIterator end() const {
258 return FixedStreamArrayIterator(*this, size());
259 }
260
261 BinaryStreamRef getUnderlyingStream() const { return Stream; }
262
263 private:
264 BinaryStreamRef Stream;
265 };
266
267 template
268 class FixedStreamArrayIterator
269 : public iterator_facade_base,
270 std::random_access_iterator_tag, T> {
271
272 public:
273 FixedStreamArrayIterator(const FixedStreamArray &Array, uint32_t Index)
274 : Array(Array), Index(Index) {}
275
276 FixedStreamArrayIterator &
277 operator=(const FixedStreamArrayIterator &Other) {
278 Array = Other.Array;
279 Index = Other.Index;
280 return *this;
281 }
282
283 const T &operator*() const { return Array[Index]; }
284
285 bool operator==(const FixedStreamArrayIterator &R) const {
286 assert(Array == R.Array);
287 return (Index == R.Index) && (Array == R.Array);
288 }
289
290 FixedStreamArrayIterator &operator+=(std::ptrdiff_t N) {
291 Index += N;
292 return *this;
293 }
294
295 FixedStreamArrayIterator &operator-=(std::ptrdiff_t N) {
296 assert(Index >= N);
297 Index -= N;
298 return *this;
299 }
300
301 std::ptrdiff_t operator-(const FixedStreamArrayIterator &R) const {
302 assert(Array == R.Array);
303 assert(Index >= R.Index);
304 return Index - R.Index;
305 }
306
307 bool operator<(const FixedStreamArrayIterator &RHS) const {
308 assert(Array == RHS.Array);
309 return Index < RHS.Index;
310 }
311
312 private:
313 FixedStreamArray Array;
314 uint32_t Index;
315 };
316
317 } // namespace llvm
318
319 #endif // LLVM_SUPPORT_BINARYSTREAMARRAY_H
0 //===- BinaryStreamError.h - Error extensions for Binary Streams *- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_BINARYSTREAMERROR_H
10 #define LLVM_SUPPORT_BINARYSTREAMERROR_H
11
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/Error.h"
14
15 #include
16
17 namespace llvm {
18 enum class stream_error_code {
19 unspecified,
20 stream_too_short,
21 invalid_array_size,
22 invalid_offset,
23 filesystem_error
24 };
25
26 /// Base class for errors originating when parsing raw PDB files
27 class BinaryStreamError : public ErrorInfo {
28 public:
29 static char ID;
30 explicit BinaryStreamError(stream_error_code C);
31 explicit BinaryStreamError(StringRef Context);
32 BinaryStreamError(stream_error_code C, StringRef Context);
33
34 void log(raw_ostream &OS) const override;
35 std::error_code convertToErrorCode() const override;
36
37 StringRef getErrorMessage() const;
38
39 stream_error_code getErrorCode() const { return Code; }
40
41 private:
42 std::string ErrMsg;
43 stream_error_code Code;
44 };
45 } // namespace llvm
46
47 #endif // LLVM_SUPPORT_BINARYSTREAMERROR_H
0 //===- BinaryStreamReader.h - Reads objects from a binary stream *- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_BINARYSTREAMREADER_H
10 #define LLVM_SUPPORT_BINARYSTREAMREADER_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/Support/BinaryStreamArray.h"
15 #include "llvm/Support/BinaryStreamRef.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/MathExtras.h"
19 #include "llvm/Support/type_traits.h"
20
21 #include
22 #include
23
24 namespace llvm {
25
26 /// \brief Provides read only access to a subclass of `BinaryStream`. Provides
27 /// bounds checking and helpers for writing certain common data types such as
28 /// null-terminated strings, integers in various flavors of endianness, etc.
29 /// Can be subclassed to provide reading of custom datatypes, although no
30 /// are overridable.
31 class BinaryStreamReader {
32 public:
33 explicit BinaryStreamReader(BinaryStreamRef Stream);
34 virtual ~BinaryStreamReader() {}
35
36 /// Read as much as possible from the underlying string at the current offset
37 /// without invoking a copy, and set \p Buffer to the resulting data slice.
38 /// Updates the stream's offset to point after the newly read data.
39 ///
40 /// \returns a success error code if the data was successfully read, otherwise
41 /// returns an appropriate error code.
42 Error readLongestContiguousChunk(ArrayRef &Buffer);
43
44 /// Read \p Size bytes from the underlying stream at the current offset and
45 /// and set \p Buffer to the resulting data slice. Whether a copy occurs
46 /// depends on the implementation of the underlying stream. Updates the
47 /// stream's offset to point after the newly read data.
48 ///
49 /// \returns a success error code if the data was successfully read, otherwise
50 /// returns an appropriate error code.
51 Error readBytes(ArrayRef &Buffer, uint32_t Size);
52
53 /// Read an integer of the specified endianness into \p Dest and update the
54 /// stream's offset. The data is always copied from the stream's underlying
55 /// buffer into \p Dest. Updates the stream's offset to point after the newly
56 /// read data.
57 ///
58 /// \returns a success error code if the data was successfully read, otherwise
59 /// returns an appropriate error code.
60 template Error readInteger(T &Dest) {
61 static_assert(std::is_integral::value,
62 "Cannot call readInteger with non-integral value!");
63
64 ArrayRef Bytes;
65 if (auto EC = readBytes(Bytes, sizeof(T)))
66 return EC;
67
68 Dest = llvm::support::endian::read(
69 Bytes.data(), Stream.getEndian());
70 return Error::success();
71 }
72
73 /// Similar to readInteger.
74 template Error readEnum(T &Dest) {
75 static_assert(std::is_enum::value,
76 "Cannot call readEnum with non-enum value!");
77 typename std::underlying_type::type N;
78 if (auto EC = readInteger(N))
79 return EC;
80 Dest = static_cast(N);
81 return Error::success();
82 }
83
84 /// Read a null terminated string from \p Dest. Whether a copy occurs depends
85 /// on the implementation of the underlying stream. Updates the stream's
86 /// offset to point after the newly read data.
87 ///
88 /// \returns a success error code if the data was successfully read, otherwise
89 /// returns an appropriate error code.
90 Error readCString(StringRef &Dest);
91
92 /// Read a \p Length byte string into \p Dest. Whether a copy occurs depends
93 /// on the implementation of the underlying stream. Updates the stream's
94 /// offset to point after the newly read data.
95 ///
96 /// \returns a success error code if the data was successfully read, otherwise
97 /// returns an appropriate error code.
98 Error readFixedString(StringRef &Dest, uint32_t Length);
99
100 /// Read the entire remainder of the underlying stream into \p Ref. This is
101 /// equivalent to calling getUnderlyingStream().slice(Offset). Updates the
102 /// stream's offset to point to the end of the stream. Never causes a copy.
103 ///
104 /// \returns a success error code if the data was successfully read, otherwise
105 /// returns an appropriate error code.
106 Error readStreamRef(BinaryStreamRef &Ref);
107
108 /// Read \p Length bytes from the underlying stream into \p Ref. This is
109 /// equivalent to calling getUnderlyingStream().slice(Offset, Length).
110 /// Updates the stream's offset to point after the newly read object. Never
111 /// causes a copy.
112 ///
113 /// \returns a success error code if the data was successfully read, otherwise
114 /// returns an appropriate error code.
115 Error readStreamRef(BinaryStreamRef &Ref, uint32_t Length);
116
117 /// Get a pointer to an object of type T from the underlying stream, as if by
118 /// memcpy, and store the result into \p Dest. It is up to the caller to
119 /// ensure that objects of type T can be safely treated in this manner.
120 /// Updates the stream's offset to point after the newly read object. Whether
121 /// a copy occurs depends upon the implementation of the underlying
122 /// stream.
123 ///
124 /// \returns a success error code if the data was successfully read, otherwise
125 /// returns an appropriate error code.
126 template Error readObject(const T *&Dest) {
127 ArrayRef Buffer;
128 if (auto EC = readBytes(Buffer, sizeof(T)))
129 return EC;
130 Dest = reinterpret_cast(Buffer.data());
131 return Error::success();
132 }
133
134 /// Get a reference to a \p NumElements element array of objects of type T
135 /// from the underlying stream as if by memcpy, and store the resulting array
136 /// slice into \p array. It is up to the caller to ensure that objects of
137 /// type T can be safely treated in this manner. Updates the stream's offset
138 /// to point after the newly read object. Whether a copy occurs depends upon
139 /// the implementation of the underlying stream.
140 ///
141 /// \returns a success error code if the data was successfully read, otherwise
142 /// returns an appropriate error code.
143 template
144 Error readArray(ArrayRef &Array, uint32_t NumElements) {
145 ArrayRef Bytes;
146 if (NumElements == 0) {
147 Array = ArrayRef();
148 return Error::success();
149 }
150
151 if (NumElements > UINT32_MAX / sizeof(T))
152 return make_error(
153 stream_error_code::invalid_array_size);
154
155 if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
156 return EC;
157
158 assert(alignmentAdjustment(Bytes.data(), alignof(T)) == 0 &&
159 "Reading at invalid alignment!");
160
161 Array = ArrayRef(reinterpret_cast(Bytes.data()), NumElements);
162 return Error::success();
163 }
164
165 /// Read a VarStreamArray of size \p Size bytes and store the result into
166 /// \p Array. Updates the stream's offset to point after the newly read
167 /// array. Never causes a copy (although iterating the elements of the
168 /// VarStreamArray may, depending upon the implementation of the underlying
169 /// stream).
170 ///
171 /// \returns a success error code if the data was successfully read, otherwise
172 /// returns an appropriate error code.
173 template
174 Error readArray(VarStreamArray &Array, uint32_t Size) {
175 BinaryStreamRef S;
176 if (auto EC = readStreamRef(S, Size))
177 return EC;
178 Array = VarStreamArray(S, Array.getExtractor());
179 return Error::success();
180 }
181
182 /// Read a FixedStreamArray of \p NumItems elements and store the result into
183 /// \p Array. Updates the stream's offset to point after the newly read
184 /// array. Never causes a copy (although iterating the elements of the
185 /// FixedStreamArray may, depending upon the implementation of the underlying
186 /// stream).
187 ///
188 /// \returns a success error code if the data was successfully read, otherwise
189 /// returns an appropriate error code.
190 template
191 Error readArray(FixedStreamArray &Array, uint32_t NumItems) {
192 if (NumItems == 0) {
193 Array = FixedStreamArray();
194 return Error::success();
195 }
196
197 if (NumItems > UINT32_MAX / sizeof(T))
198 return make_error(
199 stream_error_code::invalid_array_size);
200
201 BinaryStreamRef View;
202 if (auto EC = readStreamRef(View, NumItems * sizeof(T)))
203 return EC;
204
205 Array = FixedStreamArray(View);
206 return Error::success();
207 }
208
209 bool empty() const { return bytesRemaining() == 0; }
210 void setOffset(uint32_t Off) { Offset = Off; }
211 uint32_t getOffset() const { return Offset; }
212 uint32_t getLength() const { return Stream.getLength(); }
213 uint32_t bytesRemaining() const { return getLength() - getOffset(); }
214
215 /// Advance the stream's offset by \p Amount bytes.
216 ///
217 /// \returns a success error code if at least \p Amount bytes remain in the
218 /// stream, otherwise returns an appropriate error code.
219 Error skip(uint32_t Amount);
220
221 /// Examine the next byte of the underlying stream without advancing the
222 /// stream's offset. If the stream is empty the behavior is undefined.
223 ///
224 /// \returns the next byte in the stream.
225 uint8_t peek() const;
226
227 private:
228 BinaryStreamRef Stream;
229 uint32_t Offset;
230 };
231 } // namespace llvm
232
233 #endif // LLVM_SUPPORT_BINARYSTREAMREADER_H
0 //===- BinaryStreamRef.h - A copyable reference to a stream -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_BINARYSTREAMREF_H
10 #define LLVM_SUPPORT_BINARYSTREAMREF_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/Support/BinaryStream.h"
14 #include "llvm/Support/BinaryStreamError.h"
15 #include "llvm/Support/Error.h"
16 #include
17 #include
18
19 namespace llvm {
20
21 /// Common stuff for mutable and immutable StreamRefs.
22 template class BinaryStreamRefBase {
23 public:
24 BinaryStreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {}
25 BinaryStreamRefBase(StreamType &Stream, uint32_t Offset, uint32_t Length)
26 : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
27
28 llvm::support::endianness getEndian() const { return Stream->getEndian(); }
29
30 uint32_t getLength() const { return Length; }
31 const StreamType *getStream() const { return Stream; }
32
33 /// Return a new BinaryStreamRef with the first \p N elements removed.
34 RefType drop_front(uint32_t N) const {
35 if (!Stream)
36 return RefType();
37
38 N = std::min(N, Length);
39 return RefType(*Stream, ViewOffset + N, Length - N);
40 }
41
42 /// Return a new BinaryStreamRef with only the first \p N elements remaining.
43 RefType keep_front(uint32_t N) const {
44 if (!Stream)
45 return RefType();
46 N = std::min(N, Length);
47 return RefType(*Stream, ViewOffset, N);
48 }
49
50 /// Return a new BinaryStreamRef with the first \p Offset elements removed,
51 /// and retaining exactly \p Len elements.
52 RefType slice(uint32_t Offset, uint32_t Len) const {
53 return drop_front(Offset).keep_front(Len);
54 }
55
56 bool operator==(const RefType &Other) const {
57 if (Stream != Other.Stream)
58 return false;
59 if (ViewOffset != Other.ViewOffset)
60 return false;
61 if (Length != Other.Length)
62 return false;
63 return true;
64 }
65
66 protected:
67 Error checkOffset(uint32_t Offset, uint32_t DataSize) const {
68 if (Offset > getLength())
69 return make_error(stream_error_code::invalid_offset);
70 if (getLength() < DataSize + Offset)
71 return make_error(stream_error_code::stream_too_short);
72 return Error::success();
73 }
74
75 StreamType *Stream;
76 uint32_t ViewOffset;
77 uint32_t Length;
78 };
79
80 /// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It
81 /// provides copy-semantics and read only access to a "window" of the underlying
82 /// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream. That is to
83 /// say, it does not inherit and override the methods of BinaryStream. In
84 /// general, you should not pass around pointers or references to BinaryStreams
85 /// and use inheritance to achieve polymorphism. Instead, you should pass
86 /// around BinaryStreamRefs by value and achieve polymorphism that way.
87 class BinaryStreamRef
88 : public BinaryStreamRefBase {
89 public:
90 BinaryStreamRef() = default;
91 BinaryStreamRef(BinaryStream &Stream)
92 : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {}
93 BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length)
94 : BinaryStreamRefBase(Stream, Offset, Length) {}
95
96 // Use BinaryStreamRef.slice() instead.
97 BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset,
98 uint32_t Length) = delete;
99
100 /// Given an Offset into this StreamRef and a Size, return a reference to a
101 /// buffer owned by the stream.
102 ///
103 /// \returns a success error code if the entire range of data is within the
104 /// bounds of this BinaryStreamRef's view and the implementation could read
105 /// the data, and an appropriate error code otherwise.
106 Error readBytes(uint32_t Offset, uint32_t Size,
107 ArrayRef &Buffer) const {
108 if (auto EC = checkOffset(Offset, Size))
109 return EC;
110
111 return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
112 }
113
114 /// Given an Offset into this BinaryStreamRef, return a reference to the
115 /// largest buffer the stream could support without necessitating a copy.
116 ///
117 /// \returns a success error code if implementation could read the data,
118 /// and an appropriate error code otherwise.
119 Error readLongestContiguousChunk(uint32_t Offset,
120 ArrayRef &Buffer) const {
121 if (auto EC = checkOffset(Offset, 1))
122 return EC;
123
124 if (auto EC =
125 Stream->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
126 return EC;
127 // This StreamRef might refer to a smaller window over a larger stream. In
128 // that case we will have read out more bytes than we should return, because
129 // we should not read past the end of the current view.
130 uint32_t MaxLength = Length - Offset;
131 if (Buffer.size() > MaxLength)
132 Buffer = Buffer.slice(0, MaxLength);
133 return Error::success();
134 }
135 };
136
137 class WritableBinaryStreamRef
138 : public BinaryStreamRefBase
139 WritableBinaryStreamRef> {
140 public:
141 WritableBinaryStreamRef() = default;
142 WritableBinaryStreamRef(WritableBinaryStream &Stream)
143 : BinaryStreamRefBase(Stream, 0, Stream.getLength()) {}
144 WritableBinaryStreamRef(WritableBinaryStream &Stream, uint32_t Offset,
145 uint32_t Length)
146 : BinaryStreamRefBase(Stream, Offset, Length) {}
147
148 // Use WritableBinaryStreamRef.slice() instead.
149 WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint32_t Offset,
150 uint32_t Length) = delete;
151
152 /// Given an Offset into this WritableBinaryStreamRef and some input data,
153 /// writes the data to the underlying stream.
154 ///
155 /// \returns a success error code if the data could fit within the underlying
156 /// stream at the specified location and the implementation could write the
157 /// data, and an appropriate error code otherwise.
158 Error writeBytes(uint32_t Offset, ArrayRef Data) const {
159 if (auto EC = checkOffset(Offset, Data.size()))
160 return EC;
161
162 return Stream->writeBytes(ViewOffset + Offset, Data);
163 }
164
165 operator BinaryStreamRef() { return BinaryStreamRef(*Stream); }
166
167 /// \brief For buffered streams, commits changes to the backing store.
168 Error commit() { return Stream->commit(); }
169 };
170
171 } // end namespace llvm
172
173 #endif // LLVM_SUPPORT_BINARYSTREAMREF_H
0 //===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- C++-*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_BINARYSTREAMWRITER_H
10 #define LLVM_SUPPORT_BINARYSTREAMWRITER_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/BinaryStreamArray.h"
16 #include "llvm/Support/BinaryStreamError.h"
17 #include "llvm/Support/BinaryStreamRef.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/Error.h"
20 #include
21 #include
22
23 namespace llvm {
24
25 /// \brief Provides write only access to a subclass of `WritableBinaryStream`.
26 /// Provides bounds checking and helpers for writing certain common data types
27 /// such as null-terminated strings, integers in various flavors of endianness,
28 /// etc. Can be subclassed to provide reading and writing of custom datatypes,
29 /// although no methods are overridable.
30 class BinaryStreamWriter {
31 public:
32 BinaryStreamWriter() = default;
33 explicit BinaryStreamWriter(WritableBinaryStreamRef Stream);
34 virtual ~BinaryStreamWriter() {}
35
36 /// Write the bytes specified in \p Buffer to the underlying stream.
37 /// On success, updates the offset so that subsequent writes will occur
38 /// at the next unwritten position.
39 ///
40 /// \returns a success error code if the data was successfully written,
41 /// otherwise returns an appropriate error code.
42 Error writeBytes(ArrayRef Buffer);
43
44 /// Write the the integer \p Value to the underlying stream in the
45 /// specified endianness. On success, updates the offset so that
46 /// subsequent writes occur at the next unwritten position.
47 ///
48 /// \returns a success error code if the data was successfully written,
49 /// otherwise returns an appropriate error code.
50 template Error writeInteger(T Value) {
51 static_assert(std::is_integral::value,
52 "Cannot call writeInteger with non-integral value!");
53 uint8_t Buffer[sizeof(T)];
54 llvm::support::endian::write(
55 Buffer, Value, Stream.getEndian());
56 return writeBytes(Buffer);
57 }
58
59 /// Similar to writeInteger
60 template Error writeEnum(T Num) {
61 static_assert(std::is_enum::value,
62 "Cannot call writeEnum with non-Enum type");
63
64 using U = typename std::underlying_type::type;
65 return writeInteger(static_cast(Num));
66 }
67
68 /// Write the the string \p Str to the underlying stream followed by a null
69 /// terminator. On success, updates the offset so that subsequent writes
70 /// occur at the next unwritten position. \p Str need not be null terminated
71 /// on input.
72 ///
73 /// \returns a success error code if the data was successfully written,
74 /// otherwise returns an appropriate error code.
75 Error writeCString(StringRef Str);
76
77 /// Write the the string \p Str to the underlying stream without a null
78 /// terminator. On success, updates the offset so that subsequent writes
79 /// occur at the next unwritten position.
80 ///
81 /// \returns a success error code if the data was successfully written,
82 /// otherwise returns an appropriate error code.
83 Error writeFixedString(StringRef Str);
84
85 /// Efficiently reads all data from \p Ref, and writes it to this stream.
86 /// This operation will not invoke any copies of the source data, regardless
87 /// of the source stream's implementation.
88 ///
89 /// \returns a success error code if the data was successfully written,
90 /// otherwise returns an appropriate error code.
91 Error writeStreamRef(BinaryStreamRef Ref);
92
93 /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream.
94 /// This operation will not invoke any copies of the source data, regardless
95 /// of the source stream's implementation.
96 ///
97 /// \returns a success error code if the data was successfully written,
98 /// otherwise returns an appropriate error code.
99 Error writeStreamRef(BinaryStreamRef Ref, uint32_t Size);
100
101 /// Writes the object \p Obj to the underlying stream, as if by using memcpy.
102 /// It is up to the caller to ensure that type of \p Obj can be safely copied
103 /// in this fashion, as no checks are made to ensure that this is safe.
104 ///
105 /// \returns a success error code if the data was successfully written,
106 /// otherwise returns an appropriate error code.
107 template Error writeObject(const T &Obj) {
108 static_assert(!std::is_pointer::value,
109 "writeObject should not be used with pointers, to write "
110 "the pointed-to value dereference the pointer before calling "
111 "writeObject");
112 return writeBytes(
113 ArrayRef(reinterpret_cast(&Obj), sizeof(T)));
114 }
115
116 /// Writes an array of objects of type T to the underlying stream, as if by
117 /// using memcpy. It is up to the caller to ensure that type of \p Obj can
118 /// be safely copied in this fashion, as no checks are made to ensure that
119 /// this is safe.
120 ///
121 /// \returns a success error code if the data was successfully written,
122 /// otherwise returns an appropriate error code.
123 template Error writeArray(ArrayRef Array) {
124 if (Array.empty())
125 return Error::success();
126 if (Array.size() > UINT32_MAX / sizeof(T))
127 return make_error(
128 stream_error_code::invalid_array_size);
129
130 return writeBytes(
131 ArrayRef(reinterpret_cast(Array.data()),
132 Array.size() * sizeof(T)));
133 }
134
135 /// Writes all data from the array \p Array to the underlying stream.
136 ///
137 /// \returns a success error code if the data was successfully written,
138 /// otherwise returns an appropriate error code.
139 template
140 Error writeArray(VarStreamArray Array) {
141 return writeStreamRef(Array.getUnderlyingStream());
142 }
143
144 /// Writes all elements from the array \p Array to the underlying stream.
145 ///
146 /// \returns a success error code if the data was successfully written,
147 /// otherwise returns an appropriate error code.
148 template Error writeArray(FixedStreamArray Array) {
149 return writeStreamRef(Array.getUnderlyingStream());
150 }
151
152 void setOffset(uint32_t Off) { Offset = Off; }
153 uint32_t getOffset() const { return Offset; }
154 uint32_t getLength() const { return Stream.getLength(); }
155 uint32_t bytesRemaining() const { return getLength() - getOffset(); }
156
157 protected:
158 WritableBinaryStreamRef Stream;
159 uint32_t Offset = 0;
160 };
161
162 } // end namespace llvm
163
164 #endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H
2222 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
2323 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
2424 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
25 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
26 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
2725 #include "llvm/IR/Constants.h"
2826 #include "llvm/MC/MCAsmInfo.h"
2927 #include "llvm/MC/MCExpr.h"
3028 #include "llvm/MC/MCSectionCOFF.h"
3129 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Support/BinaryByteStream.h"
31 #include "llvm/Support/BinaryStreamReader.h"
3232 #include "llvm/Support/COFF.h"
3333 #include "llvm/Support/ScopedPrinter.h"
3434 #include "llvm/Target/TargetFrameLowering.h"
1010
1111 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
1212 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
13 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
13 #include "llvm/Support/BinaryByteStream.h"
1414
1515 using namespace llvm;
1616 using namespace llvm::codeview;
1313 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
1414 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
1515 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
16 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
16 #include "llvm/Support/BinaryByteStream.h"
1717
1818 using namespace llvm;
1919 using namespace llvm::codeview;
1515 #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
1616 #include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
1717 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
18 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
19 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
18 #include "llvm/Support/BinaryByteStream.h"
19 #include "llvm/Support/BinaryStreamReader.h"
2020
2121 using namespace llvm;
2222 using namespace llvm::codeview;
99 #include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
1010 #include "llvm/DebugInfo/CodeView/CodeView.h"
1111 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
12 #include "llvm/Support/BinaryStreamReader.h"
13 #include "llvm/Support/BinaryStreamWriter.h"
1414
1515 using namespace llvm;
1616 using namespace llvm::codeview;
88
99 #include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
1010
11 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
11 #include "llvm/Support/BinaryStreamReader.h"
1212
1313 using namespace llvm;
1414 using namespace llvm::codeview;
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h"
10 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
11 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
10 #include "llvm/Support/BinaryStreamReader.h"
11 #include "llvm/Support/BinaryStreamRef.h"
1212
1313 using namespace llvm;
1414 using namespace llvm::codeview;
1515 #include "llvm/ADT/APSInt.h"
1616 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
1717 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
18 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
18 #include "llvm/Support/BinaryByteStream.h"
1919
2020 using namespace llvm;
2121 using namespace llvm::codeview;
1818 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
1919 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
2020 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
21 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
21 #include "llvm/Support/BinaryByteStream.h"
2222 #include "llvm/Support/FormatVariadic.h"
2323 #include "llvm/Support/ScopedPrinter.h"
2424
99 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
1010 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
1111 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
12 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
12 #include "llvm/Support/BinaryByteStream.h"
13 #include "llvm/Support/BinaryStreamReader.h"
1414
1515 using namespace llvm;
1616 using namespace llvm::codeview;
88
99 #include "llvm/DebugInfo/CodeView/TypeSerializer.h"
1010
11 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
11 #include "llvm/Support/BinaryStreamWriter.h"
1212
1313 #include
1414
+0
-56
lib/DebugInfo/MSF/BinaryStreamError.cpp less more
None //===- BinaryStreamError.cpp - Error extensions for streams -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
10 #include "llvm/Support/ErrorHandling.h"
11
12 using namespace llvm;
13
14 char BinaryStreamError::ID = 0;
15
16 BinaryStreamError::BinaryStreamError(stream_error_code C)
17 : BinaryStreamError(C, "") {}
18
19 BinaryStreamError::BinaryStreamError(StringRef Context)
20 : BinaryStreamError(stream_error_code::unspecified, Context) {}
21
22 BinaryStreamError::BinaryStreamError(stream_error_code C, StringRef Context)
23 : Code(C) {
24 ErrMsg = "Stream Error: ";
25 switch (C) {
26 case stream_error_code::unspecified:
27 ErrMsg += "An unspecified error has occurred.";
28 break;
29 case stream_error_code::stream_too_short:
30 ErrMsg += "The stream is too short to perform the requested operation.";
31 break;
32 case stream_error_code::invalid_array_size:
33 ErrMsg += "The buffer size is not a multiple of the array element size.";
34 break;
35 case stream_error_code::invalid_offset:
36 ErrMsg += "The specified offset is invalid for the current stream.";
37 break;
38 case stream_error_code::filesystem_error:
39 ErrMsg += "An I/O error occurred on the file system.";
40 break;
41 }
42
43 if (!Context.empty()) {
44 ErrMsg += " ";
45 ErrMsg += Context;
46 }
47 }
48
49 void BinaryStreamError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
50
51 StringRef BinaryStreamError::getErrorMessage() const { return ErrMsg; }
52
53 std::error_code BinaryStreamError::convertToErrorCode() const {
54 return inconvertibleErrorCode();
55 }
+0
-95
lib/DebugInfo/MSF/BinaryStreamReader.cpp less more
None //===- BinaryStreamReader.cpp - Reads objects from a binary stream --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
10
11 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
13
14 using namespace llvm;
15
16 BinaryStreamReader::BinaryStreamReader(BinaryStreamRef S)
17 : Stream(S), Offset(0) {}
18
19 Error BinaryStreamReader::readLongestContiguousChunk(
20 ArrayRef &Buffer) {
21 if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer))
22 return EC;
23 Offset += Buffer.size();
24 return Error::success();
25 }
26
27 Error BinaryStreamReader::readBytes(ArrayRef &Buffer, uint32_t Size) {
28 if (auto EC = Stream.readBytes(Offset, Size, Buffer))
29 return EC;
30 Offset += Size;
31 return Error::success();
32 }
33
34 Error BinaryStreamReader::readCString(StringRef &Dest) {
35 // TODO: This could be made more efficient by using readLongestContiguousChunk
36 // and searching for null terminators in the resulting buffer.
37
38 uint32_t Length = 0;
39 // First compute the length of the string by reading 1 byte at a time.
40 uint32_t OriginalOffset = getOffset();
41 const char *C;
42 while (true) {
43 if (auto EC = readObject(C))
44 return EC;
45 if (*C == '\0')
46 break;
47 ++Length;
48 }
49 // Now go back and request a reference for that many bytes.
50 uint32_t NewOffset = getOffset();
51 setOffset(OriginalOffset);
52
53 if (auto EC = readFixedString(Dest, Length))
54 return EC;
55
56 // Now set the offset back to where it was after we calculated the length.
57 setOffset(NewOffset);
58 return Error::success();
59 }
60
61 Error BinaryStreamReader::readFixedString(StringRef &Dest, uint32_t Length) {
62 ArrayRef Bytes;
63 if (auto EC = readBytes(Bytes, Length))
64 return EC;
65 Dest = StringRef(reinterpret_cast(Bytes.begin()), Bytes.size());
66 return Error::success();
67 }
68
69 Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref) {
70 return readStreamRef(Ref, bytesRemaining());
71 }
72
73 Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref, uint32_t Length) {
74 if (bytesRemaining() < Length)
75 return make_error(stream_error_code::stream_too_short);
76 Ref = Stream.slice(Offset, Length);
77 Offset += Length;
78 return Error::success();
79 }
80
81 Error BinaryStreamReader::skip(uint32_t Amount) {
82 if (Amount > bytesRemaining())
83 return make_error(stream_error_code::stream_too_short);
84 Offset += Amount;
85 return Error::success();
86 }
87
88 uint8_t BinaryStreamReader::peek() const {
89 ArrayRef Buffer;
90 auto EC = Stream.readBytes(Offset, 1, Buffer);
91 assert(!EC && "Cannot peek an empty buffer!");
92 llvm::consumeError(std::move(EC));
93 return Buffer[0];
94 }
+0
-59
lib/DebugInfo/MSF/BinaryStreamWriter.cpp less more
None //===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
10
11 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
13
14 using namespace llvm;
15
16 BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef S)
17 : Stream(S), Offset(0) {}
18
19 Error BinaryStreamWriter::writeBytes(ArrayRef Buffer) {
20 if (auto EC = Stream.writeBytes(Offset, Buffer))
21 return EC;
22 Offset += Buffer.size();
23 return Error::success();
24 }
25
26 Error BinaryStreamWriter::writeCString(StringRef Str) {
27 if (auto EC = writeFixedString(Str))
28 return EC;
29 if (auto EC = writeObject('\0'))
30 return EC;
31
32 return Error::success();
33 }
34
35 Error BinaryStreamWriter::writeFixedString(StringRef Str) {
36 return writeBytes(ArrayRef(Str.bytes_begin(), Str.bytes_end()));
37 }
38
39 Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) {
40 return writeStreamRef(Ref, Ref.getLength());
41 }
42
43 Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint32_t Length) {
44 BinaryStreamReader SrcReader(Ref.slice(0, Length));
45 // This is a bit tricky. If we just call readBytes, we are requiring that it
46 // return us the entire stream as a contiguous buffer. There is no guarantee
47 // this can be satisfied by returning a reference straight from the buffer, as
48 // an implementation may not store all data in a single contiguous buffer. So
49 // we iterate over each contiguous chunk, writing each one in succession.
50 while (SrcReader.bytesRemaining() > 0) {
51 ArrayRef Chunk;
52 if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))
53 return EC;
54 if (auto EC = writeBytes(Chunk))
55 return EC;
56 }
57 return Error::success();
58 }
0 add_llvm_library(LLVMDebugInfoMSF
1 BinaryStreamError.cpp
2 BinaryStreamReader.cpp
3 BinaryStreamWriter.cpp
41 MappedBlockStream.cpp
52 MSFBuilder.cpp
63 MSFCommon.cpp
88
99 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1010
11 #include "llvm/DebugInfo/MSF/BinaryStreamError.h"
1211 #include "llvm/DebugInfo/MSF/IMSFFile.h"
1312 #include "llvm/DebugInfo/MSF/MSFCommon.h"
1413 #include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
14 #include "llvm/Support/BinaryStreamError.h"
1515
1616 using namespace llvm;
1717 using namespace llvm::msf;
88
99 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
1010 #include "llvm/ADT/StringRef.h"
11 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
1311 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1412 #include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
1513 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
2018 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
2119 #include "llvm/DebugInfo/PDB/PDBTypes.h"
2220 #include "llvm/Object/COFF.h"
21 #include "llvm/Support/BinaryStreamArray.h"
22 #include "llvm/Support/BinaryStreamReader.h"
2323 #include "llvm/Support/Error.h"
2424 #include
2525 #include
99 #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
1010
1111 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
1312 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
1413 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1514 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
1615 #include "llvm/DebugInfo/PDB/Native/RawError.h"
1716 #include "llvm/Object/COFF.h"
17 #include "llvm/Support/BinaryStreamWriter.h"
1818 #include "llvm/Support/COFF.h"
1919
2020 using namespace llvm;
88
99 #include "GSI.h"
1010
11 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
1311 #include "llvm/DebugInfo/PDB/Native/RawError.h"
1412 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
13 #include "llvm/Support/BinaryStreamArray.h"
14 #include "llvm/Support/BinaryStreamReader.h"
1515
1616 #include "llvm/Support/Error.h"
1717
2424 #ifndef LLVM_LIB_DEBUGINFO_PDB_RAW_GSI_H
2525 #define LLVM_LIB_DEBUGINFO_PDB_RAW_GSI_H
2626
27 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
2827 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
28 #include "llvm/Support/BinaryStreamArray.h"
2929
3030 #include "llvm/Support/Endian.h"
3131 #include "llvm/Support/Error.h"
88
99 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
1010 #include "GSI.h"
11 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
11 #include "llvm/Support/BinaryStreamReader.h"
1212 #include "llvm/Support/Error.h"
1313 #include
1414
99 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
1010 #include "llvm/ADT/BitVector.h"
1111 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
1412 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1513 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
1614 #include "llvm/DebugInfo/PDB/Native/RawError.h"
1715 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
16 #include "llvm/Support/BinaryStreamReader.h"
17 #include "llvm/Support/BinaryStreamWriter.h"
1818
1919 using namespace llvm;
2020 using namespace llvm::codeview;
88
99 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
1010
11 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
1211 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
1312 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1413 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
1615 #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
1716 #include "llvm/DebugInfo/PDB/Native/RawError.h"
1817 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
18 #include "llvm/Support/BinaryStreamWriter.h"
1919
2020 using namespace llvm;
2121 using namespace llvm::codeview;
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/DebugInfo/PDB/Native/ModInfo.h"
10 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
1110 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
11 #include "llvm/Support/BinaryStreamReader.h"
1212 #include "llvm/Support/Endian.h"
1313 #include "llvm/Support/Error.h"
1414 #include "llvm/Support/MathExtras.h"
99 #include "llvm/DebugInfo/PDB/Native/ModStream.h"
1010 #include "llvm/ADT/iterator_range.h"
1111 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
1412 #include "llvm/DebugInfo/PDB/Native/ModInfo.h"
1513 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1614 #include "llvm/DebugInfo/PDB/Native/RawError.h"
1715 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
16 #include "llvm/Support/BinaryStreamReader.h"
17 #include "llvm/Support/BinaryStreamRef.h"
1818 #include "llvm/Support/Error.h"
1919 #include
2020 #include
1212 #include "llvm/ADT/StringMap.h"
1313 #include "llvm/ADT/StringRef.h"
1414 #include "llvm/ADT/iterator_range.h"
15 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
1615 #include "llvm/DebugInfo/PDB/Native/HashTable.h"
1716 #include "llvm/DebugInfo/PDB/Native/RawError.h"
17 #include "llvm/Support/BinaryStreamReader.h"
1818 #include "llvm/Support/Error.h"
1919 #include
2020 #include
99 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
1010
1111 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
1312 #include "llvm/DebugInfo/PDB/GenericError.h"
1413 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
1514 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
1918 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
2019 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
2120 #include "llvm/Support/Allocator.h"
21 #include "llvm/Support/BinaryByteStream.h"
2222 #include "llvm/Support/Error.h"
2323 #include "llvm/Support/ErrorOr.h"
2424 #include "llvm/Support/MemoryBuffer.h"
99 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1010 #include "llvm/ADT/ArrayRef.h"
1111 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/DebugInfo/MSF/BinaryStream.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
1512 #include "llvm/DebugInfo/MSF/MSFCommon.h"
1613 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1714 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
2219 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
2320 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
2421 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
22 #include "llvm/Support/BinaryStream.h"
23 #include "llvm/Support/BinaryStreamArray.h"
24 #include "llvm/Support/BinaryStreamReader.h"
2525 #include "llvm/Support/Endian.h"
2626 #include "llvm/Support/Error.h"