Zachary Turner | 3b7c9b9 | 2016-11-14 17:59:21 +0000 | [diff] [blame] | 1 | ======================================== |
| 2 | The PDB Info Stream (aka the PDB Stream) |
| 3 | ======================================== |
| 4 | |
| 5 | .. contents:: |
| 6 | :local: |
| 7 | |
| 8 | .. _pdb_stream_header: |
| 9 | |
| 10 | Stream Header |
| 11 | ============= |
| 12 | At offset 0 of the PDB Stream is a header with the following layout: |
| 13 | |
| 14 | |
| 15 | .. code-block:: c++ |
| 16 | |
| 17 | struct PdbStreamHeader { |
| 18 | ulittle32_t Version; |
| 19 | ulittle32_t Signature; |
| 20 | ulittle32_t Age; |
| 21 | Guid UniqueId; |
| 22 | }; |
| 23 | |
| 24 | - **Version** - A Value from the following enum: |
| 25 | |
| 26 | .. code-block:: c++ |
| 27 | |
| 28 | enum class PdbStreamVersion : uint32_t { |
| 29 | VC2 = 19941610, |
| 30 | VC4 = 19950623, |
| 31 | VC41 = 19950814, |
| 32 | VC50 = 19960307, |
| 33 | VC98 = 19970604, |
| 34 | VC70Dep = 19990604, |
| 35 | VC70 = 20000404, |
| 36 | VC80 = 20030901, |
| 37 | VC110 = 20091201, |
| 38 | VC140 = 20140508, |
| 39 | }; |
| 40 | |
| 41 | While the meaning of this field appears to be obvious, in practice we have |
| 42 | never observed a value other than ``VC70``, even with modern versions of |
| 43 | the toolchain, and it is unclear why the other values exist. It is assumed |
| 44 | that certain aspects of the PDB stream's layout, and perhaps even that of |
| 45 | the other streams, will change if the value is something other than ``VC70``. |
| 46 | |
| 47 | - **Signature** - A 32-bit time-stamp generated with a call to ``time()`` at |
| 48 | the time the PDB file is written. Note that due to the inherent uniqueness |
| 49 | problems of using a timestamp with 1-second granularity, this field does not |
| 50 | really serve its intended purpose, and as such is typically ignored in favor |
| 51 | of the ``Guid`` field, described below. |
| 52 | |
| 53 | - **Age** - The number of times the PDB file has been written. This can be used |
| 54 | along with ``Guid`` to match the PDB to its corresponding executable. |
| 55 | |
| 56 | - **Guid** - A 128-bit identifier guaranteed to be unique across space and time. |
| 57 | In general, this can be thought of as the result of calling the Win32 API |
| 58 | `UuidCreate <https://msdn.microsoft.com/en-us/library/windows/desktop/aa379205(v=vs.85).aspx>`__, |
| 59 | although LLVM cannot rely on that, as it must work on non-Windows platforms. |
| 60 | |
| 61 | Matching a PDB to its executable |
| 62 | ================================ |
| 63 | The linker is responsible for writing both the PDB and the final executable, and |
| 64 | as a result is the only entity capable of writing the information necessary to |
| 65 | match the PDB to the executable. |
| 66 | |
| 67 | In order to accomplish this, the linker generates a guid for the PDB (or |
| 68 | re-uses the existing guid if it is linking incrementally) and increments the Age |
| 69 | field. |
| 70 | |
| 71 | The executable is a PE/COFF file, and part of a PE/COFF file is the presence of |
| 72 | number of "directories". For our purposes here, we are interested in the "debug |
| 73 | directory". The exact format of a debug directory is described by the |
| 74 | `IMAGE_DEBUG_DIRECTORY structure <https://msdn.microsoft.com/en-us/library/windows/desktop/ms680307(v=vs.85).aspx>`__. |
| 75 | For this particular case, the linker emits a debug directory of type |
| 76 | ``IMAGE_DEBUG_TYPE_CODEVIEW``. The format of this record is defined in |
| 77 | ``llvm/DebugInfo/CodeView/CVDebugRecord.h``, but it suffices to say here only |
| 78 | that it includes the same ``Guid`` and ``Age`` fields. At runtime, a |
| 79 | debugger or tool can scan the COFF executable image for the presence of |
| 80 | a debug directory of the correct type and verify that the Guid and Age match. |