/* * Copyright (C) 2020-2024 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 RelocationX8664Type : uint32_t { relocation64 = 0x1, relocation32 = 0xa }; template struct ProgramHeaderAndData { const ElfProgramHeader *header = nullptr; ArrayRef data; }; template struct SectionHeaderAndData { const ElfSectionHeader *header; ArrayRef data; }; template struct Elf { 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 { if (sectionHeaders.size() > id && sectionHeaders.size() > elfFileHeader->shStrNdx) { auto sectionHeaderNamesData = sectionHeaders[elfFileHeader->shStrNdx].data; return std::string(reinterpret_cast(sectionHeaderNamesData.begin()) + sectionHeaders[id].header->name); } else { return std::string(""); } } std::string getName(uint32_t nameOffset) const { auto sectionHeaderNamesData = sectionHeaders[elfFileHeader->shStrNdx].data; return std::string(reinterpret_cast(sectionHeaderNamesData.begin()) + nameOffset); } MOCKABLE_VIRTUAL std::string getSymbolName(uint32_t nameOffset) const { return getName(nameOffset); } decltype(ElfSymbolEntry::value) getSymbolValue(uint32_t idx) const { return symbolTable[idx].value; } decltype(ElfSectionHeader::offset) getSectionOffset(uint32_t idx) const { return sectionHeaders[idx].header->offset; } const Relocations &getRelocations() const { return relocations; } const Relocations &getDebugInfoRelocations() const { return debugInfoRelocations; } const SymbolsTable &getSymbols() const { return symbolTable; } const ElfFileHeader *elfFileHeader = nullptr; StackVec, 32> programHeaders; StackVec, 32> 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; }; struct DecodedNote { ConstStringRef name; ConstStringRef desc; uint32_t type; }; template bool decodeNoteSection(ArrayRef sectionData, std::vector &out, std::string &outErrReason, std::string &outWarning); extern template bool decodeNoteSection(ArrayRef sectionData, std::vector &out, std::string &outErrReason, std::string &outWarning); extern template bool decodeNoteSection(ArrayRef sectionData, std::vector &out, std::string &outErrReason, std::string &outWarning); 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 ElfIdentifierClass 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