File indexing completed on 2026-05-10 08:43:43
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_MSF_MSFCOMMON_H
0010 #define LLVM_DEBUGINFO_MSF_MSFCOMMON_H
0011
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/ADT/BitVector.h"
0014 #include "llvm/Support/Endian.h"
0015 #include "llvm/Support/Error.h"
0016 #include "llvm/Support/MathExtras.h"
0017 #include <cstdint>
0018 #include <vector>
0019
0020 namespace llvm {
0021 namespace msf {
0022
0023 static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
0024 't', ' ', 'C', '/', 'C', '+', '+', ' ',
0025 'M', 'S', 'F', ' ', '7', '.', '0', '0',
0026 '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'};
0027
0028
0029
0030
0031 struct SuperBlock {
0032 char MagicBytes[sizeof(Magic)];
0033
0034
0035
0036 support::ulittle32_t BlockSize;
0037
0038 support::ulittle32_t FreeBlockMapBlock;
0039
0040
0041
0042 support::ulittle32_t NumBlocks;
0043
0044 support::ulittle32_t NumDirectoryBytes;
0045
0046 support::ulittle32_t Unknown1;
0047
0048 support::ulittle32_t BlockMapAddr;
0049 };
0050
0051 struct MSFLayout {
0052 MSFLayout() = default;
0053
0054 uint32_t mainFpmBlock() const {
0055 assert(SB->FreeBlockMapBlock == 1 || SB->FreeBlockMapBlock == 2);
0056 return SB->FreeBlockMapBlock;
0057 }
0058
0059 uint32_t alternateFpmBlock() const {
0060
0061 return 3U - mainFpmBlock();
0062 }
0063
0064 const SuperBlock *SB = nullptr;
0065 BitVector FreePageMap;
0066 ArrayRef<support::ulittle32_t> DirectoryBlocks;
0067 ArrayRef<support::ulittle32_t> StreamSizes;
0068 std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
0069 };
0070
0071
0072
0073
0074
0075
0076
0077 class MSFStreamLayout {
0078 public:
0079 uint32_t Length;
0080 std::vector<support::ulittle32_t> Blocks;
0081 };
0082
0083
0084
0085
0086 MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf,
0087 bool IncludeUnusedFpmData = false,
0088 bool AltFpm = false);
0089
0090 inline bool isValidBlockSize(uint32_t Size) {
0091 switch (Size) {
0092 case 512:
0093 case 1024:
0094 case 2048:
0095 case 4096:
0096 case 8192:
0097 case 16384:
0098 case 32768:
0099 return true;
0100 }
0101 return false;
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111 inline uint64_t getMaxFileSizeFromBlockSize(uint32_t Size) {
0112 switch (Size) {
0113 case 8192:
0114 return (uint64_t)UINT32_MAX * 2ULL;
0115 case 16384:
0116 return (uint64_t)UINT32_MAX * 3ULL;
0117 case 32768:
0118 return (uint64_t)UINT32_MAX * 4ULL;
0119 default:
0120 return (uint64_t)UINT32_MAX;
0121 }
0122 }
0123
0124
0125 inline uint32_t getMinimumBlockCount() { return 4; }
0126
0127
0128
0129 inline uint32_t getFirstUnreservedBlock() { return 3; }
0130
0131 inline uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize) {
0132 return divideCeil(NumBytes, BlockSize);
0133 }
0134
0135 inline uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize) {
0136 return BlockNumber * BlockSize;
0137 }
0138
0139 inline uint32_t getFpmIntervalLength(const MSFLayout &L) {
0140 return L.SB->BlockSize;
0141 }
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 inline uint32_t getNumFpmIntervals(uint32_t BlockSize, uint32_t NumBlocks,
0156 bool IncludeUnusedFpmData, int FpmNumber) {
0157 assert(FpmNumber == 1 || FpmNumber == 2);
0158 if (IncludeUnusedFpmData) {
0159
0160
0161
0162
0163 return divideCeil(NumBlocks - FpmNumber, BlockSize);
0164 }
0165
0166
0167
0168 return divideCeil(NumBlocks, 8 * BlockSize);
0169 }
0170
0171 inline uint32_t getNumFpmIntervals(const MSFLayout &L,
0172 bool IncludeUnusedFpmData = false,
0173 bool AltFpm = false) {
0174 return getNumFpmIntervals(L.SB->BlockSize, L.SB->NumBlocks,
0175 IncludeUnusedFpmData,
0176 AltFpm ? L.alternateFpmBlock() : L.mainFpmBlock());
0177 }
0178
0179 Error validateSuperBlock(const SuperBlock &SB);
0180
0181 }
0182 }
0183
0184 #endif