/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- MSFCommon.h - Common types and functions for MSF files ---*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | |
10 | | #ifndef LLVM_DEBUGINFO_MSF_MSFCOMMON_H |
11 | | #define LLVM_DEBUGINFO_MSF_MSFCOMMON_H |
12 | | |
13 | | #include "llvm/ADT/ArrayRef.h" |
14 | | #include "llvm/ADT/BitVector.h" |
15 | | #include "llvm/Support/Endian.h" |
16 | | #include "llvm/Support/Error.h" |
17 | | #include "llvm/Support/MathExtras.h" |
18 | | #include <cstdint> |
19 | | #include <vector> |
20 | | |
21 | | namespace llvm { |
22 | | namespace msf { |
23 | | |
24 | | static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', |
25 | | 't', ' ', 'C', '/', 'C', '+', '+', ' ', |
26 | | 'M', 'S', 'F', ' ', '7', '.', '0', '0', |
27 | | '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'}; |
28 | | |
29 | | // The superblock is overlaid at the beginning of the file (offset 0). |
30 | | // It starts with a magic header and is followed by information which |
31 | | // describes the layout of the file system. |
32 | | struct SuperBlock { |
33 | | char MagicBytes[sizeof(Magic)]; |
34 | | // The file system is split into a variable number of fixed size elements. |
35 | | // These elements are referred to as blocks. The size of a block may vary |
36 | | // from system to system. |
37 | | support::ulittle32_t BlockSize; |
38 | | // The index of the free block map. |
39 | | support::ulittle32_t FreeBlockMapBlock; |
40 | | // This contains the number of blocks resident in the file system. In |
41 | | // practice, NumBlocks * BlockSize is equivalent to the size of the MSF |
42 | | // file. |
43 | | support::ulittle32_t NumBlocks; |
44 | | // This contains the number of bytes which make up the directory. |
45 | | support::ulittle32_t NumDirectoryBytes; |
46 | | // This field's purpose is not yet known. |
47 | | support::ulittle32_t Unknown1; |
48 | | // This contains the block # of the block map. |
49 | | support::ulittle32_t BlockMapAddr; |
50 | | }; |
51 | | |
52 | | struct MSFLayout { |
53 | 169 | MSFLayout() = default; |
54 | | |
55 | | const SuperBlock *SB = nullptr; |
56 | | BitVector FreePageMap; |
57 | | ArrayRef<support::ulittle32_t> DirectoryBlocks; |
58 | | ArrayRef<support::ulittle32_t> StreamSizes; |
59 | | std::vector<ArrayRef<support::ulittle32_t>> StreamMap; |
60 | | }; |
61 | | |
62 | | /// \brief Describes the layout of a stream in an MSF layout. A "stream" here |
63 | | /// is defined as any logical unit of data which may be arranged inside the MSF |
64 | | /// file as a sequence of (possibly discontiguous) blocks. When we want to read |
65 | | /// from a particular MSF Stream, we fill out a stream layout structure and the |
66 | | /// reader uses it to determine which blocks in the underlying MSF file contain |
67 | | /// the data, so that it can be pieced together in the right order. |
68 | | class MSFStreamLayout { |
69 | | public: |
70 | | uint32_t Length; |
71 | | std::vector<support::ulittle32_t> Blocks; |
72 | | }; |
73 | | |
74 | | /// \brief Determine the layout of the FPM stream, given the MSF layout. An FPM |
75 | | /// stream spans 1 or more blocks, each at equally spaced intervals throughout |
76 | | /// the file. |
77 | | MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf, |
78 | | bool IncludeUnusedFpmData = false, |
79 | | bool AltFpm = false); |
80 | | |
81 | 177 | inline bool isValidBlockSize(uint32_t Size) { |
82 | 177 | switch (Size) { |
83 | 176 | case 512: |
84 | 176 | case 1024: |
85 | 176 | case 2048: |
86 | 176 | case 4096: |
87 | 176 | return true; |
88 | 177 | } |
89 | 1 | return false; |
90 | 177 | } |
91 | | |
92 | | // Super Block, Fpm0, Fpm1, and Block Map |
93 | 82 | inline uint32_t getMinimumBlockCount() { return 4; } |
94 | | |
95 | | // Super Block, Fpm0, and Fpm1 are reserved. The Block Map, although required |
96 | | // need not be at block 3. |
97 | 0 | inline uint32_t getFirstUnreservedBlock() { return 3; } |
98 | | |
99 | 4.04k | inline uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize) { |
100 | 4.04k | return divideCeil(NumBytes, BlockSize); |
101 | 4.04k | } |
102 | | |
103 | 31.9k | inline uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize) { |
104 | 31.9k | return BlockNumber * BlockSize; |
105 | 31.9k | } |
106 | | |
107 | 506 | inline uint32_t getFpmIntervalLength(const MSFLayout &L) { |
108 | 506 | return L.SB->BlockSize; |
109 | 506 | } |
110 | | |
111 | | inline uint32_t getNumFpmIntervals(const MSFLayout &L, |
112 | 426 | bool IncludeUnusedFpmData = false) { |
113 | 426 | if (IncludeUnusedFpmData) |
114 | 196 | return divideCeil(L.SB->NumBlocks, L.SB->BlockSize); |
115 | 426 | |
116 | 426 | // We want the minimum number of intervals required, where each interval can |
117 | 426 | // represent BlockSize * 8 blocks. |
118 | 230 | return divideCeil(L.SB->NumBlocks, 8 * L.SB->BlockSize); |
119 | 426 | } |
120 | | |
121 | | Error validateSuperBlock(const SuperBlock &SB); |
122 | | |
123 | | } // end namespace msf |
124 | | } // end namespace llvm |
125 | | |
126 | | #endif // LLVM_DEBUGINFO_MSF_MSFCOMMON_H |