Files
2026-08-14 21:31:01 +02:00

376 lines
6.6 KiB
C++

// SPDX-License-Identifier: MIT
#pragma once
#include <stdint.h>
constexpr char ELF_MAG[4] = {0x7F, 'E', 'L', 'F'};
typedef uint64_t elf64_addr_t;
typedef uint64_t elf64_off_t;
typedef uint32_t elf32_addr_t;
typedef uint32_t elf32_off_t;
enum : uint8_t {
EI_MAG0 = 0,
EI_MAG1 = 1,
EI_MAG2 = 2,
EI_MAG3 = 3,
EI_CLASS = 4,
EI_DATA = 5,
EI_VERSION = 6,
EI_OSABI = 7,
EI_ABIVERSION = 8,
EI_PAD = 9,
EI_NIDENT = 16,
};
enum : uint16_t {
EM_X86_64 = 62,
EM_AARCH64 = 183,
EM_RISCV = 243,
EM_LOONGARCH = 258,
};
enum : uint32_t {
ELFCLASS32 = 1,
ELFCLASS64 = 2,
};
enum : uint32_t {
ELFDATA2LSB = 1,
ELFDATA2MSB = 2,
};
enum : uint32_t {
EV_NONE = 0,
EV_CURRENT = 1,
EV_NUM = 2,
};
enum : uint32_t {
ELFOSABI_SYSV = 0,
ELFOSABI_HPUX = 1,
ELFOSABI_STANDALONE = 255,
};
enum : uint32_t {
ET_NONE = 0,
ET_REL = 1,
ET_EXEC = 2,
ET_DYN = 3,
ET_CORE = 4,
};
enum : uint32_t {
PT_NULL = 0x00000000,
PT_LOAD = 0x00000001,
PT_DYNAMIC = 0x00000002,
PT_INTERP = 0x00000003,
PT_NOTE = 0x00000004,
PT_SHLIB = 0x00000005,
PT_PHDR = 0x00000006,
PT_TLS = 0x00000007,
};
enum : uint32_t {
PF_X = 0x00000001,
PF_W = 0x00000002,
PF_R = 0x00000004,
};
enum : uint32_t {
DT_NULL = 0,
DT_NEEDED = 1,
DT_PLTRELSZ = 2,
DT_PLTGOT = 3,
DT_HASH = 4,
DT_STRTAB = 5,
DT_SYMTAB = 6,
DT_RELA = 7,
DT_RELASZ = 8,
DT_RELAENT = 9,
DT_STRSZ = 10,
DT_SYMENT = 11,
DT_INIT = 12,
DT_FINI = 13,
DT_SONAME = 14,
DT_RPATH = 15,
DT_SYMBOLIC = 16,
DT_REL = 17,
DT_RELSZ = 18,
DT_RELENT = 19,
DT_PLTREL = 20,
DT_DEBUG = 21,
DT_TEXTREL = 22,
DT_JMPREL = 23,
DT_BIND_NOW = 24,
DT_INIT_ARRAY = 25,
DT_FINI_ARRAY = 26,
DT_INIT_ARRAYSZ = 27,
DT_FINI_ARRAYSZ = 28,
DT_LOOS = 0x60000000,
DT_HIOS = 0x6FFFFFFF,
DT_LOPROC = 0x70000000,
DT_HIPROC = 0x7FFFFFFF,
};
enum : uint32_t {
AT_NULL = 0,
AT_IGNORE = 1,
AT_EXECFD = 2,
AT_PHDR = 3,
AT_PHENT = 4,
AT_PHNUM = 5,
AT_PAGESZ = 6,
AT_BASE = 7,
AT_FLAGS = 8,
AT_ENTRY = 9,
AT_NOTELF = 10,
AT_UID = 11,
AT_EUID = 12,
AT_GID = 13,
AT_EGID = 14,
AT_HWCAP = 16,
AT_SECURE = 23,
AT_RANDOM = 25,
AT_EXECFN = 31,
AT_SYSINFO_EHDR = 33,
AT_INIT_HANDLE = 0x1000,
};
struct elf64_ehdr {
uint8_t e_ident[EI_NIDENT];
uint16_t e_type;
uint16_t e_machine;
uint32_t e_version;
elf64_addr_t e_entry;
elf64_off_t e_phoff;
elf64_off_t e_shoff;
uint32_t e_flags;
uint16_t e_ehsize;
uint16_t e_phentsize;
uint16_t e_phnum;
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
};
struct elf32_ehdr {
uint8_t e_ident[EI_NIDENT];
uint16_t e_type;
uint16_t e_machine;
uint32_t e_version;
elf32_addr_t e_entry;
elf32_off_t e_phoff;
elf32_off_t e_shoff;
uint32_t e_flags;
uint16_t e_ehsize;
uint16_t e_phentsize;
uint16_t e_phnum;
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
};
struct elf64_phdr {
uint32_t p_type;
uint32_t p_flags;
elf64_off_t p_offset;
elf64_addr_t p_vaddr;
elf64_addr_t p_paddr;
uint64_t p_filesz;
uint64_t p_memsz;
uint64_t p_align;
};
struct elf32_phdr {
uint32_t p_type;
elf32_off_t p_offset;
elf32_addr_t p_vaddr;
elf32_addr_t p_paddr;
uint32_t p_filesz;
uint32_t p_memsz;
uint32_t p_flags;
uint32_t p_align;
};
struct elf64_dyn {
int64_t d_tag;
union {
uint64_t d_val;
elf64_addr_t d_ptr;
} d_un;
};
struct elf32_dyn {
int32_t r_offset;
union {
uint32_t d_val;
elf32_addr_t d_ptr;
} d_un;
};
struct elf64_nhdr {
uint64_t n_namesz;
uint64_t n_descsz;
uint64_t n_type;
};
struct elf32_nhdr {
uint32_t n_namesz;
uint32_t n_descsz;
uint32_t n_type;
};
struct elf64_auxv {
uint64_t atype;
uint64_t avalue;
};
struct elf32_auxv {
uint32_t atype;
uint32_t avalue;
};
struct elf_hash {
uint32_t n_buckets;
uint32_t n_chain;
};
struct elf32_sym {
elf32_off_t st_name;
elf32_addr_t st_value;
elf32_off_t st_size;
uint8_t st_info;
uint8_t st_other;
uint16_t st_shndx;
};
struct elf64_sym {
uint32_t st_name;
uint8_t st_info;
uint8_t st_other;
uint16_t st_shndx;
uint64_t st_value;
uint64_t st_size;
};
static uint8_t ELF64_ST_BIND(uint8_t info) {
return info >> 4;
}
static inline uint8_t ELF64_ST_TYPE(uint8_t info) {
return info & 0x0F;
}
static inline uint8_t ELF64_ST_INFO(uint8_t bind, uint8_t type) {
return (bind << 4) | type;
}
typedef struct {
uint16_t si_boundto;
uint16_t si_flags;
} elf64_syminfo;
static inline uint8_t ELF32_ST_BIND(uint8_t info) {
return info >> 4;
}
static inline uint8_t ELF32_ST_TYPE(uint8_t info) {
return info & 0xF;
}
static inline uint8_t ELF32_ST_INFO(uint8_t bind, uint8_t type) {
return (bind << 4) | (type & 0xF);
}
enum {
STB_GLOBAL = 1,
STB_WEAK = 2,
STB_GNU_UNIQUE = 10,
STB_LOPROC = 13,
STB_HIPROC = 15
};
enum {
STT_NOTYPE = 0,
STT_OBJECT = 1,
STT_FUNC = 2,
STT_TLS = 6,
STT_GNU_IFUNC = 10,
STT_LOPROC = 13,
STT_HIPROC = 15
};
struct elf32_rela {
elf32_addr_t r_offset;
uint32_t r_info;
int32_t r_addend;
};
struct elf64_rela {
elf64_addr_t r_offset;
uint64_t r_info;
int64_t r_addend;
};
struct elf32_rel {
elf32_addr_t r_offset;
uint32_t r_info;
};
struct elf64_rel {
elf64_addr_t r_offset;
uint64_t r_info;
};
static inline uint32_t ELF32_R_SYM(uint32_t info) {
return info >> 8;
}
static inline uint32_t ELF32_R_TYPE(uint32_t info) {
return info & 0xF;
}
static inline uint32_t ELF64_R_SYM(uint64_t info) {
return info >> 32;
}
static inline uint32_t ELF64_R_TYPE(uint64_t info) {
return info & 0xFFFFFFFF;
}
// Architecture specific bits.
#ifdef __x86_64__
#define ELF_ARCH_CLASS ELFCLASS64
#define ELF_ARCH_DATA ELFDATA2LSB
#define ELF_ARCH_MACHINE EM_X86_64
#define ELF_R_SYM ELF64_R_SYM
#define ELF_R_TYPE ELF64_R_TYPE
#define ELF_ST_BIND ELF64_ST_BIND
#define ELF_ST_TYPE ELF64_ST_TYPE
#define elf_ehdr elf64_ehdr
#define elf_phdr elf64_phdr
#define elf_dyn elf64_dyn
#define elf_addr elf64_addr
#define elf_off elf64_off
#define elf_nhdr elf64_nhdr
#define elf_auxv elf64_auxv
#define elf_sym elf64_sym
#define elf_rela elf64_rela
#define elf_rel elf64_rel
enum {
R_NONE = 0,
R_COPY = 5,
R_GLOB_DAT = 6,
R_JUMP_SLOT = 7,
R_RELATIVE = 8,
R_IRELATIVE = 37,
};
#endif