1 //===------ dxcontainer2yaml.cpp - obj2yaml conversion tool -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "obj2yaml.h"
10 #include "llvm/Object/DXContainer.h"
11 #include "llvm/ObjectYAML/DXContainerYAML.h"
12 #include "llvm/Support/Error.h"
13
14 #include <algorithm>
15
16 using namespace llvm;
17 using namespace llvm::object;
18
19 static Expected<DXContainerYAML::Object *>
dumpDXContainer(MemoryBufferRef Source)20 dumpDXContainer(MemoryBufferRef Source) {
21 assert(file_magic::dxcontainer_object == identify_magic(Source.getBuffer()));
22
23 Expected<DXContainer> ExDXC = DXContainer::create(Source);
24 if (!ExDXC)
25 return ExDXC.takeError();
26 DXContainer Container = *ExDXC;
27
28 std::unique_ptr<DXContainerYAML::Object> Obj =
29 std::make_unique<DXContainerYAML::Object>();
30
31 for (uint8_t Byte : Container.getHeader().FileHash.Digest)
32 Obj->Header.Hash.push_back(Byte);
33 Obj->Header.Version.Major = Container.getHeader().Version.Major;
34 Obj->Header.Version.Minor = Container.getHeader().Version.Minor;
35 Obj->Header.FileSize = Container.getHeader().FileSize;
36 Obj->Header.PartCount = Container.getHeader().PartCount;
37
38 Obj->Header.PartOffsets = std::vector<uint32_t>();
39 for (const auto P : Container) {
40 Obj->Header.PartOffsets->push_back(P.Offset);
41 if (P.Part.getName() == "DXIL") {
42 Optional<DXContainer::DXILData> DXIL = Container.getDXIL();
43 assert(DXIL && "Since we are iterating and found a DXIL part, "
44 "this should never not have a value");
45 Obj->Parts.push_back(DXContainerYAML::Part{
46 P.Part.getName().str(), P.Part.Size,
47 DXContainerYAML::DXILProgram{
48 DXIL->first.MajorVersion, DXIL->first.MinorVersion,
49 DXIL->first.ShaderKind, DXIL->first.Size,
50 DXIL->first.Bitcode.MajorVersion,
51 DXIL->first.Bitcode.MinorVersion, DXIL->first.Bitcode.Offset,
52 DXIL->first.Bitcode.Size,
53 std::vector<llvm::yaml::Hex8>(
54 DXIL->second, DXIL->second + DXIL->first.Bitcode.Size)}});
55 } else {
56 Obj->Parts.push_back(
57 DXContainerYAML::Part{P.Part.getName().str(), P.Part.Size, None});
58 }
59 }
60
61 return Obj.release();
62 }
63
dxcontainer2yaml(llvm::raw_ostream & Out,llvm::MemoryBufferRef Source)64 llvm::Error dxcontainer2yaml(llvm::raw_ostream &Out,
65 llvm::MemoryBufferRef Source) {
66 Expected<DXContainerYAML::Object *> YAMLOrErr = dumpDXContainer(Source);
67 if (!YAMLOrErr)
68 return YAMLOrErr.takeError();
69
70 std::unique_ptr<DXContainerYAML::Object> YAML(YAMLOrErr.get());
71 yaml::Output Yout(Out);
72 Yout << *YAML;
73
74 return Error::success();
75 }
76