2023-02-16 15:09:51 +00:00
/*
* Copyright ( C ) 2022 - 2023 Intel Corporation
*
* SPDX - License - Identifier : MIT
*
*/
# include "shared/source/device_binary_format/zebin/zebin_decoder.h"
# include "shared/source/compiler_interface/intermediate_representations.h"
# include "shared/source/debug_settings/debug_settings_manager.h"
# include "shared/source/device_binary_format/device_binary_formats.h"
# include "shared/source/device_binary_format/elf/elf_decoder.h"
# include "shared/source/device_binary_format/zebin/zebin_elf.h"
# include "shared/source/device_binary_format/zebin/zeinfo_decoder.h"
# include "shared/source/helpers/aligned_memory.h"
# include "shared/source/helpers/ptr_math.h"
# include "shared/source/program/kernel_info.h"
# include "shared/source/program/program_info.h"
2023-04-14 15:13:15 +00:00
# include "shared/source/utilities/logger.h"
2023-02-16 15:09:51 +00:00
# include "platforms.h"
namespace NEO {
template < >
bool isDeviceBinaryFormat < NEO : : DeviceBinaryFormat : : Zebin > ( const ArrayRef < const uint8_t > binary ) {
return Zebin : : isZebin < Elf : : EI_CLASS_64 > ( binary ) | | Zebin : : isZebin < Elf : : EI_CLASS_32 > ( binary ) ;
} ;
namespace Zebin {
void setKernelMiscInfoPosition ( ConstStringRef metadata , NEO : : ProgramInfo & dst ) {
dst . kernelMiscInfoPos = metadata . str ( ) . find ( ZeInfo : : Tags : : kernelMiscInfo . str ( ) ) ;
}
template bool isZebin < Elf : : EI_CLASS_32 > ( ArrayRef < const uint8_t > binary ) ;
template bool isZebin < Elf : : EI_CLASS_64 > ( ArrayRef < const uint8_t > binary ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
bool isZebin ( ArrayRef < const uint8_t > binary ) {
auto fileHeader = Elf : : decodeElfFileHeader < numBits > ( binary ) ;
return fileHeader ! = nullptr & &
( fileHeader - > type = = Elf : : ET_REL | |
fileHeader - > type = = Elf : : ET_ZEBIN_EXE ) ;
}
bool validateTargetDevice ( const TargetDevice & targetDevice , Elf : : ELF_IDENTIFIER_CLASS numBits , PRODUCT_FAMILY productFamily , GFXCORE_FAMILY gfxCore , AOT : : PRODUCT_CONFIG productConfig , Elf : : ZebinTargetFlags targetMetadata ) {
if ( targetDevice . maxPointerSizeInBytes = = 4 & & static_cast < uint32_t > ( numBits = = Elf : : EI_CLASS_64 ) ) {
return false ;
}
2023-10-24 20:25:42 +02:00
if ( productConfig ! = AOT : : UNKNOWN_ISA ) {
2023-02-16 15:09:51 +00:00
return targetDevice . aotConfig . value = = productConfig ;
}
if ( gfxCore = = IGFX_UNKNOWN_CORE & & productFamily = = IGFX_UNKNOWN ) {
return false ;
}
if ( gfxCore ! = IGFX_UNKNOWN_CORE ) {
if ( targetDevice . coreFamily ! = gfxCore ) {
return false ;
}
}
if ( productFamily ! = IGFX_UNKNOWN ) {
if ( targetDevice . productFamily ! = productFamily ) {
return false ;
}
}
if ( targetMetadata . validateRevisionId ) {
bool isValidStepping = ( targetDevice . stepping > = targetMetadata . minHwRevisionId ) & & ( targetDevice . stepping < = targetMetadata . maxHwRevisionId ) ;
if ( false = = isValidStepping ) {
return false ;
}
}
return true ;
}
2023-06-09 15:23:03 +00:00
template bool validateTargetDevice < Elf : : EI_CLASS_32 > ( const Elf : : Elf < Elf : : EI_CLASS_32 > & elf , const TargetDevice & targetDevice , std : : string & outErrReason , std : : string & outWarning , GeneratorType & generatorType ) ;
template bool validateTargetDevice < Elf : : EI_CLASS_64 > ( const Elf : : Elf < Elf : : EI_CLASS_64 > & elf , const TargetDevice & targetDevice , std : : string & outErrReason , std : : string & outWarning , GeneratorType & generatorType ) ;
2023-02-16 15:09:51 +00:00
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
2023-06-09 15:23:03 +00:00
bool validateTargetDevice ( const Elf : : Elf < numBits > & elf , const TargetDevice & targetDevice , std : : string & outErrReason , std : : string & outWarning , GeneratorType & generatorType ) {
2023-02-16 15:09:51 +00:00
GFXCORE_FAMILY gfxCore = IGFX_UNKNOWN_CORE ;
PRODUCT_FAMILY productFamily = IGFX_UNKNOWN ;
AOT : : PRODUCT_CONFIG productConfig = AOT : : UNKNOWN_ISA ;
Elf : : ZebinTargetFlags targetMetadata = { } ;
std : : vector < Elf : : IntelGTNote > intelGTNotes = { } ;
auto decodeError = getIntelGTNotes ( elf , intelGTNotes , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = decodeError ) {
return false ;
}
for ( const auto & intelGTNote : intelGTNotes ) {
switch ( intelGTNote . type ) {
case Elf : : IntelGTSectionType : : ProductFamily : {
DEBUG_BREAK_IF ( sizeof ( uint32_t ) ! = intelGTNote . data . size ( ) ) ;
auto productFamilyData = reinterpret_cast < const uint32_t * > ( intelGTNote . data . begin ( ) ) ;
productFamily = static_cast < PRODUCT_FAMILY > ( * productFamilyData ) ;
break ;
}
case Elf : : IntelGTSectionType : : GfxCore : {
DEBUG_BREAK_IF ( sizeof ( uint32_t ) ! = intelGTNote . data . size ( ) ) ;
auto gfxCoreData = reinterpret_cast < const uint32_t * > ( intelGTNote . data . begin ( ) ) ;
gfxCore = static_cast < GFXCORE_FAMILY > ( * gfxCoreData ) ;
break ;
}
case Elf : : IntelGTSectionType : : TargetMetadata : {
DEBUG_BREAK_IF ( sizeof ( uint32_t ) ! = intelGTNote . data . size ( ) ) ;
auto targetMetadataPacked = reinterpret_cast < const uint32_t * > ( intelGTNote . data . begin ( ) ) ;
targetMetadata . packed = static_cast < uint32_t > ( * targetMetadataPacked ) ;
2023-06-09 15:23:03 +00:00
generatorType = static_cast < GeneratorType > ( targetMetadata . generatorId ) ;
2023-02-16 15:09:51 +00:00
break ;
}
case Elf : : IntelGTSectionType : : ZebinVersion : {
auto zebinVersionData = reinterpret_cast < const char * > ( intelGTNote . data . begin ( ) ) ;
ConstStringRef versionString ( zebinVersionData ) ;
ZeInfo : : Types : : Version receivedZeInfoVersion { 0 , 0 } ;
decodeError = ZeInfo : : populateZeInfoVersion ( receivedZeInfoVersion , versionString , outErrReason ) ;
if ( DecodeError : : Success ! = decodeError ) {
return false ;
}
decodeError = ZeInfo : : validateZeInfoVersion ( receivedZeInfoVersion , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = decodeError ) {
return false ;
}
break ;
}
case Elf : : IntelGTSectionType : : ProductConfig : {
2023-07-12 15:03:57 +00:00
DEBUG_BREAK_IF ( sizeof ( uint32_t ) ! = intelGTNote . data . size ( ) ) ;
auto productConfigData = reinterpret_cast < const uint32_t * > ( intelGTNote . data . begin ( ) ) ;
productConfig = static_cast < AOT : : PRODUCT_CONFIG > ( * productConfigData ) ;
2023-02-16 15:09:51 +00:00
break ;
}
2023-06-22 00:01:08 +00:00
case Elf : : IntelGTSectionType : : vISAAbiVersion : {
break ;
}
2023-02-16 15:09:51 +00:00
default :
outWarning . append ( " DeviceBinaryFormat::Zebin : Unrecognized IntelGTNote type: " + std : : to_string ( intelGTNote . type ) + " \n " ) ;
break ;
}
}
return validateTargetDevice ( targetDevice , numBits , productFamily , gfxCore , productConfig , targetMetadata ) ;
}
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError decodeIntelGTNoteSection ( ArrayRef < const uint8_t > intelGTNotesSection , std : : vector < Elf : : IntelGTNote > & intelGTNotes , std : : string & outErrReason , std : : string & outWarning ) {
uint64_t currentPos = 0 ;
auto sectionSize = intelGTNotesSection . size ( ) ;
while ( currentPos < sectionSize ) {
auto intelGTNote = reinterpret_cast < const Elf : : ElfNoteSection * > ( intelGTNotesSection . begin ( ) + currentPos ) ;
auto nameSz = intelGTNote - > nameSize ;
auto descSz = intelGTNote - > descSize ;
auto currOffset = sizeof ( Elf : : ElfNoteSection ) + alignUp ( nameSz , 4 ) + alignUp ( descSz , 4 ) ;
if ( currentPos + currOffset > sectionSize ) {
intelGTNotes . clear ( ) ;
outErrReason . append ( " DeviceBinaryFormat::Zebin : Offseting will cause out-of-bound memory read! Section size: " + std : : to_string ( sectionSize ) +
" , current section data offset: " + std : : to_string ( currentPos ) + " , next offset : " + std : : to_string ( currOffset ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
currentPos + = currOffset ;
auto ownerName = reinterpret_cast < const char * > ( ptrOffset ( intelGTNote , sizeof ( Elf : : ElfNoteSection ) ) ) ;
bool isValidGTNote = Elf : : IntelGTNoteOwnerName . size ( ) + 1 = = nameSz ;
isValidGTNote & = Elf : : IntelGTNoteOwnerName = = ConstStringRef ( ownerName , nameSz - 1 ) ;
if ( false = = isValidGTNote ) {
if ( 0u = = nameSz ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Empty owner name. \n " ) ;
} else {
std : : string invalidOwnerName { ownerName , nameSz } ;
invalidOwnerName . erase ( std : : remove_if ( invalidOwnerName . begin ( ) ,
invalidOwnerName . end ( ) ,
[ ] ( unsigned char c ) { return ' \0 ' = = c ; } ) ) ;
outWarning . append ( " DeviceBinaryFormat::Zebin : Invalid owner name : " + invalidOwnerName + " for IntelGTNote - note will not be used. \n " ) ;
}
continue ;
}
auto notesData = ArrayRef < const uint8_t > ( reinterpret_cast < const uint8_t * > ( ptrOffset ( ownerName , nameSz ) ) , descSz ) ;
if ( intelGTNote - > type = = Elf : : IntelGTSectionType : : ZebinVersion ) {
isValidGTNote & = notesData [ descSz - 1 ] = = ' \0 ' ;
if ( false = = isValidGTNote ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Versioning string is not null-terminated: " + ConstStringRef ( reinterpret_cast < const char * > ( notesData . begin ( ) ) , descSz ) . str ( ) + " - note will not be used. \n " ) ;
continue ;
}
}
intelGTNotes . push_back ( Elf : : IntelGTNote { static_cast < Elf : : IntelGTSectionType > ( intelGTNote - > type ) , notesData } ) ;
}
return DecodeError : : Success ;
}
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError getIntelGTNotes ( const Elf : : Elf < numBits > & elf , std : : vector < Elf : : IntelGTNote > & intelGTNotes , std : : string & outErrReason , std : : string & outWarning ) {
for ( size_t i = 0 ; i < elf . sectionHeaders . size ( ) ; i + + ) {
auto section = elf . sectionHeaders [ i ] ;
if ( Elf : : SHT_NOTE = = section . header - > type & & Elf : : SectionNames : : noteIntelGT = = elf . getSectionName ( static_cast < uint32_t > ( i ) ) ) {
return decodeIntelGTNoteSection < numBits > ( section . data , intelGTNotes , outErrReason , outWarning ) ;
}
}
return DecodeError : : Success ;
}
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError extractZebinSections ( NEO : : Elf : : Elf < numBits > & elf , ZebinSections < numBits > & out , std : : string & outErrReason , std : : string & outWarning ) {
if ( ( elf . elfFileHeader - > shStrNdx > = elf . sectionHeaders . size ( ) ) | | ( NEO : : Elf : : SHN_UNDEF = = elf . elfFileHeader - > shStrNdx ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid or missing shStrNdx in elf header \n " ) ;
return DecodeError : : InvalidBinary ;
}
auto sectionHeaderNamesData = elf . sectionHeaders [ elf . elfFileHeader - > shStrNdx ] . data ;
ConstStringRef sectionHeaderNamesString ( reinterpret_cast < const char * > ( sectionHeaderNamesData . begin ( ) ) , sectionHeaderNamesData . size ( ) ) ;
for ( auto & elfSectionHeader : elf . sectionHeaders ) {
ConstStringRef sectionName = ConstStringRef ( sectionHeaderNamesString . begin ( ) + elfSectionHeader . header - > name ) ;
switch ( elfSectionHeader . header - > type ) {
default :
outErrReason . append ( " DeviceBinaryFormat::Zebin : Unhandled ELF section header type : " + std : : to_string ( elfSectionHeader . header - > type ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
case Elf : : SHT_PROGBITS :
if ( sectionName . startsWith ( Elf : : SectionNames : : textPrefix . data ( ) ) ) {
out . textKernelSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName = = Elf : : SectionNames : : dataConst ) {
out . constDataSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName = = Elf : : SectionNames : : dataGlobalConst ) {
outWarning . append ( " Misspelled section name : " + sectionName . str ( ) + " , should be : " + Elf : : SectionNames : : dataConst . str ( ) + " \n " ) ;
out . constDataSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName = = Elf : : SectionNames : : dataGlobal ) {
out . globalDataSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName = = Elf : : SectionNames : : dataConstString ) {
out . constDataStringSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName . startsWith ( Elf : : SectionNames : : debugPrefix . data ( ) ) ) {
// ignoring intentionally
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Unhandled SHT_PROGBITS section : " + sectionName . str ( ) + " currently supports only : " + Elf : : SectionNames : : textPrefix . str ( ) + " KERNEL_NAME, " + Elf : : SectionNames : : dataConst . str ( ) + " , " + Elf : : SectionNames : : dataGlobal . str ( ) + " and " + Elf : : SectionNames : : debugPrefix . str ( ) + " * . \n " ) ;
return DecodeError : : InvalidBinary ;
}
break ;
case Elf : : SHT_ZEBIN_ZEINFO :
out . zeInfoSections . push_back ( & elfSectionHeader ) ;
break ;
case NEO : : Elf : : SHT_SYMTAB :
out . symtabSections . push_back ( & elfSectionHeader ) ;
break ;
case Elf : : SHT_ZEBIN_SPIRV :
out . spirvSections . push_back ( & elfSectionHeader ) ;
break ;
case NEO : : Elf : : SHT_NOTE :
if ( sectionName = = Elf : : SectionNames : : noteIntelGT ) {
out . noteIntelGTSections . push_back ( & elfSectionHeader ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin : Unhandled SHT_NOTE section : " + sectionName . str ( ) + " currently supports only : " + Elf : : SectionNames : : noteIntelGT . str ( ) + " . \n " ) ;
}
break ;
case Elf : : SHT_ZEBIN_MISC :
if ( sectionName = = Elf : : SectionNames : : buildOptions ) {
out . buildOptionsSection . push_back ( & elfSectionHeader ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin : unhandled SHT_ZEBIN_MISC section : " + sectionName . str ( ) + " currently supports only : " + Elf : : SectionNames : : buildOptions . str ( ) + " . \n " ) ;
}
break ;
case NEO : : Elf : : SHT_STRTAB :
// ignoring intentionally - section header names
continue ;
case NEO : : Elf : : SHT_REL :
case NEO : : Elf : : SHT_RELA :
// ignoring intentionally - rel/rela sections handled by Elf decoder
continue ;
case Elf : : SHT_ZEBIN_GTPIN_INFO :
if ( sectionName . startsWith ( Elf : : SectionNames : : gtpinInfo . data ( ) ) ) {
out . gtpinInfoSections . push_back ( & elfSectionHeader ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin : Unhandled SHT_ZEBIN_GTPIN_INFO section : " + sectionName . str ( ) + " , currently supports only : " + Elf : : SectionNames : : gtpinInfo . str ( ) + " KERNEL_NAME \n " ) ;
}
break ;
case Elf : : SHT_ZEBIN_VISA_ASM :
// ignoring intentionally - visa asm
continue ;
case NEO : : Elf : : SHT_NULL :
// ignoring intentionally, inactive section, probably UNDEF
continue ;
case NEO : : Elf : : SHT_NOBITS :
if ( sectionName = = Elf : : SectionNames : : dataConstZeroInit ) {
out . constZeroInitDataSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName = = Elf : : SectionNames : : dataGlobalZeroInit ) {
out . globalZeroInitDataSections . push_back ( & elfSectionHeader ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin : unhandled SHT_NOBITS section : " + sectionName . str ( ) + " currently supports only : " + Elf : : SectionNames : : dataConstZeroInit . str ( ) + " and " + Elf : : SectionNames : : dataGlobalZeroInit . str ( ) + " . \n " ) ;
}
break ;
}
}
return DecodeError : : Success ;
}
template < typename ContainerT >
bool validateZebinSectionsCountAtMost ( const ContainerT & sectionsContainer , ConstStringRef sectionName , uint32_t max , std : : string & outErrReason , std : : string & outWarning ) {
if ( sectionsContainer . size ( ) < = max ) {
return true ;
}
outErrReason . append ( " DeviceBinaryFormat::Zebin : Expected at most " + std : : to_string ( max ) + " of " + sectionName . str ( ) + " section, got : " + std : : to_string ( sectionsContainer . size ( ) ) + " \n " ) ;
return false ;
}
template DecodeError validateZebinSectionsCount < Elf : : EI_CLASS_32 > ( const ZebinSections < Elf : : EI_CLASS_32 > & sections , std : : string & outErrReason , std : : string & outWarning ) ;
template DecodeError validateZebinSectionsCount < Elf : : EI_CLASS_64 > ( const ZebinSections < Elf : : EI_CLASS_64 > & sections , std : : string & outErrReason , std : : string & outWarning ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError validateZebinSectionsCount ( const ZebinSections < numBits > & sections , std : : string & outErrReason , std : : string & outWarning ) {
bool valid = validateZebinSectionsCountAtMost ( sections . zeInfoSections , Elf : : SectionNames : : zeInfo , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . globalDataSections , Elf : : SectionNames : : dataGlobal , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . globalZeroInitDataSections , Elf : : SectionNames : : dataGlobalZeroInit , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . constDataSections , Elf : : SectionNames : : dataConst , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . constZeroInitDataSections , Elf : : SectionNames : : dataConstZeroInit , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . constDataStringSections , Elf : : SectionNames : : dataConstString , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . symtabSections , Elf : : SectionNames : : symtab , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . spirvSections , Elf : : SectionNames : : spv , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . noteIntelGTSections , Elf : : SectionNames : : noteIntelGT , 1U , outErrReason , outWarning ) ;
return valid ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
ConstStringRef extractZeInfoMetadataString ( const ArrayRef < const uint8_t > zebin , std : : string & outErrReason , std : : string & outWarning ) {
auto decodedElf = NEO : : Elf : : decodeElf < numBits > ( zebin , outErrReason , outWarning ) ;
for ( const auto & sectionHeader : decodedElf . sectionHeaders ) {
if ( sectionHeader . header - > type = = Elf : : SHT_ZEBIN_ZEINFO ) {
auto zeInfoData = sectionHeader . data ;
return ConstStringRef { reinterpret_cast < const char * > ( zeInfoData . begin ( ) ) , zeInfoData . size ( ) } ;
}
}
return ConstStringRef { } ;
}
ConstStringRef getZeInfoFromZebin ( const ArrayRef < const uint8_t > zebin , std : : string & outErrReason , std : : string & outWarning ) {
return Elf : : isElf < Elf : : EI_CLASS_32 > ( zebin )
? extractZeInfoMetadataString < Elf : : EI_CLASS_32 > ( zebin , outErrReason , outWarning )
: extractZeInfoMetadataString < Elf : : EI_CLASS_64 > ( zebin , outErrReason , outWarning ) ;
}
template DecodeError decodeZebin < Elf : : EI_CLASS_32 > ( ProgramInfo & dst , NEO : : Elf : : Elf < Elf : : EI_CLASS_32 > & elf , std : : string & outErrReason , std : : string & outWarning ) ;
template DecodeError decodeZebin < Elf : : EI_CLASS_64 > ( ProgramInfo & dst , NEO : : Elf : : Elf < Elf : : EI_CLASS_64 > & elf , std : : string & outErrReason , std : : string & outWarning ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError decodeZebin ( ProgramInfo & dst , NEO : : Elf : : Elf < numBits > & elf , std : : string & outErrReason , std : : string & outWarning ) {
ZebinSections < numBits > zebinSections ;
auto extractError = extractZebinSections ( elf , zebinSections , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = extractError ) {
return extractError ;
}
extractError = validateZebinSectionsCount ( zebinSections , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = extractError ) {
return extractError ;
}
if ( false = = zebinSections . globalDataSections . empty ( ) ) {
dst . globalVariables . initData = zebinSections . globalDataSections [ 0 ] - > data . begin ( ) ;
dst . globalVariables . size = zebinSections . globalDataSections [ 0 ] - > data . size ( ) ;
}
if ( false = = zebinSections . globalZeroInitDataSections . empty ( ) ) {
dst . globalVariables . zeroInitSize = static_cast < size_t > ( zebinSections . globalZeroInitDataSections [ 0 ] - > header - > size ) ;
}
if ( false = = zebinSections . constDataSections . empty ( ) ) {
dst . globalConstants . initData = zebinSections . constDataSections [ 0 ] - > data . begin ( ) ;
dst . globalConstants . size = zebinSections . constDataSections [ 0 ] - > data . size ( ) ;
}
if ( false = = zebinSections . constZeroInitDataSections . empty ( ) ) {
dst . globalConstants . zeroInitSize = static_cast < size_t > ( zebinSections . constZeroInitDataSections [ 0 ] - > header - > size ) ;
}
if ( false = = zebinSections . constDataStringSections . empty ( ) ) {
dst . globalStrings . initData = zebinSections . constDataStringSections [ 0 ] - > data . begin ( ) ;
dst . globalStrings . size = zebinSections . constDataStringSections [ 0 ] - > data . size ( ) ;
}
if ( zebinSections . zeInfoSections . empty ( ) ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Expected at least one " + Elf : : SectionNames : : zeInfo . str ( ) + " section, got 0 \n " ) ;
return DecodeError : : Success ;
}
auto metadataSectionData = zebinSections . zeInfoSections [ 0 ] - > data ;
ConstStringRef zeinfo ( reinterpret_cast < const char * > ( metadataSectionData . begin ( ) ) , metadataSectionData . size ( ) ) ;
2023-04-14 15:13:15 +00:00
std : : string logStr ( " \n === ZEInfo logging begin === \n " ) ;
logStr . append ( zeinfo . str ( ) ) ;
logStr . append ( " === ZEInfo logging end === \n " ) ;
DBG_LOG ( LogZEInfo , logStr . c_str ( ) ) ;
2023-02-16 15:09:51 +00:00
setKernelMiscInfoPosition ( zeinfo , dst ) ;
if ( std : : string : : npos ! = dst . kernelMiscInfoPos ) {
zeinfo = zeinfo . substr ( static_cast < size_t > ( 0 ) , dst . kernelMiscInfoPos ) ;
}
auto decodeZeInfoError = ZeInfo : : decodeZeInfo ( dst , zeinfo , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = decodeZeInfoError ) {
return decodeZeInfoError ;
}
for ( auto & kernelInfo : dst . kernelInfos ) {
ConstStringRef kernelName ( kernelInfo - > kernelDescriptor . kernelMetadata . kernelName ) ;
auto kernelInstructions = getKernelHeap ( kernelName , elf , zebinSections ) ;
if ( kernelInstructions . empty ( ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Could not find text section for kernel " + kernelName . str ( ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
auto gtpinInfoForKernel = getKernelGtpinInfo ( kernelName , elf , zebinSections ) ;
if ( false = = gtpinInfoForKernel . empty ( ) ) {
kernelInfo - > igcInfoForGtpin = reinterpret_cast < const gtpin : : igc_info_t * > ( gtpinInfoForKernel . begin ( ) ) ;
}
kernelInfo - > heapInfo . pKernelHeap = kernelInstructions . begin ( ) ;
2023-04-28 09:38:31 +00:00
kernelInfo - > heapInfo . kernelHeapSize = static_cast < uint32_t > ( kernelInstructions . size ( ) ) ;
kernelInfo - > heapInfo . kernelUnpaddedSize = static_cast < uint32_t > ( kernelInstructions . size ( ) ) ;
2023-02-16 15:09:51 +00:00
auto & kernelSSH = kernelInfo - > kernelDescriptor . generatedSsh ;
kernelInfo - > heapInfo . pSsh = kernelSSH . data ( ) ;
2023-04-28 09:38:31 +00:00
kernelInfo - > heapInfo . surfaceStateHeapSize = static_cast < uint32_t > ( kernelSSH . size ( ) ) ;
2023-02-16 15:09:51 +00:00
auto & kernelDSH = kernelInfo - > kernelDescriptor . generatedDsh ;
kernelInfo - > heapInfo . pDsh = kernelDSH . data ( ) ;
2023-04-28 09:38:31 +00:00
kernelInfo - > heapInfo . dynamicStateHeapSize = static_cast < uint32_t > ( kernelDSH . size ( ) ) ;
2023-02-16 15:09:51 +00:00
}
return DecodeError : : Success ;
}
template ArrayRef < const uint8_t > getKernelHeap < Elf : : EI_CLASS_32 > ( ConstStringRef & kernelName , Elf : : Elf < Elf : : EI_CLASS_32 > & elf , const ZebinSections < Elf : : EI_CLASS_32 > & zebinSections ) ;
template ArrayRef < const uint8_t > getKernelHeap < Elf : : EI_CLASS_64 > ( ConstStringRef & kernelName , Elf : : Elf < Elf : : EI_CLASS_64 > & elf , const ZebinSections < Elf : : EI_CLASS_64 > & zebinSections ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
ArrayRef < const uint8_t > getKernelHeap ( ConstStringRef & kernelName , Elf : : Elf < numBits > & elf , const ZebinSections < numBits > & zebinSections ) {
auto sectionHeaderNamesData = elf . sectionHeaders [ elf . elfFileHeader - > shStrNdx ] . data ;
ConstStringRef sectionHeaderNamesString ( reinterpret_cast < const char * > ( sectionHeaderNamesData . begin ( ) ) , sectionHeaderNamesData . size ( ) ) ;
for ( auto * textSection : zebinSections . textKernelSections ) {
ConstStringRef sectionName = ConstStringRef ( sectionHeaderNamesString . begin ( ) + textSection - > header - > name ) ;
auto sufix = sectionName . substr ( static_cast < int > ( Elf : : SectionNames : : textPrefix . length ( ) ) ) ;
if ( sufix = = kernelName ) {
return textSection - > data ;
}
}
return { } ;
}
template ArrayRef < const uint8_t > getKernelGtpinInfo < Elf : : EI_CLASS_32 > ( ConstStringRef & kernelName , Elf : : Elf < Elf : : EI_CLASS_32 > & elf , const ZebinSections < Elf : : EI_CLASS_32 > & zebinSections ) ;
template ArrayRef < const uint8_t > getKernelGtpinInfo < Elf : : EI_CLASS_64 > ( ConstStringRef & kernelName , Elf : : Elf < Elf : : EI_CLASS_64 > & elf , const ZebinSections < Elf : : EI_CLASS_64 > & zebinSections ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
ArrayRef < const uint8_t > getKernelGtpinInfo ( ConstStringRef & kernelName , Elf : : Elf < numBits > & elf , const ZebinSections < numBits > & zebinSections ) {
auto sectionHeaderNamesData = elf . sectionHeaders [ elf . elfFileHeader - > shStrNdx ] . data ;
ConstStringRef sectionHeaderNamesString ( reinterpret_cast < const char * > ( sectionHeaderNamesData . begin ( ) ) , sectionHeaderNamesData . size ( ) ) ;
for ( auto * gtpinInfoSection : zebinSections . gtpinInfoSections ) {
ConstStringRef sectionName = ConstStringRef ( sectionHeaderNamesString . begin ( ) + gtpinInfoSection - > header - > name ) ;
auto sufix = sectionName . substr ( static_cast < int > ( Elf : : SectionNames : : gtpinInfo . length ( ) ) ) ;
if ( sufix = = kernelName ) {
return gtpinInfoSection - > data ;
}
}
return { } ;
}
} // namespace Zebin
} // namespace NEO