Skip to content

Commit a5d7faf

Browse files
committed
[docs][tools][DirectX] Document DXContainer debug info parts
This patch adds ILDB, ILDN, VERS, SRCI parts format documentation. It describes how to use LLVM tools to inspect them. Additionally, llvm-pdbutil documentation has been expanded with information on how to inspect PDB files generated by the DirectX compiler.
1 parent 407fc9b commit a5d7faf

2 files changed

Lines changed: 339 additions & 4 deletions

File tree

llvm/docs/CommandGuide/llvm-pdbutil.rst

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ in the sections that follow.
4040
reconstructed.
4141
* :ref:`merge_subcommand` - Given two PDBs, produce a third PDB that is the
4242
result of merging the two input PDBs.
43+
* :ref:`export_subcommand` - Write the contents of a PDB stream to a file.
4344

4445
.. _pretty_subcommand:
4546

@@ -407,6 +408,14 @@ Miscellaneous Options
407408

408409
Dump image section headers.
409410

411+
.. option:: -dxcontainer
412+
413+
Dump a summary of the DXContainer stored in the PDB file's DXContainer stream.
414+
Shader companion PDB files produced by the DirectX backend store debug-related
415+
container parts in this stream. For example::
416+
417+
llvm-pdbutil dump --dxcontainer shader.pdb
418+
410419
.. option:: -section-map
411420

412421
Dump section map.
@@ -539,9 +548,22 @@ USAGE: :program:`llvm-pdbutil` pdb2yaml [*options*] <input PDB file>
539548
Summary
540549
^^^^^^^
541550

551+
Produce a YAML description of some or all of a PDB file's contents.
552+
542553
Options
543554
^^^^^^^
544555

556+
.. option:: -all
557+
558+
Implies most other options in this category.
559+
560+
.. option:: -dxcontainer
561+
562+
Dump the DXContainer stored in the PDB file's DXContainer stream to YAML.
563+
For example::
564+
565+
llvm-pdbutil pdb2yaml --dxcontainer shader.pdb
566+
545567
.. _yaml2pdb_subcommand:
546568

547569
yaml2pdb
@@ -565,6 +587,55 @@ Options
565587

566588
Write the resulting PDB to the specified file.
567589

590+
.. _export_subcommand:
591+
592+
export
593+
~~~~~~
594+
595+
USAGE: :program:`llvm-pdbutil` export --out=<file> [*options*] <input PDB file>
596+
597+
.. program:: llvm-pdbutil export
598+
599+
Summary
600+
^^^^^^^
601+
602+
Write the binary contents of a PDB stream to a file.
603+
604+
DirectX Shader PDBs
605+
^^^^^^^^^^^^^^^^^^^
606+
607+
When a DirectX shader is compiled with debug information and a companion PDB
608+
file is requested, the PDB contains a DXContainer stream with debug-related
609+
parts such as ILDB, ILDN, SRCI, and VERS. To extract that container as a
610+
standalone DXContainer file::
611+
612+
llvm-pdbutil export --dxcontainer --out=shader.dxbc shader.pdb
613+
614+
The resulting file can be inspected with the same DXContainer tooling used for
615+
the main shader output, such as :program:`obj2yaml` and
616+
:program:`llvm-objcopy`. See :doc:`../DirectX/DXContainer` for part format
617+
details. To inspect the embedded container without extracting it, use
618+
:ref:`llvm-pdbutil dump <dump_subcommand>` or
619+
:ref:`llvm-pdbutil pdb2yaml <pdb2yaml_subcommand>`.
620+
621+
Options
622+
^^^^^^^
623+
624+
.. option:: --out=<file>
625+
626+
The file to write the exported stream data to.
627+
628+
.. option:: --dxcontainer
629+
630+
A synonym for the :option:`--stream=5` option.
631+
Export the DXContainer stored in the PDB file's DXContainer stream. This is
632+
the usual way to recover the debug-related container parts from a shader
633+
companion PDB file.
634+
635+
.. option:: --stream=<index-or-name>
636+
637+
Export the contents of the specified PDB stream.
638+
568639
.. _merge_subcommand:
569640

570641
merge

llvm/docs/DirectX/DXContainer.rst

