1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
//===- MappedBlockStream.h - Discontiguous stream data in an MSF -*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H
#define LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/DebugInfo/MSF/StreamInterface.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <vector>
namespace llvm {
namespace msf {
struct MSFLayout;
/// MappedBlockStream represents data stored in an MSF file into chunks of a
/// particular size (called the Block Size), and whose chunks may not be
/// necessarily contiguous. The arrangement of these chunks MSF the file
/// is described by some other metadata contained within the MSF file. In
/// the case of a standard MSF Stream, the layout of the stream's blocks
/// is described by the MSF "directory", but in the case of the directory
/// itself, the layout is described by an array at a fixed location within
/// the MSF. MappedBlockStream provides methods for reading from and writing
/// to one of these streams transparently, as if it were a contiguous sequence
/// of bytes.
class MappedBlockStream : public ReadableStream {
friend class WritableMappedBlockStream;
public:
static std::unique_ptr<MappedBlockStream>
createStream(uint32_t BlockSize, uint32_t NumBlocks,
const MSFStreamLayout &Layout, const ReadableStream &MsfData);
static std::unique_ptr<MappedBlockStream>
createIndexedStream(const MSFLayout &Layout, const ReadableStream &MsfData,
uint32_t StreamIndex);
static std::unique_ptr<MappedBlockStream>
createFpmStream(const MSFLayout &Layout, const ReadableStream &MsfData);
static std::unique_ptr<MappedBlockStream>
createDirectoryStream(const MSFLayout &Layout, const ReadableStream &MsfData);
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const override;
Error readLongestContiguousChunk(uint32_t Offset,
ArrayRef<uint8_t> &Buffer) const override;
uint32_t getLength() const override;
uint32_t getNumBytesCopied() const;
llvm::BumpPtrAllocator &getAllocator() { return Pool; }
void invalidateCache();
uint32_t getBlockSize() const { return BlockSize; }
uint32_t getNumBlocks() const { return NumBlocks; }
uint32_t getStreamLength() const { return StreamLayout.Length; }
protected:
MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
const MSFStreamLayout &StreamLayout,
const ReadableStream &MsfData);
private:
const MSFStreamLayout &getStreamLayout() const { return StreamLayout; }
void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const;
Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const;
bool tryReadContiguously(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const;
const uint32_t BlockSize;
const uint32_t NumBlocks;
const MSFStreamLayout StreamLayout;
const ReadableStream &MsfData;
typedef MutableArrayRef<uint8_t> CacheEntry;
mutable llvm::BumpPtrAllocator Pool;
mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
};
class WritableMappedBlockStream : public WritableStream {
public:
static std::unique_ptr<WritableMappedBlockStream>
createStream(uint32_t BlockSize, uint32_t NumBlocks,
const MSFStreamLayout &Layout, const WritableStream &MsfData);
static std::unique_ptr<WritableMappedBlockStream>
createIndexedStream(const MSFLayout &Layout, const WritableStream &MsfData,
uint32_t StreamIndex);
static std::unique_ptr<WritableMappedBlockStream>
createDirectoryStream(const MSFLayout &Layout, const WritableStream &MsfData);
static std::unique_ptr<WritableMappedBlockStream>
createFpmStream(const MSFLayout &Layout, const WritableStream &MsfData);
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const override;
Error readLongestContiguousChunk(uint32_t Offset,
ArrayRef<uint8_t> &Buffer) const override;
uint32_t getLength() const override;
Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
Error commit() const override;
const MSFStreamLayout &getStreamLayout() const {
return ReadInterface.getStreamLayout();
}
uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); }
uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); }
uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); }
protected:
WritableMappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
const MSFStreamLayout &StreamLayout,
const WritableStream &MsfData);
private:
MappedBlockStream ReadInterface;
const WritableStream &WriteInterface;
};
} // end namespace pdb
} // end namespace llvm
#endif // LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H
|