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

source code of llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h