Lines changed: 268 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ FXC are marked with \*.
9797

9898
#. `DXIL`_† - Stores the DXIL bytecode.
9999
#. `HASH`_† - Stores the shader MD5 hash.
100-
#. ILDB† - Stores the DXIL bytecode with LLVM Debug Information embedded in the module.
101-
#. ILDN† - Stores shader debug name for external debug information.
100+
#. `ILDB`_† - Stores the DXIL bytecode with LLVM Debug Information embedded in the module.
101+
#. `ILDN`_† - Stores shader debug name for external debug information.
102102
#. `ISG1`_ - Stores the input signature for Shader Model 5.1+.
103103
#. ISGN\* - Stores the input signature for Shader Model 4 and earlier.
104104
#. `OSG1`_ - Stores the output signature for Shader Model 5.1+.
@@ -116,9 +116,9 @@ FXC are marked with \*.
116116
#. SHDR\* - Stores compiled DXBC bytecode.
117117
#. SHEX\* - Stores compiled DXBC bytecode.
118118
#. DXBC\* - Stores compiled DXBC bytecode.
119-
#. SRCI† - Stores shader source information.
119+
#. `SRCI`_† - Stores shader source information.
120120
#. STAT† - Stores shader statistics.
121-
#. VERS† - Stores shader compiler version information.
121+
#. `VERS`_† - Stores shader compiler version information.
122122

123123
DXIL Part
124124
---------
@@ -143,6 +143,270 @@ a 128-bit MD5 hash digest. The flags field can either have the value ``0`` to
143143
indicate no flags, or ``1`` to indicate that the file hash was computed
144144
including the source code that produced the binary.
145145

