1 //===- MappedBlockStream.h - Discontiguous stream data in an MSF -*- C++
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H
12 #define LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
18 #include "llvm/Support/Allocator.h"
19 #include "llvm/Support/BinaryStream.h"
20 #include "llvm/Support/BinaryStreamRef.h"
21 #include "llvm/Support/Endian.h"
22 #include "llvm/Support/Error.h"
31 /// MappedBlockStream represents data stored in an MSF file into chunks of a
32 /// particular size (called the Block Size), and whose chunks may not be
33 /// necessarily contiguous. The arrangement of these chunks MSF the file
34 /// is described by some other metadata contained within the MSF file. In
35 /// the case of a standard MSF Stream, the layout of the stream's blocks
36 /// is described by the MSF "directory", but in the case of the directory
37 /// itself, the layout is described by an array at a fixed location within
38 /// the MSF. MappedBlockStream provides methods for reading from and writing
39 /// to one of these streams transparently, as if it were a contiguous sequence
41 class MappedBlockStream : public BinaryStream {
42 friend class WritableMappedBlockStream;
44 static std::unique_ptr<MappedBlockStream>
45 createStream(uint32_t BlockSize, const MSFStreamLayout &Layout,
46 BinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
48 static std::unique_ptr<MappedBlockStream>
49 createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
50 uint32_t StreamIndex, BumpPtrAllocator &Allocator);
52 static std::unique_ptr<MappedBlockStream>
53 createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
54 BumpPtrAllocator &Allocator);
56 static std::unique_ptr<MappedBlockStream>
57 createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
58 BumpPtrAllocator &Allocator);
60 llvm::support::endianness getEndian() const override {
61 return llvm::support::little;
64 Error readBytes(uint32_t Offset, uint32_t Size,
65 ArrayRef<uint8_t> &Buffer) override;
66 Error readLongestContiguousChunk(uint32_t Offset,
67 ArrayRef<uint8_t> &Buffer) override;
69 uint32_t getLength() override;
71 llvm::BumpPtrAllocator &getAllocator() { return Allocator; }
73 void invalidateCache();
75 uint32_t getBlockSize() const { return BlockSize; }
76 uint32_t getNumBlocks() const { return StreamLayout.Blocks.size(); }
77 uint32_t getStreamLength() const { return StreamLayout.Length; }
80 MappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout,
81 BinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
84 const MSFStreamLayout &getStreamLayout() const { return StreamLayout; }
85 void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const;
87 Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer);
88 bool tryReadContiguously(uint32_t Offset, uint32_t Size,
89 ArrayRef<uint8_t> &Buffer);
91 const uint32_t BlockSize;
92 const MSFStreamLayout StreamLayout;
93 BinaryStreamRef MsfData;
95 typedef MutableArrayRef<uint8_t> CacheEntry;
97 // We just store the allocator by reference. We use this to allocate
98 // contiguous memory for things like arrays or strings that cross a block
99 // boundary, and this memory is expected to outlive the stream. For example,
100 // someone could create a stream, read some stuff, then close the stream, and
101 // we would like outstanding references to fields to remain valid since the
102 // entire file is mapped anyway. Because of that, the user must supply the
103 // allocator to allocate broken records from.
104 BumpPtrAllocator &Allocator;
105 DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
108 class WritableMappedBlockStream : public WritableBinaryStream {
110 static std::unique_ptr<WritableMappedBlockStream>
111 createStream(uint32_t BlockSize, const MSFStreamLayout &Layout,
112 WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
114 static std::unique_ptr<WritableMappedBlockStream>
115 createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
116 uint32_t StreamIndex, BumpPtrAllocator &Allocator);
118 static std::unique_ptr<WritableMappedBlockStream>
119 createDirectoryStream(const MSFLayout &Layout,
120 WritableBinaryStreamRef MsfData,
121 BumpPtrAllocator &Allocator);
123 static std::unique_ptr<WritableMappedBlockStream>
124 createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
125 BumpPtrAllocator &Allocator);
127 llvm::support::endianness getEndian() const override {
128 return llvm::support::little;
131 Error readBytes(uint32_t Offset, uint32_t Size,
132 ArrayRef<uint8_t> &Buffer) override;
133 Error readLongestContiguousChunk(uint32_t Offset,
134 ArrayRef<uint8_t> &Buffer) override;
135 uint32_t getLength() override;
137 Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override;
139 Error commit() override;
141 const MSFStreamLayout &getStreamLayout() const {
142 return ReadInterface.getStreamLayout();
144 uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); }
145 uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); }
146 uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); }
149 WritableMappedBlockStream(uint32_t BlockSize,
150 const MSFStreamLayout &StreamLayout,
151 WritableBinaryStreamRef MsfData,
152 BumpPtrAllocator &Allocator);
155 MappedBlockStream ReadInterface;
157 WritableBinaryStreamRef WriteInterface;
160 } // end namespace pdb
161 } // end namespace llvm
163 #endif // LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H