129 lines
3.7 KiB
C++
129 lines
3.7 KiB
C++
//===- DXContainer.h - DXContainer file implementation ----------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file declares the DXContainerFile class, which implements the ObjectFile
|
|
// interface for DXContainer files.
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_OBJECT_DXCONTAINER_H
|
|
#define LLVM_OBJECT_DXCONTAINER_H
|
|
|
|
#include "llvm/ADT/Optional.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/BinaryFormat/DXContainer.h"
|
|
#include "llvm/Support/Error.h"
|
|
#include "llvm/Support/MemoryBufferRef.h"
|
|
|
|
namespace llvm {
|
|
namespace object {
|
|
class DXContainer {
|
|
public:
|
|
using DXILData = std::pair<dxbc::ProgramHeader, const char *>;
|
|
|
|
private:
|
|
DXContainer(MemoryBufferRef O);
|
|
|
|
MemoryBufferRef Data;
|
|
dxbc::Header Header;
|
|
SmallVector<uint32_t, 4> PartOffsets;
|
|
Optional<DXILData> DXIL;
|
|
Optional<uint64_t> ShaderFlags;
|
|
|
|
Error parseHeader();
|
|
Error parsePartOffsets();
|
|
Error parseDXILHeader(uint32_t Offset);
|
|
Error parseShaderFlags(uint32_t Offset);
|
|
friend class PartIterator;
|
|
|
|
public:
|
|
// The PartIterator is a wrapper around the iterator for the PartOffsets
|
|
// member of the DXContainer. It contains a refernce to the container, and the
|
|
// current iterator value, as well as storage for a parsed part header.
|
|
class PartIterator {
|
|
const DXContainer &Container;
|
|
SmallVectorImpl<uint32_t>::const_iterator OffsetIt;
|
|
struct PartData {
|
|
dxbc::PartHeader Part;
|
|
uint32_t Offset;
|
|
StringRef Data;
|
|
} IteratorState;
|
|
|
|
friend class DXContainer;
|
|
|
|
PartIterator(const DXContainer &C,
|
|
SmallVectorImpl<uint32_t>::const_iterator It)
|
|
: Container(C), OffsetIt(It) {
|
|
if (OffsetIt == Container.PartOffsets.end())
|
|
updateIteratorImpl(Container.PartOffsets.back());
|
|
else
|
|
updateIterator();
|
|
}
|
|
|
|
// Updates the iterator's state data. This results in copying the part
|
|
// header into the iterator and handling any required byte swapping. This is
|
|
// called when incrementing or decrementing the iterator.
|
|
void updateIterator() {
|
|
if (OffsetIt != Container.PartOffsets.end())
|
|
updateIteratorImpl(*OffsetIt);
|
|
}
|
|
|
|
// Implementation for updating the iterator state based on a specified
|
|
// offest.
|
|
void updateIteratorImpl(const uint32_t Offset);
|
|
|
|
public:
|
|
PartIterator &operator++() {
|
|
if (OffsetIt == Container.PartOffsets.end())
|
|
return *this;
|
|
++OffsetIt;
|
|
updateIterator();
|
|
return *this;
|
|
}
|
|
|
|
PartIterator operator++(int) {
|
|
PartIterator Tmp = *this;
|
|
++(*this);
|
|
return Tmp;
|
|
}
|
|
|
|
bool operator==(const PartIterator &RHS) const {
|
|
return OffsetIt == RHS.OffsetIt;
|
|
}
|
|
|
|
bool operator!=(const PartIterator &RHS) const {
|
|
return OffsetIt != RHS.OffsetIt;
|
|
}
|
|
|
|
const PartData &operator*() { return IteratorState; }
|
|
const PartData *operator->() { return &IteratorState; }
|
|
};
|
|
|
|
PartIterator begin() const {
|
|
return PartIterator(*this, PartOffsets.begin());
|
|
}
|
|
|
|
PartIterator end() const { return PartIterator(*this, PartOffsets.end()); }
|
|
|
|
StringRef getData() const { return Data.getBuffer(); }
|
|
static Expected<DXContainer> create(MemoryBufferRef Object);
|
|
|
|
const dxbc::Header &getHeader() const { return Header; }
|
|
|
|
Optional<DXILData> getDXIL() const { return DXIL; }
|
|
|
|
Optional<uint64_t> getShaderFlags() const { return ShaderFlags; }
|
|
};
|
|
|
|
} // namespace object
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_OBJECT_DXCONTAINER_H
|