Decode relocations in ELF

Related-To: NEO-4769, NEO-5323

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2021-01-11 18:29:55 +01:00
committed by Compute-Runtime-Automation
parent d9b6280511
commit ffb6e955b1
9 changed files with 683 additions and 14 deletions

View File

@@ -1,16 +1,129 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device_binary_format/elf/elf.h"
#include "shared/source/device_binary_format/elf/elf_decoder.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/source/helpers/array_count.h"
#include "shared/source/helpers/file_io.h"
#include "shared/test/unit_test/mocks/mock_elf.h"
#include "test.h"
#include "gmock/gmock.h"
using namespace NEO::Elf;
using ELF_CLASS = NEO::Elf::ELF_IDENTIFIER_CLASS;
class TestElf {
public:
TestElf() {
memset(dummyData, 0, sizeof(dummyData));
}
std::vector<uint8_t> createRelocateableElfWithDebugData() {
MockElfEncoder<> elfEncoder;
elfEncoder.getElfFileHeader().type = ELF_TYPE::ET_REL;
elfEncoder.getElfFileHeader().machine = ELF_MACHINE::EM_NONE;
elfEncoder.appendSection(SHT_PROGBITS, SpecialSectionNames::text.str(), ArrayRef<const uint8_t>(dummyData, sizeof(dummyData)));
auto textSectionIndex = elfEncoder.getLastSectionHeaderIndex();
ElfRela<ELF_CLASS::EI_CLASS_64> relocationsWithAddend[2];
relocationsWithAddend[0].addend = relaAddend;
relocationsWithAddend[0].info = relaSymbolIndexes[0] << 32 | uint32_t(RELOCATION_X8664_TYPE::R_X8664_64);
relocationsWithAddend[0].offset = relaOffsets[0];
relocationsWithAddend[1].addend = relaAddend;
relocationsWithAddend[1].info = relaSymbolIndexes[1] << 32 | uint32_t(RELOCATION_X8664_TYPE::R_X8664_32);
relocationsWithAddend[1].offset = relaOffsets[1];
elfEncoder.appendSection(SHT_PROGBITS, SpecialSectionNames::debug, ArrayRef<const uint8_t>(dummyData, sizeof(dummyData)));
auto debugSectionIndex = elfEncoder.getLastSectionHeaderIndex();
elfEncoder.appendSection(SHT_RELA, SpecialSectionNames::relaPrefix.str() + SpecialSectionNames::debug.str(),
ArrayRef<const uint8_t>(reinterpret_cast<uint8_t *>(relocationsWithAddend), sizeof(relocationsWithAddend)));
auto relaDebugSectionIndex = elfEncoder.getLastSectionHeaderIndex();
auto relaDebugSection = elfEncoder.getSectionHeader(relaDebugSectionIndex);
relaDebugSection->info = debugSectionIndex;
ElfRel<ELF_CLASS::EI_CLASS_64> relocation;
relocation.info = relSymbolIndex << 32 | uint64_t(RELOCATION_X8664_TYPE::R_X8664_64);
relocation.offset = relOffset;
elfEncoder.appendSection(SHT_PROGBITS, SpecialSectionNames::line, std::string{"dummy_line_data______________________"});
auto lineSectionIndex = elfEncoder.getLastSectionHeaderIndex();
elfEncoder.appendSection(SHT_REL, SpecialSectionNames::relPrefix.str() + SpecialSectionNames::line.str(),
ArrayRef<const uint8_t>(reinterpret_cast<uint8_t *>(&relocation), sizeof(relocation)));
auto relLineSectionIndex = elfEncoder.getLastSectionHeaderIndex();
auto relLineSection = elfEncoder.getSectionHeader(relLineSectionIndex);
relLineSection->info = lineSectionIndex;
elfEncoder.appendSection(SHT_PROGBITS, SpecialSectionNames::data, std::string{"global_data_memory"});
auto dataSectionIndex = elfEncoder.getLastSectionHeaderIndex();
symbolTable.resize(4 * sizeof(ElfSymbolEntry<ELF_CLASS::EI_CLASS_64>));
symbols = reinterpret_cast<ElfSymbolEntry<ELF_CLASS::EI_CLASS_64> *>(symbolTable.data());
symbols[0].name = 0; // undef
symbols[0].info = 0;
symbols[0].shndx = 0;
symbols[0].size = 0;
symbols[0].value = 0;
symbols[1].name = elfEncoder.appendSectionName(NEO::ConstStringRef("local_function_symbol_1"));
symbols[1].info = SYMBOL_TABLE_TYPE::STT_FUNC | SYMBOL_TABLE_BIND::STB_LOCAL << 4;
symbols[1].shndx = textSectionIndex;
symbols[1].size = 8;
symbols[1].value = 0;
symbols[1].other = 0;
symbols[2].name = elfEncoder.appendSectionName(NEO::ConstStringRef("section_symbol_2"));
symbols[2].info = SYMBOL_TABLE_TYPE::STT_SECTION | SYMBOL_TABLE_BIND::STB_LOCAL << 4;
symbols[2].shndx = textSectionIndex;
symbols[2].size = 0;
symbols[2].value = 0;
symbols[2].other = 0;
symbols[3].name = elfEncoder.appendSectionName(NEO::ConstStringRef("global_object_symbol_0"));
symbols[3].info = SYMBOL_TABLE_TYPE::STT_OBJECT | SYMBOL_TABLE_BIND::STB_GLOBAL << 4;
symbols[3].shndx = dataSectionIndex;
symbols[3].size = 4;
symbols[3].value = 7; // offset to "data" string in data section
symbols[3].other = 0;
elfEncoder.appendSection(SHT_SYMTAB, SpecialSectionNames::symtab.str(), ArrayRef<const uint8_t>(symbolTable.data(), symbolTable.size()));
auto symTabSectionIndex = elfEncoder.getLastSectionHeaderIndex();
relaDebugSection->link = symTabSectionIndex;
relLineSection->link = symTabSectionIndex;
auto symTabSectionHeader = elfEncoder.getSectionHeader(symTabSectionIndex);
symTabSectionHeader->info = 4; // one greater than last LOCAL symbol
symTabSectionHeader->link = elfEncoder.getLastSectionHeaderIndex() + 1; //strtab section added as last
return elfEncoder.encode();
}
const int64_t relaAddend = 16;
const uint64_t relaSymbolIndexes[2] = {3, 1};
const uint64_t relaOffsets[2] = {8, 24};
const uint64_t relSymbolIndex = 2;
const uint64_t relOffset = 16;
uint8_t dummyData[8 * 10];
std::vector<uint8_t> symbolTable;
ElfSymbolEntry<ELF_CLASS::EI_CLASS_64> *symbols = nullptr;
};
TEST(ElfDecoder, WhenEmptyDataThenElfHeaderDecodingFails) {
ArrayRef<const uint8_t> empty;
EXPECT_EQ(nullptr, decodeElfFileHeader<EI_CLASS_32>(empty));
@@ -342,3 +455,265 @@ TEST(ElfDecoder, WhenSectionDoesNotHaveDataInFileThenDataIsSetAsEmpty) {
EXPECT_EQ(storage.data() + sectionHeader0.offset, elf64.sectionHeaders[0].data.begin());
EXPECT_EQ(sectionHeader0.size, elf64.sectionHeaders[0].data.size());
}
TEST(ElfDecoder, WhenElfContainsInvalidSymbolSectionHeaderThenDecodingFailsAndErrorIsEmitted) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 1;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfSectionHeader<EI_CLASS_64> sectionHeader0;
sectionHeader0.type = SECTION_HEADER_TYPE::SHT_SYMTAB;
sectionHeader0.size = sizeof(sectionHeader0);
sectionHeader0.offset = header.shOff;
sectionHeader0.entsize = sizeof(ElfSymbolEntry<EI_CLASS_64>) + 4; //invalid entSize
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader0), reinterpret_cast<const uint8_t *>(&sectionHeader0 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
ASSERT_FALSE(decodeErrors.empty());
EXPECT_STREQ("Invalid symbol table entries size - expected : 24, got : 28\n", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty());
}
TEST(ElfDecoder, WhenElfContainsInvalidRelocationSectionHeaderThenDecodingFailsAndErrorIsEmitted) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 1;
ElfSectionHeader<EI_CLASS_64> sectionHeader0;
sectionHeader0.size = sizeof(sectionHeader0);
sectionHeader0.offset = header.shOff;
SECTION_HEADER_TYPE types[] = {SECTION_HEADER_TYPE::SHT_REL, SECTION_HEADER_TYPE::SHT_RELA};
size_t entSizes[] = {sizeof(ElfRel<EI_CLASS_64>) + 4, sizeof(ElfRela<EI_CLASS_64>) + 4};
std::string errors[] = {"Invalid rel entries size - expected : ",
"Invalid rela entries size - expected : "};
for (int i = 0; i < 2; i++) {
sectionHeader0.type = types[i];
sectionHeader0.entsize = entSizes[i];
storage.clear();
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader0), reinterpret_cast<const uint8_t *>(&sectionHeader0 + 1));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
EXPECT_EQ(nullptr, elf64.elfFileHeader);
EXPECT_TRUE(elf64.programHeaders.empty());
EXPECT_TRUE(elf64.sectionHeaders.empty());
ASSERT_FALSE(decodeErrors.empty());
EXPECT_THAT(decodeErrors.c_str(), testing::HasSubstr(errors[i]));
EXPECT_TRUE(decodeWarnings.empty());
}
}
TEST(ElfDecoder, GivenElf64WhenExtractingDataFromElfRelocationThenCorrectRelocTypeAndSymbolIndexIsReturned) {
ElfFileHeader<EI_CLASS_64> header64;
Elf<EI_CLASS_64> elf = {};
elf.elfFileHeader = &header64;
ElfRela<EI_CLASS_64> rela;
rela.info = decltype(ElfRela<EI_CLASS_64>::info)(RELOCATION_X8664_TYPE::R_X8664_64) | decltype(ElfRela<EI_CLASS_64>::info)(5) << 32;
auto type = elf.extractRelocType(rela);
auto symbolIndex = elf.extractSymbolIndex(rela);
EXPECT_EQ(uint32_t(RELOCATION_X8664_TYPE::R_X8664_64), type);
EXPECT_EQ(5, symbolIndex);
ElfRel<EI_CLASS_64> rel;
rel.info = decltype(ElfRela<EI_CLASS_64>::info)(RELOCATION_X8664_TYPE::R_X8664_32) | decltype(ElfRela<EI_CLASS_64>::info)(6) << 32;
type = elf.extractRelocType(rel);
symbolIndex = elf.extractSymbolIndex(rel);
EXPECT_EQ(uint32_t(RELOCATION_X8664_TYPE::R_X8664_32), type);
EXPECT_EQ(6, symbolIndex);
}
TEST(ElfDecoder, GivenElf32WhenExtractingDataFromElfRelocationThenCorrectRelocTypeAndSymbolIndexIsReturned) {
ElfFileHeader<EI_CLASS_32> header64;
Elf<EI_CLASS_32> elf = {};
elf.elfFileHeader = &header64;
ElfRela<EI_CLASS_32> rela;
rela.info = decltype(ElfRela<EI_CLASS_32>::info)(RELOCATION_X8664_TYPE::R_X8664_32) | decltype(ElfRela<EI_CLASS_32>::info)(5) << 8;
auto type = elf.extractRelocType(rela);
auto symbolIndex = elf.extractSymbolIndex(rela);
EXPECT_EQ(uint32_t(RELOCATION_X8664_TYPE::R_X8664_32), type);
EXPECT_EQ(5, symbolIndex);
ElfRel<EI_CLASS_32> rel;
rel.info = decltype(ElfRel<EI_CLASS_32>::info)(RELOCATION_X8664_TYPE::R_X8664_32) | decltype(ElfRel<EI_CLASS_32>::info)(6) << 8;
type = elf.extractRelocType(rel);
symbolIndex = elf.extractSymbolIndex(rel);
EXPECT_EQ(uint32_t(RELOCATION_X8664_TYPE::R_X8664_32), type);
EXPECT_EQ(6, symbolIndex);
}
TEST(ElfDecoder, GivenElfWhenExtractingDataFromElfSymbolThenCorrectTypeAndBindIsReturned) {
ElfFileHeader<EI_CLASS_64> header64;
Elf<EI_CLASS_64> elf = {};
elf.elfFileHeader = &header64;
ElfSymbolEntry<EI_CLASS_64> symbolEntry;
symbolEntry.info = SYMBOL_TABLE_TYPE::STT_OBJECT | SYMBOL_TABLE_BIND::STB_GLOBAL << 4;
auto type = elf.extractSymbolType(symbolEntry);
auto symbolBind = elf.extractSymbolBind(symbolEntry);
EXPECT_EQ(SYMBOL_TABLE_TYPE::STT_OBJECT, type);
EXPECT_EQ(SYMBOL_TABLE_BIND::STB_GLOBAL, symbolBind);
}
TEST(ElfDecoder, GivenElfWithStringTableSectionWhenGettingSectionNameThenCorrectNameIsReturned) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 3;
header.shStrNdx = 2;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
ElfSectionHeader<EI_CLASS_64> sectionHeader0;
sectionHeader0.size = sizeof(sectionHeader0) * 2;
sectionHeader0.offset = header.shOff;
ElfSectionHeader<EI_CLASS_64> sectionHeader1;
sectionHeader1.size = 0;
sectionHeader1.offset = header.shOff + sizeof(sectionHeader0);
std::string_view strTab("\000123456789\0section0\0section1\0", 30);
sectionHeader0.name = static_cast<uint32_t>(strTab.find("section0"));
sectionHeader1.name = static_cast<uint32_t>(strTab.find("section1"));
ElfSectionHeader<EI_CLASS_64> sectionHeaderStrTab;
sectionHeaderStrTab.size = strTab.size();
sectionHeaderStrTab.offset = header.shOff + 3 * sizeof(ElfSectionHeader<EI_CLASS_64>);
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader0), reinterpret_cast<const uint8_t *>(&sectionHeader0 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeader1), reinterpret_cast<const uint8_t *>(&sectionHeader1 + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeaderStrTab), reinterpret_cast<const uint8_t *>(&sectionHeaderStrTab + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(strTab.data()), reinterpret_cast<const uint8_t *>(strTab.data() + strTab.size()));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
auto section0 = elf64.getSectionName(0);
EXPECT_STREQ("section0", section0.c_str());
auto section1 = elf64.getSectionName(1);
EXPECT_STREQ("section1", section1.c_str());
}
TEST(ElfDecoder, GivenElfWithStringTableSectionWhenGettingSymbolNameThenCorrectNameIsReturned) {
std::vector<uint8_t> storage;
ElfFileHeader<EI_CLASS_64> header;
header.shOff = header.ehSize;
header.shNum = 1;
header.shStrNdx = 0;
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&header), reinterpret_cast<const uint8_t *>(&header + 1));
std::string_view strTab("abcdef_symbol\0", 15);
ElfSectionHeader<EI_CLASS_64> sectionHeaderStrTab;
sectionHeaderStrTab.size = strTab.size();
sectionHeaderStrTab.offset = header.shOff + sizeof(ElfSectionHeader<EI_CLASS_64>);
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(&sectionHeaderStrTab), reinterpret_cast<const uint8_t *>(&sectionHeaderStrTab + 1));
storage.insert(storage.end(), reinterpret_cast<const uint8_t *>(strTab.data()), reinterpret_cast<const uint8_t *>(strTab.data() + strTab.size()));
std::string decodeWarnings;
std::string decodeErrors;
auto elf64 = decodeElf<EI_CLASS_64>(storage, decodeErrors, decodeWarnings);
auto nameOffset = static_cast<uint32_t>(strTab.find("symbol"));
auto symbol = elf64.getSymbolName(nameOffset);
EXPECT_STREQ("symbol", symbol.c_str());
}
TEST(ElfDecoder, WhenGettingSymbolAddressThenCorectValueIsReturned) {
MockElf<EI_CLASS_64> elf;
ElfSymbolEntry<EI_CLASS_64> symbol;
symbol.info = SYMBOL_TABLE_TYPE::STT_OBJECT;
symbol.name = 0;
symbol.shndx = 1;
symbol.size = 8;
symbol.value = 0x1234000;
elf.symbolTable.push_back(symbol);
symbol.value = 0xfffff000;
elf.symbolTable.push_back(symbol);
auto address0 = elf.getSymbolAddress(0);
auto address1 = elf.getSymbolAddress(1);
EXPECT_EQ(0x1234000u, address0);
EXPECT_EQ(0xfffff000u, address1);
}
TEST(ElfDecoder, GivenElfWithRelocationsWhenDecodedThenCorrectRelocationsAndSymolsAreExtracted) {
std::string decodeWarnings;
std::string decodeErrors;
TestElf testElf;
auto elfFile = testElf.createRelocateableElfWithDebugData();
size_t size = elfFile.size();
auto elf64 = decodeElf<EI_CLASS_64>(ArrayRef<uint8_t>(elfFile.data(), size), decodeErrors, decodeWarnings);
EXPECT_NE(nullptr, elf64.elfFileHeader);
auto relocations = elf64.getRelocations();
ASSERT_EQ(3u, relocations.size());
EXPECT_EQ(testElf.relaAddend, relocations[0].addend);
EXPECT_EQ(testElf.relaOffsets[0], relocations[0].offset);
EXPECT_EQ(uint32_t(RELOCATION_X8664_TYPE::R_X8664_64), relocations[0].relocType);
EXPECT_STREQ("global_object_symbol_0", relocations[0].symbolName.c_str());
EXPECT_EQ(6, relocations[0].symbolSectionIndex);
EXPECT_EQ(3, relocations[0].symbolTableIndex);
EXPECT_EQ(2, relocations[0].targetSectionIndex);
EXPECT_EQ(testElf.relaAddend, relocations[1].addend);
EXPECT_EQ(testElf.relaOffsets[1], relocations[1].offset);
EXPECT_EQ(uint32_t(RELOCATION_X8664_TYPE::R_X8664_32), relocations[1].relocType);
EXPECT_STREQ("local_function_symbol_1", relocations[1].symbolName.c_str());
EXPECT_EQ(1, relocations[1].symbolSectionIndex);
EXPECT_EQ(1, relocations[1].symbolTableIndex);
EXPECT_EQ(2, relocations[1].targetSectionIndex);
EXPECT_EQ(0u, relocations[2].addend);
EXPECT_EQ(testElf.relOffset, relocations[2].offset);
EXPECT_EQ(uint32_t(RELOCATION_X8664_TYPE::R_X8664_64), relocations[2].relocType);
EXPECT_STREQ("section_symbol_2", relocations[2].symbolName.c_str());
EXPECT_EQ(1, relocations[2].symbolSectionIndex);
EXPECT_EQ(2, relocations[2].symbolTableIndex);
EXPECT_EQ(4, relocations[2].targetSectionIndex);
auto symbolTable = elf64.getSymbols();
ASSERT_EQ(4u, symbolTable.size());
EXPECT_EQ(SYMBOL_TABLE_TYPE::STT_NOTYPE, elf64.extractSymbolType(symbolTable[0]));
EXPECT_EQ(SYMBOL_TABLE_BIND::STB_LOCAL, elf64.extractSymbolBind(symbolTable[0]));
EXPECT_EQ(SYMBOL_TABLE_TYPE::STT_FUNC, elf64.extractSymbolType(symbolTable[1]));
EXPECT_EQ(SYMBOL_TABLE_BIND::STB_LOCAL, elf64.extractSymbolBind(symbolTable[1]));
EXPECT_EQ(SYMBOL_TABLE_TYPE::STT_SECTION, elf64.extractSymbolType(symbolTable[2]));
EXPECT_EQ(SYMBOL_TABLE_BIND::STB_LOCAL, elf64.extractSymbolBind(symbolTable[2]));
EXPECT_EQ(SYMBOL_TABLE_TYPE::STT_OBJECT, elf64.extractSymbolType(symbolTable[3]));
EXPECT_EQ(SYMBOL_TABLE_BIND::STB_GLOBAL, elf64.extractSymbolBind(symbolTable[3]));
}

