xref: /openbsd-src/gnu/llvm/llvm/include/llvm/Object/DXContainer.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
1 //===- DXContainer.h - DXContainer file implementation ----------*- 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 // This file declares the DXContainerFile class, which implements the ObjectFile
10 // interface for DXContainer files.
11 //
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_OBJECT_DXCONTAINER_H
16 #define LLVM_OBJECT_DXCONTAINER_H
17 
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/BinaryFormat/DXContainer.h"
21 #include "llvm/Support/Error.h"
22 #include "llvm/Support/MemoryBufferRef.h"
23 
24 namespace llvm {
25 namespace object {
26 class DXContainer {
27 public:
28   using DXILData = std::pair<dxbc::ProgramHeader, const char *>;
29 
30 private:
31   DXContainer(MemoryBufferRef O);
32 
33   MemoryBufferRef Data;
34   dxbc::Header Header;
35   SmallVector<uint32_t, 4> PartOffsets;
36   std::optional<DXILData> DXIL;
37   std::optional<uint64_t> ShaderFlags;
38   std::optional<dxbc::ShaderHash> Hash;
39 
40   Error parseHeader();
41   Error parsePartOffsets();
42   Error parseDXILHeader(StringRef Part);
43   Error parseShaderFlags(StringRef Part);
44   Error parseHash(StringRef Part);
45   friend class PartIterator;
46 
47 public:
48   // The PartIterator is a wrapper around the iterator for the PartOffsets
49   // member of the DXContainer. It contains a refernce to the container, and the
50   // current iterator value, as well as storage for a parsed part header.
51   class PartIterator {
52     const DXContainer &Container;
53     SmallVectorImpl<uint32_t>::const_iterator OffsetIt;
54     struct PartData {
55       dxbc::PartHeader Part;
56       uint32_t Offset;
57       StringRef Data;
58     } IteratorState;
59 
60     friend class DXContainer;
61 
PartIterator(const DXContainer & C,SmallVectorImpl<uint32_t>::const_iterator It)62     PartIterator(const DXContainer &C,
63                  SmallVectorImpl<uint32_t>::const_iterator It)
64         : Container(C), OffsetIt(It) {
65       if (OffsetIt == Container.PartOffsets.end())
66         updateIteratorImpl(Container.PartOffsets.back());
67       else
68         updateIterator();
69     }
70 
71     // Updates the iterator's state data. This results in copying the part
72     // header into the iterator and handling any required byte swapping. This is
73     // called when incrementing or decrementing the iterator.
updateIterator()74     void updateIterator() {
75       if (OffsetIt != Container.PartOffsets.end())
76         updateIteratorImpl(*OffsetIt);
77     }
78 
79     // Implementation for updating the iterator state based on a specified
80     // offest.
81     void updateIteratorImpl(const uint32_t Offset);
82 
83   public:
84     PartIterator &operator++() {
85       if (OffsetIt == Container.PartOffsets.end())
86         return *this;
87       ++OffsetIt;
88       updateIterator();
89       return *this;
90     }
91 
92     PartIterator operator++(int) {
93       PartIterator Tmp = *this;
94       ++(*this);
95       return Tmp;
96     }
97 
98     bool operator==(const PartIterator &RHS) const {
99       return OffsetIt == RHS.OffsetIt;
100     }
101 
102     bool operator!=(const PartIterator &RHS) const {
103       return OffsetIt != RHS.OffsetIt;
104     }
105 
106     const PartData &operator*() { return IteratorState; }
107     const PartData *operator->() { return &IteratorState; }
108   };
109 
begin()110   PartIterator begin() const {
111     return PartIterator(*this, PartOffsets.begin());
112   }
113 
end()114   PartIterator end() const { return PartIterator(*this, PartOffsets.end()); }
115 
getData()116   StringRef getData() const { return Data.getBuffer(); }
117   static Expected<DXContainer> create(MemoryBufferRef Object);
118 
getHeader()119   const dxbc::Header &getHeader() const { return Header; }
120 
getDXIL()121   std::optional<DXILData> getDXIL() const { return DXIL; }
122 
getShaderFlags()123   std::optional<uint64_t> getShaderFlags() const { return ShaderFlags; }
124 
getShaderHash()125   std::optional<dxbc::ShaderHash> getShaderHash() const { return Hash; }
126 };
127 
128 } // namespace object
129 } // namespace llvm
130 
131 #endif // LLVM_OBJECT_DXCONTAINER_H
132