1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/*
* Copyright (C) 2020-2025 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 <queue>
#include <string>
#include <unordered_map>
#include <vector>
namespace NEO {
namespace Elf {
struct StringSectionBuilder {
StringSectionBuilder() {
stringTable.push_back('\0');
undefStringIdx = 0U;
}
void setInitialStringsTab(ArrayRef<const uint8_t> data) {
DEBUG_BREAK_IF(stringTable.size() > 1);
stringTable.assign(reinterpret_cast<const char *>(data.begin()), reinterpret_cast<const char *>(data.end()));
if (stringTable.size() < 1) {
stringTable.push_back('\0');
}
if (*stringTable.rbegin() != '\0') {
stringTable.push_back('\0');
}
auto it = stringTable.begin() + 1;
while (it != stringTable.end()) {
stringOffsetsMap[std::string(&*it)] = static_cast<uint32_t>(it - stringTable.begin());
while (*it != '\0') {
++it;
}
++it;
}
}
uint32_t appendString(ConstStringRef str) {
if (str.empty()) {
return undefStringIdx;
}
auto existingEntry = stringOffsetsMap.find(str.str());
if (stringOffsetsMap.end() != existingEntry) {
return existingEntry->second;
}
uint32_t offset = static_cast<uint32_t>(stringTable.size());
stringTable.insert(stringTable.end(), str.begin(), str.end());
if (str[str.size() - 1] != '\0') {
stringTable.push_back('\0');
}
stringOffsetsMap[str.str()] = offset;
return offset;
}
ArrayRef<const uint8_t> data() const {
return ArrayRef<const uint8_t>::fromAny(stringTable.data(), stringTable.size());
}
uint32_t undef() const {
return undefStringIdx;
}
protected:
std::vector<char> stringTable;
std::unordered_map<std::string, uint32_t> stringOffsetsMap;
uint32_t undefStringIdx;
};
template <ElfIdentifierClass numBits = EI_CLASS_64>
struct ElfEncoder {
ElfEncoder(bool addUndefSectionHeader = true, bool addHeaderSectionNamesSection = true,
typename ElfSectionHeaderTypes<numBits>::AddrAlign defaultDataAlignment = 8U);
void setInitialStringsTab(ArrayRef<const uint8_t> data) {
strSecBuilder.setInitialStringsTab(data);
}
ElfSectionHeader<numBits> &appendSection(const ElfSectionHeader<numBits> §ionHeader, const ArrayRef<const uint8_t> sectionData);
ElfProgramHeader<numBits> &appendSegment(const ElfProgramHeader<numBits> &programHeader, const ArrayRef<const uint8_t> segmentData);
ElfSectionHeader<numBits> &appendSection(SectionHeaderType sectionType, ConstStringRef sectionLabel, const ArrayRef<const uint8_t> sectionData);
ElfProgramHeader<numBits> &appendSegment(ProgramHeaderType segmentType, const ArrayRef<const uint8_t> segmentData);
uint32_t getSectionHeaderIndex(const ElfSectionHeader<numBits> §ionHeader);
void appendProgramHeaderLoad(size_t sectionId, uint64_t vAddr, uint64_t segSize);
template <typename SectionHeaderEnumT>
ElfSectionHeader<numBits> &appendSection(SectionHeaderEnumT sectionType, ConstStringRef sectionLabel, const ArrayRef<const uint8_t> sectionData) {
return appendSection(static_cast<SectionHeaderType>(sectionType), sectionLabel, sectionData); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
}
template <typename SectionHeaderEnumT>
ElfSectionHeader<numBits> &appendSection(SectionHeaderEnumT sectionType, ConstStringRef sectionLabel, const std::string §ionData) {
return appendSection(static_cast<SectionHeaderType>(sectionType), sectionLabel, // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(sectionData.c_str()), sectionData.size() + 1));
}
uint32_t appendSectionName(ConstStringRef str);
std::vector<uint8_t> encode() const;
ElfFileHeader<numBits> &getElfFileHeader() {
return elfFileHeader;
}
protected:
bool addUndefSectionHeader = false;
bool addHeaderSectionNamesSection = false;
typename ElfSectionHeaderTypes<numBits>::AddrAlign defaultDataAlignment = 8U;
uint64_t maxDataAlignmentNeeded = 1U;
ElfFileHeader<numBits> elfFileHeader;
StackVec<ElfProgramHeader<numBits>, 32> programHeaders;
StackVec<ElfSectionHeader<numBits>, 32> sectionHeaders;
std::vector<uint8_t> data;
StringSectionBuilder strSecBuilder;
struct ProgramSectionID {
size_t programId;
size_t sectionId;
};
StackVec<ProgramSectionID, 32> programSectionLookupTable;
uint32_t shStrTabNameOffset = 0;
};
struct NoteToEncode {
std::string name;
std::string desc;
uint32_t type;
};
template <ElfIdentifierClass numBits = EI_CLASS_64>
std::vector<uint8_t> encodeNoteSectionData(ArrayRef<const NoteToEncode> notes);
extern template std::vector<uint8_t> encodeNoteSectionData<EI_CLASS_64>(ArrayRef<const NoteToEncode> notes);
extern template std::vector<uint8_t> encodeNoteSectionData<EI_CLASS_32>(ArrayRef<const NoteToEncode> notes);
extern template struct ElfEncoder<EI_CLASS_32>;
extern template struct ElfEncoder<EI_CLASS_64>;
} // namespace Elf
} // namespace NEO
|