mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 21:18:24 +08:00
Reorganization directory structure [3/n]
Change-Id: If3dfa3f6007f8810a6a1ae1a4f0c7da38544648d
This commit is contained in:
342
shared/source/device_binary_format/elf/elf.h
Normal file
342
shared/source/device_binary_format/elf/elf.h
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utilities/const_stringref.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
namespace Elf {
|
||||
|
||||
// Elf identifier class
|
||||
enum ELF_IDENTIFIER_CLASS : uint8_t {
|
||||
EI_CLASS_NONE = 0, // undefined
|
||||
EI_CLASS_32 = 1, // 32-bit elf file
|
||||
EI_CLASS_64 = 2, // 64-bit elf file
|
||||
};
|
||||
|
||||
// Elf identifier data
|
||||
enum ELF_IDENTIFIER_DATA : uint8_t {
|
||||
EI_DATA_NONE = 0, // undefined
|
||||
EI_DATA_LITTLE_ENDIAN = 1, // little-endian
|
||||
EI_DATA_BIG_ENDIAN = 2, // big-endian
|
||||
};
|
||||
|
||||
// Target machine
|
||||
enum ELF_MACHINE : uint16_t {
|
||||
EM_NONE = 0, // No specific instrution set
|
||||
};
|
||||
|
||||
// Elf version
|
||||
enum ELF_VERSION_ : uint8_t {
|
||||
EV_INVALID = 0, // undefined
|
||||
EV_CURRENT = 1, // current
|
||||
};
|
||||
|
||||
// Elf type
|
||||
enum ELF_TYPE : uint16_t {
|
||||
ET_NONE = 0, // undefined
|
||||
ET_REL = 1, // relocatable
|
||||
ET_EXEC = 2, // executable
|
||||
ET_DYN = 3, // shared object
|
||||
ET_CORE = 4, // core file
|
||||
ET_LOPROC = 0xff00, // start of processor-specific type
|
||||
ET_OPENCL_RESERVED_START = 0xff01, // start of Intel OCL ELF_TYPES
|
||||
ET_OPENCL_RESERVED_END = 0xff05, // end of Intel OCL ELF_TYPES
|
||||
ET_HIPROC = 0xffff // end of processor-specific types
|
||||
};
|
||||
|
||||
// Section header type
|
||||
enum SECTION_HEADER_TYPE : uint32_t {
|
||||
SHT_NULL = 0, // inactive section header
|
||||
SHT_PROGBITS = 1, // program data
|
||||
SHT_SYMTAB = 2, // symbol table
|
||||
SHT_STRTAB = 3, // string table
|
||||
SHT_RELA = 4, // relocation entries with add
|
||||
SHT_HASH = 5, // symbol hash table
|
||||
SHT_DYNAMIC = 6, // dynamic linking info
|
||||
SHT_NOTE = 7, // notes
|
||||
SHT_NOBITS = 8, // program "no data" space (bss)
|
||||
SHT_REL = 9, // relocation entries (without add)
|
||||
SHT_SHLIB = 10, // reserved
|
||||
SHT_DYNSYM = 11, // dynamic linker symbol table
|
||||
SHT_INIT_ARRAY = 14, // array of constructors
|
||||
SHT_FINI_ARRAY = 15, // array of destructors
|
||||
SHT_PREINIT_ARRAY = 16, // aaray of pre-constructors
|
||||
SHT_GROUP = 17, // section group
|
||||
SHT_SYMTAB_SHNDX = 18, // extended section indices
|
||||
SHT_NUM = 19, // number of defined types
|
||||
SHT_LOOS = 0x60000000, // start of os-specifc
|
||||
SHT_OPENCL_RESERVED_START = 0xff000000, // start of Intel OCL SHT_TYPES
|
||||
SHT_OPENCL_RESERVED_END = 0xff00000a // end of Intel OCL SHT_TYPES
|
||||
};
|
||||
|
||||
enum SPECIAL_SECTION_HEADER_NUMBER : uint16_t {
|
||||
SHN_UNDEF = 0U, // undef section
|
||||
};
|
||||
|
||||
enum SECTION_HEADER_FLAGS : uint32_t {
|
||||
SHF_NONE = 0x0, // no flags
|
||||
SHF_WRITE = 0x1, // writeable data
|
||||
SHF_ALLOC = 0x2, // occupies memory during execution
|
||||
SHF_EXECINSTR = 0x4, // executable machine instructions
|
||||
SHF_MERGE = 0x10, // data of section can be merged
|
||||
SHF_STRINGS = 0x20, // data of section is null-terminated strings
|
||||
SHF_INFO_LINK = 0x40, // section's sh_info is valid index
|
||||
SHF_LINK_ORDER = 0x80, // has ordering requirements
|
||||
SHF_OS_NONCONFORM = 0x100, // requires os-specific processing
|
||||
SHF_GROUP = 0x200, // section is part of section group
|
||||
SHF_TLS = 0x400, // thread-local storage
|
||||
SHF_MASKOS = 0x0ff00000, // operating-system-specific flags
|
||||
SHF_MASKPROC = 0xf0000000, // processor-specific flags
|
||||
};
|
||||
|
||||
enum PROGRAM_HEADER_TYPE {
|
||||
PT_NULL = 0x0, // unused segment
|
||||
PT_LOAD = 0x1, // loadable segment
|
||||
PT_DYNAMIC = 0x2, // dynamic linking information
|
||||
PT_INTERP = 0x3, // path name to invoke as an interpreter
|
||||
PT_NOTE = 0x4, // auxiliary information
|
||||
PT_SHLIB = 0x5, // reserved
|
||||
PT_PHDR = 0x6, // location and of programe header table
|
||||
PT_TLS = 0x7, // thread-local storage template
|
||||
PT_LOOS = 0x60000000, // start os-specifc segments
|
||||
PT_HIOS = 0x6FFFFFFF, // end of os-specific segments
|
||||
PT_LOPROC = 0x70000000, // start processor-specific segments
|
||||
PT_HIPROC = 0x7FFFFFFF // end processor-specific segments
|
||||
};
|
||||
|
||||
enum PROGRAM_HEADER_FLAGS : uint32_t {
|
||||
PF_NONE = 0x0, // all access denied
|
||||
PF_X = 0x1, // execute
|
||||
PF_W = 0x2, // write
|
||||
PF_R = 0x4, // read
|
||||
PF_MASKOS = 0x0ff00000, // operating-system-specific flags
|
||||
PF_MASKPROC = 0xf0000000 // processor-specific flags
|
||||
|
||||
};
|
||||
|
||||
constexpr const char elfMagic[4] = {0x7f, 'E', 'L', 'F'};
|
||||
|
||||
struct ElfFileHeaderIdentity {
|
||||
ElfFileHeaderIdentity(ELF_IDENTIFIER_CLASS classBits)
|
||||
: eClass(classBits) {
|
||||
}
|
||||
char magic[4] = {elfMagic[0], elfMagic[1], elfMagic[2], elfMagic[3]}; // should match elfMagic
|
||||
uint8_t eClass = EI_CLASS_NONE; // 32- or 64-bit format
|
||||
uint8_t data = EI_DATA_LITTLE_ENDIAN; // endianness
|
||||
uint8_t version = EV_CURRENT; // elf file version
|
||||
uint8_t osAbi = 0U; // target system
|
||||
uint8_t abiVersion = 0U; // abi
|
||||
char padding[7] = {}; // pad to 16 bytes
|
||||
};
|
||||
static_assert(sizeof(ElfFileHeaderIdentity) == 16, "");
|
||||
|
||||
template <int NumBits>
|
||||
struct ElfProgramHeaderTypes;
|
||||
|
||||
template <>
|
||||
struct ElfProgramHeaderTypes<EI_CLASS_32> {
|
||||
using Type = uint32_t;
|
||||
using Flags = uint32_t;
|
||||
using Offset = uint32_t;
|
||||
using VAddr = uint32_t;
|
||||
using PAddr = uint32_t;
|
||||
using FileSz = uint32_t;
|
||||
using MemSz = uint32_t;
|
||||
using Align = uint32_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ElfProgramHeaderTypes<EI_CLASS_64> {
|
||||
using Type = uint32_t;
|
||||
using Flags = uint32_t;
|
||||
using Offset = uint64_t;
|
||||
using VAddr = uint64_t;
|
||||
using PAddr = uint64_t;
|
||||
using FileSz = uint64_t;
|
||||
using MemSz = uint64_t;
|
||||
using Align = uint64_t;
|
||||
};
|
||||
|
||||
template <int NumBits>
|
||||
struct ElfProgramHeader;
|
||||
|
||||
template <>
|
||||
struct ElfProgramHeader<EI_CLASS_32> {
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::Type type = PT_NULL; // type of segment
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::Offset offset = 0U; // absolute offset of segment data in file
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::VAddr vAddr = 0U; // VA of segment in memory
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::PAddr pAddr = 0U; // PA of segment in memory
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::FileSz fileSz = 0U; // size of segment in file
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::MemSz memSz = 0U; // size of segment in memory
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::Flags flags = PF_NONE; // segment-dependent flags
|
||||
ElfProgramHeaderTypes<EI_CLASS_32>::Align align = 1U; // alignment
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ElfProgramHeader<EI_CLASS_64> {
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::Type type = PT_NULL; // type of segment
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::Flags flags = PF_NONE; // segment-dependent flags
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::Offset offset = 0U; // absolute offset of segment data in file
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::VAddr vAddr = 0U; // VA of segment in memory
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::PAddr pAddr = 0U; // PA of segment in memory
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::FileSz fileSz = 0U; // size of segment in file
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::MemSz memSz = 0U; // size of segment in memory
|
||||
ElfProgramHeaderTypes<EI_CLASS_64>::Align align = 1U; // alignment
|
||||
};
|
||||
|
||||
static_assert(sizeof(ElfProgramHeader<EI_CLASS_32>) == 0x20, "");
|
||||
static_assert(sizeof(ElfProgramHeader<EI_CLASS_64>) == 0x38, "");
|
||||
|
||||
template <int NumBits>
|
||||
struct ElfSectionHeaderTypes;
|
||||
|
||||
template <>
|
||||
struct ElfSectionHeaderTypes<EI_CLASS_32> {
|
||||
using Name = uint32_t;
|
||||
using Type = uint32_t;
|
||||
using Flags = uint32_t;
|
||||
using Addr = uint32_t;
|
||||
using Offset = uint32_t;
|
||||
using Size = uint32_t;
|
||||
using Link = uint32_t;
|
||||
using Info = uint32_t;
|
||||
using AddrAlign = uint32_t;
|
||||
using EntSize = uint32_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ElfSectionHeaderTypes<EI_CLASS_64> {
|
||||
using Name = uint32_t;
|
||||
using Type = uint32_t;
|
||||
using Flags = uint64_t;
|
||||
using Addr = uint64_t;
|
||||
using Offset = uint64_t;
|
||||
using Size = uint64_t;
|
||||
using Link = uint32_t;
|
||||
using Info = uint32_t;
|
||||
using AddrAlign = uint64_t;
|
||||
using EntSize = uint64_t;
|
||||
};
|
||||
|
||||
template <int NumBits>
|
||||
struct ElfSectionHeader {
|
||||
typename ElfSectionHeaderTypes<NumBits>::Name name = 0U; // offset to string in string section names
|
||||
typename ElfSectionHeaderTypes<NumBits>::Type type = SHT_NULL; // section type
|
||||
typename ElfSectionHeaderTypes<NumBits>::Flags flags = SHF_NONE; // section flags
|
||||
typename ElfSectionHeaderTypes<NumBits>::Addr addr = 0U; // VA of section in memory
|
||||
typename ElfSectionHeaderTypes<NumBits>::Offset offset = 0U; // absolute offset of section data in file
|
||||
typename ElfSectionHeaderTypes<NumBits>::Size size = 0U; // size of section's data
|
||||
typename ElfSectionHeaderTypes<NumBits>::Link link = SHN_UNDEF; // index of associated section
|
||||
typename ElfSectionHeaderTypes<NumBits>::Info info = 0U; // extra information
|
||||
typename ElfSectionHeaderTypes<NumBits>::AddrAlign addralign = 0U; // section alignment
|
||||
typename ElfSectionHeaderTypes<NumBits>::EntSize entsize = 0U; // section's entries size
|
||||
};
|
||||
|
||||
static_assert(sizeof(ElfSectionHeader<EI_CLASS_32>) == 0x28, "");
|
||||
static_assert(sizeof(ElfSectionHeader<EI_CLASS_64>) == 0x40, "");
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
struct ElfFileHeaderTypes;
|
||||
|
||||
template <>
|
||||
struct ElfFileHeaderTypes<EI_CLASS_32> {
|
||||
using Type = uint16_t;
|
||||
using Machine = uint16_t;
|
||||
using Version = uint32_t;
|
||||
using Entry = uint32_t;
|
||||
using PhOff = uint32_t;
|
||||
using ShOff = uint32_t;
|
||||
using Flags = uint32_t;
|
||||
using EhSize = uint16_t;
|
||||
using PhEntSize = uint16_t;
|
||||
using PhNum = uint16_t;
|
||||
using ShEntSize = uint16_t;
|
||||
using ShNum = uint16_t;
|
||||
using ShStrNdx = uint16_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ElfFileHeaderTypes<EI_CLASS_64> {
|
||||
using Type = uint16_t;
|
||||
using Machine = uint16_t;
|
||||
using Version = uint32_t;
|
||||
using Entry = uint64_t;
|
||||
using PhOff = uint64_t;
|
||||
using ShOff = uint64_t;
|
||||
using Flags = uint32_t;
|
||||
using EhSize = uint16_t;
|
||||
using PhEntSize = uint16_t;
|
||||
using PhNum = uint16_t;
|
||||
using ShEntSize = uint16_t;
|
||||
using ShNum = uint16_t;
|
||||
using ShStrNdx = uint16_t;
|
||||
};
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
struct ElfFileHeader {
|
||||
ElfFileHeaderIdentity identity = ElfFileHeaderIdentity(NumBits); // elf file identity
|
||||
typename ElfFileHeaderTypes<NumBits>::Type type = ET_NONE; // elf file type
|
||||
typename ElfFileHeaderTypes<NumBits>::Machine machine = EM_NONE; // target machine
|
||||
typename ElfFileHeaderTypes<NumBits>::Version version = 1U; // elf file version
|
||||
typename ElfFileHeaderTypes<NumBits>::Entry entry = 0U; // entry point (start address)
|
||||
typename ElfFileHeaderTypes<NumBits>::PhOff phOff = 0U; // absolute offset to program header table in file
|
||||
typename ElfFileHeaderTypes<NumBits>::ShOff shOff = 0U; // absolute offset to section header table in file
|
||||
typename ElfFileHeaderTypes<NumBits>::Flags flags = 0U; // target-dependent flags
|
||||
typename ElfFileHeaderTypes<NumBits>::EhSize ehSize = sizeof(ElfFileHeader<NumBits>); // header size
|
||||
typename ElfFileHeaderTypes<NumBits>::PhEntSize phEntSize = sizeof(ElfProgramHeader<NumBits>); // size of entries in program header table
|
||||
typename ElfFileHeaderTypes<NumBits>::PhNum phNum = 0U; // number of entries in pogram header table
|
||||
typename ElfFileHeaderTypes<NumBits>::ShEntSize shEntSize = sizeof(ElfSectionHeader<NumBits>); // size of entries section header table
|
||||
typename ElfFileHeaderTypes<NumBits>::ShNum shNum = 0U; // number of entries in section header table
|
||||
typename ElfFileHeaderTypes<NumBits>::ShStrNdx shStrNdx = SHN_UNDEF; // index of section header table with section names
|
||||
};
|
||||
|
||||
static_assert(sizeof(ElfFileHeader<EI_CLASS_32>) == 0x34, "");
|
||||
static_assert(sizeof(ElfFileHeader<EI_CLASS_64>) == 0x40, "");
|
||||
|
||||
namespace SpecialSectionNames {
|
||||
static constexpr ConstStringRef bss = ".bss"; // uninitialized memory
|
||||
static constexpr ConstStringRef comment = ".comment"; // version control information
|
||||
static constexpr ConstStringRef data = ".data"; // initialized memory
|
||||
static constexpr ConstStringRef data1 = ".data1"; // initialized memory
|
||||
static constexpr ConstStringRef debug = ".debug"; // debug symbols
|
||||
static constexpr ConstStringRef dynamic = ".dynamic"; // dynamic linking information
|
||||
static constexpr ConstStringRef dynstr = ".dynstr"; // strings for dynamic linking
|
||||
static constexpr ConstStringRef dynsym = ".dynsym"; // dynamic linking symbol table
|
||||
static constexpr ConstStringRef fini = ".fini"; // executable instructions of program termination
|
||||
static constexpr ConstStringRef finiArray = ".fini_array"; // function pointers of termination array
|
||||
static constexpr ConstStringRef got = ".got"; // global offset table
|
||||
static constexpr ConstStringRef hash = ".hash"; // symnol hash table
|
||||
static constexpr ConstStringRef init = ".init"; // executable instructions of program initializaion
|
||||
static constexpr ConstStringRef initArray = ".init_array"; // function pointers of initialization array
|
||||
static constexpr ConstStringRef interp = ".interp"; // path name of program interpreter
|
||||
static constexpr ConstStringRef line = ".line"; // line number info for symbolic debugging
|
||||
static constexpr ConstStringRef note = ".note"; // note section
|
||||
static constexpr ConstStringRef plt = ".plt"; // procedure linkage table
|
||||
static constexpr ConstStringRef preinitArray = ".preinit_array"; // function pointers of pre-initialization array
|
||||
static constexpr ConstStringRef relPrefix = ".rel"; // prefix of .relNAME - relocations for NAME section
|
||||
static constexpr ConstStringRef relaPrefix = ".rela"; // prefix of .relaNAME - rela relocations for NAME section
|
||||
static constexpr ConstStringRef rodata = ".rodata"; // read-only data
|
||||
static constexpr ConstStringRef rodata1 = ".rodata1"; // read-only data
|
||||
static constexpr ConstStringRef shStrTab = ".shstrtab"; // section names (strings)
|
||||
static constexpr ConstStringRef strtab = ".strtab"; // strings
|
||||
static constexpr ConstStringRef symtab = ".symtab"; // symbol table
|
||||
static constexpr ConstStringRef symtabShndx = ".symtab_shndx"; // special symbol table section index array
|
||||
static constexpr ConstStringRef tbss = ".tbss"; // uninitialized thread-local data
|
||||
static constexpr ConstStringRef tadata = ".tdata"; // initialided thread-local data
|
||||
static constexpr ConstStringRef tdata1 = ".tdata1"; // initialided thread-local data
|
||||
static constexpr ConstStringRef text = ".text"; // executable instructions
|
||||
} // namespace SpecialSectionNames
|
||||
|
||||
} // namespace Elf
|
||||
|
||||
} // namespace NEO
|
||||
89
shared/source/device_binary_format/elf/elf_decoder.cpp
Normal file
89
shared/source/device_binary_format/elf/elf_decoder.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "device_binary_format/elf/elf_decoder.h"
|
||||
|
||||
#include "helpers/ptr_math.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
namespace Elf {
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
const ElfFileHeader<NumBits> *decodeElfFileHeader(const ArrayRef<const uint8_t> binary) {
|
||||
if (binary.size() < sizeof(ElfFileHeader<NumBits>)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ElfFileHeader<NumBits> *header = reinterpret_cast<const ElfFileHeader<NumBits> *>(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<EI_CLASS_32> *decodeElfFileHeader<EI_CLASS_32>(const ArrayRef<const uint8_t>);
|
||||
template const ElfFileHeader<EI_CLASS_64> *decodeElfFileHeader<EI_CLASS_64>(const ArrayRef<const uint8_t>);
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
Elf<NumBits> decodeElf(const ArrayRef<const uint8_t> binary, std::string &outErrReason, std::string &outWarning) {
|
||||
Elf<NumBits> ret = {};
|
||||
ret.elfFileHeader = decodeElfFileHeader<NumBits>(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<NumBits> *programHeader = reinterpret_cast<const ElfProgramHeader<NumBits> *>(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<const uint8_t> data(binary.begin() + programHeader->offset, static_cast<size_t>(programHeader->fileSz));
|
||||
ret.programHeaders.push_back({programHeader, data});
|
||||
programHeader = ptrOffset(programHeader, ret.elfFileHeader->phEntSize);
|
||||
}
|
||||
|
||||
const ElfSectionHeader<NumBits> *sectionHeader = reinterpret_cast<const ElfSectionHeader<NumBits> *>(binary.begin() + ret.elfFileHeader->shOff);
|
||||
for (decltype(ret.elfFileHeader->shNum) i = 0; i < ret.elfFileHeader->shNum; ++i) {
|
||||
ArrayRef<const uint8_t> 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<const uint8_t>(binary.begin() + sectionHeader->offset, static_cast<size_t>(sectionHeader->size));
|
||||
}
|
||||
ret.sectionHeaders.push_back({sectionHeader, data});
|
||||
sectionHeader = ptrOffset(sectionHeader, ret.elfFileHeader->shEntSize);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template Elf<EI_CLASS_32> decodeElf<EI_CLASS_32>(const ArrayRef<const uint8_t>, std::string &, std::string &);
|
||||
template Elf<EI_CLASS_64> decodeElf<EI_CLASS_64>(const ArrayRef<const uint8_t>, std::string &, std::string &);
|
||||
|
||||
} // namespace Elf
|
||||
|
||||
} // namespace NEO
|
||||
67
shared/source/device_binary_format/elf/elf_decoder.h
Normal file
67
shared/source/device_binary_format/elf/elf_decoder.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "device_binary_format/elf/elf.h"
|
||||
#include "utilities/arrayref.h"
|
||||
#include "utilities/const_stringref.h"
|
||||
#include "utilities/stackvec.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
namespace Elf {
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits = EI_CLASS_64>
|
||||
struct Elf {
|
||||
struct ProgramHeaderAndData {
|
||||
const ElfProgramHeader<NumBits> *header = nullptr;
|
||||
ArrayRef<const uint8_t> data;
|
||||
};
|
||||
|
||||
struct SectionHeaderAndData {
|
||||
const ElfSectionHeader<NumBits> *header;
|
||||
ArrayRef<const uint8_t> data;
|
||||
};
|
||||
|
||||
const ElfFileHeader<NumBits> *elfFileHeader = nullptr;
|
||||
StackVec<ProgramHeaderAndData, 32> programHeaders;
|
||||
StackVec<SectionHeaderAndData, 32> sectionHeaders;
|
||||
};
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits = EI_CLASS_64>
|
||||
const ElfFileHeader<NumBits> *decodeElfFileHeader(const ArrayRef<const uint8_t> binary);
|
||||
extern template const ElfFileHeader<EI_CLASS_32> *decodeElfFileHeader<EI_CLASS_32>(const ArrayRef<const uint8_t>);
|
||||
extern template const ElfFileHeader<EI_CLASS_64> *decodeElfFileHeader<EI_CLASS_64>(const ArrayRef<const uint8_t>);
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits = EI_CLASS_64>
|
||||
Elf<NumBits> decodeElf(const ArrayRef<const uint8_t> binary, std::string &outErrReason, std::string &outWarning);
|
||||
extern template Elf<EI_CLASS_32> decodeElf<EI_CLASS_32>(const ArrayRef<const uint8_t>, std::string &, std::string &);
|
||||
extern template Elf<EI_CLASS_64> decodeElf<EI_CLASS_64>(const ArrayRef<const uint8_t>, std::string &, std::string &);
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
inline bool isElf(const ArrayRef<const uint8_t> binary) {
|
||||
return (nullptr != decodeElfFileHeader<NumBits>(binary));
|
||||
}
|
||||
|
||||
inline bool isElf(const ArrayRef<const uint8_t> binary) {
|
||||
return isElf<EI_CLASS_32>(binary) || isElf<EI_CLASS_64>(binary);
|
||||
}
|
||||
|
||||
inline ELF_IDENTIFIER_CLASS getElfNumBits(const ArrayRef<const uint8_t> binary) {
|
||||
if (isElf<EI_CLASS_32>(binary)) {
|
||||
return EI_CLASS_32;
|
||||
} else if (isElf<EI_CLASS_64>(binary)) {
|
||||
return EI_CLASS_64;
|
||||
}
|
||||
return EI_CLASS_NONE;
|
||||
}
|
||||
|
||||
} // namespace Elf
|
||||
|
||||
} // namespace NEO
|
||||
178
shared/source/device_binary_format/elf/elf_encoder.cpp
Normal file
178
shared/source/device_binary_format/elf/elf_encoder.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "device_binary_format/elf/elf_encoder.h"
|
||||
|
||||
#include "utilities/range.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
namespace Elf {
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
ElfEncoder<NumBits>::ElfEncoder(bool addUndefSectionHeader, bool addHeaderSectionNamesSection, uint64_t defaultDataAlignemnt)
|
||||
: addUndefSectionHeader(addUndefSectionHeader), addHeaderSectionNamesSection(addHeaderSectionNamesSection), defaultDataAlignment(defaultDataAlignemnt) {
|
||||
// add special strings
|
||||
UNRECOVERABLE_IF(defaultDataAlignment == 0);
|
||||
stringTable.push_back('\0');
|
||||
specialStringsOffsets.undef = 0U;
|
||||
specialStringsOffsets.shStrTab = this->appendSectionName(SpecialSectionNames::shStrTab);
|
||||
|
||||
if (addUndefSectionHeader) {
|
||||
ElfSectionHeader<NumBits> undefSection;
|
||||
sectionHeaders.push_back(undefSection);
|
||||
}
|
||||
}
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
void ElfEncoder<NumBits>::appendSection(const ElfSectionHeader<NumBits> §ionHeader, const ArrayRef<const uint8_t> sectionData) {
|
||||
sectionHeaders.push_back(sectionHeader);
|
||||
if ((SHT_NOBITS != sectionHeader.type) && (false == sectionData.empty())) {
|
||||
auto sectionDataAlignment = std::min<uint64_t>(defaultDataAlignment, 8U);
|
||||
auto alignedOffset = alignUp(this->data.size(), static_cast<size_t>(sectionDataAlignment));
|
||||
auto alignedSize = alignUp(sectionData.size(), static_cast<size_t>(sectionDataAlignment));
|
||||
this->data.reserve(alignedOffset + alignedSize);
|
||||
this->data.resize(alignedOffset, 0U);
|
||||
this->data.insert(this->data.end(), sectionData.begin(), sectionData.end());
|
||||
this->data.resize(alignedOffset + alignedSize, 0U);
|
||||
sectionHeaders.rbegin()->offset = static_cast<decltype(sectionHeaders.rbegin()->offset)>(alignedOffset);
|
||||
sectionHeaders.rbegin()->size = static_cast<decltype(sectionHeaders.rbegin()->size)>(sectionData.size());
|
||||
}
|
||||
}
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
void ElfEncoder<NumBits>::appendSegment(const ElfProgramHeader<NumBits> &programHeader, const ArrayRef<const uint8_t> segmentData) {
|
||||
maxDataAlignmentNeeded = std::max<uint64_t>(maxDataAlignmentNeeded, static_cast<uint64_t>(programHeader.align));
|
||||
programHeaders.push_back(programHeader);
|
||||
if (false == segmentData.empty()) {
|
||||
UNRECOVERABLE_IF(programHeader.align == 0);
|
||||
auto alignedOffset = alignUp(this->data.size(), static_cast<size_t>(programHeader.align));
|
||||
auto alignedSize = alignUp(segmentData.size(), static_cast<size_t>(programHeader.align));
|
||||
this->data.reserve(alignedOffset + alignedSize);
|
||||
this->data.resize(alignedOffset, 0U);
|
||||
this->data.insert(this->data.end(), segmentData.begin(), segmentData.end());
|
||||
this->data.resize(alignedOffset + alignedSize, 0U);
|
||||
programHeaders.rbegin()->offset = static_cast<decltype(programHeaders.rbegin()->offset)>(alignedOffset);
|
||||
programHeaders.rbegin()->fileSz = static_cast<decltype(programHeaders.rbegin()->fileSz)>(segmentData.size());
|
||||
}
|
||||
}
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
ElfSectionHeader<NumBits> &ElfEncoder<NumBits>::appendSection(SECTION_HEADER_TYPE sectionType, ConstStringRef sectionLabel, const ArrayRef<const uint8_t> sectionData) {
|
||||
ElfSectionHeader<NumBits> section = {};
|
||||
section.type = static_cast<decltype(section.type)>(sectionType);
|
||||
section.flags = static_cast<decltype(section.flags)>(SHF_NONE);
|
||||
section.offset = 0U;
|
||||
section.name = appendSectionName(sectionLabel);
|
||||
section.addralign = 8U;
|
||||
appendSection(section, sectionData);
|
||||
return *sectionHeaders.rbegin();
|
||||
}
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
ElfProgramHeader<NumBits> &ElfEncoder<NumBits>::appendSegment(PROGRAM_HEADER_TYPE segmentType, const ArrayRef<const uint8_t> segmentData) {
|
||||
ElfProgramHeader<NumBits> segment = {};
|
||||
segment.type = static_cast<decltype(segment.type)>(segmentType);
|
||||
segment.flags = static_cast<decltype(segment.flags)>(PF_NONE);
|
||||
segment.offset = 0U;
|
||||
segment.align = static_cast<decltype(segment.align)>(defaultDataAlignment);
|
||||
appendSegment(segment, segmentData);
|
||||
return *programHeaders.rbegin();
|
||||
}
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
uint32_t ElfEncoder<NumBits>::appendSectionName(ConstStringRef str) {
|
||||
if (str.empty() || (false == addHeaderSectionNamesSection)) {
|
||||
return specialStringsOffsets.undef;
|
||||
}
|
||||
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');
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits>
|
||||
std::vector<uint8_t> ElfEncoder<NumBits>::encode() const {
|
||||
ElfFileHeader<NumBits> elfFileHeader = this->elfFileHeader;
|
||||
StackVec<ElfProgramHeader<NumBits>, 32> programHeaders = this->programHeaders;
|
||||
StackVec<ElfSectionHeader<NumBits>, 32> sectionHeaders = this->sectionHeaders;
|
||||
|
||||
if (addUndefSectionHeader && (1U == sectionHeaders.size())) {
|
||||
sectionHeaders.clear();
|
||||
}
|
||||
|
||||
ElfSectionHeader<NumBits> sectionHeaderNamesSection;
|
||||
size_t alignedSectionNamesDataSize = 0U;
|
||||
size_t dataPaddingBeforeSectionNames = 0U;
|
||||
if ((false == sectionHeaders.empty()) && addHeaderSectionNamesSection) {
|
||||
auto alignedDataSize = alignUp(data.size(), static_cast<size_t>(defaultDataAlignment));
|
||||
dataPaddingBeforeSectionNames = alignedDataSize - data.size();
|
||||
sectionHeaderNamesSection.type = SHT_STRTAB;
|
||||
sectionHeaderNamesSection.name = specialStringsOffsets.shStrTab;
|
||||
sectionHeaderNamesSection.offset = static_cast<decltype(sectionHeaderNamesSection.offset)>(alignedDataSize);
|
||||
sectionHeaderNamesSection.size = static_cast<decltype(sectionHeaderNamesSection.size)>(stringTable.size());
|
||||
sectionHeaderNamesSection.addralign = static_cast<decltype(sectionHeaderNamesSection.addralign)>(defaultDataAlignment);
|
||||
elfFileHeader.shStrNdx = static_cast<decltype(elfFileHeader.shStrNdx)>(sectionHeaders.size());
|
||||
sectionHeaders.push_back(sectionHeaderNamesSection);
|
||||
alignedSectionNamesDataSize = alignUp(stringTable.size(), static_cast<size_t>(sectionHeaderNamesSection.addralign));
|
||||
}
|
||||
|
||||
elfFileHeader.phNum = static_cast<decltype(elfFileHeader.phNum)>(programHeaders.size());
|
||||
elfFileHeader.shNum = static_cast<decltype(elfFileHeader.shNum)>(sectionHeaders.size());
|
||||
|
||||
auto programHeadersOffset = elfFileHeader.ehSize;
|
||||
auto sectionHeadersOffset = programHeadersOffset + elfFileHeader.phEntSize * elfFileHeader.phNum;
|
||||
|
||||
if (false == programHeaders.empty()) {
|
||||
elfFileHeader.phOff = static_cast<decltype(elfFileHeader.phOff)>(programHeadersOffset);
|
||||
}
|
||||
if (false == sectionHeaders.empty()) {
|
||||
elfFileHeader.shOff = static_cast<decltype(elfFileHeader.shOff)>(sectionHeadersOffset);
|
||||
}
|
||||
|
||||
auto dataOffset = alignUp(sectionHeadersOffset + elfFileHeader.shEntSize * elfFileHeader.shNum, static_cast<size_t>(maxDataAlignmentNeeded));
|
||||
auto stringTabOffset = dataOffset + data.size();
|
||||
|
||||
std::vector<uint8_t> ret;
|
||||
ret.reserve(stringTabOffset + alignedSectionNamesDataSize);
|
||||
ret.insert(ret.end(), reinterpret_cast<uint8_t *>(&elfFileHeader), reinterpret_cast<uint8_t *>(&elfFileHeader + 1));
|
||||
ret.resize(programHeadersOffset, 0U);
|
||||
|
||||
for (auto &programHeader : programHeaders) {
|
||||
if (0 != programHeader.fileSz) {
|
||||
programHeader.offset = static_cast<decltype(programHeader.offset)>(programHeader.offset + dataOffset);
|
||||
}
|
||||
ret.insert(ret.end(), reinterpret_cast<uint8_t *>(&programHeader), reinterpret_cast<uint8_t *>(&programHeader + 1));
|
||||
ret.resize(ret.size() + elfFileHeader.phEntSize - sizeof(programHeader), 0U);
|
||||
}
|
||||
|
||||
for (auto §ionHeader : sectionHeaders) {
|
||||
if ((SHT_NOBITS != sectionHeader.type) && (0 != sectionHeader.size)) {
|
||||
sectionHeader.offset = static_cast<decltype(sectionHeader.offset)>(sectionHeader.offset + dataOffset);
|
||||
}
|
||||
ret.insert(ret.end(), reinterpret_cast<uint8_t *>(§ionHeader), reinterpret_cast<uint8_t *>(§ionHeader + 1));
|
||||
ret.resize(ret.size() + elfFileHeader.shEntSize - sizeof(sectionHeader), 0U);
|
||||
}
|
||||
|
||||
ret.resize(dataOffset, 0U);
|
||||
ret.insert(ret.end(), data.begin(), data.end());
|
||||
ret.resize(ret.size() + dataPaddingBeforeSectionNames, 0U);
|
||||
ret.insert(ret.end(), reinterpret_cast<const uint8_t *>(stringTable.data()), reinterpret_cast<const uint8_t *>(stringTable.data() + static_cast<size_t>(sectionHeaderNamesSection.size)));
|
||||
ret.resize(ret.size() + alignedSectionNamesDataSize - static_cast<size_t>(sectionHeaderNamesSection.size), 0U);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template struct ElfEncoder<EI_CLASS_32>;
|
||||
template struct ElfEncoder<EI_CLASS_64>;
|
||||
|
||||
} // namespace Elf
|
||||
|
||||
} // namespace NEO
|
||||
72
shared/source/device_binary_format/elf/elf_encoder.h
Normal file
72
shared/source/device_binary_format/elf/elf_encoder.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "device_binary_format/elf/elf.h"
|
||||
#include "helpers/aligned_memory.h"
|
||||
#include "utilities/arrayref.h"
|
||||
#include "utilities/const_stringref.h"
|
||||
#include "utilities/stackvec.h"
|
||||
|
||||
#include <queue>
|
||||
#include <string>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
namespace Elf {
|
||||
|
||||
template <ELF_IDENTIFIER_CLASS NumBits = EI_CLASS_64>
|
||||
struct ElfEncoder {
|
||||
ElfEncoder(bool addUndefSectionHeader = true, bool addHeaderSectionNamesSection = true, uint64_t defaultDataAlignment = 8U);
|
||||
|
||||
void appendSection(const ElfSectionHeader<NumBits> §ionHeader, const ArrayRef<const uint8_t> sectionData);
|
||||
void appendSegment(const ElfProgramHeader<NumBits> &programHeader, const ArrayRef<const uint8_t> segmentData);
|
||||
|
||||
ElfSectionHeader<NumBits> &appendSection(SECTION_HEADER_TYPE sectionType, ConstStringRef sectionLabel, const ArrayRef<const uint8_t> sectionData);
|
||||
ElfProgramHeader<NumBits> &appendSegment(PROGRAM_HEADER_TYPE segmentType, const ArrayRef<const uint8_t> segmentData);
|
||||
|
||||
template <typename SectionHeaderEnumT>
|
||||
ElfSectionHeader<NumBits> &appendSection(SectionHeaderEnumT sectionType, ConstStringRef sectionLabel, const ArrayRef<const uint8_t> sectionData) {
|
||||
return appendSection(static_cast<SECTION_HEADER_TYPE>(sectionType), sectionLabel, sectionData);
|
||||
}
|
||||
|
||||
template <typename SectionHeaderEnumT>
|
||||
ElfSectionHeader<NumBits> &appendSection(SectionHeaderEnumT sectionType, ConstStringRef sectionLabel, const std::string §ionData) {
|
||||
return appendSection(static_cast<SECTION_HEADER_TYPE>(sectionType), sectionLabel,
|
||||
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;
|
||||
uint64_t defaultDataAlignment = 8U;
|
||||
uint64_t maxDataAlignmentNeeded = 1U;
|
||||
ElfFileHeader<NumBits> elfFileHeader;
|
||||
StackVec<ElfProgramHeader<NumBits>, 32> programHeaders;
|
||||
StackVec<ElfSectionHeader<NumBits>, 32> sectionHeaders;
|
||||
std::vector<uint8_t> data;
|
||||
std::vector<char> stringTable;
|
||||
struct {
|
||||
uint32_t shStrTab = 0;
|
||||
uint32_t undef = 0;
|
||||
} specialStringsOffsets;
|
||||
};
|
||||
|
||||
extern template struct ElfEncoder<EI_CLASS_32>;
|
||||
extern template struct ElfEncoder<EI_CLASS_64>;
|
||||
|
||||
} // namespace Elf
|
||||
|
||||
} // namespace NEO
|
||||
59
shared/source/device_binary_format/elf/ocl_elf.h
Normal file
59
shared/source/device_binary_format/elf/ocl_elf.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
// Abstract: Defines the types used for ELF headers/sections.
|
||||
#pragma once
|
||||
|
||||
#include "device_binary_format/elf/elf.h"
|
||||
#include "utilities/const_stringref.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
namespace Elf {
|
||||
|
||||
enum ELF_TYPE_OPENCL : uint16_t {
|
||||
ET_OPENCL_SOURCE = 0xff01, // format used to pass CL text sections to FE
|
||||
ET_OPENCL_OBJECTS = 0xff02, // format used to pass LLVM objects / store LLVM binary output
|
||||
ET_OPENCL_LIBRARY = 0xff03, // format used to store LLVM archive output
|
||||
ET_OPENCL_EXECUTABLE = 0xff04, // format used to store executable output
|
||||
ET_OPENCL_DEBUG = 0xff05, // format used to store debug output
|
||||
};
|
||||
static_assert(sizeof(ELF_TYPE_OPENCL) == sizeof(ELF_TYPE), "");
|
||||
static_assert(static_cast<uint16_t>(ET_OPENCL_SOURCE) == static_cast<uint16_t>(ET_OPENCL_RESERVED_START), "");
|
||||
static_assert(static_cast<uint16_t>(ET_OPENCL_DEBUG) == static_cast<uint16_t>(ET_OPENCL_RESERVED_END), "");
|
||||
|
||||
enum SHT_OPENCL : uint32_t {
|
||||
SHT_OPENCL_SOURCE = 0xff000000, // CL source to link into LLVM binary
|
||||
SHT_OPENCL_HEADER = 0xff000001, // CL header to link into LLVM binary
|
||||
SHT_OPENCL_LLVM_TEXT = 0xff000002, // LLVM text
|
||||
SHT_OPENCL_LLVM_BINARY = 0xff000003, // LLVM byte code
|
||||
SHT_OPENCL_LLVM_ARCHIVE = 0xff000004, // LLVM archives(s)
|
||||
SHT_OPENCL_DEV_BINARY = 0xff000005, // Device binary (coherent by default)
|
||||
SHT_OPENCL_OPTIONS = 0xff000006, // CL Options
|
||||
SHT_OPENCL_PCH = 0xff000007, // PCH (pre-compiled headers)
|
||||
SHT_OPENCL_DEV_DEBUG = 0xff000008, // Device debug
|
||||
SHT_OPENCL_SPIRV = 0xff000009, // SPIRV
|
||||
SHT_NON_COHERENT_DEV_BINARY = 0xff00000a, // Non-coherent Device binary
|
||||
};
|
||||
static_assert(sizeof(SHT_OPENCL) == sizeof(SECTION_HEADER_TYPE), "");
|
||||
static_assert(static_cast<uint32_t>(SHT_OPENCL_SOURCE) == static_cast<uint32_t>(SHT_OPENCL_RESERVED_START), "");
|
||||
static_assert(static_cast<uint32_t>(SHT_NON_COHERENT_DEV_BINARY) == static_cast<uint32_t>(SHT_OPENCL_RESERVED_END), "");
|
||||
|
||||
namespace SectionNamesOpenCl {
|
||||
static constexpr ConstStringRef buildOptions = "BuildOptions";
|
||||
static constexpr ConstStringRef spirvObject = "SPIRV Object";
|
||||
static constexpr ConstStringRef llvmObject = "Intel(R) OpenCL LLVM Object";
|
||||
static constexpr ConstStringRef deviceDebug = "Intel(R) OpenCL Device Debug";
|
||||
static constexpr ConstStringRef deviceBinary = "Intel(R) OpenCL Device Binary";
|
||||
} // namespace SectionNamesOpenCl
|
||||
|
||||
} // namespace Elf
|
||||
|
||||
} // namespace NEO
|
||||
Reference in New Issue
Block a user