[llvm] Reapply "[PDB][llvm-pdbutil] Add DXContainer support for `pdb2yaml` and `yaml2pdb`" (PR #201092)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 2 04:06:38 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-debuginfo

Author: Ilia Kuklin (kuilpd)

<details>
<summary>Changes</summary>

This reapplies #<!-- -->198351 with 2 issues fixed:
- `-Wchanges-meaning` causing an error in `PdbYaml.h`
- UB when parsing DXContainer header from a null buffer, fixed in #<!-- -->200865

Original patch description:

This patch enables the following:
1. Attempting to parse a `DXContainer` from stream 5 (generated by DirectX tools) of a PDB file, to be used later in `llvm-pdbutil`.
2. Outputting a PDB file with a built in DXContainer as YAML. Existing DirectX tools form a PDB container with empty DBI, TPI and IPI streams, so this patch also allows them to be empty when dumping a PDB file as YAML.
3. Creating a PDB file from YAML with an built in DXContainer. When creating a PDB with a DXContainer, streams DBI, TPI and IPI can be completely empty, so this patch also includes adjustments to allow forming such a PDB file. This is done to maintain compatibility with other DirectX tools.

---

Patch is 23.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/201092.diff


13 Files Affected:

- (modified) llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h (+3) 
- (modified) llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h (+3-1) 
- (modified) llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h (+1) 
- (modified) llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h (+4-1) 
- (modified) llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp (+25-1) 
- (modified) llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp (+49-22) 
- (added) llvm/test/tools/llvm-pdbutil/dxcontainer.test (+143) 
- (modified) llvm/tools/llvm-pdbutil/PdbYaml.cpp (+6) 
- (modified) llvm/tools/llvm-pdbutil/PdbYaml.h (+7) 
- (modified) llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp (+31) 
- (modified) llvm/tools/llvm-pdbutil/YAMLOutputStyle.h (+1) 
- (modified) llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp (+40-10) 
- (modified) llvm/tools/llvm-pdbutil/llvm-pdbutil.h (+1) 


``````````diff
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
index 62e2c665e546e..80f9519ebb482 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
@@ -11,6 +11,7 @@
 
 #include "llvm/DebugInfo/MSF/IMSFFile.h"
 #include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/Object/DXContainer.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/BinaryStreamRef.h"
 #include "llvm/Support/Compiler.h"
@@ -105,6 +106,7 @@ class LLVM_ABI PDBFile : public msf::IMSFFile {
   Expected<SymbolStream &> getPDBSymbolStream();
   Expected<PDBStringTable &> getStringTable();
   Expected<InjectedSourceStream &> getInjectedSourceStream();
+  Expected<object::DXContainer &> getDXContainerStream();
 
   BumpPtrAllocator &getAllocator() { return Allocator; }
 
@@ -133,6 +135,7 @@ class LLVM_ABI PDBFile : public msf::IMSFFile {
   std::unique_ptr<DbiStream> Dbi;
   std::unique_ptr<TpiStream> Tpi;
   std::unique_ptr<TpiStream> Ipi;
+  std::unique_ptr<object::DXContainer> Dxc;
   std::unique_ptr<PublicsStream> Publics;
   std::unique_ptr<SymbolStream> Symbols;
   std::unique_ptr<msf::MappedBlockStream> DirectoryStream;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
index abb1b623c5a8a..6093a63dddfc6 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
@@ -53,6 +53,7 @@ class PDBFileBuilder {
   LLVM_ABI TpiStreamBuilder &getIpiBuilder();
   LLVM_ABI PDBStringTableBuilder &getStringTableBuilder();
   LLVM_ABI GSIStreamBuilder &getGsiBuilder();
+  LLVM_ABI std::unique_ptr<SmallVector<char>> &getDXContainerData();
 
   // If HashPDBContentsToGUID is true on the InfoStreamBuilder, Guid is filled
   // with the computed PDB GUID on return.
@@ -96,8 +97,9 @@ class PDBFileBuilder {
   std::unique_ptr<GSIStreamBuilder> Gsi;
   std::unique_ptr<TpiStreamBuilder> Tpi;
   std::unique_ptr<TpiStreamBuilder> Ipi;
+  std::unique_ptr<SmallVector<char>> Dxc;
 
-  PDBStringTableBuilder Strings;
+  std::unique_ptr<PDBStringTableBuilder> Strings;
   StringTableHashTraits InjectedSourceHashTraits;
   HashTable<SrcHeaderBlockEntry> InjectedSourceTable;
 
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
index 4ef583a227c0c..8deb065c4ef71 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
@@ -35,6 +35,7 @@ class PDBStringTableBuilder;
 struct StringTableHashTraits {
   PDBStringTableBuilder *Table;
 
+  LLVM_ABI StringTableHashTraits() = default;
   LLVM_ABI explicit StringTableHashTraits(PDBStringTableBuilder &Table);
   LLVM_ABI uint32_t hashLookupKey(StringRef S) const;
   LLVM_ABI StringRef storageKeyToLookupKey(uint32_t Offset) const;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h b/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
index dacd0281ac53b..367b9d0735fe9 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/RawConstants.h
@@ -80,7 +80,10 @@ enum SpecialStream : uint32_t {
   StreamDBI = 3,
   StreamIPI = 4,
 
-  kSpecialStreamCount
+  kSpecialStreamCount = 5,
+  // Fixed index of DXContainer stream, but it's not one of the special
+  // streams and is produced only by DirectX tools.
+  StreamDXContainer = 5
 };
 
 enum class DbgHeaderType : uint16_t {
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
index 0232cae6e3897..2bc2570a5121b 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -398,6 +398,28 @@ Expected<InjectedSourceStream &> PDBFile::getInjectedSourceStream() {
   return *InjectedSources;
 }
 
+llvm::Expected<object::DXContainer &> PDBFile::getDXContainerStream() {
+  if (!Dxc) {
+    auto MBS = safelyCreateIndexedStream(StreamDXContainer);
+    if (!MBS)
+      return MBS.takeError();
+    auto StreamSize = getStreamByteSize(StreamDXContainer);
+    ArrayRef<uint8_t> StreamData;
+    auto Error = MBS->get()->readBytes(0, StreamSize, StreamData);
+    if (Error)
+      return Error;
+
+    StringRef Ref(reinterpret_cast<const char *>(StreamData.data()),
+                  StreamSize);
+    MemoryBufferRef MemBuf(Ref, "DXContainerStream");
+    auto DXC = object::DXContainer::create(MemBuf);
+    if (!DXC)
+      return DXC.takeError();
+    Dxc = std::make_unique<object::DXContainer>(std::move(*DXC));
+  }
+  return *Dxc;
+}
+
 uint32_t PDBFile::getPointerSize() {
   auto DbiS = getPDBDbiStream();
   if (!DbiS)
@@ -451,7 +473,9 @@ bool PDBFile::hasPDBSymbolStream() {
   return DbiS->getSymRecordStreamIndex() < getNumStreams();
 }
 
-bool PDBFile::hasPDBTpiStream() const { return StreamTPI < getNumStreams(); }
+bool PDBFile::hasPDBTpiStream() const {
+  return StreamTPI < getNumStreams() && getStreamByteSize(StreamTPI) != 0;
+}
 
 bool PDBFile::hasPDBStringTable() {
   auto IS = getPDBInfoStream();
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index 77fa9d38822ae..14c5e22115415 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -40,8 +40,7 @@ class WritableBinaryStream;
 }
 
 PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
-    : Allocator(Allocator), InjectedSourceHashTraits(Strings),
-      InjectedSourceTable(2) {}
+    : Allocator(Allocator), InjectedSourceTable(2) {}
 
 PDBFileBuilder::~PDBFileBuilder() = default;
 
@@ -80,7 +79,11 @@ TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
 }
 
 PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
-  return Strings;
+  if (!Strings) {
+    Strings = std::make_unique<PDBStringTableBuilder>();
+    InjectedSourceHashTraits = StringTableHashTraits(*Strings);
+  }
+  return *Strings;
 }
 
 GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() {
@@ -89,6 +92,12 @@ GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() {
   return *Gsi;
 }
 
+std::unique_ptr<SmallVector<char>> &PDBFileBuilder::getDXContainerData() {
+  if (!Dxc)
+    Dxc = std::make_unique<SmallVector<char>>();
+  return Dxc;
+}
+
 Expected<uint32_t> PDBFileBuilder::allocateNamedStream(StringRef Name,
                                                        uint32_t Size) {
   auto ExpectedStream = Msf->addStream(Size);
@@ -140,11 +149,14 @@ Error PDBFileBuilder::finalizeMsfLayout() {
     Info.addFeature(PdbRaw_FeatureSig::VC140);
   }
 
-  uint32_t StringsLen = Strings.calculateSerializedSize();
-
-  Expected<uint32_t> SN = allocateNamedStream("/LinkInfo", 0);
-  if (!SN)
-    return SN.takeError();
+  if (Dxc) {
+    if (auto EC = Msf->setStreamSize(StreamDXContainer, Dxc->size()))
+      return EC;
+  } else {
+    Expected<uint32_t> SN = allocateNamedStream("/LinkInfo", 0);
+    if (!SN)
+      return SN.takeError();
+  }
 
   if (Gsi) {
     if (auto EC = Gsi->finalizeMsfLayout())
@@ -163,10 +175,12 @@ Error PDBFileBuilder::finalizeMsfLayout() {
     if (auto EC = Dbi->finalizeMsfLayout())
       return EC;
   }
-  SN = allocateNamedStream("/names", StringsLen);
-  if (!SN)
-    return SN.takeError();
-
+  if (Strings) {
+    uint32_t StringsLen = Strings->calculateSerializedSize();
+    Expected<uint32_t> SN = allocateNamedStream("/names", StringsLen);
+    if (!SN)
+      return SN.takeError();
+  }
   if (Ipi) {
     if (auto EC = Ipi->finalizeMsfLayout())
       return EC;
@@ -203,7 +217,8 @@ Error PDBFileBuilder::finalizeMsfLayout() {
     uint32_t SrcHeaderBlockSize =
         sizeof(SrcHeaderBlockHeader) +
         InjectedSourceTable.calculateSerializedLength();
-    SN = allocateNamedStream("/src/headerblock", SrcHeaderBlockSize);
+    Expected<uint32_t> SN =
+        allocateNamedStream("/src/headerblock", SrcHeaderBlockSize);
     if (!SN)
       return SN.takeError();
     for (const auto &IS : InjectedSources) {
@@ -282,16 +297,17 @@ Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
     return ExpectedMsfBuffer.takeError();
   FileBufferByteStream Buffer = std::move(*ExpectedMsfBuffer);
 
-  auto ExpectedSN = getNamedStreamIndex("/names");
-  if (!ExpectedSN)
-    return ExpectedSN.takeError();
-
-  auto NS = WritableMappedBlockStream::createIndexedStream(
-      Layout, Buffer, *ExpectedSN, Allocator);
-  BinaryStreamWriter NSWriter(*NS);
-  if (auto EC = Strings.commit(NSWriter))
-    return EC;
+  if (Strings) {
+    auto ExpectedSN = getNamedStreamIndex("/names");
+    if (!ExpectedSN)
+      return ExpectedSN.takeError();
 
+    auto NS = WritableMappedBlockStream::createIndexedStream(
+        Layout, Buffer, *ExpectedSN, Allocator);
+    BinaryStreamWriter NSWriter(*NS);
+    if (auto EC = Strings->commit(NSWriter))
+      return EC;
+  }
   {
     llvm::TimeTraceScope timeScope("Named stream data");
     for (const auto &NSE : NamedStreamData) {
@@ -331,6 +347,17 @@ Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
       return EC;
   }
 
+  if (Dxc) {
+    llvm::TimeTraceScope timeScope("DXContainer stream");
+    auto DxcS = WritableMappedBlockStream::createIndexedStream(
+        Layout, Buffer, StreamDXContainer, Allocator);
+    BinaryStreamWriter Writer(*DxcS);
+    llvm::ArrayRef<uint8_t> DataRef(reinterpret_cast<uint8_t *>(Dxc->data()),
+                                    Dxc->size());
+    if (auto EC = Writer.writeBytes(DataRef))
+      return EC;
+  }
+
   auto InfoStreamBlocks = Layout.StreamMap[StreamPDB];
   assert(!InfoStreamBlocks.empty());
   uint64_t InfoStreamFileOffset =
diff --git a/llvm/test/tools/llvm-pdbutil/dxcontainer.test b/llvm/test/tools/llvm-pdbutil/dxcontainer.test
new file mode 100644
index 0000000000000..0be2637a1707f
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbutil/dxcontainer.test
@@ -0,0 +1,143 @@
+## Check DXContainer support within a PDB file.
+
+# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t.pdb
+# RUN: llvm-pdbutil pdb2yaml --all %t.pdb > %t.yaml
+# RUN: llvm-pdbutil yaml2pdb %t.yaml --pdb=%t.yaml.pdb
+
+## Check that converting YAML to PDB and back results in the same YAML.
+# RUN: FileCheck -input-file=%t.yaml %s
+
+## Check that converting PDB to YAML and back results in the same binary.
+# RUN: diff %t.pdb %t.yaml.pdb
+
+# CHECK: ---
+# CHECK: MSF:
+# CHECK:   SuperBlock:
+# CHECK:     BlockSize:       512
+# CHECK:     FreeBlockMap:    2
+# CHECK:     NumBlocks:       7
+# CHECK:     NumDirectoryBytes: 36
+# CHECK:     Unknown1:        0
+# CHECK:     BlockMapAddr:    3
+# CHECK:   NumDirectoryBlocks: 1
+# CHECK:   DirectoryBlocks: [ 6 ]
+# CHECK:   NumStreams:      6
+# CHECK:   FileSize:        3584
+# CHECK: StreamSizes:     [ 0, 52, 0, 0, 0, 140 ]
+# CHECK: StreamMap:
+# CHECK:   - Stream:          [  ]
+# CHECK:   - Stream:          [ 5 ]
+# CHECK:   - Stream:          [  ]
+# CHECK:   - Stream:          [  ]
+# CHECK:   - Stream:          [  ]
+# CHECK:   - Stream:          [ 4 ]
+# CHECK: PdbStream:
+# CHECK:   Age:             1
+# CHECK:   Guid:            '{15C920AB-F953-7F22-4045-454D275D98D6}'
+# CHECK:   Signature:       0
+# CHECK:   Version:         VC70
+# CHECK: PublicsStream:
+# CHECK:   Records:         []
+# CHECK: DXContainerStream:
+# CHECK:   DXContainer: !dxcontainer
+# CHECK:     Header:
+# CHECK:       Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+# CHECK:                          0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+# CHECK:       Version:
+# CHECK:         Major:           1
+# CHECK:         Minor:           0
+# CHECK:       FileSize:        140
+# CHECK:       PartCount:       3
+# CHECK:       PartOffsets:     [ 52, 76, 104 ]
+# CHECK:     Parts:
+# CHECK:       - Name:            ILDN
+# CHECK:         Size:            16
+# CHECK:         DebugName:
+# CHECK:           Flags:           0
+# CHECK:           NameLength:      10
+# CHECK:           DebugName:       simple.pdb
+# CHECK:       - Name:            HASH
+# CHECK:         Size:            20
+# CHECK:         Hash:
+# CHECK:           IncludesSource:  false
+# CHECK:           Digest:          [ 0xAB, 0x20, 0xC9, 0x15, 0x53, 0xF9, 0x22,
+# CHECK:                              0x7F, 0x40, 0x45, 0x45, 0x4D, 0x27, 0x5D,
+# CHECK:                              0x98, 0xD6 ]
+# CHECK:       - Name:            ILDB
+# CHECK:         Size:            28
+# CHECK:         Program:
+# CHECK:           MajorVersion:    6
+# CHECK:           MinorVersion:    5
+# CHECK:           ShaderKind:      6
+# CHECK:           Size:            8
+# CHECK:           DXILMajorVersion: 1
+# CHECK:           DXILMinorVersion: 5
+# CHECK:           DXILSize:        4
+# CHECK:           DXIL:            [ 0x42, 0x43, 0xC0, 0xDE ]
+# CHECK: ...
+
+---
+MSF:
+  SuperBlock:
+    BlockSize:       512
+    FreeBlockMap:    2
+    NumBlocks:       7
+    NumDirectoryBytes: 36
+    Unknown1:        0
+    BlockMapAddr:    3
+  NumDirectoryBlocks: 1
+  DirectoryBlocks: [ 6 ]
+  NumStreams:      6
+  FileSize:        3584
+StreamSizes:     [ 0, 52, 0, 0, 0, 140 ]
+StreamMap:
+  - Stream:          [  ]
+  - Stream:          [ 5 ]
+  - Stream:          [  ]
+  - Stream:          [  ]
+  - Stream:          [  ]
+  - Stream:          [ 4 ]
+PdbStream:
+  Age:             1
+  Guid:            '{15C920AB-F953-7F22-4045-454D275D98D6}'
+  Signature:       0
+  Version:         VC70
+PublicsStream:
+  Records:         []
+DXContainerStream:
+  DXContainer: !dxcontainer
+    Header:
+      Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                         0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+      Version:
+        Major:           1
+        Minor:           0
+      FileSize:        140
+      PartCount:       3
+      PartOffsets:     [ 52, 76, 104 ]
+    Parts:
+      - Name:            ILDN
+        Size:            16
+        DebugName:
+          Flags:           0
+          NameLength:      10
+          DebugName:       simple.pdb
+      - Name:            HASH
+        Size:            20
+        Hash:
+          IncludesSource:  false
+          Digest:          [ 0xAB, 0x20, 0xC9, 0x15, 0x53, 0xF9, 0x22,
+                             0x7F, 0x40, 0x45, 0x45, 0x4D, 0x27, 0x5D,
+                             0x98, 0xD6 ]
+      - Name:            ILDB
+        Size:            28
+        Program:
+          MajorVersion:    6
+          MinorVersion:    5
+          ShaderKind:      6
+          Size:            8
+          DXILMajorVersion: 1
+          DXILMinorVersion: 5
+          DXILSize:        4
+          DXIL:            [ 0x42, 0x43, 0xC0, 0xDE ]
+...
diff --git a/llvm/tools/llvm-pdbutil/PdbYaml.cpp b/llvm/tools/llvm-pdbutil/PdbYaml.cpp
index 4131292c5c908..c67e7824457dd 100644
--- a/llvm/tools/llvm-pdbutil/PdbYaml.cpp
+++ b/llvm/tools/llvm-pdbutil/PdbYaml.cpp
@@ -112,6 +112,7 @@ void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
   IO.mapOptional("TpiStream", Obj.TpiStream);
   IO.mapOptional("IpiStream", Obj.IpiStream);
   IO.mapOptional("PublicsStream", Obj.PublicsStream);
+  IO.mapOptional("DXContainerStream", Obj.DXContainerStream);
 }
 
 void MappingTraits<MSFHeaders>::mapping(IO &IO, MSFHeaders &Obj) {
@@ -239,3 +240,8 @@ void MappingTraits<PdbDbiModuleInfo>::mapping(IO &IO, PdbDbiModuleInfo &Obj) {
   IO.mapOptional("Subsections", Obj.Subsections);
   IO.mapOptional("Modi", Obj.Modi);
 }
+
+void MappingTraits<PdbDXContainerStream>::mapping(
+    IO &IO, pdb::yaml::PdbDXContainerStream &Obj) {
+  IO.mapRequired("DXContainer", Obj.DXC);
+}
diff --git a/llvm/tools/llvm-pdbutil/PdbYaml.h b/llvm/tools/llvm-pdbutil/PdbYaml.h
index 874667577218d..cd823195268cc 100644
--- a/llvm/tools/llvm-pdbutil/PdbYaml.h
+++ b/llvm/tools/llvm-pdbutil/PdbYaml.h
@@ -22,6 +22,7 @@
 #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
 #include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
+#include "llvm/ObjectYAML/DXContainerYAML.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/YAMLTraits.h"
 
@@ -109,6 +110,10 @@ struct PdbTpiStream {
   std::vector<CodeViewYAML::LeafRecord> Records;
 };
 
+struct PdbDXContainerStream {
+  DXContainerYAML::Object DXC;
+};
+
 struct PdbPublicsStream {
   std::vector<CodeViewYAML::SymbolRecord> PubSyms;
 };
@@ -123,6 +128,7 @@ struct PdbObject {
   std::optional<PdbDbiStream> DbiStream;
   std::optional<PdbTpiStream> TpiStream;
   std::optional<PdbTpiStream> IpiStream;
+  std::optional<PdbDXContainerStream> DXContainerStream;
   std::optional<PdbPublicsStream> PublicsStream;
 
   std::optional<std::vector<StringRef>> StringTable;
@@ -145,5 +151,6 @@ LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::PdbPublicsStream)
 LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::NamedStreamMapping)
 LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::PdbModiStream)
 LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::PdbDbiModuleInfo)
+LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::PdbDXContainerStream)
 
 #endif // LLVM_TOOLS_LLVMPDBDUMP_PDBYAML_H
diff --git a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp
index 8fe7f600d173c..a4065d7a7d5c7 100644
--- a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp
@@ -74,6 +74,9 @@ Error YAMLOutputStyle::dump() {
   if (auto EC = dumpPublics())
     return EC;
 
+  if (auto EC = dumpDXContainer())
+    return EC;
+
   // Fake Coff header for dumping register enumerations.
   COFF::header Header;
   auto MachineType =
@@ -116,6 +119,9 @@ Error YAMLOutputStyle::dumpStringTable() {
   if (!RequiresStringTable && !RequestedStringTable)
     return Error::success();
 
+  if (!File.hasPDBStringTable())
+    return Error::success();
+
   auto ExpectedST = File.getStringTable();
   if (!ExpectedST)
     return ExpectedST.takeError();
@@ -310,6 +316,9 @@ Error YAMLOutputStyle::dumpTpiStream() {
   if (!opts::pdb2yaml::TpiStream)
     return Error::success();
 
+  if (!File.hasPDBTpiStream())
+    return Error::success();
+
   auto TpiS = File.getPDBTpiStream();
   if (!TpiS)
     return TpiS.takeError();
@@ -331,6 +340,9 @@ Error YAMLOutputStyle::dumpIpiStream() {
   if (!opts::pdb2yaml::IpiStream)
     return Error::success();
 
+  if (!File.hasPDBIpiStream())
+    return Error::success();
+
   auto InfoS = File.getPDBInfoStream();
   if (!InfoS)
     return InfoS.takeError();
@@ -391,6 +403,25 @@ Error YAMLOutputStyle::dumpPublics() {
   return Error::success();
 }
 
+Error YAMLOutputStyle::dumpDXContainer() {
+  if (!opts::pdb2yaml::DXContainerStream)
+    return Error::success();
+
+  auto DxcS = File.getDXContainerStream();
+  if (!DxcS) {
+    // Not finding a DXContainer is not an error.
+    consumeError(DxcS.takeError());
+    return Error::success();
+  }
+
+  auto DXCYaml = DXContainerYAML::fromDXContainer(*DxcS);
+  if (!DXCYaml)
+    return DXCYaml.takeError();
+  Obj.DXContainerStream.emplace();
+  Obj.DXContainerStream->DXC = *DXCYaml->get();
+  return Error::success();
+}
+
 void YAMLOutputStyle::flush() {
   Out << Obj;
   outs().flush();
diff --git a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.h b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.h
index 5d53e0b65d03c..49ebcc13a5246 100644
--- a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.h
+++ b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.h
@@ -33,6 +33,7 @@ class YAMLOutputStyle : public OutputStyle {
   Error dumpDbiStream();
   Error dumpTpiStream();
   Error dumpIpiStream();
+  Error dumpDXContainer();
   Error dumpPublics();
 
   void flush();
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index 16ecc59b0db87..b9267fb496c53 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -76,6 +76,7 @@
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/ObjectYAML/yaml2obj.h"
 #include "llvm/Support/BinaryByteStream.h"
 #include "llvm/Support/COM.h"
 #include "llvm/Support/CommandLine.h"
@@ -700,6 +701,10 @@ cl::opt<bool> IpiStream("ipi-stream",
                         cl::desc("Dump the IPI Stream (Stream 5)"),
        ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/201092


More information about the llvm-commits mailing list