/* * Copyright (C) 2020 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/device_binary_format/elf/elf_decoder.h" #include "shared/source/helpers/ptr_math.h" #include namespace NEO { namespace Elf { template const ElfFileHeader *decodeElfFileHeader(const ArrayRef binary) { if (binary.size() < sizeof(ElfFileHeader)) { return nullptr; } const ElfFileHeader *header = reinterpret_cast *>(binary.begin()); bool validHeader = (header->identity.magic[0] == elfMagic[0]); validHeader &= (header->identity.magic[1] == elfMagic[1]); validHeader &= (header->identity.magic[2] == elfMagic[2]); validHeader &= (header->identity.magic[3] == elfMagic[3]); validHeader &= (header->identity.eClass == NumBits); return validHeader ? header : nullptr; } template const ElfFileHeader *decodeElfFileHeader(const ArrayRef); template const ElfFileHeader *decodeElfFileHeader(const ArrayRef); template Elf decodeElf(const ArrayRef binary, std::string &outErrReason, std::string &outWarning) { Elf ret = {}; ret.elfFileHeader = decodeElfFileHeader(binary); if (nullptr == ret.elfFileHeader) { outErrReason = "Invalid or missing ELF header"; return {}; } if (ret.elfFileHeader->phOff + ret.elfFileHeader->phNum * ret.elfFileHeader->phEntSize > binary.size()) { outErrReason = "Out of bounds program headers table"; return {}; } if (ret.elfFileHeader->shOff + ret.elfFileHeader->shNum * ret.elfFileHeader->shEntSize > binary.size()) { outErrReason = "Out of bounds section headers table"; return {}; } const ElfProgramHeader *programHeader = reinterpret_cast *>(binary.begin() + ret.elfFileHeader->phOff); for (decltype(ret.elfFileHeader->phNum) i = 0; i < ret.elfFileHeader->phNum; ++i) { if (programHeader->offset + programHeader->fileSz > binary.size()) { outErrReason = "Out of bounds program header offset/filesz, program header idx : " + std::to_string(i); return {}; } ArrayRef data(binary.begin() + programHeader->offset, static_cast(programHeader->fileSz)); ret.programHeaders.push_back({programHeader, data}); programHeader = ptrOffset(programHeader, ret.elfFileHeader->phEntSize); } const ElfSectionHeader *sectionHeader = reinterpret_cast *>(binary.begin() + ret.elfFileHeader->shOff); for (decltype(ret.elfFileHeader->shNum) i = 0; i < ret.elfFileHeader->shNum; ++i) { ArrayRef data; if (SHT_NOBITS != sectionHeader->type) { if (sectionHeader->offset + sectionHeader->size > binary.size()) { outErrReason = "Out of bounds section header offset/size, section header idx : " + std::to_string(i); return {}; } data = ArrayRef(binary.begin() + sectionHeader->offset, static_cast(sectionHeader->size)); } ret.sectionHeaders.push_back({sectionHeader, data}); sectionHeader = ptrOffset(sectionHeader, ret.elfFileHeader->shEntSize); } return ret; } template Elf decodeElf(const ArrayRef, std::string &, std::string &); template Elf decodeElf(const ArrayRef, std::string &, std::string &); } // namespace Elf } // namespace NEO