View File

@@ -1652,7 +1652,7 @@ TEST(DecodeSingleDeviceBinaryZebin, GivenConstDataSectionThenSetsUpInitDataAndSi
EXPECT_EQ(nullptr, programInfo.globalVariables.initData);
}
TEST(DecodeSingleDeviceBinaryZebin, GivenSymtabSectionThenEmirsWarningAndSkipsIt) {
TEST(DecodeSingleDeviceBinaryZebin, GivenSymtabSectionThenEmitsWarningAndSkipsIt) {
ZebinTestData::ValidEmptyProgram zebin;
const uint8_t data[] = {2, 3, 5, 7, 11, 13, 17, 19};
zebin.appendSection(NEO::Elf::SHT_SYMTAB, NEO::Elf::SectionsNamesZebin::symtab, data).entsize = sizeof(NEO::Elf::ElfSymbolEntry<NEO::Elf::EI_CLASS_64>);
@@ -1680,7 +1680,7 @@ TEST(DecodeSingleDeviceBinaryZebin, GivenSymtabWithInvalidSymEntriesThenFails) {
std::string decodeWarnings;
auto error = NEO::decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(programInfo, singleBinary, decodeErrors, decodeWarnings);
EXPECT_EQ(NEO::DecodeError::InvalidBinary, error);
EXPECT_STREQ("DeviceBinaryFormat::Zebin : Invalid symbol table entries size - expected : 24, got : 23\n", decodeErrors.c_str());
EXPECT_STREQ("Invalid symbol table entries size - expected : 24, got : 23\n", decodeErrors.c_str());
EXPECT_TRUE(decodeWarnings.empty()) << decodeWarnings;
}

View File

@@ -18,6 +18,7 @@ set(NEO_CORE_tests_mocks
${CMAKE_CURRENT_SOURCE_DIR}/mock_debugger.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_device.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_device.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_elf.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_graphics_allocation.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_os_library.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_sip.cpp

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/device_binary_format/elf/elf_decoder.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
template <NEO::Elf::ELF_IDENTIFIER_CLASS NumBits = NEO::Elf::EI_CLASS_64>
struct MockElf : public NEO::Elf::Elf<NumBits> {
using BaseClass = NEO::Elf::Elf<NumBits>;
using BaseClass::relocations;
using BaseClass::symbolTable;
};
template <NEO::Elf::ELF_IDENTIFIER_CLASS NumBits = NEO::Elf::EI_CLASS_64>
struct MockElfEncoder : public NEO::Elf::ElfEncoder<NumBits> {
using NEO::Elf::ElfEncoder<NumBits>::sectionHeaders;
uint32_t getLastSectionHeaderIndex() {
return uint32_t(sectionHeaders.size()) - 1;
}
NEO::Elf::ElfSectionHeader<NumBits> *getSectionHeader(uint32_t idx) {
return sectionHeaders.data() + idx;
}
};