]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / DebugInfo / MSF / MappedBlockStream.h
1 //==- MappedBlockStream.h - Discontiguous stream data in an MSF --*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H
10 #define LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/DebugInfo/MSF/MSFCommon.h"
15 #include "llvm/Support/Allocator.h"
16 #include "llvm/Support/BinaryStream.h"
17 #include "llvm/Support/BinaryStreamRef.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/Error.h"
20 #include <cstdint>
21 #include <memory>
22 #include <vector>
23
24 namespace llvm {
25 namespace msf {
26
27 struct MSFLayout;
28
29 /// MappedBlockStream represents data stored in an MSF file into chunks of a
30 /// particular size (called the Block Size), and whose chunks may not be
31 /// necessarily contiguous.  The arrangement of these chunks MSF the file
32 /// is described by some other metadata contained within the MSF file.  In
33 /// the case of a standard MSF Stream, the layout of the stream's blocks
34 /// is described by the MSF "directory", but in the case of the directory
35 /// itself, the layout is described by an array at a fixed location within
36 /// the MSF.  MappedBlockStream provides methods for reading from and writing
37 /// to one of these streams transparently, as if it were a contiguous sequence
38 /// of bytes.
39 class MappedBlockStream : public BinaryStream {
40   friend class WritableMappedBlockStream;
41
42 public:
43   static std::unique_ptr<MappedBlockStream>
44   createStream(uint32_t BlockSize, const MSFStreamLayout &Layout,
45                BinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
46
47   static std::unique_ptr<MappedBlockStream>
48   createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
49                       uint32_t StreamIndex, BumpPtrAllocator &Allocator);
50
51   static std::unique_ptr<MappedBlockStream>
52   createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
53                   BumpPtrAllocator &Allocator);
54
55   static std::unique_ptr<MappedBlockStream>
56   createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
57                         BumpPtrAllocator &Allocator);
58
59   support::endianness getEndian() const override {
60     return support::little;
61   }
62
63   Error readBytes(uint32_t Offset, uint32_t Size,
64                   ArrayRef<uint8_t> &Buffer) override;
65   Error readLongestContiguousChunk(uint32_t Offset,
66                                    ArrayRef<uint8_t> &Buffer) override;
67
68   uint32_t getLength() override;
69
70   BumpPtrAllocator &getAllocator() { return Allocator; }
71
72   void invalidateCache();
73
74   uint32_t getBlockSize() const { return BlockSize; }
75   uint32_t getNumBlocks() const { return StreamLayout.Blocks.size(); }
76   uint32_t getStreamLength() const { return StreamLayout.Length; }
77
78 protected:
79   MappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout,
80                     BinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
81
82 private:
83   const MSFStreamLayout &getStreamLayout() const { return StreamLayout; }
84   void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const;
85
86   Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer);
87   bool tryReadContiguously(uint32_t Offset, uint32_t Size,
88                            ArrayRef<uint8_t> &Buffer);
89
90   const uint32_t BlockSize;
91   const MSFStreamLayout StreamLayout;
92   BinaryStreamRef MsfData;
93
94   using CacheEntry = MutableArrayRef<uint8_t>;
95
96   // We just store the allocator by reference.  We use this to allocate
97   // contiguous memory for things like arrays or strings that cross a block
98   // boundary, and this memory is expected to outlive the stream.  For example,
99   // someone could create a stream, read some stuff, then close the stream, and
100   // we would like outstanding references to fields to remain valid since the
101   // entire file is mapped anyway.  Because of that, the user must supply the
102   // allocator to allocate broken records from.
103   BumpPtrAllocator &Allocator;
104   DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
105 };
106
107 class WritableMappedBlockStream : public WritableBinaryStream {
108 public:
109   static std::unique_ptr<WritableMappedBlockStream>
110   createStream(uint32_t BlockSize, const MSFStreamLayout &Layout,
111                WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator);
112
113   static std::unique_ptr<WritableMappedBlockStream>
114   createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
115                       uint32_t StreamIndex, BumpPtrAllocator &Allocator);
116
117   static std::unique_ptr<WritableMappedBlockStream>
118   createDirectoryStream(const MSFLayout &Layout,
119                         WritableBinaryStreamRef MsfData,
120                         BumpPtrAllocator &Allocator);
121
122   static std::unique_ptr<WritableMappedBlockStream>
123   createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
124                   BumpPtrAllocator &Allocator, bool AltFpm = false);
125
126   support::endianness getEndian() const override {
127     return support::little;
128   }
129
130   Error readBytes(uint32_t Offset, uint32_t Size,
131                   ArrayRef<uint8_t> &Buffer) override;
132   Error readLongestContiguousChunk(uint32_t Offset,
133                                    ArrayRef<uint8_t> &Buffer) override;
134   uint32_t getLength() override;
135
136   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override;
137
138   Error commit() override;
139
140   const MSFStreamLayout &getStreamLayout() const {
141     return ReadInterface.getStreamLayout();
142   }
143
144   uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); }
145   uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); }
146   uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); }
147
148 protected:
149   WritableMappedBlockStream(uint32_t BlockSize,
150                             const MSFStreamLayout &StreamLayout,
151                             WritableBinaryStreamRef MsfData,
152                             BumpPtrAllocator &Allocator);
153
154 private:
155   MappedBlockStream ReadInterface;
156   WritableBinaryStreamRef WriteInterface;
157 };
158
159 } // end namespace pdb
160 } // end namespace llvm
161
162 #endif // LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H