/* * Copyright (C) 2017-2020 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "shared/source/utilities/const_stringref.h" #include #include 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 struct ElfProgramHeaderTypes; template <> struct ElfProgramHeaderTypes { 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 { 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 struct ElfProgramHeader; template <> struct ElfProgramHeader { ElfProgramHeaderTypes::Type type = PT_NULL; // type of segment ElfProgramHeaderTypes::Offset offset = 0U; // absolute offset of segment data in file ElfProgramHeaderTypes::VAddr vAddr = 0U; // VA of segment in memory ElfProgramHeaderTypes::PAddr pAddr = 0U; // PA of segment in memory ElfProgramHeaderTypes::FileSz fileSz = 0U; // size of segment in file ElfProgramHeaderTypes::MemSz memSz = 0U; // size of segment in memory ElfProgramHeaderTypes::Flags flags = PF_NONE; // segment-dependent flags ElfProgramHeaderTypes::Align align = 1U; // alignment }; template <> struct ElfProgramHeader { ElfProgramHeaderTypes::Type type = PT_NULL; // type of segment ElfProgramHeaderTypes::Flags flags = PF_NONE; // segment-dependent flags ElfProgramHeaderTypes::Offset offset = 0U; // absolute offset of segment data in file ElfProgramHeaderTypes::VAddr vAddr = 0U; // VA of segment in memory ElfProgramHeaderTypes::PAddr pAddr = 0U; // PA of segment in memory ElfProgramHeaderTypes::FileSz fileSz = 0U; // size of segment in file ElfProgramHeaderTypes::MemSz memSz = 0U; // size of segment in memory ElfProgramHeaderTypes::Align align = 1U; // alignment }; static_assert(sizeof(ElfProgramHeader) == 0x20, ""); static_assert(sizeof(ElfProgramHeader) == 0x38, ""); template struct ElfSectionHeaderTypes; template <> struct ElfSectionHeaderTypes { 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 { 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 struct ElfSectionHeader { typename ElfSectionHeaderTypes::Name name = 0U; // offset to string in string section names typename ElfSectionHeaderTypes::Type type = SHT_NULL; // section type typename ElfSectionHeaderTypes::Flags flags = SHF_NONE; // section flags typename ElfSectionHeaderTypes::Addr addr = 0U; // VA of section in memory typename ElfSectionHeaderTypes::Offset offset = 0U; // absolute offset of section data in file typename ElfSectionHeaderTypes::Size size = 0U; // size of section's data typename ElfSectionHeaderTypes::Link link = SHN_UNDEF; // index of associated section typename ElfSectionHeaderTypes::Info info = 0U; // extra information typename ElfSectionHeaderTypes::AddrAlign addralign = 0U; // section alignment typename ElfSectionHeaderTypes::EntSize entsize = 0U; // section's entries size }; static_assert(sizeof(ElfSectionHeader) == 0x28, ""); static_assert(sizeof(ElfSectionHeader) == 0x40, ""); template struct ElfFileHeaderTypes; template <> struct ElfFileHeaderTypes { 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 { 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 struct ElfFileHeader { ElfFileHeaderIdentity identity = ElfFileHeaderIdentity(NumBits); // elf file identity typename ElfFileHeaderTypes::Type type = ET_NONE; // elf file type typename ElfFileHeaderTypes::Machine machine = EM_NONE; // target machine typename ElfFileHeaderTypes::Version version = 1U; // elf file version typename ElfFileHeaderTypes::Entry entry = 0U; // entry point (start address) typename ElfFileHeaderTypes::PhOff phOff = 0U; // absolute offset to program header table in file typename ElfFileHeaderTypes::ShOff shOff = 0U; // absolute offset to section header table in file typename ElfFileHeaderTypes::Flags flags = 0U; // target-dependent flags typename ElfFileHeaderTypes::EhSize ehSize = sizeof(ElfFileHeader); // header size typename ElfFileHeaderTypes::PhEntSize phEntSize = sizeof(ElfProgramHeader); // size of entries in program header table typename ElfFileHeaderTypes::PhNum phNum = 0U; // number of entries in pogram header table typename ElfFileHeaderTypes::ShEntSize shEntSize = sizeof(ElfSectionHeader); // size of entries section header table typename ElfFileHeaderTypes::ShNum shNum = 0U; // number of entries in section header table typename ElfFileHeaderTypes::ShStrNdx shStrNdx = SHN_UNDEF; // index of section header table with section names }; static_assert(sizeof(ElfFileHeader) == 0x34, ""); static_assert(sizeof(ElfFileHeader) == 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