[llvm] [DirectX][ObjectYAML] Add ILDN part support (PR #194508)
Vladislav Dzhidzhoev via llvm-commits
llvm-commits at lists.llvm.org
Sun May 3 14:28:05 PDT 2026
https://github.com/dzhidzhoev updated https://github.com/llvm/llvm-project/pull/194508
>From 02e0e19542a1ffff2d0c5358ef18a540d3339a5d Mon Sep 17 00:00:00 2001
From: Vladislav Dzhidzhoev <vdzhidzhoev at accesssoftek.com>
Date: Wed, 1 Apr 2026 14:31:42 +0200
Subject: [PATCH 1/2] [DirectX][ObjectYAML] Add ILDN part support
Add support for DXContainer ILDN part in the ObjectYAML pipeline
so it can be represented in structured YAML and round-tripped
through yaml2obj/obj2yaml.
ILDN part is meant to store the name of PDB file that contains shader debug info.
---
llvm/include/llvm/BinaryFormat/DXContainer.h | 13 ++++
.../BinaryFormat/DXContainerConstants.def | 1 +
llvm/include/llvm/Object/DXContainer.h | 5 ++
.../include/llvm/ObjectYAML/DXContainerYAML.h | 11 ++++
llvm/lib/Object/DXContainer.cpp | 48 +++++++++++++-
llvm/lib/ObjectYAML/DXContainerEmitter.cpp | 15 +++++
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 8 +++
.../tools/obj2yaml/DXContainer/ILDNPart.yaml | 64 +++++++++++++++++++
llvm/tools/obj2yaml/dxcontainer2yaml.cpp | 10 +++
llvm/unittests/Object/DXContainerTest.cpp | 39 +++++++++++
.../ObjectYAML/DXContainerYAMLTest.cpp | 36 +++++++++++
11 files changed, 248 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/tools/obj2yaml/DXContainer/ILDNPart.yaml
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 1756ab0b555ff..edcaaaf630fdb 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -803,6 +803,19 @@ enum class RootSignatureVersion {
V1_2 = 0x3,
};
+struct DebugNameHeader {
+ uint16_t Flags;
+ /// Debug file name length, without null terminator.
+ uint16_t NameLength;
+
+ void swapBytes() {
+ sys::swapByteOrder(Flags);
+ sys::swapByteOrder(NameLength);
+ }
+};
+
+static_assert(sizeof(DebugNameHeader) == 4, "DebugNameHeader size incorrect.");
+
} // namespace dxbc
} // namespace llvm
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index f576d958037cd..4c5070d18578c 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -1,6 +1,7 @@
#ifdef CONTAINER_PART
CONTAINER_PART(DXIL)
+CONTAINER_PART(ILDN)
CONTAINER_PART(SFI0)
CONTAINER_PART(HASH)
CONTAINER_PART(PSV0)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index c5888b87d6ad7..f2ce39770b097 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -460,6 +460,7 @@ class Signature {
class DXContainer {
public:
using DXILData = std::pair<dxbc::ProgramHeader, const char *>;
+ using ILDNData = std::pair<dxbc::DebugNameHeader, StringRef>;
private:
DXContainer(MemoryBufferRef O);
@@ -475,10 +476,12 @@ class DXContainer {
DirectX::Signature InputSignature;
DirectX::Signature OutputSignature;
DirectX::Signature PatchConstantSignature;
+ std::optional<ILDNData> DebugName;
Error parseHeader();
Error parsePartOffsets();
Error parseDXILHeader(StringRef Part);
+ Error parseDebugName(StringRef Part);
Error parseShaderFeatureFlags(StringRef Part);
Error parseHash(StringRef Part);
Error parseRootSignature(StringRef Part);
@@ -563,6 +566,8 @@ class DXContainer {
const std::optional<DXILData> &getDXIL() const { return DXIL; }
+ const std::optional<ILDNData> getDebugName() const { return DebugName; }
+
std::optional<uint64_t> getShaderFeatureFlags() const {
return ShaderFeatureFlags;
}
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index fbfe3069566d3..bead4292b002f 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -287,6 +287,12 @@ struct Signature {
llvm::SmallVector<SignatureParameter> Parameters;
};
+struct DebugName {
+ uint16_t Flags;
+ uint16_t NameLength;
+ std::string DebugName;
+};
+
struct Part {
Part() = default;
Part(std::string N, uint32_t S) : Name(N), Size(S) {}
@@ -298,6 +304,7 @@ struct Part {
std::optional<PSVInfo> Info;
std::optional<DXContainerYAML::Signature> Signature;
std::optional<DXContainerYAML::RootSignatureYamlDesc> RootSignature;
+ std::optional<DXContainerYAML::DebugName> DebugName;
};
struct Object {
@@ -363,6 +370,10 @@ template <> struct MappingTraits<DXContainerYAML::PSVInfo> {
LLVM_ABI static void mapping(IO &IO, DXContainerYAML::PSVInfo &PSV);
};
+template <> struct MappingTraits<DXContainerYAML::DebugName> {
+ LLVM_ABI static void mapping(IO &IO, DXContainerYAML::DebugName &DebugName);
+};
+
template <> struct MappingTraits<DXContainerYAML::Part> {
LLVM_ABI static void mapping(IO &IO, DXContainerYAML::Part &Version);
};
diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp
index 7b7b8d88c63fc..bb06af6d7c9c3 100644
--- a/llvm/lib/Object/DXContainer.cpp
+++ b/llvm/lib/Object/DXContainer.cpp
@@ -20,10 +20,14 @@ static Error parseFailed(const Twine &Msg) {
return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
}
+static bool readOutOfBounds(StringRef Buffer, const char *Src, size_t Size) {
+ return Src < Buffer.begin() || Src + Size > Buffer.end();
+}
+
template <typename T>
static Error readStruct(StringRef Buffer, const char *Src, T &Struct) {
// Don't read before the beginning or past the end of the file
- if (Src < Buffer.begin() || Src + sizeof(T) > Buffer.end())
+ if (readOutOfBounds(Buffer, Src, sizeof(T)))
return parseFailed("Reading structure out of file bounds");
memcpy(&Struct, Src, sizeof(T));
@@ -39,7 +43,7 @@ static Error readInteger(StringRef Buffer, const char *Src, T &Val,
static_assert(std::is_integral_v<T>,
"Cannot call readInteger on non-integral type.");
// Don't read before the beginning or past the end of the file
- if (Src < Buffer.begin() || Src + sizeof(T) > Buffer.end())
+ if (readOutOfBounds(Buffer, Src, sizeof(T)))
return parseFailed(Twine("Reading ") + Str + " out of file bounds");
// The DXContainer offset table is comprised of uint32_t values but not padded
@@ -55,6 +59,22 @@ static Error readInteger(StringRef Buffer, const char *Src, T &Val,
return Error::success();
}
+static Error readString(StringRef Buffer, const char *&Src, size_t MaxSize,
+ StringRef &Val, Twine Desc) {
+ if (readOutOfBounds(Buffer, Src, MaxSize))
+ return parseFailed(Desc + " is out of file bounds");
+
+ // Ensure that the null-terminator is somewhere within MaxSize bytes.
+ Buffer = Buffer.substr(Src - Buffer.data(), MaxSize);
+ size_t Length = Buffer.find('\0');
+ if (Length == Buffer.npos)
+ return parseFailed(Desc + " does not end with null-terminator");
+
+ Val = StringRef(Buffer.data(), Length);
+ Src += Length + 1;
+ return Error::success();
+}
+
DXContainer::DXContainer(MemoryBufferRef O) : Data(O) {}
Error DXContainer::parseHeader() {
@@ -73,6 +93,26 @@ Error DXContainer::parseDXILHeader(StringRef Part) {
return Error::success();
}
+Error DXContainer::parseDebugName(StringRef Part) {
+ if (DebugName)
+ return parseFailed("More than one ILDN part is present in the file");
+ const char *Current = Part.begin();
+ dxbc::DebugNameHeader Header;
+ if (Error Err = readStruct(Part, Current, Header))
+ return Err;
+ Current += sizeof(Header);
+
+ StringRef Name;
+ if (Error Err = readString(Part, Current, Header.NameLength + 1, Name,
+ "Debug file name"))
+ return Err;
+ if (Name.size() != Header.NameLength)
+ return parseFailed("Debug file name length mismatch");
+ DebugName.emplace(Header, Name.data());
+
+ return Error::success();
+}
+
Error DXContainer::parseShaderFeatureFlags(StringRef Part) {
if (ShaderFeatureFlags)
return parseFailed("More than one SFI0 part is present in the file");
@@ -177,6 +217,10 @@ Error DXContainer::parsePartOffsets() {
if (Error Err = parseDXILHeader(PartData))
return Err;
break;
+ case dxbc::PartType::ILDN:
+ if (Error Err = parseDebugName(PartData))
+ return Err;
+ break;
case dxbc::PartType::SFI0:
if (Error Err = parseShaderFeatureFlags(PartData))
return Err;
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index b00e45d912be1..044ecacddde27 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -172,6 +172,21 @@ Error DXContainerWriter::writeParts(raw_ostream &OS) {
}
break;
}
+ case dxbc::PartType::ILDN: {
+ if (!P.DebugName)
+ continue;
+
+ dxbc::DebugNameHeader Header;
+ Header.Flags = P.DebugName->Flags;
+ Header.NameLength = P.DebugName->NameLength;
+
+ if (sys::IsBigEndianHost)
+ Header.swapBytes();
+ OS.write(reinterpret_cast<const char *>(&Header),
+ sizeof(dxbc::DebugNameHeader));
+ OS.write(P.DebugName->DebugName.c_str(), P.DebugName->NameLength + 1);
+ break;
+ }
case dxbc::PartType::SFI0: {
// If we don't have any flags we can continue here and the data will be
// zeroed out.
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 15f614871f57e..d91d5a83e7b3e 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -531,6 +531,13 @@ void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
+void MappingTraits<DXContainerYAML::DebugName>::mapping(
+ IO &IO, DXContainerYAML::DebugName &DebugName) {
+ IO.mapRequired("Flags", DebugName.Flags);
+ IO.mapRequired("NameLength", DebugName.NameLength);
+ IO.mapRequired("DebugName", DebugName.DebugName);
+}
+
void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
DXContainerYAML::Part &P) {
IO.mapRequired("Name", P.Name);
@@ -541,6 +548,7 @@ void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
IO.mapOptional("PSVInfo", P.Info);
IO.mapOptional("Signature", P.Signature);
IO.mapOptional("RootSignature", P.RootSignature);
+ IO.mapOptional("DebugName", P.DebugName);
}
void MappingTraits<DXContainerYAML::Object>::mapping(
diff --git a/llvm/test/tools/obj2yaml/DXContainer/ILDNPart.yaml b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart.yaml
new file mode 100644
index 0000000000000..02e42417f39d8
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart.yaml
@@ -0,0 +1,64 @@
+# RUN: yaml2obj %s 2>&1 | obj2yaml 2>&1 | FileCheck %s
+
+--- !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: 3600
+ PartCount: 8
+ PartOffsets: [64, 80, 96, 112, 240, 1936, 1964, 2016]
+Parts:
+ - Name: FKE0
+ Size: 8
+ - Name: FKE1
+ Size: 8
+ - Name: FKE2
+ Size: 8
+ - Name: FKE3
+ Size: 120
+ - Name: FKE4
+ Size: 1688
+ - Name: FKE5
+ Size: 20
+ - Name: ILDN
+ Size: 44
+ DebugName:
+ Flags: 0
+ NameLength: 36
+ DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
+ - Name: DXIL
+ Size: 28
+ Program:
+ MajorVersion: 6
+ MinorVersion: 5
+ ShaderKind: 5
+ Size: 7
+ DXILMajorVersion: 1
+ DXILMinorVersion: 5
+ DXILSize: 4
+ DXIL: [ 0x42, 0x43, 0xC0, 0xDE, ]
+...
+
+
+
+
+#CHECK: - Name: ILDN
+#CHECK-NEXT: Size: 44
+#CHECK-NEXT: DebugName:
+#CHECK-NEXT: Flags: 0
+#CHECK-NEXT: NameLength: 36
+#CHECK-NEXT: DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
+#CHECK-NEXT: - Name: DXIL
+#CHECK-NEXT: Size: 28
+#CHECK-NEXT: Program:
+#CHECK-NEXT: MajorVersion: 6
+#CHECK-NEXT: MinorVersion: 5
+#CHECK-NEXT: ShaderKind: 5
+#CHECK-NEXT: Size: 7
+#CHECK-NEXT: DXILMajorVersion: 1
+#CHECK-NEXT: DXILMinorVersion: 5
+#CHECK-NEXT: DXILSize: 4
+#CHECK-NEXT: DXIL: [ 0x42, 0x43, 0xC0, 0xDE
diff --git a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp
index c727595406767..584c75b4478c4 100644
--- a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp
+++ b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "obj2yaml.h"
+#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/DXContainer.h"
#include "llvm/ObjectYAML/DXContainerYAML.h"
#include "llvm/Support/Error.h"
@@ -70,6 +71,15 @@ dumpDXContainer(MemoryBufferRef Source) {
DXIL->second, DXIL->second + DXIL->first.Bitcode.Size)};
break;
}
+ case dxbc::PartType::ILDN: {
+ std::optional<DXContainer::ILDNData> DebugName = Container.getDebugName();
+ assert(DebugName && "Since we are iterating and found a ILDN part, this "
+ "should never not have a value");
+ NewPart.DebugName = DXContainerYAML::DebugName{
+ DebugName->first.Flags, DebugName->first.NameLength,
+ DebugName->second.str()};
+ break;
+ }
case dxbc::PartType::SFI0: {
std::optional<uint64_t> Flags = Container.getShaderFeatureFlags();
// Omit the flags in the YAML if they are missing or zero.
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index d6f7b26b99cd7..72a995117fdc9 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -220,6 +220,45 @@ TEST(DXCFile, ParseDXILPart) {
EXPECT_EQ(Header.Bitcode.MinorVersion, 5u);
}
+// This test verifies that ILDN part is correctly parsed.
+// This test is based on the binary output constructed from this yaml.
+// --- !dxcontainer
+// Header:
+// Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+// 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+// Version:
+// Major: 1
+// Minor: 0
+// PartCount: 1
+// Parts:
+// - Name: ILDN
+// Size: 44
+// DebugName:
+// Flags: 0
+// NameLength: 36
+// DebugName: 49405c8bb27f1f8733cbf9f29b1d100c.pdb
+// ...
+TEST(DXCFile, ParseILDNPart) {
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x49, 0x4c, 0x44, 0x4e, 0x2c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x00, 0x34, 0x39, 0x34, 0x30, 0x35, 0x63, 0x38,
+ 0x62, 0x62, 0x32, 0x37, 0x66, 0x31, 0x66, 0x38, 0x37, 0x33, 0x33,
+ 0x63, 0x62, 0x66, 0x39, 0x66, 0x32, 0x39, 0x62, 0x31, 0x64, 0x31,
+ 0x30, 0x30, 0x63, 0x2E, 0x70, 0x64, 0x62, 0x00, 0x00, 0x00, 0x00};
+ DXContainer C =
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<116>(Buffer)));
+ EXPECT_EQ(C.getHeader().PartCount, 1u);
+ const std::optional<object::DXContainer::ILDNData> &ILDN = C.getDebugName();
+ EXPECT_TRUE(ILDN.has_value());
+ dxbc::DebugNameHeader Header = ILDN->first;
+ EXPECT_EQ(Header.Flags, 0u);
+ EXPECT_EQ(Header.NameLength, 36u);
+ EXPECT_EQ(ILDN->second, "49405c8bb27f1f8733cbf9f29b1d100c.pdb");
+}
+
static Expected<DXContainer>
generateDXContainer(StringRef Yaml, SmallVectorImpl<char> &BinaryData) {
DXContainerYAML::Object Obj;
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index 1b21fe01dfca9..a690992ab49ca 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -577,3 +577,39 @@ TEST(RootSignature, ParseStaticSamplersV13) {
EXPECT_EQ(Storage.size(), 148U);
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 148U) == 0);
}
+
+TEST(DXCFile, ParseILDNPart) {
+ SmallString<128> Storage;
+
+ // First read a fully explicit yaml with all sizes and offsets provided
+ ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
+ Header:
+ Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+ Version:
+ Major: 1
+ Minor: 0
+ PartCount: 1
+ PartOffsets: [ 36 ]
+ Parts:
+ - Name: ILDN
+ Size: 44
+ DebugName:
+ Flags: 0
+ NameLength: 36
+ DebugName: 49405c8bb27f1f8733cbf9f29b1d100c.pdb
+ )"));
+
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24,
+ 0x00, 0x00, 0x00, 0x49, 0x4c, 0x44, 0x4e, 0x2c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x00, 0x34, 0x39, 0x34, 0x30, 0x35, 0x63, 0x38,
+ 0x62, 0x62, 0x32, 0x37, 0x66, 0x31, 0x66, 0x38, 0x37, 0x33, 0x33,
+ 0x63, 0x62, 0x66, 0x39, 0x66, 0x32, 0x39, 0x62, 0x31, 0x64, 0x31,
+ 0x30, 0x30, 0x63, 0x2E, 0x70, 0x64, 0x62, 0x00, 0x00, 0x00, 0x00};
+
+ EXPECT_EQ(Storage.size(), 88u);
+ EXPECT_TRUE(memcmp(Buffer, Storage.data(), 88u) == 0);
+}
>From 14d66ef4df006fc672ee76e3a76d6a26ceebbb52 Mon Sep 17 00:00:00 2001
From: Vladislav Dzhidzhoev <vdzhidzhoev at accesssoftek.com>
Date: Sun, 3 May 2026 01:00:41 +0200
Subject: [PATCH 2/2] Make ILDN fields optional, move ILDN writer to MC
---
llvm/include/llvm/MC/DXContainerInfo.h | 32 +++++++++++++++
.../include/llvm/ObjectYAML/DXContainerYAML.h | 4 +-
llvm/lib/MC/CMakeLists.txt | 1 +
llvm/lib/MC/DXContainerInfo.cpp | 41 +++++++++++++++++++
llvm/lib/ObjectYAML/DXContainerEmitter.cpp | 19 +++++----
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 4 +-
.../DXContainer/ILDNPart-compute-flags.yaml | 26 ++++++++++++
.../DXContainer/ILDNPart-compute-length.yaml | 26 ++++++++++++
.../DXContainer/ILDNPart-compute.yaml | 25 +++++++++++
9 files changed, 165 insertions(+), 13 deletions(-)
create mode 100644 llvm/include/llvm/MC/DXContainerInfo.h
create mode 100644 llvm/lib/MC/DXContainerInfo.cpp
create mode 100644 llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-flags.yaml
create mode 100644 llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-length.yaml
create mode 100644 llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute.yaml
diff --git a/llvm/include/llvm/MC/DXContainerInfo.h b/llvm/include/llvm/MC/DXContainerInfo.h
new file mode 100644
index 0000000000000..78d4b4da45558
--- /dev/null
+++ b/llvm/include/llvm/MC/DXContainerInfo.h
@@ -0,0 +1,32 @@
+//===----- llvm/MC/DXContainerInfo.h - DXContainer Info ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_DXCONTAINERINFO_H
+#define LLVM_MC_DXCONTAINERINFO_H
+
+#include "llvm/Object/DXContainer.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+namespace mcdxbc {
+
+struct DebugName {
+ object::DXContainer::ILDNData BaseData;
+
+ DebugName() { BaseData.first.Flags = 0; }
+
+ void setFileName(StringRef FileName);
+ void write(raw_ostream &OS) const;
+};
+
+} // namespace mcdxbc
+} // namespace llvm
+
+#endif // LLVM_MC_DXCONTAINERINFO_H
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index bead4292b002f..036890248a989 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -288,8 +288,8 @@ struct Signature {
};
struct DebugName {
- uint16_t Flags;
- uint16_t NameLength;
+ std::optional<uint16_t> Flags;
+ std::optional<uint16_t> NameLength;
std::string DebugName;
};
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 7a9e26af415c6..b85cbaa08a653 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -1,5 +1,6 @@
add_llvm_component_library(LLVMMC
ConstantPools.cpp
+ DXContainerInfo.cpp
DXContainerPSVInfo.cpp
DXContainerRootSignature.cpp
ELFObjectWriter.cpp
diff --git a/llvm/lib/MC/DXContainerInfo.cpp b/llvm/lib/MC/DXContainerInfo.cpp
new file mode 100644
index 0000000000000..d96dfd65cbd15
--- /dev/null
+++ b/llvm/lib/MC/DXContainerInfo.cpp
@@ -0,0 +1,41 @@
+//===- llvm/MC/DXContainerInfo.cpp - DXContainer Info -----*- C++ -------*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/DXContainerInfo.h"
+#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Object/DXContainer.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include <type_traits>
+
+using namespace llvm;
+using namespace llvm::mcdxbc;
+
+template <typename StructT>
+static void writeStruct(raw_ostream &OS, StructT S) {
+ static_assert(std::is_class<StructT>() &&
+ "This method must be used for writing structure types.");
+ if (sys::IsBigEndianHost)
+ S.swapBytes();
+ OS.write(reinterpret_cast<const char *>(&S), sizeof(StructT));
+}
+
+static void writeString(raw_ostream &OS, StringRef S) {
+ OS.write(S.data(), S.size());
+ // Write null terminator.
+ OS.write_zeros(1);
+}
+
+void DebugName::setFileName(StringRef DebugFileName) {
+ BaseData.first.NameLength = DebugFileName.size();
+ BaseData.second = DebugFileName;
+}
+
+void DebugName::write(raw_ostream &OS) const {
+ writeStruct(OS, BaseData.first);
+ writeString(OS, BaseData.second.substr(0, BaseData.first.NameLength));
+}
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index 044ecacddde27..e141c1db521e3 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/MC/DXContainerInfo.h"
#include "llvm/MC/DXContainerPSVInfo.h"
#include "llvm/MC/DXContainerRootSignature.h"
#include "llvm/ObjectYAML/ObjectYAML.h"
@@ -176,15 +177,15 @@ Error DXContainerWriter::writeParts(raw_ostream &OS) {
if (!P.DebugName)
continue;
- dxbc::DebugNameHeader Header;
- Header.Flags = P.DebugName->Flags;
- Header.NameLength = P.DebugName->NameLength;
-
- if (sys::IsBigEndianHost)
- Header.swapBytes();
- OS.write(reinterpret_cast<const char *>(&Header),
- sizeof(dxbc::DebugNameHeader));
- OS.write(P.DebugName->DebugName.c_str(), P.DebugName->NameLength + 1);
+ mcdxbc::DebugName DebugName;
+ DebugName.setFileName(P.DebugName->DebugName);
+ // Override default flags with value from YAML.
+ if (P.DebugName->Flags)
+ DebugName.BaseData.first.Flags = *P.DebugName->Flags;
+ // Override computed filename length with value from YAML.
+ if (P.DebugName->NameLength)
+ DebugName.BaseData.first.NameLength = *P.DebugName->NameLength;
+ DebugName.write(OS);
break;
}
case dxbc::PartType::SFI0: {
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index d91d5a83e7b3e..497ae6b152dd9 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -533,8 +533,8 @@ void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
void MappingTraits<DXContainerYAML::DebugName>::mapping(
IO &IO, DXContainerYAML::DebugName &DebugName) {
- IO.mapRequired("Flags", DebugName.Flags);
- IO.mapRequired("NameLength", DebugName.NameLength);
+ IO.mapOptional("Flags", DebugName.Flags);
+ IO.mapOptional("NameLength", DebugName.NameLength);
IO.mapRequired("DebugName", DebugName.DebugName);
}
diff --git a/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-flags.yaml b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-flags.yaml
new file mode 100644
index 0000000000000..ea92645b28436
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-flags.yaml
@@ -0,0 +1,26 @@
+# RUN: yaml2obj %s 2>&1 | obj2yaml 2>&1 | FileCheck %s
+
+--- !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: 88
+ PartCount: 1
+ PartOffsets: [36]
+Parts:
+ - Name: ILDN
+ Size: 44
+ DebugName:
+ NameLength: 36
+ DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
+...
+
+#CHECK: - Name: ILDN
+#CHECK-NEXT: Size: 44
+#CHECK-NEXT: DebugName:
+#CHECK-NEXT: Flags: 0
+#CHECK-NEXT: NameLength: 36
+#CHECK-NEXT: DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
diff --git a/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-length.yaml b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-length.yaml
new file mode 100644
index 0000000000000..128135ed91188
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute-length.yaml
@@ -0,0 +1,26 @@
+# RUN: yaml2obj %s 2>&1 | obj2yaml 2>&1 | FileCheck %s
+
+--- !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: 88
+ PartCount: 1
+ PartOffsets: [36]
+Parts:
+ - Name: ILDN
+ Size: 44
+ DebugName:
+ Flags: 0
+ DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
+...
+
+#CHECK: - Name: ILDN
+#CHECK-NEXT: Size: 44
+#CHECK-NEXT: DebugName:
+#CHECK-NEXT: Flags: 0
+#CHECK-NEXT: NameLength: 36
+#CHECK-NEXT: DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
diff --git a/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute.yaml b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute.yaml
new file mode 100644
index 0000000000000..f6f47f1809c97
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/DXContainer/ILDNPart-compute.yaml
@@ -0,0 +1,25 @@
+# RUN: yaml2obj %s 2>&1 | obj2yaml 2>&1 | FileCheck %s
+
+--- !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: 88
+ PartCount: 1
+ PartOffsets: [36]
+Parts:
+ - Name: ILDN
+ Size: 44
+ DebugName:
+ DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
+...
+
+#CHECK: - Name: ILDN
+#CHECK-NEXT: Size: 44
+#CHECK-NEXT: DebugName:
+#CHECK-NEXT: Flags: 0
+#CHECK-NEXT: NameLength: 36
+#CHECK-NEXT: DebugName: 0b40fc8650d90fa2e9fd5cadc8eaaace.pdb
More information about the llvm-commits
mailing list