Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- MSFCommon.h - Common types and functions for MSF files ---*- 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_MSFCOMMON_H
  10. #define LLVM_DEBUGINFO_MSF_MSFCOMMON_H
  11.  
  12. #include "llvm/ADT/ArrayRef.h"
  13. #include "llvm/ADT/BitVector.h"
  14. #include "llvm/Support/Endian.h"
  15. #include "llvm/Support/Error.h"
  16. #include "llvm/Support/MathExtras.h"
  17. #include <cstdint>
  18. #include <vector>
  19.  
  20. namespace llvm {
  21. namespace msf {
  22.  
  23. static const char Magic[] = {'M',  'i',  'c',    'r', 'o', 's',  'o',  'f',
  24.                              't',  ' ',  'C',    '/', 'C', '+',  '+',  ' ',
  25.                              'M',  'S',  'F',    ' ', '7', '.',  '0',  '0',
  26.                              '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'};
  27.  
  28. // The superblock is overlaid at the beginning of the file (offset 0).
  29. // It starts with a magic header and is followed by information which
  30. // describes the layout of the file system.
  31. struct SuperBlock {
  32.   char MagicBytes[sizeof(Magic)];
  33.   // The file system is split into a variable number of fixed size elements.
  34.   // These elements are referred to as blocks.  The size of a block may vary
  35.   // from system to system.
  36.   support::ulittle32_t BlockSize;
  37.   // The index of the free block map.
  38.   support::ulittle32_t FreeBlockMapBlock;
  39.   // This contains the number of blocks resident in the file system.  In
  40.   // practice, NumBlocks * BlockSize is equivalent to the size of the MSF
  41.   // file.
  42.   support::ulittle32_t NumBlocks;
  43.   // This contains the number of bytes which make up the directory.
  44.   support::ulittle32_t NumDirectoryBytes;
  45.   // This field's purpose is not yet known.
  46.   support::ulittle32_t Unknown1;
  47.   // This contains the block # of the block map.
  48.   support::ulittle32_t BlockMapAddr;
  49. };
  50.  
  51. struct MSFLayout {
  52.   MSFLayout() = default;
  53.  
  54.   uint32_t mainFpmBlock() const {
  55.     assert(SB->FreeBlockMapBlock == 1 || SB->FreeBlockMapBlock == 2);
  56.     return SB->FreeBlockMapBlock;
  57.   }
  58.  
  59.   uint32_t alternateFpmBlock() const {
  60.     // If mainFpmBlock is 1, this is 2.  If mainFpmBlock is 2, this is 1.
  61.     return 3U - mainFpmBlock();
  62.   }
  63.  
  64.   const SuperBlock *SB = nullptr;
  65.   BitVector FreePageMap;
  66.   ArrayRef<support::ulittle32_t> DirectoryBlocks;
  67.   ArrayRef<support::ulittle32_t> StreamSizes;
  68.   std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
  69. };
  70.  
  71. /// Describes the layout of a stream in an MSF layout.  A "stream" here
  72. /// is defined as any logical unit of data which may be arranged inside the MSF
  73. /// file as a sequence of (possibly discontiguous) blocks.  When we want to read
  74. /// from a particular MSF Stream, we fill out a stream layout structure and the
  75. /// reader uses it to determine which blocks in the underlying MSF file contain
  76. /// the data, so that it can be pieced together in the right order.
  77. class MSFStreamLayout {
  78. public:
  79.   uint32_t Length;
  80.   std::vector<support::ulittle32_t> Blocks;
  81. };
  82.  
  83. /// Determine the layout of the FPM stream, given the MSF layout.  An FPM
  84. /// stream spans 1 or more blocks, each at equally spaced intervals throughout
  85. /// the file.
  86. MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf,
  87.                                    bool IncludeUnusedFpmData = false,
  88.                                    bool AltFpm = false);
  89.  
  90. inline bool isValidBlockSize(uint32_t Size) {
  91.   switch (Size) {
  92.   case 512:
  93.   case 1024:
  94.   case 2048:
  95.   case 4096:
  96.   case 8192:
  97.   case 16384:
  98.   case 32768:
  99.     return true;
  100.   }
  101.   return false;
  102. }
  103.  
  104. /// Given the specified block size, returns the maximum possible file size.
  105. /// Block Size  |  Max File Size
  106. /// <= 4096     |      4GB
  107. ///    8192     |      8GB
  108. ///   16384     |      16GB
  109. ///   32768     |      32GB
  110. /// \p Size - the block size of the MSF
  111. inline uint64_t getMaxFileSizeFromBlockSize(uint32_t Size) {
  112.   switch (Size) {
  113.   case 8192:
  114.     return (uint64_t)UINT32_MAX * 2ULL;
  115.   case 16384:
  116.     return (uint64_t)UINT32_MAX * 3ULL;
  117.   case 32768:
  118.     return (uint64_t)UINT32_MAX * 4ULL;
  119.   default:
  120.     return (uint64_t)UINT32_MAX;
  121.   }
  122. }
  123.  
  124. // Super Block, Fpm0, Fpm1, and Block Map
  125. inline uint32_t getMinimumBlockCount() { return 4; }
  126.  
  127. // Super Block, Fpm0, and Fpm1 are reserved.  The Block Map, although required
  128. // need not be at block 3.
  129. inline uint32_t getFirstUnreservedBlock() { return 3; }
  130.  
  131. inline uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize) {
  132.   return divideCeil(NumBytes, BlockSize);
  133. }
  134.  
  135. inline uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize) {
  136.   return BlockNumber * BlockSize;
  137. }
  138.  
  139. inline uint32_t getFpmIntervalLength(const MSFLayout &L) {
  140.   return L.SB->BlockSize;
  141. }
  142.  
  143. /// Given an MSF with the specified block size and number of blocks, determine
  144. /// how many pieces the specified Fpm is split into.
  145. /// \p BlockSize - the block size of the MSF
  146. /// \p NumBlocks - the total number of blocks in the MSF
  147. /// \p IncludeUnusedFpmData - When true, this will count every block that is
  148. ///    both in the file and matches the form of an FPM block, even if some of
  149. ///    those FPM blocks are unused (a single FPM block can describe the
  150. ///    allocation status of up to 32,767 blocks, although one appears only
  151. ///    every 4,096 blocks).  So there are 8x as many blocks that match the
  152. ///    form as there are blocks that are necessary to describe the allocation
  153. ///    status of the file.  When this parameter is false, these extraneous
  154. ///    trailing blocks are not counted.
  155. inline uint32_t getNumFpmIntervals(uint32_t BlockSize, uint32_t NumBlocks,
  156.                                    bool IncludeUnusedFpmData, int FpmNumber) {
  157.   assert(FpmNumber == 1 || FpmNumber == 2);
  158.   if (IncludeUnusedFpmData) {
  159.     // This calculation determines how many times a number of the form
  160.     // BlockSize * k + N appears in the range [0, NumBlocks).  We only need to
  161.     // do this when unused data is included, since the number of blocks dwarfs
  162.     // the number of fpm blocks.
  163.     return divideCeil(NumBlocks - FpmNumber, BlockSize);
  164.   }
  165.  
  166.   // We want the minimum number of intervals required, where each interval can
  167.   // represent BlockSize * 8 blocks.
  168.   return divideCeil(NumBlocks, 8 * BlockSize);
  169. }
  170.  
  171. inline uint32_t getNumFpmIntervals(const MSFLayout &L,
  172.                                    bool IncludeUnusedFpmData = false,
  173.                                    bool AltFpm = false) {
  174.   return getNumFpmIntervals(L.SB->BlockSize, L.SB->NumBlocks,
  175.                             IncludeUnusedFpmData,
  176.                             AltFpm ? L.alternateFpmBlock() : L.mainFpmBlock());
  177. }
  178.  
  179. Error validateSuperBlock(const SuperBlock &SB);
  180.  
  181. } // end namespace msf
  182. } // end namespace llvm
  183.  
  184. #endif // LLVM_DEBUGINFO_MSF_MSFCOMMON_H
  185.