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