1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00
llvm-mirror/include/llvm/DebugInfo/MSF/MSFCommon.h
Chandler Carruth ae65e281f3 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00

162 lines
6.1 KiB
C++

//===- MSFCommon.h - Common types and functions for MSF files ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_MSF_MSFCOMMON_H
#define LLVM_DEBUGINFO_MSF_MSFCOMMON_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
#include <cstdint>
#include <vector>
namespace llvm {
namespace msf {
static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
't', ' ', 'C', '/', 'C', '+', '+', ' ',
'M', 'S', 'F', ' ', '7', '.', '0', '0',
'\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'};
// The superblock is overlaid at the beginning of the file (offset 0).
// It starts with a magic header and is followed by information which
// describes the layout of the file system.
struct SuperBlock {
char MagicBytes[sizeof(Magic)];
// The file system is split into a variable number of fixed size elements.
// These elements are referred to as blocks. The size of a block may vary
// from system to system.
support::ulittle32_t BlockSize;
// The index of the free block map.
support::ulittle32_t FreeBlockMapBlock;
// This contains the number of blocks resident in the file system. In
// practice, NumBlocks * BlockSize is equivalent to the size of the MSF
// file.
support::ulittle32_t NumBlocks;
// This contains the number of bytes which make up the directory.
support::ulittle32_t NumDirectoryBytes;
// This field's purpose is not yet known.
support::ulittle32_t Unknown1;
// This contains the block # of the block map.
support::ulittle32_t BlockMapAddr;
};
struct MSFLayout {
MSFLayout() = default;
uint32_t mainFpmBlock() const {
assert(SB->FreeBlockMapBlock == 1 || SB->FreeBlockMapBlock == 2);
return SB->FreeBlockMapBlock;
}
uint32_t alternateFpmBlock() const {
// If mainFpmBlock is 1, this is 2. If mainFpmBlock is 2, this is 1.
return 3U - mainFpmBlock();
}
const SuperBlock *SB = nullptr;
BitVector FreePageMap;
ArrayRef<support::ulittle32_t> DirectoryBlocks;
ArrayRef<support::ulittle32_t> StreamSizes;
std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
};
/// Describes the layout of a stream in an MSF layout. A "stream" here
/// is defined as any logical unit of data which may be arranged inside the MSF
/// file as a sequence of (possibly discontiguous) blocks. When we want to read
/// from a particular MSF Stream, we fill out a stream layout structure and the
/// reader uses it to determine which blocks in the underlying MSF file contain
/// the data, so that it can be pieced together in the right order.
class MSFStreamLayout {
public:
uint32_t Length;
std::vector<support::ulittle32_t> Blocks;
};
/// Determine the layout of the FPM stream, given the MSF layout. An FPM
/// stream spans 1 or more blocks, each at equally spaced intervals throughout
/// the file.
MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf,
bool IncludeUnusedFpmData = false,
bool AltFpm = false);
inline bool isValidBlockSize(uint32_t Size) {
switch (Size) {
case 512:
case 1024:
case 2048:
case 4096:
return true;
}
return false;
}
// Super Block, Fpm0, Fpm1, and Block Map
inline uint32_t getMinimumBlockCount() { return 4; }
// Super Block, Fpm0, and Fpm1 are reserved. The Block Map, although required
// need not be at block 3.
inline uint32_t getFirstUnreservedBlock() { return 3; }
inline uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize) {
return divideCeil(NumBytes, BlockSize);
}
inline uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize) {
return BlockNumber * BlockSize;
}
inline uint32_t getFpmIntervalLength(const MSFLayout &L) {
return L.SB->BlockSize;
}
/// Given an MSF with the specified block size and number of blocks, determine
/// how many pieces the specified Fpm is split into.
/// \p BlockSize - the block size of the MSF
/// \p NumBlocks - the total number of blocks in the MSF
/// \p IncludeUnusedFpmData - When true, this will count every block that is
/// both in the file and matches the form of an FPM block, even if some of
/// those FPM blocks are unused (a single FPM block can describe the
/// allocation status of up to 32,767 blocks, although one appears only
/// every 4,096 blocks). So there are 8x as many blocks that match the
/// form as there are blocks that are necessary to describe the allocation
/// status of the file. When this parameter is false, these extraneous
/// trailing blocks are not counted.
inline uint32_t getNumFpmIntervals(uint32_t BlockSize, uint32_t NumBlocks,
bool IncludeUnusedFpmData, int FpmNumber) {
assert(FpmNumber == 1 || FpmNumber == 2);
if (IncludeUnusedFpmData) {
// This calculation determines how many times a number of the form
// BlockSize * k + N appears in the range [0, NumBlocks). We only need to
// do this when unused data is included, since the number of blocks dwarfs
// the number of fpm blocks.
return divideCeil(NumBlocks - FpmNumber, BlockSize);
}
// We want the minimum number of intervals required, where each interval can
// represent BlockSize * 8 blocks.
return divideCeil(NumBlocks, 8 * BlockSize);
}
inline uint32_t getNumFpmIntervals(const MSFLayout &L,
bool IncludeUnusedFpmData = false,
bool AltFpm = false) {
return getNumFpmIntervals(L.SB->BlockSize, L.SB->NumBlocks,
IncludeUnusedFpmData,
AltFpm ? L.alternateFpmBlock() : L.mainFpmBlock());
}
Error validateSuperBlock(const SuperBlock &SB);
} // end namespace msf
} // end namespace llvm
#endif // LLVM_DEBUGINFO_MSF_MSFCOMMON_H