diff --git a/shared/source/device_binary_format/elf/elf.h b/shared/source/device_binary_format/elf/elf.h index 9ef9c0dc85..bc1c3c1ad0 100644 --- a/shared/source/device_binary_format/elf/elf.h +++ b/shared/source/device_binary_format/elf/elf.h @@ -347,13 +347,57 @@ struct ElfSymbolEntryTypes { }; template -struct ElfSymbolEntry { - using Name = typename ElfSymbolEntryTypes::Name; - using Value = typename ElfSymbolEntryTypes::Value; - using Size = typename ElfSymbolEntryTypes::Size; - using Info = typename ElfSymbolEntryTypes::Info; - using Other = typename ElfSymbolEntryTypes::Other; - using Shndx = typename ElfSymbolEntryTypes::Shndx; +struct ElfSymbolEntry; + +template <> +struct ElfSymbolEntry { + using Name = typename ElfSymbolEntryTypes::Name; + using Value = typename ElfSymbolEntryTypes::Value; + using Size = typename ElfSymbolEntryTypes::Size; + using Info = typename ElfSymbolEntryTypes::Info; + using Other = typename ElfSymbolEntryTypes::Other; + using Shndx = typename ElfSymbolEntryTypes::Shndx; + Name name = 0U; + Value value = 0U; + Size size = 0U; + Info info = 0U; + Other other = 0U; + Shndx shndx = SHN_UNDEF; + + Info getBinding() const { + return info >> 4; + } + + Info getType() const { + return info & 0xF; + } + + Other getVisibility() const { + return other & 0x3; + } + + void setBinding(Info binding) { + info = (info & 0xF) | (binding << 4); + } + + void setType(Info type) { + info = (info & (~0xF)) | (type & 0xF); + } + + void setVisibility(Other visibility) { + other = (other & (~0x3)) | (visibility & 0x3); + } +}; +static_assert(sizeof(ElfSymbolEntry) == 0x10, ""); + +template <> +struct ElfSymbolEntry { + using Name = typename ElfSymbolEntryTypes::Name; + using Value = typename ElfSymbolEntryTypes::Value; + using Size = typename ElfSymbolEntryTypes::Size; + using Info = typename ElfSymbolEntryTypes::Info; + using Other = typename ElfSymbolEntryTypes::Other; + using Shndx = typename ElfSymbolEntryTypes::Shndx; Name name = 0U; Info info = 0U; Other other = 0U; @@ -385,8 +429,6 @@ struct ElfSymbolEntry { other = (other & (~0x3)) | (visibility & 0x3); } }; - -static_assert(sizeof(ElfSymbolEntry) == 0x10, ""); static_assert(sizeof(ElfSymbolEntry) == 0x18, ""); template diff --git a/shared/test/unit_test/device_binary_format/elf/elf_tests.cpp b/shared/test/unit_test/device_binary_format/elf/elf_tests.cpp index 6d0ecd673d..e15343df1a 100644 --- a/shared/test/unit_test/device_binary_format/elf/elf_tests.cpp +++ b/shared/test/unit_test/device_binary_format/elf/elf_tests.cpp @@ -10,8 +10,7 @@ using namespace NEO::Elf; -TEST(ElfFormat, WhenAccessingFieldsFromElfSymbolEntryThenAdequateValueIsSetOrReturned) { - // fields info and other have same size in both 32bit and 64bit elf +TEST(ElfFormat, WhenAccessingFieldsFrom64BitElfSymbolEntryThenAdequateValueIsSetOrReturned) { ElfSymbolEntry elfSym{0}; uint8_t binding = 1U; @@ -42,14 +41,45 @@ TEST(ElfFormat, WhenAccessingFieldsFromElfSymbolEntryThenAdequateValueIsSetOrRet EXPECT_EQ(visibility, elfSym.other & 0x3); } +TEST(ElfFormat, WhenAccessingFieldsFrom32BitElfSymbolEntryThenAdequateValueIsSetOrReturned) { + ElfSymbolEntry elfSym{0}; + + uint8_t binding = 1U; + elfSym.info = 0U; + elfSym.info = (elfSym.info & 0xFU) | (binding << 4U); + EXPECT_EQ(binding, elfSym.getBinding()); + + elfSym.info = 0U; + elfSym.setBinding(binding); + EXPECT_EQ(binding, elfSym.info >> 4); + + uint8_t type = 2U; + elfSym.info = 0U; + elfSym.info = (elfSym.info & (~0xFU)) | type; + EXPECT_EQ(type, elfSym.getType()); + + elfSym.info = 0U; + elfSym.setType(type); + EXPECT_EQ(type, elfSym.info & 0xF); + + uint8_t visibility = 3U; + elfSym.other = 0U; + elfSym.other = (elfSym.other & (~0x3)) | visibility; + EXPECT_EQ(visibility, elfSym.getVisibility()); + + elfSym.other = 0U; + elfSym.setVisibility(visibility); + EXPECT_EQ(visibility, elfSym.other & 0x3); +} + TEST(ElfFormat, Elf32SymbolsAreReadCorrectly) { uint8_t elfSymbolData32b[0x10] = {0}; auto &name = *reinterpret_cast(elfSymbolData32b); - auto &info = *reinterpret_cast(elfSymbolData32b + 4); - auto &other = *reinterpret_cast(elfSymbolData32b + 5); - auto &shndx = *reinterpret_cast(elfSymbolData32b + 6); - auto &value = *reinterpret_cast(elfSymbolData32b + 8); - auto &size = *reinterpret_cast(elfSymbolData32b + 0xC); + auto &value = *reinterpret_cast(elfSymbolData32b + 4); + auto &size = *reinterpret_cast(elfSymbolData32b + 8); + auto &info = *reinterpret_cast(elfSymbolData32b + 12); + auto &other = *reinterpret_cast(elfSymbolData32b + 13); + auto &shndx = *reinterpret_cast(elfSymbolData32b + 14); uint8_t type = 1U; uint8_t bind = 2U; diff --git a/shared/test/unit_test/device_binary_format/zebin_debug_binary_tests.cpp b/shared/test/unit_test/device_binary_format/zebin_debug_binary_tests.cpp index e8d40c673f..d6d6c2a799 100644 --- a/shared/test/unit_test/device_binary_format/zebin_debug_binary_tests.cpp +++ b/shared/test/unit_test/device_binary_format/zebin_debug_binary_tests.cpp @@ -125,7 +125,6 @@ TEST(DebugZebinTest, givenValidZebinThenDebugZebinIsGenerated) { NEO::Debug::Segments segments; segments.constData = {0x10000000, 0x10000}; segments.varData = {0x20000000, 0x20000}; - segments.stringData = {0x30000000, 0x30000}; segments.nameToSegMap["kernel"] = {0x40000000, 0x50000}; auto zebinBin = elfEncoder.encode(); @@ -148,10 +147,10 @@ TEST(DebugZebinTest, givenValidZebinThenDebugZebinIsGenerated) { EXPECT_EQ(zebin.sectionHeaders.size(), debugZebin.sectionHeaders.size()); - uint64_t offsetKernel, offsetConstData, offsetVarData, offsetStringData; - uint64_t fileSzKernel, fileSzConstData, fileSzVarData, fileSzStringData; - offsetKernel = offsetConstData = offsetVarData = offsetStringData = std::numeric_limits::max(); - fileSzKernel = fileSzConstData = fileSzVarData = fileSzStringData = 0; + uint64_t offsetKernel, offsetConstData, offsetVarData; + uint64_t fileSzKernel, fileSzConstData, fileSzVarData; + offsetKernel = offsetConstData = offsetVarData = std::numeric_limits::max(); + fileSzKernel = fileSzConstData = fileSzVarData = 0; for (uint32_t i = 0; i < zebin.sectionHeaders.size(); ++i) { EXPECT_EQ(zebin.sectionHeaders[i].header->type, debugZebin.sectionHeaders[i].header->type); EXPECT_EQ(zebin.sectionHeaders[i].header->link, debugZebin.sectionHeaders[i].header->link); @@ -175,10 +174,6 @@ TEST(DebugZebinTest, givenValidZebinThenDebugZebinIsGenerated) { offsetVarData = sectionHeader->offset; fileSzVarData = sectionHeader->size; EXPECT_EQ(segments.varData.address, sectionHeader->addr); - } else if (refSectionName == SectionsNamesZebin::dataConstString) { - offsetStringData = sectionHeader->offset; - fileSzStringData = sectionHeader->size; - EXPECT_EQ(segments.stringData.address, sectionHeader->addr); } else if (refSectionName == SectionsNamesZebin::debugInfo) { auto ptrDebugInfo = sectionData.begin(); EXPECT_EQ(segments.nameToSegMap["kernel"].address + symbols[0].value + debugRelocations[0].addend,