From a8c94589361cc317cdeb09c9e4a13eac5ae40d94 Mon Sep 17 00:00:00 2001 From: Krystian Chmielewski Date: Thu, 13 Oct 2022 14:41:41 +0000 Subject: [PATCH] Unpack 32bit zebin correctly Signed-off-by: Krystian Chmielewski --- .../device_binary_format_zebin.cpp | 19 +++++++--- .../device_binary_format/zebin_decoder.cpp | 2 +- .../device_binary_formats_tests.cpp | 35 +++++++++++-------- .../zebin_decoder_tests.cpp | 26 ++++++++++++++ 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/shared/source/device_binary_format/device_binary_format_zebin.cpp b/shared/source/device_binary_format/device_binary_format_zebin.cpp index e6ef229386..97ff8c4b09 100644 --- a/shared/source/device_binary_format/device_binary_format_zebin.cpp +++ b/shared/source/device_binary_format/device_binary_format_zebin.cpp @@ -18,10 +18,11 @@ namespace NEO { -template <> -SingleDeviceBinary unpackSingleDeviceBinary(const ArrayRef archive, const ConstStringRef requestedProductAbbreviation, const TargetDevice &requestedTargetDevice, - std::string &outErrReason, std::string &outWarning) { - auto elf = Elf::decodeElf(archive, outErrReason, outWarning); +template +SingleDeviceBinary unpackSingleZebin(const ArrayRef archive, const ConstStringRef requestedProductAbbreviation, const TargetDevice &requestedTargetDevice, + std::string &outErrReason, std::string &outWarning) { + + auto elf = Elf::decodeElf(archive, outErrReason, outWarning); if (nullptr == elf.elfFileHeader) { return {}; } @@ -60,7 +61,7 @@ SingleDeviceBinary unpackSingleDeviceBinary(cons ? (requestedTargetDevice.coreFamily == static_cast(elf.elfFileHeader->machine)) : (requestedTargetDevice.productFamily == static_cast(elf.elfFileHeader->machine)); validForTarget &= (0 == flags.validateRevisionId) | ((requestedTargetDevice.stepping >= flags.minHwRevisionId) & (requestedTargetDevice.stepping <= flags.maxHwRevisionId)); - validForTarget &= (8U == requestedTargetDevice.maxPointerSizeInBytes); + validForTarget &= (requestedTargetDevice.maxPointerSizeInBytes >= static_cast(numBits == Elf::EI_CLASS_32 ? 4 : 8)); } if (false == validForTarget) { @@ -76,6 +77,14 @@ SingleDeviceBinary unpackSingleDeviceBinary(cons return ret; } +template <> +SingleDeviceBinary unpackSingleDeviceBinary(const ArrayRef archive, const ConstStringRef requestedProductAbbreviation, const TargetDevice &requestedTargetDevice, + std::string &outErrReason, std::string &outWarning) { + return Elf::isElf(archive) + ? unpackSingleZebin(archive, requestedProductAbbreviation, requestedTargetDevice, outErrReason, outWarning) + : unpackSingleZebin(archive, requestedProductAbbreviation, requestedTargetDevice, outErrReason, outWarning); +} + template void prepareLinkerInputForZebin(ProgramInfo &programInfo, Elf::Elf &elf) { programInfo.prepareLinkerInputStorage(); diff --git a/shared/source/device_binary_format/zebin_decoder.cpp b/shared/source/device_binary_format/zebin_decoder.cpp index 2d30065768..bcb8b5e520 100644 --- a/shared/source/device_binary_format/zebin_decoder.cpp +++ b/shared/source/device_binary_format/zebin_decoder.cpp @@ -93,7 +93,7 @@ bool validateTargetDevice(const Elf::Elf &elf, const TargetDevice &targ validForTarget &= (gfxCore != IGFX_UNKNOWN_CORE) ? targetDevice.coreFamily == gfxCore : true; validForTarget &= (productFamily != IGFX_UNKNOWN) ? targetDevice.productFamily == productFamily : true; validForTarget &= (0 == targetMetadata.validateRevisionId) | ((targetDevice.stepping >= targetMetadata.minHwRevisionId) & (targetDevice.stepping <= targetMetadata.maxHwRevisionId)); - validForTarget &= (8U == targetDevice.maxPointerSizeInBytes); + validForTarget &= (targetDevice.maxPointerSizeInBytes >= static_cast(numBits == Elf::EI_CLASS_32 ? 4 : 8)); return validForTarget; } diff --git a/shared/test/unit_test/device_binary_format/device_binary_formats_tests.cpp b/shared/test/unit_test/device_binary_format/device_binary_formats_tests.cpp index d6158591c5..d7b5da6368 100644 --- a/shared/test/unit_test/device_binary_format/device_binary_formats_tests.cpp +++ b/shared/test/unit_test/device_binary_format/device_binary_formats_tests.cpp @@ -159,27 +159,32 @@ TEST(UnpackSingleDeviceBinary, GivenArBinaryWithOclElfThenReturnPatchtokensBinar } TEST(UnpackSingleDeviceBinary, GivenZebinThenReturnSelf) { - ZebinTestData::ValidEmptyProgram zebinProgram; + ZebinTestData::ValidEmptyProgram zebin64BitProgram; + ZebinTestData::ValidEmptyProgram zebin32BitProgram; + auto requestedProductAbbreviation = "unk"; NEO::TargetDevice requestedTargetDevice; - requestedTargetDevice.productFamily = static_cast(zebinProgram.elfHeader->machine); + requestedTargetDevice.productFamily = static_cast(zebin64BitProgram.elfHeader->machine); requestedTargetDevice.stepping = 0U; requestedTargetDevice.maxPointerSizeInBytes = 8U; std::string outErrors; std::string outWarnings; - auto unpacked = NEO::unpackSingleDeviceBinary(zebinProgram.storage, requestedProductAbbreviation, requestedTargetDevice, outErrors, outWarnings); - EXPECT_TRUE(unpacked.buildOptions.empty()); - EXPECT_TRUE(unpacked.debugData.empty()); - EXPECT_FALSE(unpacked.deviceBinary.empty()); - EXPECT_EQ(zebinProgram.storage.data(), unpacked.deviceBinary.begin()); - EXPECT_EQ(zebinProgram.storage.size(), unpacked.deviceBinary.size()); - EXPECT_TRUE(unpacked.intermediateRepresentation.empty()); - EXPECT_EQ(NEO::DeviceBinaryFormat::Zebin, unpacked.format); - EXPECT_EQ(requestedTargetDevice.coreFamily, unpacked.targetDevice.coreFamily); - EXPECT_EQ(requestedTargetDevice.stepping, unpacked.targetDevice.stepping); - EXPECT_EQ(8U, unpacked.targetDevice.maxPointerSizeInBytes); - EXPECT_TRUE(outWarnings.empty()); - EXPECT_TRUE(outErrors.empty()); + + for (auto zebin : {&zebin64BitProgram.storage, &zebin32BitProgram.storage}) { + auto unpacked = NEO::unpackSingleDeviceBinary(*zebin, requestedProductAbbreviation, requestedTargetDevice, outErrors, outWarnings); + EXPECT_TRUE(unpacked.buildOptions.empty()); + EXPECT_TRUE(unpacked.debugData.empty()); + EXPECT_FALSE(unpacked.deviceBinary.empty()); + EXPECT_EQ(zebin->data(), unpacked.deviceBinary.begin()); + EXPECT_EQ(zebin->size(), unpacked.deviceBinary.size()); + EXPECT_TRUE(unpacked.intermediateRepresentation.empty()); + EXPECT_EQ(NEO::DeviceBinaryFormat::Zebin, unpacked.format); + EXPECT_EQ(requestedTargetDevice.coreFamily, unpacked.targetDevice.coreFamily); + EXPECT_EQ(requestedTargetDevice.stepping, unpacked.targetDevice.stepping); + EXPECT_EQ(8U, unpacked.targetDevice.maxPointerSizeInBytes); + EXPECT_TRUE(outWarnings.empty()); + EXPECT_TRUE(outErrors.empty()); + } } TEST(IsAnyPackedDeviceBinaryFormat, GivenUnknownFormatThenReturnFalse) { diff --git a/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp b/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp index 8fdc0d44d7..e8bccc15e6 100644 --- a/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp +++ b/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp @@ -5635,6 +5635,32 @@ TEST_F(IntelGTNotesFixture, WhenValidatingTargetDeviceGivenValidTargetDeviceAndV EXPECT_TRUE(validateTargetDevice(elf, targetDevice, outErrReason, outWarning)); } +TEST(ValidateTargetDevice32BitZebin, Given32BitZebinAndValidIntelGTNotesWhenValidatingTargetDeviceThenReturnTrue) { + TargetDevice targetDevice; + targetDevice.productFamily = productFamily; + targetDevice.coreFamily = renderCoreFamily; + targetDevice.maxPointerSizeInBytes = 4; + targetDevice.stepping = hardwareInfoTable[productFamily]->platform.usRevId; + + ZebinTestData::ValidEmptyProgram zebin; + zebin.elfHeader->type = Elf::ET_REL; + zebin.elfHeader->machine = Elf::ELF_MACHINE::EM_INTELGT; + + Elf::ZebinTargetFlags targetMetadata; + targetMetadata.validateRevisionId = true; + targetMetadata.minHwRevisionId = targetDevice.stepping; + targetMetadata.maxHwRevisionId = targetDevice.stepping; + auto currentVersion = versionToString(NEO::zeInfoDecoderVersion); + auto intelGTNotesSection = ZebinTestData::createIntelGTNoteSection(productFamily, renderCoreFamily, targetMetadata, currentVersion); + zebin.appendSection(Elf::SHT_NOTE, Elf::SectionsNamesZebin::noteIntelGT, intelGTNotesSection); + std::string outErrReason, outWarning; + auto elf = Elf::decodeElf(zebin.storage, outErrReason, outWarning); + EXPECT_TRUE(outWarning.empty()); + EXPECT_TRUE(outErrReason.empty()); + + EXPECT_TRUE(validateTargetDevice(elf, targetDevice, outErrReason, outWarning)); +} + TEST_F(IntelGTNotesFixture, WhenValidatingTargetDeviceGivenValidTargetDeviceAndNoNotesThenReturnFalse) { TargetDevice targetDevice; targetDevice.productFamily = productFamily;