File: PdbStream.html

package info (click to toggle)
llvm-toolchain-13 1%3A13.0.1-6~deb10u4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,418,792 kB
  • sloc: cpp: 5,290,827; ansic: 996,570; asm: 544,593; python: 188,212; objc: 72,027; lisp: 30,291; f90: 25,395; sh: 24,900; javascript: 9,780; pascal: 9,398; perl: 7,484; ml: 5,432; awk: 3,523; makefile: 2,892; xml: 953; cs: 573; fortran: 539
file content (307 lines) | stat: -rw-r--r-- 17,840 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307


<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>The PDB Info Stream (aka the PDB Stream) &#8212; LLVM 13 documentation</title>
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
    <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script src="../_static/jquery.js"></script>
    <script src="../_static/underscore.js"></script>
    <script src="../_static/doctools.js"></script>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="The PDB TPI and IPI Streams" href="TpiStream.html" />
    <link rel="prev" title="The MSF File Format" href="MsfFile.html" />
<style type="text/css">
  table.right { float: right; margin-left: 20px; }
  table.right td { border: 1px solid #ccc; }
</style>

  </head><body>
<div class="logo">
  <a href="../index.html">
    <img src="../_static/logo.png"
         alt="LLVM Logo" width="250" height="88"/></a>
</div>

    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="TpiStream.html" title="The PDB TPI and IPI Streams"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="MsfFile.html" title="The MSF File Format"
             accesskey="P">previous</a> |</li>
  <li><a href="https://llvm.org/">LLVM Home</a>&nbsp;|&nbsp;</li>
  <li><a href="../index.html">Documentation</a>&raquo;</li>

          <li class="nav-item nav-item-1"><a href="../Reference.html" >Reference</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="index.html" accesskey="U">The PDB File Format</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">The PDB Info Stream (aka the PDB Stream)</a></li> 
      </ul>
    </div>

      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">

<h3>Documentation</h3>

<ul class="want-points">
    <li><a href="https://llvm.org/docs/GettingStartedTutorials.html">Getting Started/Tutorials</a></li>
    <li><a href="https://llvm.org/docs/UserGuides.html">User Guides</a></li>
    <li><a href="https://llvm.org/docs/Reference.html">Reference</a></li>
</ul>

<h3>Getting Involved</h3>

<ul class="want-points">
    <li><a href="https://llvm.org/docs/Contributing.html">Contributing to LLVM</a></li>
    <li><a href="https://llvm.org/docs/HowToSubmitABug.html">Submitting Bug Reports</a></li>
    <li><a href="https://llvm.org/docs/GettingInvolved.html#mailing-lists">Mailing Lists</a></li>
    <li><a href="https://llvm.org/docs/GettingInvolved.html#irc">IRC</a></li>
    <li><a href="https://llvm.org/docs/GettingInvolved.html#meetups-and-social-events">Meetups and Social Events</a></li>
</ul>

<h3>Additional Links</h3>

<ul class="want-points">
    <li><a href="https://llvm.org/docs/FAQ.html">FAQ</a></li>
    <li><a href="https://llvm.org/docs/Lexicon.html">Glossary</a></li>
    <li><a href="https://llvm.org/pubs">Publications</a></li>
    <li><a href="https://github.com/llvm/llvm-project//">Github Repository</a></li>
</ul>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/PDB/PdbStream.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" />
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>$('#searchbox').show(0);</script>
        </div>
      </div>

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="the-pdb-info-stream-aka-the-pdb-stream">
<h1>The PDB Info Stream (aka the PDB Stream)<a class="headerlink" href="#the-pdb-info-stream-aka-the-pdb-stream" title="Permalink to this headline">¶</a></h1>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#stream-header" id="id1">Stream Header</a></p></li>
<li><p><a class="reference internal" href="#named-stream-map" id="id2">Named Stream Map</a></p></li>
<li><p><a class="reference internal" href="#pdb-feature-codes" id="id3">PDB Feature Codes</a></p></li>
<li><p><a class="reference internal" href="#matching-a-pdb-to-its-executable" id="id4">Matching a PDB to its executable</a></p></li>
</ul>
</div>
<div class="section" id="stream-header">
<span id="pdb-stream-header"></span><h2><a class="toc-backref" href="#id1">Stream Header</a><a class="headerlink" href="#stream-header" title="Permalink to this headline">¶</a></h2>
<p>At offset 0 of the PDB Stream is a header with the following layout:</p>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span> <span class="nc">PdbStreamHeader</span> <span class="p">{</span>
  <span class="n">ulittle32_t</span> <span class="n">Version</span><span class="p">;</span>
  <span class="n">ulittle32_t</span> <span class="n">Signature</span><span class="p">;</span>
  <span class="n">ulittle32_t</span> <span class="n">Age</span><span class="p">;</span>
  <span class="n">Guid</span> <span class="n">UniqueId</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>Version</strong> - A Value from the following enum:</p></li>
</ul>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">enum</span> <span class="k">class</span> <span class="nc">PdbStreamVersion</span> <span class="o">:</span> <span class="kt">uint32_t</span> <span class="p">{</span>
  <span class="n">VC2</span> <span class="o">=</span> <span class="mi">19941610</span><span class="p">,</span>
  <span class="n">VC4</span> <span class="o">=</span> <span class="mi">19950623</span><span class="p">,</span>
  <span class="n">VC41</span> <span class="o">=</span> <span class="mi">19950814</span><span class="p">,</span>
  <span class="n">VC50</span> <span class="o">=</span> <span class="mi">19960307</span><span class="p">,</span>
  <span class="n">VC98</span> <span class="o">=</span> <span class="mi">19970604</span><span class="p">,</span>
  <span class="n">VC70Dep</span> <span class="o">=</span> <span class="mi">19990604</span><span class="p">,</span>
  <span class="n">VC70</span> <span class="o">=</span> <span class="mi">20000404</span><span class="p">,</span>
  <span class="n">VC80</span> <span class="o">=</span> <span class="mi">20030901</span><span class="p">,</span>
  <span class="n">VC110</span> <span class="o">=</span> <span class="mi">20091201</span><span class="p">,</span>
  <span class="n">VC140</span> <span class="o">=</span> <span class="mi">20140508</span><span class="p">,</span>
<span class="p">};</span>
</pre></div>
</div>
<p>While the meaning of this field appears to be obvious, in practice we have
never observed a value other than <code class="docutils literal notranslate"><span class="pre">VC70</span></code>, even with modern versions of
the toolchain, and it is unclear why the other values exist.  It is assumed
that certain aspects of the PDB stream’s layout, and perhaps even that of
the other streams, will change if the value is something other than <code class="docutils literal notranslate"><span class="pre">VC70</span></code>.</p>
<ul class="simple">
<li><p><strong>Signature</strong> - A 32-bit time-stamp generated with a call to <code class="docutils literal notranslate"><span class="pre">time()</span></code> at
the time the PDB file is written.  Note that due to the inherent uniqueness
problems of using a timestamp with 1-second granularity, this field does not
really serve its intended purpose, and as such is typically ignored in favor
of the <code class="docutils literal notranslate"><span class="pre">Guid</span></code> field, described below.</p></li>
<li><p><strong>Age</strong> - The number of times the PDB file has been written.  This can be used
along with <code class="docutils literal notranslate"><span class="pre">Guid</span></code> to match the PDB to its corresponding executable.</p></li>
<li><p><strong>Guid</strong> - A 128-bit identifier guaranteed to be unique across space and time.
In general, this can be thought of as the result of calling the Win32 API
<a class="reference external" href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa379205(v=vs.85).aspx">UuidCreate</a>,
although LLVM cannot rely on that, as it must work on non-Windows platforms.</p></li>
</ul>
</div>
<div class="section" id="named-stream-map">
<span id="pdb-named-stream-map"></span><h2><a class="toc-backref" href="#id2">Named Stream Map</a><a class="headerlink" href="#named-stream-map" title="Permalink to this headline">¶</a></h2>
<p>Following the header is a serialized hash table whose key type is a string, and
whose value type is an integer.  The existence of a mapping <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">-&gt;</span> <span class="pre">Y</span></code> means
that the stream with the name <code class="docutils literal notranslate"><span class="pre">X</span></code> has stream index <code class="docutils literal notranslate"><span class="pre">Y</span></code> in the underlying MSF
file.  Note that not all streams are named (for example, the
<a class="reference internal" href="TpiStream.html"><span class="doc">TPI Stream</span></a> has a fixed index and as such there is no need to
look up its index by name).  In practice, there are usually only a small number
of named streams and these are enumerated in the table of streams in <a class="reference internal" href="index.html"><span class="doc">The PDB File Format</span></a>.
A corollary of this is if a stream does have a name (and as such is in the named
stream map) then consulting the Named Stream Map is likely to be the only way to
discover the stream’s MSF stream index.  Several important streams (such as the
global string table, which is called <code class="docutils literal notranslate"><span class="pre">/names</span></code>) can only be located this way, and
so it is important to both produce and consume this correctly as tools will not
function correctly without it.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Some streams are located by fixed indices (e.g TPI Stream has index 2), but
other streams are located by fixed names (e.g. the string table is called
<code class="docutils literal notranslate"><span class="pre">/names</span></code>) and can only be located by consulting the Named Stream Map.</p>
</div>
<p>The on-disk layout of the Named Stream Map consists of 2 components.  The first is
a buffer of string data prefixed by a 32-bit length.  The second is a serialized
hash table whose key and value types are both <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code>.  The key is the offset
of a null-terminated string in the string data buffer specifying the name of the
stream, and the value is the MSF stream index of the stream with said name.
Note that although the key is an integer, the hash function used to find the right
bucket hashes the string at the corresponding offset in the string data buffer.</p>
<p>The on-disk layout of the serialized hash table is described at <a class="reference internal" href="HashTable.html"><span class="doc">The PDB Serialized Hash Table Format</span></a>.</p>
<p>Note that the entire Named Stream Map is not length-prefixed, so the only way to
get to the data following it is to de-serialize it in its entirety.</p>
</div>
<div class="section" id="pdb-feature-codes">
<span id="pdb-stream-features"></span><h2><a class="toc-backref" href="#id3">PDB Feature Codes</a><a class="headerlink" href="#pdb-feature-codes" title="Permalink to this headline">¶</a></h2>
<p>Following the Named Stream Map, and consuming all remaining bytes of the PDB
Stream is a list of values from the following enumeration:</p>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">enum</span> <span class="k">class</span> <span class="nc">PdbRaw_FeatureSig</span> <span class="o">:</span> <span class="kt">uint32_t</span> <span class="p">{</span>
  <span class="n">VC110</span> <span class="o">=</span> <span class="mi">20091201</span><span class="p">,</span>
  <span class="n">VC140</span> <span class="o">=</span> <span class="mi">20140508</span><span class="p">,</span>
  <span class="n">NoTypeMerge</span> <span class="o">=</span> <span class="mh">0x4D544F4E</span><span class="p">,</span>
  <span class="n">MinimalDebugInfo</span> <span class="o">=</span> <span class="mh">0x494E494D</span><span class="p">,</span>
<span class="p">};</span>
</pre></div>
</div>
<p>The meaning of these values is summarized by the following table:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 27%" />
<col style="width: 73%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>Flag</p></th>
<th class="head"><p>Meaning</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>VC110</p></td>
<td><ul class="simple">
<li><p>No other features flags are present</p></li>
<li><p>PDB contains an <a class="reference internal" href="TpiStream.html"><span class="doc">IPI Stream</span></a></p></li>
</ul>
</td>
</tr>
<tr class="row-odd"><td><p>VC140</p></td>
<td><ul class="simple">
<li><p>Other feature flags may be present</p></li>
<li><p>PDB contains an <a class="reference internal" href="TpiStream.html"><span class="doc">IPI Stream</span></a></p></li>
</ul>
</td>
</tr>
<tr class="row-even"><td><p>NoTypeMerge</p></td>
<td><ul class="simple">
<li><p>Presumably duplicate types can appear in the
TPI Stream, although it’s unclear why this
might happen.</p></li>
</ul>
</td>
</tr>
<tr class="row-odd"><td><p>MinimalDebugInfo</p></td>
<td><ul class="simple">
<li><p>Program was linked with /DEBUG:FASTLINK</p></li>
<li><p>There is no TPI / IPI stream, all type info
is contained in the original object files.</p></li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="matching-a-pdb-to-its-executable">
<h2><a class="toc-backref" href="#id4">Matching a PDB to its executable</a><a class="headerlink" href="#matching-a-pdb-to-its-executable" title="Permalink to this headline">¶</a></h2>
<p>The linker is responsible for writing both the PDB and the final executable, and
as a result is the only entity capable of writing the information necessary to
match the PDB to the executable.</p>
<p>In order to accomplish this, the linker generates a guid for the PDB (or
re-uses the existing guid if it is linking incrementally) and increments the Age
field.</p>
<p>The executable is a PE/COFF file, and part of a PE/COFF file is the presence of
number of “directories”.  For our purposes here, we are interested in the “debug
directory”.  The exact format of a debug directory is described by the
<a class="reference external" href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms680307(v=vs.85).aspx">IMAGE_DEBUG_DIRECTORY structure</a>.
For this particular case, the linker emits a debug directory of type
<code class="docutils literal notranslate"><span class="pre">IMAGE_DEBUG_TYPE_CODEVIEW</span></code>.  The format of this record is defined in
<code class="docutils literal notranslate"><span class="pre">llvm/DebugInfo/CodeView/CVDebugRecord.h</span></code>, but it suffices to say here only
that it includes the same <code class="docutils literal notranslate"><span class="pre">Guid</span></code> and <code class="docutils literal notranslate"><span class="pre">Age</span></code> fields.  At runtime, a
debugger or tool can scan the COFF executable image for the presence of
a debug directory of the correct type and verify that the Guid and Age match.</p>
</div>
</div>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="TpiStream.html" title="The PDB TPI and IPI Streams"
             >next</a> |</li>
        <li class="right" >
          <a href="MsfFile.html" title="The MSF File Format"
             >previous</a> |</li>
  <li><a href="https://llvm.org/">LLVM Home</a>&nbsp;|&nbsp;</li>
  <li><a href="../index.html">Documentation</a>&raquo;</li>

          <li class="nav-item nav-item-1"><a href="../Reference.html" >Reference</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="index.html" >The PDB File Format</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">The PDB Info Stream (aka the PDB Stream)</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2003-2021, LLVM Project.
      Last updated on 2021-09-18.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.5.4.
    </div>
  </body>
</html>