146+
ILDB Part
147+
---------
148+
.. _ILDB:
149+
150+
The ILDB part follows the structure of the `DXIL`_ part. It stores the
151+
unstripped DXIL bitcode module with debug information embedded.
152+
153+
The ILDB part is emitted when the shader is compiled with debug information.
154+
The stripped `DXIL`_ part has the ``Dwarf Version`` and ``Debug Info Version``
155+
module flags removed, and ``dx.source`` metadata nodes are stripped from it.
156+
Those nodes are preserved in the ILDB module when source is embedded in the
157+
debug module; otherwise they are replaced with empty placeholder values in the
158+
ILDB module written to the companion PDB file.
159+
160+
By default, when debug information is present and no companion PDB file is
161+
requested, the ILDB part is embedded in the main DXContainer output. When a
162+
companion PDB file is requested, the ILDB part is written to the PDB unless
163+
llc's ``--dx-embed-debug`` is specified, in which case it is written to both the main
164+
DXContainer and the PDB.
165+
166+
.. rubric:: Reading this part
167+
168+
When the ILDB part is present in a DXContainer file, :program:`obj2yaml` prints
169+
it under a ``Program`` mapping with the embedded DXIL bitcode. Use
170+
:program:`llvm-objcopy` to extract the raw bitcode, then :program:`llvm-dis` to
171+
disassemble it::
172+
173+
llvm-objcopy --dump-section=ILDB=shader.bc shader.dxbc
174+
llvm-dis shader.bc
175+
176+
When the ILDB part is stored in a companion PDB file, use :program:`llvm-pdbutil`
177+
to access it (see :doc:`llvm-pdbutil <../CommandGuide/llvm-pdbutil>`).
178+
179+
ILDN Part
180+
---------
181+
.. _ILDN:
182+
183+
The ILDN part stores the name of the companion PDB file used for external
184+
debug information. It is always emitted when the shader is compiled with debug
185+
information, and is included in both the main DXContainer output and the
186+
companion PDB file.
187+
188+
The part begins with a ``DebugNameHeader`` followed by a null-terminated UTF-8
189+
string containing the debug file name:
190+
191+
.. code-block:: c
192+
193+
struct DebugNameHeader {
194+
uint16_t Flags;
195+
uint16_t NameLength;
196+
};
197+
198+
The ``Flags`` field is reserved and must be zero. ``NameLength`` is the length
199+
of the debug file name in bytes, not including the null terminator.
200+
201+
If no PDB output path is specified, the debug file name defaults to
202+
``<MD5 hash>.pdb``, where ``<MD5 hash>`` is the stringified MD5 digest from the
203+
`HASH`_ part. When the ``-dx-Zss`` flag is used, the digest is computed from the
204+
ILDB bitcode; otherwise it is computed from the stripped `DXIL`_ bitcode. If a
205+
PDB output path is specified with `-dx-Fd`, that path is used as the debug file name.
206+
When the path names a directory, the default ``<MD5 hash>.pdb`` file name is placed in
207+
that directory.
208+
209+
.. rubric:: Reading this part
210+
211+
When the ILDN part is present in a DXContainer file, :program:`obj2yaml` prints
212+
it under a ``DebugName`` mapping.
213+
214+
SRCI Part
215+
---------
216+
.. _SRCI:
217+
218+
The SRCI part stores shader source information extracted from ``dx.source``
219+
metadata in the LLVM module. It is emitted when source information is available
220+
and source is not embedded in the debug module. When source is embedded in the
221+
debug module, the ``dx.source`` metadata nodes remain in the `ILDB`_ module
222+
instead and the SRCI part is not generated.
223+
224+
The SRCI part is written to the companion PDB file. It consists of a part
225+
header followed by three 4-byte aligned sections. Each section begins with a
226+
``SectionHeader`` and is followed by section-specific data:
227+
228+
.. code-block:: c
229+
230+
struct Header {
231+
uint32_t AlignedSizeInBytes;
232+
uint16_t Flags;
233+
uint16_t SectionCount;
234+
};
235+
236+
struct SectionHeader {
237+
uint32_t AlignedSizeInBytes;
238+
uint16_t Flags;
239+
uint16_t Type;
240+
};
241+
242+
The part ``Flags`` field is reserved and must be zero. ``SectionCount`` must be
243+
``3``. Each section ``Flags`` field is reserved and must be zero. The
244+
``Type`` field identifies the section. The section type values are:
245+
246+
.. code-block:: c
247+
248+
SOURCE_INFO_TYPE(0, SourceContents)
249+
SOURCE_INFO_TYPE(1, SourceNames)
250+
SOURCE_INFO_TYPE(2, Args)
251+
252+
Source Names Section
253+
~~~~~~~~~~~~~~~~~~~~~~~~~
254+
255+
The source names section stores the file names of the HLSL translation units
256+
that contributed source to the shader. It begins with a section header of type
257+
``SourceNames``, followed by a section-specific header and a sequence of name
258+
entries:
259+
260+
.. code-block:: c
261+
262+
struct SourceNamesHeader {
263+
uint32_t Flags;
264+
uint32_t Count;
265+
uint16_t EntriesSizeInBytes;
266+
};
267+
268+
struct SourceNamesEntry {
269+
uint32_t AlignedSizeInBytes;
270+
uint32_t Flags;
271+
uint32_t NameSizeInBytes;
272+
uint32_t ContentSizeInBytes;
273+
};
274+
275+
The section-specific ``Flags`` field is reserved and must be zero. ``Count`` is
276+
the number of entries that follow. ``EntriesSizeInBytes`` is the total size of
277+
the entry data following the section-specific header, including entry padding.
278+
279+
Each entry is 4-byte aligned. The first entry is usually the main shader source
280+
file, and the remaining entries are sorted by file name.
281+
282+
Each entry is followed by a null-terminated UTF-8 file name of length
283+
``NameSizeInBytes``. The ``ContentSizeInBytes`` field records the size of the
284+
corresponding source content entry in the source contents section, including its
285+
null terminator.
286+
287+
Source Contents Section
288+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
289+
290+
The source contents section stores the HLSL source text for each file named in
291+
the source names section. It begins with a section header of type
292+
``SourceContents``, followed by a section-specific header and the (optionally
293+
compressed) entry data:
294+
295+
.. code-block:: c
296+
297+
struct SourceContentsHeader {
298+
uint32_t AlignedSizeInBytes;
299+
uint16_t Flags;
300+
uint16_t Type;
301+
uint32_t EntriesSizeInBytes;
302+
uint32_t UncompressedEntriesSizeInBytes;
303+
uint32_t Count;
304+
};
305+
306+
struct SourceContentsEntry {
307+
uint32_t AlignedSizeInBytes;
308+
uint32_t Flags;
309+
uint32_t ContentSizeInBytes;
310+
};
311+
312+
The section-specific ``Flags`` field is reserved and must be zero. The
313+
``Type`` field specifies the compression applied to the entry data. The
314+
compression type values are:
315+
316+
.. code-block:: c
317+
318+
COMPRESSION_TYPE(0, None)
319+
COMPRESSION_TYPE(1, Zlib)
320+
321+
When no compression is used, ``EntriesSizeInBytes`` and
322+
``UncompressedEntriesSizeInBytes`` are equal.
323+
324+
When Zlib compression is used, the bytes following the section-specific header
325+
contain the compressed aggregate of all entries. After decompression, the data is
326+
a sequence of ``Count`` entries.
327+
328+
Each uncompressed entry is 4-byte aligned and is followed by a null-terminated
329+
UTF-8 string containing the file source text.
330+
331+
The entries must appear in the same order as the entries in the source names
332+
section.
333+
334+
Args Section
335+
~~~~~~~~~~~~~~~~~
336+
337+
The args section stores the HLSL compiler command-line arguments used to produce
338+
the shader. It begins with a section header of type ``Args``, followed by a
339+
section-specific header and the argument data:
340+
341+
.. code-block:: c
342+
343+
struct ArgsHeader {
344+
uint32_t Flags;
345+
uint32_t SizeInBytes;
346+
uint32_t Count;
347+
};
348+
349+
The section-specific ``Flags`` field is reserved and must be zero.
350+
``SizeInBytes`` is the total size of the argument data following the
351+
section-specific header. ``Count`` is the number of argument pairs that
352+
follow.
353+
354+
The header is followed by ``Count`` argument pairs. Each pair consists of two
355+
null-terminated UTF-8 strings: an argument name and an argument value.
356+
357+
Padding is not applied between argument pairs. The section is padded with zero
358+
bytes at the end to a 4-byte boundary.
359+
360+
.. rubric:: Reading this part
361+
362+
The SRCI part is normally found in a companion PDB file rather than the main
363+
DXContainer output. When present, :program:`obj2yaml` prints it under a
364+
``SourceInfo`` mapping.
365+
366+
To read SRCI part from a companion PDB file, use :program:`llvm-pdbutil`.
367+
368+
VERS Part
369+
---------
370+
.. _VERS:
371+
372+
The VERS part stores compiler version information. It is emitted when the
373+
shader is compiled with debug information. When a companion PDB file is produced,
374+
the VERS part is written to that file. When compiling a shader library, the VERS
375+
part is also written to the main DXContainer output.
376+
377+
The part begins with a ``CompilerVersionHeader`` followed by two sequential
378+
null-terminated UTF-8 strings: the compiler commit SHA and a custom version
379+
string:
380+
381+
.. code-block:: c
382+
383+
struct CompilerVersionHeader {
384+
uint16_t Major;
385+
uint16_t Minor;
386+
uint32_t Flags;
387+
uint32_t CommitCount;
388+
uint32_t ContentSizeInBytes;
389+
};
390+
391+
``Major`` and ``Minor`` encode the compiler version. ``CommitCount`` is the
392+
value produced by ``git rev-list --count HEAD`` in the compiler repository, or
393+
``0`` when that value is unavailable. ``ContentSizeInBytes`` is the combined
394+
size of the commit SHA and custom version strings, including their null
395+
terminators but excluding any trailing part padding.
396+
397+
The ``Flags`` field is a bitmask. The flag values are:
398+
399+
* ``Default`` (``0``) - default value
400+
* ``Debug`` (``1``) - indicates whether the compiler was built in debug mode
401+
* ``Internal`` (``2``) - indicates whether the shader was modified by a validator
402+
403+
.. rubric:: Reading this part
404+
405+
When the VERS part is present in a DXContainer file, :program:`obj2yaml` prints
406+
it under a ``CompilerVersion`` mapping.
407+
408+
To read VERS part from a companion PDB file, use :program:`llvm-pdbutil`.
409+
146410
Program Signature (SG1) Parts
147411
-----------------------------
148412
.. _ISG1:

0 commit comments

Comments
 (0)