1818#include " llvm/ADT/SmallVector.h"
1919#include " llvm/ADT/StringRef.h"
2020#include " llvm/BinaryFormat/DXContainer.h"
21+ #include " llvm/Object/Error.h"
2122#include " llvm/Support/Error.h"
2223#include " llvm/Support/MemoryBufferRef.h"
2324#include " llvm/TargetParser/Triple.h"
2425#include < array>
26+ #include < cstddef>
2527#include < variant>
2628
2729namespace llvm {
@@ -116,6 +118,40 @@ template <typename T> struct ViewArray {
116118};
117119
118120namespace DirectX {
121+ struct RootParameterView {
122+ const dxbc::RootParameterHeader &Header;
123+ StringRef ParamData;
124+ RootParameterView (const dxbc::RootParameterHeader &H, StringRef P)
125+ : Header(H), ParamData(P) {}
126+
127+ template <typename T> Expected<T> readParameter () {
128+ T Struct;
129+ if (sizeof (T) != ParamData.size ())
130+ return make_error<GenericBinaryError>(
131+ " Reading structure out of file bounds" , object_error::parse_failed);
132+
133+ memcpy (&Struct, ParamData.data (), sizeof (T));
134+ // DXContainer is always little endian
135+ if (sys::IsBigEndianHost)
136+ Struct.swapBytes ();
137+ return Struct;
138+ }
139+ };
140+
141+ struct RootConstantView : RootParameterView {
142+ static bool classof (const RootParameterView *V) {
143+ return V->Header .ParameterType ==
144+ (uint32_t )dxbc::RootParameterType::Constants32Bit;
145+ }
146+
147+ llvm::Expected<dxbc::RootConstants> read () {
148+ return readParameter<dxbc::RootConstants>();
149+ }
150+ };
151+
152+ static Error parseFailed (const Twine &Msg) {
153+ return make_error<GenericBinaryError>(Msg.str (), object_error::parse_failed);
154+ }
119155
120156class RootSignature {
121157private:
@@ -125,17 +161,49 @@ class RootSignature {
125161 uint32_t NumStaticSamplers;
126162 uint32_t StaticSamplersOffset;
127163 uint32_t Flags;
164+ ViewArray<dxbc::RootParameterHeader> ParametersHeaders;
165+ StringRef PartData;
166+
167+ using param_header_iterator = ViewArray<dxbc::RootParameterHeader>::iterator;
128168
129169public:
130- RootSignature () {}
170+ RootSignature (StringRef PD) : PartData(PD ) {}
131171
132- Error parse (StringRef Data );
172+ Error parse ();
133173 uint32_t getVersion () const { return Version; }
134174 uint32_t getNumParameters () const { return NumParameters; }
135175 uint32_t getRootParametersOffset () const { return RootParametersOffset; }
136176 uint32_t getNumStaticSamplers () const { return NumStaticSamplers; }
137177 uint32_t getStaticSamplersOffset () const { return StaticSamplersOffset; }
178+ uint32_t getNumRootParameters () const { return ParametersHeaders.size (); }
179+ llvm::iterator_range<param_header_iterator> param_headers () const {
180+ return llvm::make_range (ParametersHeaders.begin (), ParametersHeaders.end ());
181+ }
138182 uint32_t getFlags () const { return Flags; }
183+
184+ llvm::Expected<RootParameterView>
185+ getParameter (const dxbc::RootParameterHeader &Header) const {
186+ size_t DataSize;
187+
188+ if (!dxbc::isValidParameterType (Header.ParameterType ))
189+ return parseFailed (" invalid parameter type" );
190+
191+ switch (static_cast <dxbc::RootParameterType>(Header.ParameterType )) {
192+ case dxbc::RootParameterType::Constants32Bit:
193+ DataSize = sizeof (dxbc::RootConstants);
194+ break ;
195+ }
196+ size_t EndOfSectionByte = getNumStaticSamplers () == 0
197+ ? PartData.size ()
198+ : getStaticSamplersOffset ();
199+
200+ if (Header.ParameterOffset + DataSize > EndOfSectionByte)
201+ return parseFailed (" Reading structure out of file bounds" );
202+
203+ StringRef Buff = PartData.substr (Header.ParameterOffset , DataSize);
204+ RootParameterView View = RootParameterView (Header, Buff);
205+ return View;
206+ }
139207};
140208
141209class PSVRuntimeInfo {
0 commit comments