[llvm-branch-commits] [llvm] [PDB][llvm-pdbutil] Add DXContainer support for yaml2pdb (PR #198365)
Ilia Kuklin via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 19 06:04:52 PDT 2026
https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/198365
>From cbd7709d009bd3dca262da8a88b5dea845420049 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Mon, 18 May 2026 21:21:04 +0500
Subject: [PATCH 1/3] [PDB][llvm-pdbutil] Add DXContainer support for yaml2pdb
---
.../DebugInfo/PDB/Native/PDBFileBuilder.h | 4 +-
.../DebugInfo/PDB/Native/PDBFileBuilder.cpp | 68 +++++++++++++------
llvm/test/tools/llvm-pdbutil/dxcontainer.test | 2 -
llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp | 45 +++++++++---
4 files changed, 85 insertions(+), 34 deletions(-)
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/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index 77fa9d38822ae..ed6725aa64739 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -40,7 +40,7 @@ class WritableBinaryStream;
}
PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
- : Allocator(Allocator), InjectedSourceHashTraits(Strings),
+ : Allocator(Allocator), InjectedSourceHashTraits(*Strings),
InjectedSourceTable(2) {}
PDBFileBuilder::~PDBFileBuilder() = default;
@@ -80,7 +80,9 @@ TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
}
PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
- return Strings;
+ if (!Strings)
+ Strings = std::make_unique<PDBStringTableBuilder>();
+ return *Strings;
}
GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() {
@@ -89,6 +91,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 +148,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 +174,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 +216,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 +296,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 +346,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
index 721f7261a10f8..0be2637a1707f 100644
--- a/llvm/test/tools/llvm-pdbutil/dxcontainer.test
+++ b/llvm/test/tools/llvm-pdbutil/dxcontainer.test
@@ -1,6 +1,4 @@
## Check DXContainer support within a PDB file.
-## Disable the test until yaml2pdb and pdb2yaml are implemented.
-# UNSUPPORTED: target={{.*}}
# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t.pdb
# RUN: llvm-pdbutil pdb2yaml --all %t.pdb > %t.yaml
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index 3de59b411988a..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"
@@ -817,19 +818,13 @@ static void yamlToPdb(StringRef Path) {
for (uint32_t I = 0; I < kSpecialStreamCount; ++I)
ExitOnErr(Builder.getMsfBuilder().addStream(0));
- StringsAndChecksums Strings;
- Strings.setStrings(std::make_shared<DebugStringTableSubsection>());
-
- if (YamlObj.StringTable) {
- for (auto S : *YamlObj.StringTable)
- Strings.strings()->insert(S);
+ auto &Dxc = YamlObj.DXContainerStream;
+ if (Dxc) {
+ // If there is a DXContainer, add add it as a stream #5.
+ ExitOnErr(Builder.getMsfBuilder().addStream(0));
}
pdb::yaml::PdbInfoStream DefaultInfoStream;
- pdb::yaml::PdbDbiStream DefaultDbiStream;
- pdb::yaml::PdbTpiStream DefaultTpiStream;
- pdb::yaml::PdbTpiStream DefaultIpiStream;
-
const auto &Info = YamlObj.PdbStream.value_or(DefaultInfoStream);
auto &InfoBuilder = Builder.getInfoBuilder();
@@ -840,6 +835,36 @@ static void yamlToPdb(StringRef Path) {
for (auto F : Info.Features)
InfoBuilder.addFeature(F);
+ if (Dxc) {
+ auto &Data = Builder.getDXContainerData();
+ llvm::raw_svector_ostream DataStream(*Data);
+ std::string ErrorMsg;
+ llvm::yaml::yaml2dxcontainer(
+ Dxc->DXC, DataStream, [&ErrorMsg](const Twine &Msg) {
+ ErrorMsg = (Twine("DXContainer error: ") + Msg).str();
+ });
+ if (!ErrorMsg.empty())
+ ExitOnErr(createStringError(ErrorMsg));
+
+ codeview::GUID IgnoredOutGuid;
+ ExitOnErr(
+ Builder.commit(opts::yaml2pdb::YamlPdbOutputFile, &IgnoredOutGuid));
+ // Leave all other streams empty if there is a DXContainer.
+ return;
+ }
+
+ StringsAndChecksums Strings;
+ Strings.setStrings(std::make_shared<DebugStringTableSubsection>());
+
+ if (YamlObj.StringTable) {
+ for (auto S : *YamlObj.StringTable)
+ Strings.strings()->insert(S);
+ }
+
+ pdb::yaml::PdbDbiStream DefaultDbiStream;
+ pdb::yaml::PdbTpiStream DefaultTpiStream;
+ pdb::yaml::PdbTpiStream DefaultIpiStream;
+
const auto &Dbi = YamlObj.DbiStream.value_or(DefaultDbiStream);
auto &DbiBuilder = Builder.getDbiBuilder();
DbiBuilder.setAge(Dbi.Age);
>From 0c18098815ab4ba8c79d3a9ece95ba49f3d2c5dc Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Tue, 19 May 2026 00:10:42 +0500
Subject: [PATCH 2/3] Initialize PDBFileBuilder::Strings
---
llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index ed6725aa64739..9bd23f5def326 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -40,8 +40,8 @@ class WritableBinaryStream;
}
PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
- : Allocator(Allocator), InjectedSourceHashTraits(*Strings),
- InjectedSourceTable(2) {}
+ : Allocator(Allocator), Strings(std::make_unique<PDBStringTableBuilder>()),
+ InjectedSourceHashTraits(*Strings), InjectedSourceTable(2) {}
PDBFileBuilder::~PDBFileBuilder() = default;
>From 4a4155ee4238d9c4856ba351810fce42b6498112 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Tue, 19 May 2026 18:02:45 +0500
Subject: [PATCH 3/3] Initialize InjectedSourceHashTraits along with Strings
---
.../llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h | 1 +
llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
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/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index 9bd23f5def326..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), Strings(std::make_unique<PDBStringTableBuilder>()),
- InjectedSourceHashTraits(*Strings), InjectedSourceTable(2) {}
+ : Allocator(Allocator), InjectedSourceTable(2) {}
PDBFileBuilder::~PDBFileBuilder() = default;
@@ -80,8 +79,10 @@ TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
}
PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
- if (!Strings)
+ if (!Strings) {
Strings = std::make_unique<PDBStringTableBuilder>();
+ InjectedSourceHashTraits = StringTableHashTraits(*Strings);
+ }
return *Strings;
}
More information about the llvm-branch-commits
mailing list