/* * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "shared/source/device_binary_format/elf/elf.h" #include "shared/source/utilities/arrayref.h" #include "shared/source/utilities/const_stringref.h" #include "shared/source/utilities/stackvec.h" #include namespace NEO { namespace Elf { enum class RELOCATION_X8664_TYPE : uint32_t { R_X8664_64 = 0x1, R_X8664_32 = 0xa }; template struct Elf { struct ProgramHeaderAndData { const ElfProgramHeader *header = nullptr; ArrayRef data; }; struct SectionHeaderAndData { const ElfSectionHeader *header; ArrayRef data; }; struct RelocationInfo { int symbolSectionIndex; int symbolTableIndex; int targetSectionIndex; int64_t addend; uint64_t offset; uint32_t relocType; std::string symbolName; }; using Relocations = std::vector; using SymbolsTable = std::vector>; bool decodeSections(std::string &outError); template int extractSymbolIndex(const ElfReloc &elfReloc) const; template uint32_t extractRelocType(const ElfReloc &elfReloc) const; template uint32_t extractSymbolType(const ElfSymbol &elfSymbol) const { return elfSymbol.info & 0xf; } template uint32_t extractSymbolBind(const ElfSymbol &elfSymbol) const { return (elfSymbol.info >> 4) & 0xf; } MOCKABLE_VIRTUAL std::string getSectionName(uint32_t id) const { auto sectionHeaderNamesData = sectionHeaders[elfFileHeader->shStrNdx].data; return std::string(reinterpret_cast(sectionHeaderNamesData.begin()) + sectionHeaders[id].header->name); } MOCKABLE_VIRTUAL std::string getSymbolName(uint32_t nameOffset) const { auto sectionHeaderNamesData = sectionHeaders[elfFileHeader->shStrNdx].data; return std::string(reinterpret_cast(sectionHeaderNamesData.begin()) + nameOffset); } decltype(ElfSymbolEntry::value) getSymbolAddress(uint32_t idx) const { return symbolTable[idx].value; } const Relocations &getRelocations() const { return relocations; } const Relocations &getDebugInfoRelocations() const { return debugInfoRelocations; } const SymbolsTable &getSymbols() const { return symbolTable; } const ElfFileHeader *elfFileHeader = nullptr; StackVec programHeaders; StackVec sectionHeaders; protected: bool decodeSymTab(SectionHeaderAndData §ionHeaderData, std::string &outError); bool decodeRelocations(SectionHeaderAndData §ionHeaderData, std::string &outError); bool isDebugDataRelocation(ConstStringRef sectionName); SymbolsTable symbolTable; Relocations relocations; Relocations debugInfoRelocations; }; template const ElfFileHeader *decodeElfFileHeader(const ArrayRef binary); extern template const ElfFileHeader *decodeElfFileHeader(const ArrayRef); extern template const ElfFileHeader *decodeElfFileHeader(const ArrayRef); template Elf decodeElf(const ArrayRef binary, std::string &outErrReason, std::string &outWarning); extern template Elf decodeElf(const ArrayRef, std::string &, std::string &); extern template Elf decodeElf(const ArrayRef, std::string &, std::string &); template inline bool isElf(const ArrayRef binary) { return (nullptr != decodeElfFileHeader(binary)); } inline bool isElf(const ArrayRef binary) { return isElf(binary) || isElf(binary); } inline ELF_IDENTIFIER_CLASS getElfNumBits(const ArrayRef binary) { if (isElf(binary)) { return EI_CLASS_32; } else if (isElf(binary)) { return EI_CLASS_64; } return EI_CLASS_NONE; } } // namespace Elf } // namespace NEO