feature: Adding support for zebin's .text section

Related-To: NEO-12229

Signed-off-by: Chodor, Jaroslaw <jaroslaw.chodor@intel.com>
This commit is contained in:
Chodor, Jaroslaw
2025-07-07 15:12:59 +00:00
committed by Compute-Runtime-Automation
parent a6149fca1a
commit a1da10ea75
10 changed files with 132 additions and 70 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -122,7 +122,10 @@ bool isValidInlineCollectionFormat(const char *context, const char *contextEnd)
if (isWhitespace(*context)) {
context++;
} else if (false == endNum) {
if (isAlphaNumeric(*context)) {
if (*context == ']') {
context++;
endCollection = true;
} else if (isAlphaNumeric(*context)) {
consumeAlphaNum(context);
endNum = true;
} else {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -305,7 +305,7 @@ using LinesCache = StackVec<Line, 512>;
std::string constructYamlError(size_t lineNumber, const char *lineBeg, const char *parsePos, const char *reason = nullptr);
bool isValidInlineCollectionFormat(const char *context, const char *contextEnd);
constexpr ConstStringRef inlineCollectionYamlErrorMsg = "NEO::Yaml : Inline collection is not in valid regex format - ^\\[(\\s*(\\d|\\w)+,?)+\\s*\\]\\s*\\n";
constexpr ConstStringRef inlineCollectionYamlErrorMsg = "NEO::Yaml : Inline collection is not in valid regex format - ^\\[(\\s*(\\d|\\w)+,?)*\\s*\\]\\s*\\n";
bool tokenize(ConstStringRef text, LinesCache &outLines, TokensCache &outTokens, std::string &outErrReason, std::string &outWarning);

View File

@@ -242,6 +242,8 @@ DecodeError extractZebinSections(NEO::Elf::Elf<numBits> &elf, ZebinSections<numB
case Elf::SHT_PROGBITS:
if (sectionName.startsWith(Elf::SectionNames::textPrefix.data())) {
out.textKernelSections.push_back(&elfSectionHeader);
} else if (sectionName == Elf::SectionNames::text) {
out.textSections.push_back(&elfSectionHeader);
} else if (sectionName == Elf::SectionNames::dataConst) {
out.constDataSections.push_back(&elfSectionHeader);
} else if (sectionName == Elf::SectionNames::dataGlobalConst) {
@@ -254,7 +256,7 @@ DecodeError extractZebinSections(NEO::Elf::Elf<numBits> &elf, ZebinSections<numB
} 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");
outErrReason.append("DeviceBinaryFormat::zebin : Unhandled SHT_PROGBITS section : " + sectionName.str() + " currently supports only : " + Elf::SectionNames::text.str() + " (aliased to " + Elf::SectionNames::functions.str() + "), " + Elf::SectionNames::textPrefix.str() + "KERNEL_NAME, " + Elf::SectionNames::dataConst.str() + ", " + Elf::SectionNames::dataGlobal.str() + " and " + Elf::SectionNames::debugPrefix.str() + "* .\n");
return DecodeError::invalidBinary;
}
break;
@@ -339,6 +341,7 @@ DecodeError validateZebinSectionsCount(const ZebinSections<numBits> &sections, s
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);
valid &= validateZebinSectionsCountAtMost(sections.textSections, Elf::SectionNames::text, 1U, outErrReason, outWarning);
return valid ? DecodeError::success : DecodeError::invalidBinary;
}
@@ -360,6 +363,18 @@ ConstStringRef getZeInfoFromZebin(const ArrayRef<const uint8_t> zebin, std::stri
: extractZeInfoMetadataString<Elf::EI_CLASS_64>(zebin, outErrReason, outWarning);
}
template <Elf::ElfIdentifierClass numBits>
void handleTextSection(ProgramInfo &dst, NEO::Elf::Elf<numBits> &elf, ZebinSections<numBits> &zebinSections) {
if (zebinSections.textSections.empty()) {
return;
}
zebinSections.textKernelSections.push_back(zebinSections.textSections[0]);
auto kernelInfo = std::make_unique<KernelInfo>();
kernelInfo->kernelDescriptor.kernelMetadata.kernelName = NEO::Zebin::Elf::SectionNames::externalFunctions.str();
dst.kernelInfos.push_back(kernelInfo.release());
}
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::ElfIdentifierClass numBits>
@@ -420,6 +435,8 @@ DecodeError decodeZebin(ProgramInfo &dst, NEO::Elf::Elf<numBits> &elf, std::stri
return decodeZeInfoError;
}
handleTextSection(dst, elf, zebinSections);
for (auto &kernelInfo : dst.kernelInfos) {
ConstStringRef kernelName(kernelInfo->kernelDescriptor.kernelMetadata.kernelName);
auto kernelInstructions = getKernelHeap(kernelName, elf, zebinSections);
@@ -457,14 +474,22 @@ ArrayRef<const uint8_t> getKernelHeap(ConstStringRef &kernelName, Elf::Elf<numBi
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) {
if (getKernelNameFromSectionName(sectionName) == kernelName) {
return textSection->data;
}
}
return {};
}
ConstStringRef getKernelNameFromSectionName(ConstStringRef sectionName) {
if (sectionName.startsWith(NEO::Zebin::Elf::SectionNames::textPrefix)) {
return sectionName.substr(NEO::Zebin::Elf::SectionNames::textPrefix.length());
} else {
DEBUG_BREAK_IF(sectionName != NEO::Zebin::Elf::SectionNames::text);
return Zebin::Elf::SectionNames::externalFunctions;
}
}
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::ElfIdentifierClass numBits>

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -31,6 +31,7 @@ namespace Zebin {
template <Elf::ElfIdentifierClass numBits = Elf::EI_CLASS_64>
struct ZebinSections {
using SectionHeaderData = NEO::Elf::SectionHeaderAndData<numBits>;
StackVec<SectionHeaderData *, 1> textSections;
StackVec<SectionHeaderData *, 32> textKernelSections;
StackVec<SectionHeaderData *, 32> gtpinInfoSections;
StackVec<SectionHeaderData *, 1> zeInfoSections;
@@ -78,5 +79,7 @@ void setKernelMiscInfoPosition(ConstStringRef metadata, ProgramInfo &dst);
ConstStringRef getZeInfoFromZebin(const ArrayRef<const uint8_t> zebin, std::string &outErrReason, std::string &outWarning);
ConstStringRef getKernelNameFromSectionName(ConstStringRef sectionName);
} // namespace Zebin
} // namespace NEO

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -35,6 +35,7 @@ enum RelocTypeZebin : uint32_t {
};
namespace SectionNames {
inline constexpr ConstStringRef text = ".text";
inline constexpr ConstStringRef textPrefix = ".text.";
inline constexpr ConstStringRef functions = ".text.Intel_Symbol_Table_Void_Program";
inline constexpr ConstStringRef dataConst = ".data.const";