/* * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "shared/source/device_binary_format/elf/elf.h" #include "shared/source/helpers/aligned_memory.h" #include "shared/source/utilities/arrayref.h" #include "shared/source/utilities/const_stringref.h" #include "shared/source/utilities/stackvec.h" #include #include namespace NEO { namespace Elf { struct StringSectionBuilder { StringSectionBuilder() { stringTable.push_back('\0'); undefStringIdx = 0U; } uint32_t appendString(ConstStringRef str) { if (str.empty()) { return undefStringIdx; } uint32_t offset = static_cast(stringTable.size()); stringTable.insert(stringTable.end(), str.begin(), str.end()); if (str[str.size() - 1] != '\0') { stringTable.push_back('\0'); } return offset; } ArrayRef data() const { return ArrayRef::fromAny(stringTable.data(), stringTable.size()); } uint32_t undef() const { return undefStringIdx; } protected: std::vector stringTable; uint32_t undefStringIdx; }; template struct ElfEncoder { ElfEncoder(bool addUndefSectionHeader = true, bool addHeaderSectionNamesSection = true, typename ElfSectionHeaderTypes::AddrAlign defaultDataAlignment = 8U); void appendSection(const ElfSectionHeader §ionHeader, const ArrayRef sectionData); void appendSegment(const ElfProgramHeader &programHeader, const ArrayRef segmentData); ElfSectionHeader &appendSection(SECTION_HEADER_TYPE sectionType, ConstStringRef sectionLabel, const ArrayRef sectionData); ElfProgramHeader &appendSegment(PROGRAM_HEADER_TYPE segmentType, const ArrayRef segmentData); uint32_t getSectionHeaderIndex(const ElfSectionHeader §ionHeader); void appendProgramHeaderLoad(size_t sectionId, uint64_t vAddr, uint64_t segSize); template ElfSectionHeader &appendSection(SectionHeaderEnumT sectionType, ConstStringRef sectionLabel, const ArrayRef sectionData) { return appendSection(static_cast(sectionType), sectionLabel, sectionData); } template ElfSectionHeader &appendSection(SectionHeaderEnumT sectionType, ConstStringRef sectionLabel, const std::string §ionData) { return appendSection(static_cast(sectionType), sectionLabel, ArrayRef(reinterpret_cast(sectionData.c_str()), sectionData.size() + 1)); } uint32_t appendSectionName(ConstStringRef str); std::vector encode() const; ElfFileHeader &getElfFileHeader() { return elfFileHeader; } protected: bool addUndefSectionHeader = false; bool addHeaderSectionNamesSection = false; typename ElfSectionHeaderTypes::AddrAlign defaultDataAlignment = 8U; uint64_t maxDataAlignmentNeeded = 1U; ElfFileHeader elfFileHeader; StackVec, 32> programHeaders; StackVec, 32> sectionHeaders; std::vector data; StringSectionBuilder strSecBuilder; struct ProgramSectionID { size_t programId; size_t sectionId; }; StackVec programSectionLookupTable; uint32_t shStrTabNameOffset = 0; }; extern template struct ElfEncoder; extern template struct ElfEncoder; } // namespace Elf } // namespace NEO