3737#include " DXBCUtils.hpp"
3838#include " ../../../ThirdParty/GPUOpenShaderUtils/DXBCChecksum.h"
3939#include " DataBlobImpl.hpp"
40+ #include " DefaultRawMemoryAllocator.hpp"
4041
4142namespace Diligent
4243{
@@ -871,19 +872,19 @@ inline bool PatchSpace(ResourceBindingInfo50&, ResourceExtendedInfo& Ext, const
871872}
872873
873874template <typename ResourceBindingInfoType>
874- void RemapShaderResources (const DXBCUtils::TResourceBindingMap& ResourceMap, const void * EndPtr, ResourceDefChunkHeader* RDEFHeader, TExtendedResourceMap& ExtResMap, ResourceBindingPerType& BindingsPerType)
875+ void RemapShaderResources (const DXBCUtils::TResourceBindingMap& ResourceMap, const void * EndPtr, ResourceDefChunkHeader& RDEFHeader, TExtendedResourceMap& ExtResMap, ResourceBindingPerType& BindingsPerType)
875876{
876- VERIFY_EXPR (RDEFHeader-> Magic == RDEFFourCC);
877+ VERIFY_EXPR (RDEFHeader. Magic == RDEFFourCC);
877878
878- char * Ptr = reinterpret_cast <char *>(RDEFHeader) + sizeof (ChunkHeader);
879- ResourceBindingInfoType* ResBinding = reinterpret_cast <ResourceBindingInfoType*>(Ptr + RDEFHeader-> ResBindingOffset );
880- if (ResBinding + RDEFHeader-> ResBindingCount > EndPtr)
879+ char * Ptr = reinterpret_cast <char *>(& RDEFHeader) + sizeof (ChunkHeader);
880+ ResourceBindingInfoType* ResBinding = reinterpret_cast <ResourceBindingInfoType*>(Ptr + RDEFHeader. ResBindingOffset );
881+ if (ResBinding + RDEFHeader. ResBindingCount > EndPtr)
881882 {
882883 LOG_ERROR_AND_THROW (" Resource binding data is outside of the specified byte code range. The byte code may be corrupted." );
883884 }
884885
885886 String TempName;
886- for (Uint32 r = 0 ; r < RDEFHeader-> ResBindingCount ; ++r)
887+ for (Uint32 r = 0 ; r < RDEFHeader. ResBindingCount ; ++r)
887888 {
888889 ResourceBindingInfoType& Res = ResBinding[r];
889890 const char * Name = Ptr + Res.NameOffset ;
@@ -1744,61 +1745,70 @@ RefCntAutoPtr<IDataBlob> RemapResourceBindings(const TResourceBindingMap& Resour
17441745 return {};
17451746 }
17461747
1747- RefCntAutoPtr<IDataBlob> pRemappedBytecode = DataBlobImpl::Create (Size, pBytecode);
1748+ if (sizeof (Header) + sizeof (Uint32) * Header.ChunkCount > Size)
1749+ {
1750+ LOG_ERROR_MESSAGE (" Not enough space for the chunk offsets. The byte code may be corrupted." );
1751+ return {};
1752+ }
17481753
1749- char * const Ptr = pRemappedBytecode->GetDataPtr <char >();
1750- const void * const EndPtr = Ptr + Size;
1754+ DataBlobImpl::DataBufferType RemappedBytecode{
1755+ static_cast <const Uint8*>(pBytecode),
1756+ static_cast <const Uint8*>(pBytecode) + Size,
1757+ STD_ALLOCATOR_RAW_MEM (Uint8, DefaultRawMemoryAllocator::GetAllocator (), " Allocator for vector<Uint8>" ),
1758+ };
17511759
1752- const Uint32* Chunks = reinterpret_cast <Uint32*>(Ptr + sizeof (Header));
17531760 ResourceBindingPerType BindingsPerType;
17541761 TExtendedResourceMap ExtResourceMap;
17551762
1756- bool RemapResDef = false ;
1757- bool RemapBytecode = false ;
1763+ bool RemapResDef = false ;
1764+ bool PatchOK = false ;
17581765 try
17591766 {
17601767 for (Uint32 i = 0 ; i < Header.ChunkCount ; ++i)
17611768 {
1762- ChunkHeader* pChunk = reinterpret_cast <ChunkHeader*>(Ptr + Chunks[i]);
1763- if (pChunk + 1 > EndPtr)
1769+ const Uint32* ChunkOffsets = reinterpret_cast <const Uint32*>(&RemappedBytecode[sizeof (Header)]);
1770+ const Uint32 ChunkOffset = ChunkOffsets[i];
1771+ if (ChunkOffset + sizeof (ChunkHeader) > RemappedBytecode.size ())
17641772 {
17651773 LOG_ERROR_MESSAGE (" Not enough space for the chunk header. The byte code may be corrupted." );
17661774 return {};
17671775 }
1768- if ((Ptr + Chunks[i] + pChunk->Length ) > EndPtr)
1776+
1777+ ChunkHeader& Chunk = reinterpret_cast <ChunkHeader&>(RemappedBytecode[ChunkOffset]);
1778+ if (ChunkOffset + Chunk.Length > RemappedBytecode.size ())
17691779 {
17701780 LOG_ERROR_MESSAGE (" Not enough space for the chunk data. The byte code may be corrupted." );
17711781 return {};
17721782 }
17731783
1774- if (pChunk-> Magic == RDEFFourCC)
1784+ if (Chunk. Magic == RDEFFourCC)
17751785 {
1776- ResourceDefChunkHeader* RDEFHeader = reinterpret_cast <ResourceDefChunkHeader*>(pChunk );
1786+ ResourceDefChunkHeader& RDEFHeader = reinterpret_cast <ResourceDefChunkHeader&>(Chunk );
17771787
1778- if (RDEFHeader-> MajorVersion == 5 && RDEFHeader-> MinorVersion == 1 )
1788+ if (RDEFHeader. MajorVersion == 5 && RDEFHeader. MinorVersion == 1 )
17791789 {
1780- RemapShaderResources<ResourceBindingInfo51>(ResourceMap, EndPtr , RDEFHeader, ExtResourceMap, BindingsPerType);
1790+ RemapShaderResources<ResourceBindingInfo51>(ResourceMap, RemappedBytecode. data () + RemappedBytecode. size () , RDEFHeader, ExtResourceMap, BindingsPerType);
17811791 RemapResDef = true ;
17821792 }
1783- else if ((RDEFHeader-> MajorVersion == 5 && RDEFHeader-> MinorVersion == 0 ) || RDEFHeader-> MajorVersion < 5 )
1793+ else if ((RDEFHeader. MajorVersion == 5 && RDEFHeader. MinorVersion == 0 ) || RDEFHeader. MajorVersion < 5 )
17841794 {
1785- RemapShaderResources<ResourceBindingInfo50>(ResourceMap, EndPtr , RDEFHeader, ExtResourceMap, BindingsPerType);
1795+ RemapShaderResources<ResourceBindingInfo50>(ResourceMap, RemappedBytecode. data () + RemappedBytecode. size () , RDEFHeader, ExtResourceMap, BindingsPerType);
17861796 RemapResDef = true ;
17871797 }
17881798 else
17891799 {
1790- LOG_ERROR_MESSAGE (" Unexpected shader model: " , RDEFHeader-> MajorVersion , ' .' , RDEFHeader-> MinorVersion );
1800+ LOG_ERROR_MESSAGE (" Unexpected shader model: " , RDEFHeader. MajorVersion , ' .' , RDEFHeader. MinorVersion );
17911801 }
17921802 }
17931803
1794- if (pChunk-> Magic == SHDRFourCC || pChunk-> Magic == SHEXFourCC)
1804+ if (Chunk. Magic == SHDRFourCC || Chunk. Magic == SHEXFourCC)
17951805 {
1796- Uint32* Token = reinterpret_cast <Uint32*>(Ptr + Chunks[i] + sizeof (ShaderChunkHeader));
1797- const ShaderChunkHeader& SBHeader = * reinterpret_cast <ShaderChunkHeader*>(pChunk );
1806+ Uint32* Token = reinterpret_cast <Uint32*>(&RemappedBytecode[ChunkOffset + sizeof (ShaderChunkHeader)] );
1807+ const ShaderChunkHeader& SBHeader = reinterpret_cast <ShaderChunkHeader&>(Chunk );
17981808 ShaderBytecodeRemapper Remapper{SBHeader, ExtResourceMap, BindingsPerType};
17991809
1800- Remapper.PatchBytecode (Token, EndPtr );
1801- RemapBytecode = true ;
1810+ Remapper.PatchBytecode (Token, RemappedBytecode. data () + RemappedBytecode. size () );
1811+ PatchOK = true ;
18021812 }
18031813 }
18041814 }
@@ -1813,20 +1823,20 @@ RefCntAutoPtr<IDataBlob> RemapResourceBindings(const TResourceBindingMap& Resour
18131823 return {};
18141824 }
18151825
1816- if (!RemapBytecode )
1826+ if (!PatchOK )
18171827 {
18181828 LOG_ERROR_MESSAGE (" Failed to find 'SHDR' or 'SHEX' chunk with the shader bytecode." );
18191829 return {};
18201830 }
18211831
18221832 // update checksum
18231833 DWORD Checksum[4 ] = {};
1824- CalculateDXBCChecksum (reinterpret_cast <BYTE*>(Ptr) , static_cast <DWORD>(Size ), Checksum);
1834+ CalculateDXBCChecksum (reinterpret_cast <BYTE*>(RemappedBytecode. data ()) , static_cast <DWORD>(RemappedBytecode. size () ), Checksum);
18251835
18261836 static_assert (sizeof (Header.Checksum ) == sizeof (Checksum), " Unexpected checksum size" );
1827- memcpy (pRemappedBytecode-> GetDataPtr <DXBCHeader>( )->Checksum , Checksum, sizeof (Header.Checksum ));
1837+ memcpy (reinterpret_cast <DXBCHeader*>(RemappedBytecode. data () )->Checksum , Checksum, sizeof (Header.Checksum ));
18281838
1829- return pRemappedBytecode ;
1839+ return DataBlobImpl::Create ( std::move (RemappedBytecode)) ;
18301840}
18311841
18321842} // namespace DXBCUtils
0 commit comments