mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-24 06:27:56 +00:00
Update MSF File Documentation.
This adds some more detail about the PDB container format, specifically surrounding the layout of the Free Page Map. Patch by Colden Cullen Differential Revision: https://reviews.llvm.org/D41825 llvm-svn: 322404
This commit is contained in:
parent
b58a2de2b4
commit
f67a509fe1
@ -5,6 +5,44 @@ The MSF File Format
|
|||||||
.. contents::
|
.. contents::
|
||||||
:local:
|
:local:
|
||||||
|
|
||||||
|
.. _msf_layout:
|
||||||
|
|
||||||
|
File Layout
|
||||||
|
===========
|
||||||
|
|
||||||
|
The MSF file format consists of the following components:
|
||||||
|
|
||||||
|
1. :ref:`msf_superblock`
|
||||||
|
2. :ref:`msf_freeblockmap` (also know as Free Page Map, or FPM)
|
||||||
|
3. Data
|
||||||
|
|
||||||
|
Each component is stored as an indexed block, the length of which is specified
|
||||||
|
in ``SuperBlock::BlockSize``. The file consists of 1 or more iterations of the
|
||||||
|
following pattern (sometimes referred to as an "interval"):
|
||||||
|
|
||||||
|
1. 1 block of data
|
||||||
|
2. Free Block Map 1 (corresponds to ``SuperBlock::FreeBlockMapBlock`` 1)
|
||||||
|
3. Free Block Map 2 (corresponds to ``SuperBlock::FreeBlockMapBlock`` 2)
|
||||||
|
4. ``SuperBlock::BlockSize - 3`` blocks of data
|
||||||
|
|
||||||
|
In the first interval, the first data block is used to store
|
||||||
|
:ref:`msf_superblock`.
|
||||||
|
|
||||||
|
The following diagram demonstrates the general layout of the file (\| denotes
|
||||||
|
the end of an interval, and is for visualization purposes only):
|
||||||
|
|
||||||
|
+-------------+-----------------------+------------------+------------------+----------+----+------+------+------+-------------+----+-----+
|
||||||
|
| Block Index | 0 | 1 | 2 | 3 - 4095 | \| | 4096 | 4097 | 4098 | 4099 - 8191 | \| | ... |
|
||||||
|
+=============+=======================+==================+==================+==========+====+======+======+======+=============+====+=====+
|
||||||
|
| Meaning | :ref:`msf_superblock` | Free Block Map 1 | Free Block Map 2 | Data | \| | Data | FPM1 | FPM2 | Data | \| | ... |
|
||||||
|
+-------------+-----------------------+------------------+------------------+----------+----+------+------+------+-------------+----+-----+
|
||||||
|
|
||||||
|
The file may end after any block, including immediately after a FPM1.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
LLVM only supports 4096 byte blocks (sometimes referred to as the "BigMsf"
|
||||||
|
variant), so the rest of this document will assume a block size of 4096.
|
||||||
|
|
||||||
.. _msf_superblock:
|
.. _msf_superblock:
|
||||||
|
|
||||||
The Superblock
|
The Superblock
|
||||||
@ -32,14 +70,9 @@ follows:
|
|||||||
sizes of 4KiB, and all further discussion assumes a block size of 4KiB.
|
sizes of 4KiB, and all further discussion assumes a block size of 4KiB.
|
||||||
- **FreeBlockMapBlock** - The index of a block within the file, at which begins
|
- **FreeBlockMapBlock** - The index of a block within the file, at which begins
|
||||||
a bitfield representing the set of all blocks within the file which are "free"
|
a bitfield representing the set of all blocks within the file which are "free"
|
||||||
(i.e. the data within that block is not used). This bitfield is spread across
|
(i.e. the data within that block is not used). See :ref:`msf_freeblockmap` for
|
||||||
the MSF file at ``BlockSize`` intervals.
|
more information.
|
||||||
**Important**: ``FreeBlockMapBlock`` can only be ``1`` or ``2``! This field
|
**Important**: ``FreeBlockMapBlock`` can only be ``1`` or ``2``!
|
||||||
is designed to support incremental and atomic updates of the underlying MSF
|
|
||||||
file. While writing to an MSF file, if the value of this field is `1`, you
|
|
||||||
can write your new modified bitfield to page 2, and vice versa. Only when
|
|
||||||
you commit the file to disk do you need to swap the value in the SuperBlock
|
|
||||||
to point to the new ``FreeBlockMapBlock``.
|
|
||||||
- **NumBlocks** - The total number of blocks in the file. ``NumBlocks * BlockSize``
|
- **NumBlocks** - The total number of blocks in the file. ``NumBlocks * BlockSize``
|
||||||
should equal the size of the file on disk.
|
should equal the size of the file on disk.
|
||||||
- **NumDirectoryBytes** - The size of the stream directory, in bytes. The stream
|
- **NumDirectoryBytes** - The size of the stream directory, in bytes. The stream
|
||||||
@ -54,6 +87,31 @@ follows:
|
|||||||
directory itself can be stitched together accordingly. The number of
|
directory itself can be stitched together accordingly. The number of
|
||||||
``ulittle32_t``'s in this array is given by ``ceil(NumDirectoryBytes / BlockSize)``.
|
``ulittle32_t``'s in this array is given by ``ceil(NumDirectoryBytes / BlockSize)``.
|
||||||
|
|
||||||
|
.. _msf_freeblockmap:
|
||||||
|
|
||||||
|
The Free Block Map
|
||||||
|
==================
|
||||||
|
|
||||||
|
The Free Block Map (sometimes referred to as the Free Page Map, or FPM) is a
|
||||||
|
series of blocks which contains a bit flag for every block in the file. The
|
||||||
|
flag will be set to 0 if the block is in use, and 1 if the block is unused.
|
||||||
|
|
||||||
|
Each file contains two FPMs, one of which is active at any given time. This
|
||||||
|
feature is designed to support incremental and atomic updates of the underlying
|
||||||
|
MSF file. While writing to an MSF file, if the active FPM is FPM1, you can
|
||||||
|
write your new modified bitfield to FPM2, and vice versa. Only when you commit
|
||||||
|
the file to disk do you need to swap the value in the SuperBlock to point to
|
||||||
|
the new ``FreeBlockMapBlock``.
|
||||||
|
|
||||||
|
The Free Block Maps are stored as a series of single blocks thoughout the file
|
||||||
|
at intervals of BlockSize. Because each FPM block is of size ``BlockSize``
|
||||||
|
bytes, it contains 8 times as many bits as an interval has blocks. This means
|
||||||
|
that the first block of each FPM refers to the first 8 intervals of the file
|
||||||
|
(the first 32768 blocks), the second block of each FPM refers to the next 8
|
||||||
|
blocks, and so on. This results in far more FPM blocks being present than are
|
||||||
|
required, but in order to maintain backwards compatibility the format must stay
|
||||||
|
this way.
|
||||||
|
|
||||||
The Stream Directory
|
The Stream Directory
|
||||||
====================
|
====================
|
||||||
The Stream Directory is the root of all access to the other streams in an MSF
|
The Stream Directory is the root of all access to the other streams in an MSF
|
||||||
|
Loading…
x
Reference in New Issue
Block a user