xref: /llvm-project/llvm/unittests/Object/DXContainerTest.cpp (revision fd0dbc7f4d8a5900535aa87569fbc385b7c50ba6)
14070aa01SChris Bieneman //===- DXContainerTest.cpp - Tests for DXContainerFile --------------------===//
24070aa01SChris Bieneman //
34070aa01SChris Bieneman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44070aa01SChris Bieneman // See https://llvm.org/LICENSE.txt for license information.
54070aa01SChris Bieneman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64070aa01SChris Bieneman //
74070aa01SChris Bieneman //===----------------------------------------------------------------------===//
84070aa01SChris Bieneman 
94070aa01SChris Bieneman #include "llvm/Object/DXContainer.h"
104070aa01SChris Bieneman #include "llvm/ADT/StringRef.h"
114070aa01SChris Bieneman #include "llvm/BinaryFormat/Magic.h"
12dd3f7b02SChris Bieneman #include "llvm/ObjectYAML/DXContainerYAML.h"
13dd3f7b02SChris Bieneman #include "llvm/ObjectYAML/yaml2obj.h"
144070aa01SChris Bieneman #include "llvm/Support/MemoryBufferRef.h"
154070aa01SChris Bieneman #include "llvm/Testing/Support/Error.h"
164070aa01SChris Bieneman #include "gtest/gtest.h"
174070aa01SChris Bieneman 
184070aa01SChris Bieneman using namespace llvm;
194070aa01SChris Bieneman using namespace llvm::object;
204070aa01SChris Bieneman 
214070aa01SChris Bieneman template <std::size_t X> MemoryBufferRef getMemoryBuffer(uint8_t Data[X]) {
224070aa01SChris Bieneman   StringRef Obj(reinterpret_cast<char *>(&Data[0]), X);
234070aa01SChris Bieneman   return MemoryBufferRef(Obj, "");
244070aa01SChris Bieneman }
254070aa01SChris Bieneman 
26966c40aeSChris Bieneman TEST(DXCFile, IdentifyMagic) {
2715d20b97SChris Bieneman   {
28966c40aeSChris Bieneman     StringRef Buffer("DXBC");
29966c40aeSChris Bieneman     EXPECT_EQ(identify_magic(Buffer), file_magic::dxcontainer_object);
30966c40aeSChris Bieneman   }
3115d20b97SChris Bieneman   {
3215d20b97SChris Bieneman     StringRef Buffer("DXBCBlahBlahBlah");
3315d20b97SChris Bieneman     EXPECT_EQ(identify_magic(Buffer), file_magic::dxcontainer_object);
3415d20b97SChris Bieneman   }
3515d20b97SChris Bieneman }
36966c40aeSChris Bieneman 
374070aa01SChris Bieneman TEST(DXCFile, ParseHeaderErrors) {
384070aa01SChris Bieneman   uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43};
394070aa01SChris Bieneman   EXPECT_THAT_EXPECTED(
404070aa01SChris Bieneman       DXContainer::create(getMemoryBuffer<4>(Buffer)),
414070aa01SChris Bieneman       FailedWithMessage("Reading structure out of file bounds"));
424070aa01SChris Bieneman }
434070aa01SChris Bieneman 
449e3919daSChris Bieneman TEST(DXCFile, EmptyFile) {
459e3919daSChris Bieneman   EXPECT_THAT_EXPECTED(
469e3919daSChris Bieneman       DXContainer::create(MemoryBufferRef(StringRef("", 0), "")),
479e3919daSChris Bieneman       FailedWithMessage("Reading structure out of file bounds"));
489e3919daSChris Bieneman }
499e3919daSChris Bieneman 
504070aa01SChris Bieneman TEST(DXCFile, ParseHeader) {
514070aa01SChris Bieneman   uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
524070aa01SChris Bieneman                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534070aa01SChris Bieneman                       0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
549e3919daSChris Bieneman                       0x70, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
554070aa01SChris Bieneman   DXContainer C =
564070aa01SChris Bieneman       llvm::cantFail(DXContainer::create(getMemoryBuffer<32>(Buffer)));
574070aa01SChris Bieneman   EXPECT_TRUE(memcmp(C.getHeader().Magic, "DXBC", 4) == 0);
5855e13a6bSChris Bieneman   EXPECT_TRUE(memcmp(C.getHeader().FileHash.Digest,
594070aa01SChris Bieneman                      "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0);
604070aa01SChris Bieneman   EXPECT_EQ(C.getHeader().Version.Major, 1u);
614070aa01SChris Bieneman   EXPECT_EQ(C.getHeader().Version.Minor, 0u);
624070aa01SChris Bieneman }
639e3919daSChris Bieneman 
649e3919daSChris Bieneman TEST(DXCFile, ParsePartMissingOffsets) {
659e3919daSChris Bieneman   uint8_t Buffer[] = {
669e3919daSChris Bieneman       0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679e3919daSChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
689e3919daSChris Bieneman       0x00, 0x00, 0x70, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
699e3919daSChris Bieneman   };
709e3919daSChris Bieneman   EXPECT_THAT_EXPECTED(
719e3919daSChris Bieneman       DXContainer::create(getMemoryBuffer<32>(Buffer)),
729e3919daSChris Bieneman       FailedWithMessage("Reading structure out of file bounds"));
739e3919daSChris Bieneman }
749e3919daSChris Bieneman 
759e3919daSChris Bieneman TEST(DXCFile, ParsePartInvalidOffsets) {
76621ffbcbSChris Bieneman   // This test covers a case where the part offset is beyond the buffer size.
779e3919daSChris Bieneman   uint8_t Buffer[] = {
789e3919daSChris Bieneman       0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799e3919daSChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
809e3919daSChris Bieneman       0x70, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
819e3919daSChris Bieneman   };
829e3919daSChris Bieneman   EXPECT_THAT_EXPECTED(
839e3919daSChris Bieneman       DXContainer::create(getMemoryBuffer<36>(Buffer)),
849e3919daSChris Bieneman       FailedWithMessage("Part offset points beyond boundary of the file"));
859e3919daSChris Bieneman }
869e3919daSChris Bieneman 
87621ffbcbSChris Bieneman TEST(DXCFile, ParsePartTooSmallBuffer) {
88621ffbcbSChris Bieneman   // This test covers a case where there is insufficent space to read a full
89621ffbcbSChris Bieneman   // part name, but the offset for the part is inside the buffer.
90621ffbcbSChris Bieneman   uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
91621ffbcbSChris Bieneman                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92621ffbcbSChris Bieneman                       0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
93621ffbcbSChris Bieneman                       0x26, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
94621ffbcbSChris Bieneman                       0x24, 0x00, 0x00, 0x00, 0x46, 0x4B};
95621ffbcbSChris Bieneman   EXPECT_THAT_EXPECTED(
96621ffbcbSChris Bieneman       DXContainer::create(getMemoryBuffer<38>(Buffer)),
97621ffbcbSChris Bieneman       FailedWithMessage("File not large enough to read part name"));
98621ffbcbSChris Bieneman }
99621ffbcbSChris Bieneman 
100621ffbcbSChris Bieneman TEST(DXCFile, ParsePartNoSize) {
101621ffbcbSChris Bieneman   // This test covers a case where the part's header is readable, but the size
102621ffbcbSChris Bieneman   // the part extends beyond the boundaries of the file.
103621ffbcbSChris Bieneman   uint8_t Buffer[] = {0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00,
104621ffbcbSChris Bieneman                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105621ffbcbSChris Bieneman                       0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x0D, 0x00,
106621ffbcbSChris Bieneman                       0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
107621ffbcbSChris Bieneman                       0x46, 0x4B, 0x45, 0x30, 0x00, 0x00};
108621ffbcbSChris Bieneman   EXPECT_THAT_EXPECTED(
109621ffbcbSChris Bieneman       DXContainer::create(getMemoryBuffer<42>(Buffer)),
110621ffbcbSChris Bieneman       FailedWithMessage("Reading part size out of file bounds"));
111621ffbcbSChris Bieneman }
112621ffbcbSChris Bieneman 
113621ffbcbSChris Bieneman TEST(DXCFile, ParseOverlappingParts) {
114621ffbcbSChris Bieneman   // This test covers a case where a part's offset is inside the size range
115621ffbcbSChris Bieneman   // covered by the previous part.
116621ffbcbSChris Bieneman   uint8_t Buffer[] = {
117621ffbcbSChris Bieneman       0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118621ffbcbSChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
119621ffbcbSChris Bieneman       0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
120621ffbcbSChris Bieneman       0x2C, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x30, 0x08, 0x00, 0x00, 0x00,
121621ffbcbSChris Bieneman       0x46, 0x4B, 0x45, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122621ffbcbSChris Bieneman   };
123621ffbcbSChris Bieneman   EXPECT_THAT_EXPECTED(
124621ffbcbSChris Bieneman       DXContainer::create(getMemoryBuffer<60>(Buffer)),
125621ffbcbSChris Bieneman       FailedWithMessage(
126621ffbcbSChris Bieneman           "Part offset for part 1 begins before the previous part ends"));
127621ffbcbSChris Bieneman }
128621ffbcbSChris Bieneman 
1299e3919daSChris Bieneman TEST(DXCFile, ParseEmptyParts) {
1309e3919daSChris Bieneman   uint8_t Buffer[] = {
1319e3919daSChris Bieneman       0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329e3919daSChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1339e3919daSChris Bieneman       0x70, 0x0D, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
1349e3919daSChris Bieneman       0x44, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
1359e3919daSChris Bieneman       0x5C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
13676fca147SChris Bieneman       0x46, 0x4B, 0x45, 0x30, 0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x31,
13776fca147SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x32, 0x00, 0x00, 0x00, 0x00,
13876fca147SChris Bieneman       0x46, 0x4B, 0x45, 0x33, 0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x34,
13976fca147SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x46, 0x4B, 0x45, 0x35, 0x00, 0x00, 0x00, 0x00,
14076fca147SChris Bieneman       0x46, 0x4B, 0x45, 0x36, 0x00, 0x00, 0x00, 0x00,
1419e3919daSChris Bieneman   };
1429e3919daSChris Bieneman   DXContainer C =
1439e3919daSChris Bieneman       llvm::cantFail(DXContainer::create(getMemoryBuffer<116>(Buffer)));
1449e3919daSChris Bieneman   EXPECT_EQ(C.getHeader().PartCount, 7u);
1459e3919daSChris Bieneman 
1469e3919daSChris Bieneman   // All the part sizes are 0, which makes a nice test of the range based for
1479e3919daSChris Bieneman   int ElementsVisited = 0;
1489e3919daSChris Bieneman   for (auto Part : C) {
1499e3919daSChris Bieneman     EXPECT_EQ(Part.Part.Size, 0u);
1509e3919daSChris Bieneman     EXPECT_EQ(Part.Data.size(), 0u);
1519e3919daSChris Bieneman     ++ElementsVisited;
1529e3919daSChris Bieneman   }
1539e3919daSChris Bieneman   EXPECT_EQ(ElementsVisited, 7);
1549e3919daSChris Bieneman 
1559e3919daSChris Bieneman   {
15676fca147SChris Bieneman     // These are all intended to be fake part names so that the parser doesn't
15776fca147SChris Bieneman     // try to parse the part data.
1589e3919daSChris Bieneman     auto It = C.begin();
15976fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE0", 4) == 0);
1609e3919daSChris Bieneman     ++It;
16176fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE1", 4) == 0);
1629e3919daSChris Bieneman     ++It;
16376fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE2", 4) == 0);
1649e3919daSChris Bieneman     ++It;
16576fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE3", 4) == 0);
1669e3919daSChris Bieneman     ++It;
16776fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE4", 4) == 0);
1689e3919daSChris Bieneman     ++It;
16976fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE5", 4) == 0);
1709e3919daSChris Bieneman     ++It;
17176fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE6", 4) == 0);
1729e3919daSChris Bieneman     ++It; // Don't increment past the end
17376fca147SChris Bieneman     EXPECT_TRUE(memcmp(It->Part.Name, "FKE6", 4) == 0);
1749e3919daSChris Bieneman   }
1759e3919daSChris Bieneman }
176dd3f7b02SChris Bieneman 
177f42117c8SXiang Li // This test verify DXIL part are correctly parsed.
178f42117c8SXiang Li // This test is based on the binary output constructed from this yaml.
179f42117c8SXiang Li // --- !dxcontainer
180f42117c8SXiang Li // Header:
181f42117c8SXiang Li //   Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
182f42117c8SXiang Li //                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
183f42117c8SXiang Li //   Version:
184f42117c8SXiang Li //     Major:           1
185f42117c8SXiang Li //     Minor:           0
186f42117c8SXiang Li //   PartCount:       1
187f42117c8SXiang Li // Parts:
188f42117c8SXiang Li //   - Name:            DXIL
189f42117c8SXiang Li //     Size:            28
190f42117c8SXiang Li //     Program:
191f42117c8SXiang Li //       MajorVersion:    6
192f42117c8SXiang Li //       MinorVersion:    5
193f42117c8SXiang Li //       ShaderKind:      5
194f42117c8SXiang Li //       Size:            8
195f42117c8SXiang Li //       DXILMajorVersion: 1
196f42117c8SXiang Li //       DXILMinorVersion: 5
197f42117c8SXiang Li //       DXILSize:        4
198f42117c8SXiang Li //       DXIL:            [ 0x42, 0x43, 0xC0, 0xDE, ]
199f42117c8SXiang Li // ...
200f42117c8SXiang Li TEST(DXCFile, ParseDXILPart) {
201f42117c8SXiang Li   uint8_t Buffer[] = {
202f42117c8SXiang Li       0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203f42117c8SXiang Li       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
204f42117c8SXiang Li       0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
205f42117c8SXiang Li       0x44, 0x58, 0x49, 0x4c, 0x1c, 0x00, 0x00, 0x00, 0x65, 0x00, 0x05, 0x00,
206f42117c8SXiang Li       0x08, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x05, 0x01, 0x00, 0x00,
207f42117c8SXiang Li       0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde};
208f42117c8SXiang Li   DXContainer C =
209f42117c8SXiang Li       llvm::cantFail(DXContainer::create(getMemoryBuffer<116>(Buffer)));
210f42117c8SXiang Li   EXPECT_EQ(C.getHeader().PartCount, 1u);
211f42117c8SXiang Li   const std::optional<object::DXContainer::DXILData> &DXIL = C.getDXIL();
212f42117c8SXiang Li   EXPECT_TRUE(DXIL.has_value());
213f42117c8SXiang Li   dxbc::ProgramHeader Header = DXIL->first;
214f42117c8SXiang Li   EXPECT_EQ(Header.getMajorVersion(), 6u);
215f42117c8SXiang Li   EXPECT_EQ(Header.getMinorVersion(), 5u);
216f42117c8SXiang Li   EXPECT_EQ(Header.ShaderKind, 5u);
217f42117c8SXiang Li   EXPECT_EQ(Header.Size, 8u);
218531a0b67SXiang Li   EXPECT_EQ(Header.Bitcode.MajorVersion, 1u);
219531a0b67SXiang Li   EXPECT_EQ(Header.Bitcode.MinorVersion, 5u);
220f42117c8SXiang Li }
221f42117c8SXiang Li 
222dd3f7b02SChris Bieneman static Expected<DXContainer>
223dd3f7b02SChris Bieneman generateDXContainer(StringRef Yaml, SmallVectorImpl<char> &BinaryData) {
224dd3f7b02SChris Bieneman   DXContainerYAML::Object Obj;
225dd3f7b02SChris Bieneman   SMDiagnostic GenerateDiag;
226dd3f7b02SChris Bieneman   yaml::Input YIn(
227dd3f7b02SChris Bieneman       Yaml, /*Ctxt=*/nullptr,
228dd3f7b02SChris Bieneman       [](const SMDiagnostic &Diag, void *DiagContext) {
229dd3f7b02SChris Bieneman         *static_cast<SMDiagnostic *>(DiagContext) = Diag;
230dd3f7b02SChris Bieneman       },
231dd3f7b02SChris Bieneman       &GenerateDiag);
232dd3f7b02SChris Bieneman 
233dd3f7b02SChris Bieneman   YIn >> Obj;
234dd3f7b02SChris Bieneman   if (YIn.error())
235dd3f7b02SChris Bieneman     return createStringError(YIn.error(), GenerateDiag.getMessage());
236dd3f7b02SChris Bieneman 
237dd3f7b02SChris Bieneman   raw_svector_ostream OS(BinaryData);
238dd3f7b02SChris Bieneman   std::string ErrorMsg;
239dd3f7b02SChris Bieneman   if (!yaml::yaml2dxcontainer(
240dd3f7b02SChris Bieneman           Obj, OS, [&ErrorMsg](const Twine &Msg) { ErrorMsg = Msg.str(); }))
241dd3f7b02SChris Bieneman     return createStringError(YIn.error(), ErrorMsg);
242dd3f7b02SChris Bieneman 
243dd3f7b02SChris Bieneman   MemoryBufferRef BinaryDataRef = MemoryBufferRef(OS.str(), "");
244dd3f7b02SChris Bieneman 
245dd3f7b02SChris Bieneman   return DXContainer::create(BinaryDataRef);
246dd3f7b02SChris Bieneman }
247dd3f7b02SChris Bieneman 
248dd3f7b02SChris Bieneman TEST(DXCFile, PSVResourceIterators) {
249dd3f7b02SChris Bieneman   const char *Yaml = R"(
250dd3f7b02SChris Bieneman --- !dxcontainer
251dd3f7b02SChris Bieneman Header:
252dd3f7b02SChris Bieneman   Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
253dd3f7b02SChris Bieneman                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
254dd3f7b02SChris Bieneman   Version:
255dd3f7b02SChris Bieneman     Major:           1
256dd3f7b02SChris Bieneman     Minor:           0
257dd3f7b02SChris Bieneman   PartCount:       2
258dd3f7b02SChris Bieneman Parts:
259dd3f7b02SChris Bieneman   - Name:            PSV0
260dd3f7b02SChris Bieneman     Size:            144
261dd3f7b02SChris Bieneman     PSVInfo:
262dd3f7b02SChris Bieneman       Version:         0
263dd3f7b02SChris Bieneman       ShaderStage:     14
264dd3f7b02SChris Bieneman       PayloadSizeInBytes: 4092
265dd3f7b02SChris Bieneman       MinimumWaveLaneCount: 0
266dd3f7b02SChris Bieneman       MaximumWaveLaneCount: 4294967295
2675fdf8605SChris Bieneman       ResourceStride:  16
268dd3f7b02SChris Bieneman       Resources:
269*fd0dbc7fSXiang Li         - Type:            Sampler
270dd3f7b02SChris Bieneman           Space:           1
271dd3f7b02SChris Bieneman           LowerBound:      1
272dd3f7b02SChris Bieneman           UpperBound:      1
273*fd0dbc7fSXiang Li         - Type:            CBV
274dd3f7b02SChris Bieneman           Space:           2
275dd3f7b02SChris Bieneman           LowerBound:      2
276dd3f7b02SChris Bieneman           UpperBound:      2
277*fd0dbc7fSXiang Li         - Type:            SRVTyped
278dd3f7b02SChris Bieneman           Space:           3
279dd3f7b02SChris Bieneman           LowerBound:      3
280dd3f7b02SChris Bieneman           UpperBound:      3
281dd3f7b02SChris Bieneman   - Name:            DXIL
282dd3f7b02SChris Bieneman     Size:            24
283dd3f7b02SChris Bieneman     Program:
284dd3f7b02SChris Bieneman       MajorVersion:    6
285dd3f7b02SChris Bieneman       MinorVersion:    0
286dd3f7b02SChris Bieneman       ShaderKind:      14
287dd3f7b02SChris Bieneman       Size:            6
288531a0b67SXiang Li       DXILMajorVersion: 1
289531a0b67SXiang Li       DXILMinorVersion: 0
290dd3f7b02SChris Bieneman       DXILSize:        0
291dd3f7b02SChris Bieneman ...
292dd3f7b02SChris Bieneman )";
293dd3f7b02SChris Bieneman 
294dd3f7b02SChris Bieneman   SmallVector<char, 256> BinaryData;
295dd3f7b02SChris Bieneman   auto C = generateDXContainer(Yaml, BinaryData);
296dd3f7b02SChris Bieneman 
297dd3f7b02SChris Bieneman   ASSERT_THAT_EXPECTED(C, Succeeded());
298dd3f7b02SChris Bieneman 
299dd3f7b02SChris Bieneman   const auto &PSVInfo = C->getPSVInfo();
300dd3f7b02SChris Bieneman   ASSERT_TRUE(PSVInfo.has_value());
301dd3f7b02SChris Bieneman 
302dd3f7b02SChris Bieneman   EXPECT_EQ(PSVInfo->getResourceCount(), 3u);
303dd3f7b02SChris Bieneman 
304dd3f7b02SChris Bieneman   auto It = PSVInfo->getResources().begin();
305dd3f7b02SChris Bieneman 
306dd3f7b02SChris Bieneman   EXPECT_TRUE(It == PSVInfo->getResources().begin());
307dd3f7b02SChris Bieneman 
308dd3f7b02SChris Bieneman   dxbc::PSV::v2::ResourceBindInfo Binding;
309dd3f7b02SChris Bieneman 
310dd3f7b02SChris Bieneman   Binding = *It;
311*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);
312dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
313dd3f7b02SChris Bieneman 
314dd3f7b02SChris Bieneman   ++It;
315dd3f7b02SChris Bieneman   Binding = *It;
316dd3f7b02SChris Bieneman 
317*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::CBV);
318dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
319dd3f7b02SChris Bieneman 
320dd3f7b02SChris Bieneman   --It;
321dd3f7b02SChris Bieneman   Binding = *It;
322dd3f7b02SChris Bieneman 
323dd3f7b02SChris Bieneman   EXPECT_TRUE(It == PSVInfo->getResources().begin());
324dd3f7b02SChris Bieneman 
325*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);
326dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
327dd3f7b02SChris Bieneman 
328dd3f7b02SChris Bieneman   --It;
329dd3f7b02SChris Bieneman   Binding = *It;
330dd3f7b02SChris Bieneman 
331*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);
332dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
333dd3f7b02SChris Bieneman 
334dd3f7b02SChris Bieneman   ++It;
335dd3f7b02SChris Bieneman   Binding = *It;
336dd3f7b02SChris Bieneman 
337*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::CBV);
338dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
339dd3f7b02SChris Bieneman 
340dd3f7b02SChris Bieneman   ++It;
341dd3f7b02SChris Bieneman   Binding = *It;
342dd3f7b02SChris Bieneman 
343*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVTyped);
344dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
345dd3f7b02SChris Bieneman 
346dd3f7b02SChris Bieneman   EXPECT_FALSE(It == PSVInfo->getResources().end());
347dd3f7b02SChris Bieneman 
348dd3f7b02SChris Bieneman   ++It;
349dd3f7b02SChris Bieneman   Binding = *It;
350dd3f7b02SChris Bieneman 
351dd3f7b02SChris Bieneman   EXPECT_TRUE(It == PSVInfo->getResources().end());
352dd3f7b02SChris Bieneman   EXPECT_FALSE(It != PSVInfo->getResources().end());
353dd3f7b02SChris Bieneman 
354*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);
355dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
356dd3f7b02SChris Bieneman 
357dd3f7b02SChris Bieneman   {
358dd3f7b02SChris Bieneman     auto Old = It++;
359dd3f7b02SChris Bieneman     Binding = *Old;
360dd3f7b02SChris Bieneman 
361dd3f7b02SChris Bieneman     EXPECT_TRUE(Old == PSVInfo->getResources().end());
362dd3f7b02SChris Bieneman     EXPECT_FALSE(Old != PSVInfo->getResources().end());
363dd3f7b02SChris Bieneman 
364*fd0dbc7fSXiang Li     EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);
365dd3f7b02SChris Bieneman     EXPECT_EQ(Binding.Flags, 0u);
366dd3f7b02SChris Bieneman   }
367dd3f7b02SChris Bieneman 
368dd3f7b02SChris Bieneman   Binding = *It;
369dd3f7b02SChris Bieneman 
370dd3f7b02SChris Bieneman   EXPECT_TRUE(It == PSVInfo->getResources().end());
371dd3f7b02SChris Bieneman 
372*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);
373dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
374dd3f7b02SChris Bieneman 
375dd3f7b02SChris Bieneman   {
376dd3f7b02SChris Bieneman     auto Old = It--;
377dd3f7b02SChris Bieneman     Binding = *Old;
378dd3f7b02SChris Bieneman     EXPECT_TRUE(Old == PSVInfo->getResources().end());
379dd3f7b02SChris Bieneman 
380*fd0dbc7fSXiang Li     EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);
381dd3f7b02SChris Bieneman     EXPECT_EQ(Binding.Flags, 0u);
382dd3f7b02SChris Bieneman   }
383dd3f7b02SChris Bieneman 
384dd3f7b02SChris Bieneman   Binding = *It;
385dd3f7b02SChris Bieneman 
386*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVTyped);
387dd3f7b02SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
388dd3f7b02SChris Bieneman }
3895fdf8605SChris Bieneman 
3905fdf8605SChris Bieneman // The malicious file bits in these tests are mutations of the binary produced
3915fdf8605SChris Bieneman // by the following YAML:
3925fdf8605SChris Bieneman //
3935fdf8605SChris Bieneman // --- !dxcontainer
3945fdf8605SChris Bieneman // Header:
3955fdf8605SChris Bieneman //   Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
3965fdf8605SChris Bieneman //                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
3975fdf8605SChris Bieneman //   Version:
3985fdf8605SChris Bieneman //     Major:           1
3995fdf8605SChris Bieneman //     Minor:           0
4005fdf8605SChris Bieneman //   PartCount:       3
4015fdf8605SChris Bieneman // Parts:
4025fdf8605SChris Bieneman //   - Name:            DXIL
4035fdf8605SChris Bieneman //     Size:            24
4045fdf8605SChris Bieneman //     Program:
4055fdf8605SChris Bieneman //       MajorVersion:    6
4065fdf8605SChris Bieneman //       MinorVersion:    0
4075fdf8605SChris Bieneman //       ShaderKind:      14
4085fdf8605SChris Bieneman //       Size:            6
409531a0b67SXiang Li //       DXILMajorVersion: 1
410531a0b67SXiang Li //       DXILMinorVersion: 0
4115fdf8605SChris Bieneman //       DXILSize:        0
4125fdf8605SChris Bieneman //   - Name:            PSV0
4135fdf8605SChris Bieneman //     Size:            36
4145fdf8605SChris Bieneman //     PSVInfo:
4155fdf8605SChris Bieneman //       Version:         0
4165fdf8605SChris Bieneman //       ShaderStage:     5
4175fdf8605SChris Bieneman //       MinimumWaveLaneCount: 0
4185fdf8605SChris Bieneman //       MaximumWaveLaneCount: 0
4195fdf8605SChris Bieneman //       ResourceStride:       16
4205fdf8605SChris Bieneman //       Resources: []
4215fdf8605SChris Bieneman //   - Name: BLEH
4225fdf8605SChris Bieneman //     Size: 16
4235fdf8605SChris Bieneman // ...
4245fdf8605SChris Bieneman 
4255fdf8605SChris Bieneman TEST(DXCFile, MaliciousFiles) {
4265fdf8605SChris Bieneman 
4275fdf8605SChris Bieneman   // In this file blob, the file size is specified as 96 bytes (0x60), and the
4285fdf8605SChris Bieneman   // PSV0 data is specified as 24 bytes (0x18) which extends beyond the size of
4295fdf8605SChris Bieneman   // the file.
4305fdf8605SChris Bieneman   {
4315fdf8605SChris Bieneman     uint8_t Buffer[] = {
4325fdf8605SChris Bieneman         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4335fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
4345fdf8605SChris Bieneman         0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
4355fdf8605SChris Bieneman         0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x18, 0x00, 0x00, 0x00,
4365fdf8605SChris Bieneman         0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,
4375fdf8605SChris Bieneman         0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4385fdf8605SChris Bieneman         0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
4395fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4405fdf8605SChris Bieneman     };
4415fdf8605SChris Bieneman     EXPECT_THAT_EXPECTED(
4425fdf8605SChris Bieneman         DXContainer::create(getMemoryBuffer<96>(Buffer)),
4435fdf8605SChris Bieneman         FailedWithMessage(
4445fdf8605SChris Bieneman             "Pipeline state data extends beyond the bounds of the part"));
4455fdf8605SChris Bieneman   }
4465fdf8605SChris Bieneman 
4475fdf8605SChris Bieneman   // PSV extends beyond part, but in file range. In this blob the file size is
4485fdf8605SChris Bieneman   // 144 bytes (0x90), and the PSV part is 36 bytes (0x24), and the PSV data is
4495fdf8605SChris Bieneman   // 40 bytes (0x40).
4505fdf8605SChris Bieneman   {
4515fdf8605SChris Bieneman     uint8_t Buffer[] = {
4525fdf8605SChris Bieneman         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4535fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
4545fdf8605SChris Bieneman         0x90, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
4555fdf8605SChris Bieneman         0x4C, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,
4565fdf8605SChris Bieneman         0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00,
4575fdf8605SChris Bieneman         0x44, 0x58, 0x49, 0x4C, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
4585fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00,
4595fdf8605SChris Bieneman         0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4605fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4615fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
4625fdf8605SChris Bieneman         0x42, 0x4C, 0x45, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4635fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4645fdf8605SChris Bieneman     };
4655fdf8605SChris Bieneman     EXPECT_THAT_EXPECTED(
4665fdf8605SChris Bieneman         DXContainer::create(getMemoryBuffer<144>(Buffer)),
4675fdf8605SChris Bieneman         FailedWithMessage(
4685fdf8605SChris Bieneman             "Pipeline state data extends beyond the bounds of the part"));
4695fdf8605SChris Bieneman   }
4705fdf8605SChris Bieneman 
4715fdf8605SChris Bieneman   // In this file blob, the file is 116 bytes (0x74). The file structure is
4725fdf8605SChris Bieneman   // valid except that it specifies 1 16 byte resource binding which would
4735fdf8605SChris Bieneman   // extend beyond the range of the part and file.
4745fdf8605SChris Bieneman   {
4755fdf8605SChris Bieneman     uint8_t Buffer[] = {
4765fdf8605SChris Bieneman         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4775fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
4785fdf8605SChris Bieneman         0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
4795fdf8605SChris Bieneman         0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x18, 0x00, 0x00, 0x00,
4805fdf8605SChris Bieneman         0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,
4815fdf8605SChris Bieneman         0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4825fdf8605SChris Bieneman         0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
4835fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4845fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4855fdf8605SChris Bieneman         0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
4865fdf8605SChris Bieneman     };
4875fdf8605SChris Bieneman     EXPECT_THAT_EXPECTED(
4885fdf8605SChris Bieneman         DXContainer::create(getMemoryBuffer<116>(Buffer)),
4895fdf8605SChris Bieneman         FailedWithMessage(
4905fdf8605SChris Bieneman             "Resource binding data extends beyond the bounds of the part"));
4915fdf8605SChris Bieneman   }
4925fdf8605SChris Bieneman 
4935fdf8605SChris Bieneman   // In this file blob, the file is 116 bytes (0x74). The file structure is
4945fdf8605SChris Bieneman   // valid except that it specifies 1 16 byte resource binding which would
4955fdf8605SChris Bieneman   // extend beyond the range of the part and into the `BLEH` part.
4965fdf8605SChris Bieneman   {
4975fdf8605SChris Bieneman     uint8_t Buffer[] = {
4985fdf8605SChris Bieneman         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4995fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5005fdf8605SChris Bieneman         0x90, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
5015fdf8605SChris Bieneman         0x4C, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C,
5025fdf8605SChris Bieneman         0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00,
5035fdf8605SChris Bieneman         0x44, 0x58, 0x49, 0x4C, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
5045fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x24, 0x00, 0x00, 0x00,
5055fdf8605SChris Bieneman         0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5065fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5075fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
5085fdf8605SChris Bieneman         0x42, 0x4C, 0x45, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5095fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5105fdf8605SChris Bieneman     };
5115fdf8605SChris Bieneman     EXPECT_THAT_EXPECTED(
5125fdf8605SChris Bieneman         DXContainer::create(getMemoryBuffer<144>(Buffer)),
5135fdf8605SChris Bieneman         FailedWithMessage(
5145fdf8605SChris Bieneman             "Resource binding data extends beyond the bounds of the part"));
5155fdf8605SChris Bieneman   }
5165fdf8605SChris Bieneman }
5175fdf8605SChris Bieneman 
5185fdf8605SChris Bieneman // This test verifies that the resource iterator follows the stride even if the
5195fdf8605SChris Bieneman // stride doesn't match an expected or known value. In this test, the resource
5205fdf8605SChris Bieneman // data is structured validly, with 32 bytes per resource. This test is based on
5215fdf8605SChris Bieneman // editing the binary output constructed from this yaml.
5225fdf8605SChris Bieneman //
5235fdf8605SChris Bieneman // --- !dxcontainer
5245fdf8605SChris Bieneman // Header:
5255fdf8605SChris Bieneman //   Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
5265fdf8605SChris Bieneman //                      0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
5275fdf8605SChris Bieneman //   Version:
5285fdf8605SChris Bieneman //     Major:           1
5295fdf8605SChris Bieneman //     Minor:           0
5305fdf8605SChris Bieneman //   PartCount:       2
5315fdf8605SChris Bieneman // Parts:
5325fdf8605SChris Bieneman //   - Name:            DXIL
5335fdf8605SChris Bieneman //     Size:            24
5345fdf8605SChris Bieneman //     Program:
5355fdf8605SChris Bieneman //       MajorVersion:    6
5365fdf8605SChris Bieneman //       MinorVersion:    0
5375fdf8605SChris Bieneman //       ShaderKind:      14
5385fdf8605SChris Bieneman //       Size:            6
539531a0b67SXiang Li //       DXILMajorVersion: 1
540531a0b67SXiang Li //       DXILMinorVersion: 0
5415fdf8605SChris Bieneman //       DXILSize:        0
5425fdf8605SChris Bieneman //   - Name:            PSV0
5435fdf8605SChris Bieneman //     Size:            100
5445fdf8605SChris Bieneman //     PSVInfo:
5455fdf8605SChris Bieneman //       Version:         0
5465fdf8605SChris Bieneman //       ShaderStage:     5
5475fdf8605SChris Bieneman //       MinimumWaveLaneCount: 0
5485fdf8605SChris Bieneman //       MaximumWaveLaneCount: 0
5495fdf8605SChris Bieneman //       ResourceStride:       16
5505fdf8605SChris Bieneman //       Resources:
5515fdf8605SChris Bieneman //         - Type:            1
5525fdf8605SChris Bieneman //           Space:           2
5535fdf8605SChris Bieneman //           LowerBound:      3
5545fdf8605SChris Bieneman //           UpperBound:      4
5555fdf8605SChris Bieneman //         - Type:            5
5565fdf8605SChris Bieneman //           Space:           6
5575fdf8605SChris Bieneman //           LowerBound:      7
5585fdf8605SChris Bieneman //           UpperBound:      8
5595fdf8605SChris Bieneman // ...
5605fdf8605SChris Bieneman TEST(DXCFile, PSVResourceIteratorsStride) {
5615fdf8605SChris Bieneman   uint8_t Buffer[] = {
5625fdf8605SChris Bieneman         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5635fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
5645fdf8605SChris Bieneman         0x28, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x18, 0x00, 0x00, 0x00,
5655fdf8605SChris Bieneman         0x60, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4C, 0x00, 0x01, 0x00, 0x00,
5665fdf8605SChris Bieneman         0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x64, 0x00, 0x00, 0x00,
5675fdf8605SChris Bieneman         0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5685fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
5695fdf8605SChris Bieneman         0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
5705fdf8605SChris Bieneman         0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5715fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
5725fdf8605SChris Bieneman         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5735fdf8605SChris Bieneman         0x00, 0x00, 0x00, 0x00,
5745fdf8605SChris Bieneman     };
5755fdf8605SChris Bieneman     DXContainer C =
5765fdf8605SChris Bieneman       llvm::cantFail(DXContainer::create(getMemoryBuffer<180>(Buffer)));
5775fdf8605SChris Bieneman 
5785fdf8605SChris Bieneman   const auto &PSVInfo = C.getPSVInfo();
5795fdf8605SChris Bieneman   ASSERT_TRUE(PSVInfo.has_value());
5805fdf8605SChris Bieneman 
5815fdf8605SChris Bieneman   ASSERT_EQ(PSVInfo->getResourceCount(), 2u);
5825fdf8605SChris Bieneman 
5835fdf8605SChris Bieneman   auto It = PSVInfo->getResources().begin();
5845fdf8605SChris Bieneman 
5855fdf8605SChris Bieneman   EXPECT_TRUE(It == PSVInfo->getResources().begin());
5865fdf8605SChris Bieneman 
5875fdf8605SChris Bieneman   dxbc::PSV::v2::ResourceBindInfo Binding;
5885fdf8605SChris Bieneman 
5895fdf8605SChris Bieneman   Binding = *It;
590*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);
5915fdf8605SChris Bieneman   EXPECT_EQ(Binding.Space, 2u);
5925fdf8605SChris Bieneman   EXPECT_EQ(Binding.LowerBound, 3u);
5935fdf8605SChris Bieneman   EXPECT_EQ(Binding.UpperBound, 4u);
5945fdf8605SChris Bieneman 
5955fdf8605SChris Bieneman   ++It;
5965fdf8605SChris Bieneman   Binding = *It;
5975fdf8605SChris Bieneman 
598*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVStructured);
5995fdf8605SChris Bieneman   EXPECT_EQ(Binding.Space, 6u);
6005fdf8605SChris Bieneman   EXPECT_EQ(Binding.LowerBound, 7u);
6015fdf8605SChris Bieneman   EXPECT_EQ(Binding.UpperBound, 8u);
6025fdf8605SChris Bieneman 
6035fdf8605SChris Bieneman   --It;
6045fdf8605SChris Bieneman   Binding = *It;
6055fdf8605SChris Bieneman 
6065fdf8605SChris Bieneman   EXPECT_TRUE(It == PSVInfo->getResources().begin());
6075fdf8605SChris Bieneman 
608*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);
6095fdf8605SChris Bieneman   EXPECT_EQ(Binding.Space, 2u);
6105fdf8605SChris Bieneman   EXPECT_EQ(Binding.LowerBound, 3u);
6115fdf8605SChris Bieneman   EXPECT_EQ(Binding.UpperBound, 4u);
6125fdf8605SChris Bieneman 
6135fdf8605SChris Bieneman   --It;
6145fdf8605SChris Bieneman   Binding = *It;
6155fdf8605SChris Bieneman 
616*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Sampler);
6175fdf8605SChris Bieneman   EXPECT_EQ(Binding.Space, 2u);
6185fdf8605SChris Bieneman   EXPECT_EQ(Binding.LowerBound, 3u);
6195fdf8605SChris Bieneman   EXPECT_EQ(Binding.UpperBound, 4u);
6205fdf8605SChris Bieneman 
6215fdf8605SChris Bieneman   ++It;
6225fdf8605SChris Bieneman   Binding = *It;
6235fdf8605SChris Bieneman 
624*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::SRVStructured);
6255fdf8605SChris Bieneman   EXPECT_EQ(Binding.Space, 6u);
6265fdf8605SChris Bieneman   EXPECT_EQ(Binding.LowerBound, 7u);
6275fdf8605SChris Bieneman   EXPECT_EQ(Binding.UpperBound, 8u);;
6285fdf8605SChris Bieneman 
6295fdf8605SChris Bieneman 
6305fdf8605SChris Bieneman   EXPECT_FALSE(It == PSVInfo->getResources().end());
6315fdf8605SChris Bieneman 
6325fdf8605SChris Bieneman   ++It;
6335fdf8605SChris Bieneman   Binding = *It;
6345fdf8605SChris Bieneman 
6355fdf8605SChris Bieneman   EXPECT_TRUE(It == PSVInfo->getResources().end());
6365fdf8605SChris Bieneman   EXPECT_FALSE(It != PSVInfo->getResources().end());
6375fdf8605SChris Bieneman 
638*fd0dbc7fSXiang Li   EXPECT_EQ(Binding.Type, dxbc::PSV::ResourceType::Invalid);
6395fdf8605SChris Bieneman   EXPECT_EQ(Binding.Flags, 0u);
6405fdf8605SChris Bieneman }
6410c3f51c0SChris Bieneman 
6420c3f51c0SChris Bieneman // This test binary is created using mutations of the yaml in the SigElements
6430c3f51c0SChris Bieneman // test found under test/ObjectYAML/DXContainer/SigElements.yaml.
6440c3f51c0SChris Bieneman 
6450c3f51c0SChris Bieneman TEST(DXCFile, MisalignedStringTable) {
6460c3f51c0SChris Bieneman   uint8_t Buffer[] = {
6470c3f51c0SChris Bieneman       0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6480c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
6490c3f51c0SChris Bieneman       0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
6500c3f51c0SChris Bieneman       0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x18, 0x00, 0x00, 0x00,
6510c3f51c0SChris Bieneman       0x60, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c,
6520c3f51c0SChris Bieneman       0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6530c3f51c0SChris Bieneman       0x50, 0x53, 0x56, 0x30, 0x68, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
6540c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6550c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
6560c3f51c0SChris Bieneman       0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x10, 0x20, 0x40,
6570c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6580c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6590c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6600c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6610c3f51c0SChris Bieneman   EXPECT_THAT_EXPECTED(DXContainer::create(getMemoryBuffer<168>(Buffer)),
6620c3f51c0SChris Bieneman                        FailedWithMessage("String table misaligned"));
6630c3f51c0SChris Bieneman }
6640c3f51c0SChris Bieneman 
6650c3f51c0SChris Bieneman // This test binary is created using mutations of the yaml in the SigElements
6660c3f51c0SChris Bieneman // test found under test/ObjectYAML/DXContainer/SigElements.yaml.
6670c3f51c0SChris Bieneman TEST(DXCFile, SigElementsExtendBeyondPart) {
6680c3f51c0SChris Bieneman   uint8_t Buffer[] = {
6690c3f51c0SChris Bieneman       0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6700c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
6710c3f51c0SChris Bieneman       0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
6720c3f51c0SChris Bieneman       0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x18, 0x00, 0x00, 0x00,
6730c3f51c0SChris Bieneman       0x60, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c,
6740c3f51c0SChris Bieneman       0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6750c3f51c0SChris Bieneman       0x50, 0x53, 0x56, 0x30, 0x54, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
6760c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6770c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
6780c3f51c0SChris Bieneman       0x05, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x08, 0x10, 0x20, 0x40,
6790c3f51c0SChris Bieneman       0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x00,
6800c3f51c0SChris Bieneman       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
6810c3f51c0SChris Bieneman       0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6820c3f51c0SChris Bieneman       0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x03, 0x00};
6830c3f51c0SChris Bieneman   EXPECT_THAT_EXPECTED(
6840c3f51c0SChris Bieneman       DXContainer::create(getMemoryBuffer<164>(Buffer)),
6850c3f51c0SChris Bieneman       FailedWithMessage(
6860c3f51c0SChris Bieneman           "Signature elements extend beyond the size of the part"));
6870c3f51c0SChris Bieneman }
6889f87522bSChris B 
6899f87522bSChris B TEST(DXCFile, MalformedSignature) {
6909f87522bSChris B   /*
6919f87522bSChris B   The tests here exercise the DXContainer Signature section parser. These tests
6929f87522bSChris B   are based on modifying the binary described by the following yaml:
6939f87522bSChris B 
6949f87522bSChris B   --- !dxcontainer
6959f87522bSChris B   Header:
6969f87522bSChris B     Hash:            [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
6979f87522bSChris B                       0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
6989f87522bSChris B     Version:
6999f87522bSChris B       Major:           1
7009f87522bSChris B       Minor:           0
7019f87522bSChris B     FileSize:        128
7029f87522bSChris B     PartCount:       1
7039f87522bSChris B     PartOffsets:     [ 64 ]
7049f87522bSChris B   Parts:
7059f87522bSChris B     - Name:            ISG1
7069f87522bSChris B       Size:            52
7079f87522bSChris B       Signature:
7089f87522bSChris B         Parameters:
7099f87522bSChris B           - Stream:          0
7109f87522bSChris B             Name:            AAA
7119f87522bSChris B             Index:           0
7129f87522bSChris B             SystemValue:     Undefined
7139f87522bSChris B             CompType:        Float32
7149f87522bSChris B             Register:        0
7159f87522bSChris B             Mask:            7
7169f87522bSChris B             ExclusiveMask:   2
7179f87522bSChris B             MinPrecision:    Default
7189f87522bSChris B   ...
7199f87522bSChris B 
7209f87522bSChris B   The unmodified hex sequence is:
7219f87522bSChris B 
7229f87522bSChris B   uint8_t Buffer[] = {
7239f87522bSChris B     0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7249f87522bSChris B   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80,
7259f87522bSChris B   0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
7269f87522bSChris B   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7279f87522bSChris B   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7289f87522bSChris B   0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08,
7299f87522bSChris B   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
7309f87522bSChris B   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7319f87522bSChris B   0x00, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00,
7329f87522bSChris B   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7339f87522bSChris B   };
7349f87522bSChris B 
7359f87522bSChris B   */
7369f87522bSChris B 
7379f87522bSChris B   {
7389f87522bSChris B 
7399f87522bSChris B     // This binary says the signature has 10 parameters, but the part data is
7409f87522bSChris B     // only big enough for 1.
7419f87522bSChris B     uint8_t Buffer[] = {
7429f87522bSChris B         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7439f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
7449f87522bSChris B         0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
7459f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7469f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7479f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,
7489f87522bSChris B         0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7499f87522bSChris B         0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7509f87522bSChris B         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,
7519f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,
7529f87522bSChris B         0x00, 0x00, 0x00, 0x00};
7539f87522bSChris B     EXPECT_THAT_EXPECTED(
7549f87522bSChris B         DXContainer::create(getMemoryBuffer<164>(Buffer)),
7559f87522bSChris B         FailedWithMessage(
7569f87522bSChris B             "Signature parameters extend beyond the part boundary"));
7579f87522bSChris B   }
7589f87522bSChris B 
7599f87522bSChris B   {
7609f87522bSChris B 
7619f87522bSChris B     // This binary only has one parameter, but the start offset is beyond the
7629f87522bSChris B     // size of the part.
7639f87522bSChris B     uint8_t Buffer[] = {
7649f87522bSChris B         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7659f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
7669f87522bSChris B         0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
7679f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7689f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7699f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,
7709f87522bSChris B         0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7719f87522bSChris B         0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7729f87522bSChris B         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,
7739f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,
7749f87522bSChris B         0x00, 0x00, 0x00, 0x00};
7759f87522bSChris B     EXPECT_THAT_EXPECTED(
7769f87522bSChris B         DXContainer::create(getMemoryBuffer<164>(Buffer)),
7779f87522bSChris B         FailedWithMessage(
7789f87522bSChris B             "Signature parameters extend beyond the part boundary"));
7799f87522bSChris B   }
7809f87522bSChris B 
7819f87522bSChris B   {
7829f87522bSChris B 
7839f87522bSChris B     // This parameter has a name offset of 3, which is before the start of the
7849f87522bSChris B     // string table.
7859f87522bSChris B     uint8_t Buffer[] = {
7869f87522bSChris B         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7879f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
7889f87522bSChris B         0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
7899f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7909f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7919f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,
7929f87522bSChris B         0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7939f87522bSChris B         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7949f87522bSChris B         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,
7959f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,
7969f87522bSChris B         0x00, 0x00, 0x00, 0x00};
7979f87522bSChris B     EXPECT_THAT_EXPECTED(
7989f87522bSChris B         DXContainer::create(getMemoryBuffer<164>(Buffer)),
7999f87522bSChris B         FailedWithMessage("Invalid parameter name offset: name starts before "
8009f87522bSChris B                           "the first name offset"));
8019f87522bSChris B   }
8029f87522bSChris B 
8039f87522bSChris B   {
8049f87522bSChris B     // This parameter has a name offset of 255, which is after the end of the
8059f87522bSChris B     // part.
8069f87522bSChris B     uint8_t Buffer[] = {
8079f87522bSChris B         0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8089f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
8099f87522bSChris B         0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
8109f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8119f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8129f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x34, 0x00, 0x00, 0x00,
8139f87522bSChris B         0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8149f87522bSChris B         0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8159f87522bSChris B         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00,
8169f87522bSChris B         0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00,
8179f87522bSChris B         0x00, 0x00, 0x00, 0x00};
8189f87522bSChris B     EXPECT_THAT_EXPECTED(
8199f87522bSChris B         DXContainer::create(getMemoryBuffer<164>(Buffer)),
8209f87522bSChris B         FailedWithMessage("Invalid parameter name offset: name starts after "
8219f87522bSChris B                           "the end of the part data"));
8229f87522bSChris B   }
8239f87522bSChris B }
824