#ifndef _ELF_H
#define _ELF_H
#include <SupportDefs.h>
#include <ByteOrder.h>
typedef uint32 Elf32_Addr;
typedef uint16 Elf32_Half;
typedef uint32 Elf32_Off;
typedef int32 Elf32_Sword;
typedef uint32 Elf32_Word;
typedef Elf32_Half Elf32_Versym;
typedef uint64 Elf64_Addr;
typedef uint64 Elf64_Off;
typedef uint16 Elf64_Half;
typedef uint32 Elf64_Word;
typedef int32 Elf64_Sword;
typedef uint64 Elf64_Xword;
typedef int64 Elf64_Sxword;
typedef Elf64_Half Elf64_Versym;
#define EI_NIDENT 16
typedef struct {
uint8 e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
#ifdef __cplusplus
bool IsHostEndian() const;
#endif
} Elf32_Ehdr;
typedef struct {
uint8 e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
#ifdef __cplusplus
bool IsHostEndian() const;
#endif
} Elf64_Ehdr;
#define EI_MAG0 0
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_PAD 7
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\x7f""ELF"
#define SELFMAG 4
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_LOOS 0xfe00
#define ET_HIOS 0xfeff
#define ET_LOPROC 0xff00
#define ET_HIPROC 0xffff
#define EM_NONE 0
#define EM_M32 1
#define EM_SPARC 2
#define EM_386 3
#define EM_68K 4
#define EM_88K 5
#define EM_486 6
#define EM_860 7
#define EM_MIPS 8
#define EM_S370 9
#define EM_MIPS_RS3_LE 10
#define EM_PARISC 15
#define EM_VPP550 17
#define EM_SPARC32PLUS 18
#define EM_960 19
#define EM_PPC 20
#define EM_PPC64 21
#define EM_S390 22
#define EM_V800 36
#define EM_FR20 37
#define EM_RH32 38
#define EM_MCORE 39
#define EM_RCE 39
#define EM_ARM 40
#define EM_OLD_ALPHA 41
#define EM_SH 42
#define EM_SPARCV9 43
#define EM_TRICORE 44
#define EM_ARC 45
#define EM_H8_300 46
#define EM_H8_300H 47
#define EM_H8S 48
#define EM_H8_500 49
#define EM_IA_64 50
#define EM_MIPS_X 51
#define EM_COLDFIRE 52
#define EM_68HC12 53
#define EM_MMA 54
#define EM_PCP 55
#define EM_NCPU 56
#define EM_NDR1 57
#define EM_STARCORE 58
#define EM_ME16 59
#define EM_ST100 60
#define EM_TINYJ 61
#define EM_X86_64 62
#define EM_PDSP 63
#define EM_FX66 66
#define EM_ST9PLUS 67
#define EM_ST7 68
#define EM_68HC16 69
#define EM_68HC11 70
#define EM_68HC08 71
#define EM_68HC05 72
#define EM_SVX 73
#define EM_ST19 74
#define EM_VAX 75
#define EM_CRIS 76
#define EM_JAVELIN 77
#define EM_FIREPATH 78
#define EM_ZSP 79
#define EM_MMIX 80
#define EM_HUANY 81
#define EM_PRISM 82
#define EM_AVR 83
#define EM_FR30 84
#define EM_D10V 85
#define EM_D30V 86
#define EM_V850 87
#define EM_M32R 88
#define EM_MN10300 89
#define EM_MN10200 90
#define EM_PJ 91
#define EM_OPENRISC 92
#define EM_ARC_A5 93
#define EM_XTENSA 94
#define EM_VIDCORE 95
#define EM_CR 103
#define EM_BLACKFIN 106
#define EM_ARCA 109
#define EM_VIDCORE3 137
#define EM_ARM64 183
#define EM_AARCH64 EM_ARM64
#define EM_AVR32 185
#define EM_STM8 186
#define EM_CUDA 190
#define EM_VIDCORE5 198
#define EM_NORC 218
#define EM_AMDGPU 224
#define EM_RISCV 243
#define EM_BPF 247
#define EM_ALPHA 0x9026
#define ELFCLASSNONE 0
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFDATANONE 0
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define EV_NONE 0
#define EV_CURRENT 1
typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
typedef struct {
Elf64_Word sh_name;
Elf64_Word sh_type;
Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
} Elf64_Shdr;
#define SHN_UNDEF 0
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_INIT_ARRAY 14
#define SHT_FINI_ARRAY 15
#define SHT_GNU_verdef 0x6ffffffd
#define SHT_GNU_verneed 0x6ffffffe
#define SHT_GNU_versym 0x6fffffff
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
#define SHF_WRITE 1
#define SHF_ALLOC 2
#define SHF_EXECINSTR 4
#define SHF_MASKPROC 0xf0000000
typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
#ifdef __cplusplus
bool IsReadWrite() const;
bool IsExecutable() const;
#endif
} Elf32_Phdr;
typedef struct {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
#ifdef __cplusplus
bool IsReadWrite() const;
bool IsExecutable() const;
#endif
} Elf64_Phdr;
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_TLS 7
#define PT_EH_FRAME 0x6474e550
#define PT_STACK 0x6474e551
#define PT_RELRO 0x6474e552
#define PT_LOPROC 0x70000000
#define PT_ARM_UNWIND 0x70000001
#define PT_RISCV_ATTRIBUTES 0x70000003
#define PT_HIPROC 0x7fffffff
#define PF_EXECUTE 0x1
#define PF_WRITE 0x2
#define PF_READ 0x4
#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ)
#define PF_MASKPROC 0xf0000000
typedef struct {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
uint8 st_info;
uint8 st_other;
Elf32_Half st_shndx;
#ifdef __cplusplus
uint8 Bind() const;
uint8 Type() const;
void SetInfo(uint8 bind, uint8 type);
#endif
} Elf32_Sym;
typedef struct {
Elf64_Word st_name;
uint8 st_info;
uint8 st_other;
Elf64_Half st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;
#ifdef __cplusplus
uint8 Bind() const;
uint8 Type() const;
void SetInfo(uint8 bind, uint8 type);
#endif
} Elf64_Sym;
#define ELF32_ST_BIND(i) ((i) >> 4)
#define ELF32_ST_TYPE(i) ((i) & 0xf)
#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf))
#define ELF64_ST_BIND(i) ((i) >> 4)
#define ELF64_ST_TYPE(i) ((i) & 0xf)
#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf))
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_TLS 6
#define STT_LOPROC 13
#define STT_HIPROC 15
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_LOPROC 13
#define STB_HIPROC 15
#define STN_UNDEF 0
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_386_GOT32 3
#define R_386_PLT32 4
#define R_386_COPY 5
#define R_386_GLOB_DAT 6
#define R_386_JMP_SLOT 7
#define R_386_RELATIVE 8
#define R_386_GOTOFF 9
#define R_386_GOTPC 10
#define R_386_TLS_DTPMOD32 35
#define R_386_TLS_DTPOFF32 36
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
#ifdef __cplusplus
uint8 SymbolIndex() const;
uint8 Type() const;
#endif
} Elf32_Rel;
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info;
#ifdef __cplusplus
uint8 SymbolIndex() const;
uint8 Type() const;
#endif
} Elf64_Rel;
#ifdef __cplusplus
typedef struct Elf32_Rela : public Elf32_Rel {
#else
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
#endif
Elf32_Sword r_addend;
} Elf32_Rela;
#ifdef __cplusplus
typedef struct Elf64_Rela : public Elf64_Rel {
#else
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info;
#endif
Elf64_Sxword r_addend;
} Elf64_Rela;
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char)(i))
#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t))
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xffffffffL)
#define ELF64_R_INFO(s, t) ((((Elf64_Xword)(s)) << 32) + ((t) & 0xffffffffL))
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
#define DT_NULL 0
#define DT_NEEDED 1
#define DT_PLTRELSZ 2
#define DT_PLTGOT 3
#define DT_HASH 4
#define DT_STRTAB 5
#define DT_SYMTAB 6
#define DT_RELA 7
#define DT_RELASZ 8
#define DT_RELAENT 9
#define DT_STRSZ 10
#define DT_SYMENT 11
#define DT_INIT 12
#define DT_FINI 13
#define DT_SONAME 14
#define DT_RPATH 15
#define DT_SYMBOLIC 16
#define DT_REL 17
#define DT_RELSZ 18
#define DT_RELENT 19
#define DT_PLTREL 20
#define DT_DEBUG 21
#define DT_TEXTREL 22
#define DT_JMPREL 23
#define DT_BIND_NOW 24
#define DT_INIT_ARRAY 25
#define DT_FINI_ARRAY 26
#define DT_INIT_ARRAYSZ 27
#define DT_FINI_ARRAYSZ 28
#define DT_RUNPATH 29
#define DT_FLAGS 30
#define DT_ENCODING 32
#define DT_PREINIT_ARRAY 32
#define DT_PREINIT_ARRAYSZ 33
#define DT_VERSYM 0x6ffffff0
#define DT_VERDEF 0x6ffffffc
#define DT_VERDEFNUM 0x6ffffffd
#define DT_VERNEED 0x6ffffffe
#define DT_VERNEEDNUM 0x6fffffff
#define DT_LOPROC 0x70000000
#define DT_HIPROC 0x7fffffff
#define DF_ORIGIN 0x01
#define DF_SYMBOLIC 0x02
#define DF_TEXTREL 0x04
#define DF_BIND_NOW 0x08
#define DF_STATIC_TLS 0x10
typedef struct {
Elf32_Half vd_version;
Elf32_Half vd_flags;
Elf32_Half vd_ndx;
Elf32_Half vd_cnt;
Elf32_Word vd_hash;
Elf32_Word vd_aux;
Elf32_Word vd_next;
} Elf32_Verdef;
typedef struct {
Elf64_Half vd_version;
Elf64_Half vd_flags;
Elf64_Half vd_ndx;
Elf64_Half vd_cnt;
Elf64_Word vd_hash;
Elf64_Word vd_aux;
Elf64_Word vd_next;
} Elf64_Verdef;
#define VER_DEF_NONE 0
#define VER_DEF_CURRENT 1
#define VER_DEF_NUM 2
#define VER_FLG_BASE 0x1
#define VER_FLG_WEAK 0x2
#define VER_NDX_LOCAL 0
#define VER_NDX_GLOBAL 1
#define VER_NDX_INITIAL 2
#define VER_NDX_LORESERVE 0xff00
#define VER_NDX_ELIMINATE 0xff01
#define VER_NDX_FLAG_HIDDEN 0x8000
#define VER_NDX_MASK 0x7fff
#define VER_NDX(x) ((x) & VER_NDX_MASK)
typedef struct {
Elf32_Word vda_name;
Elf32_Word vda_next;
} Elf32_Verdaux;
typedef struct {
Elf64_Word vda_name;
Elf64_Word vda_next;
} Elf64_Verdaux;
typedef struct {
Elf32_Half vn_version;
Elf32_Half vn_cnt;
Elf32_Word vn_file;
Elf32_Word vn_aux;
Elf32_Word vn_next;
} Elf32_Verneed;
typedef struct {
Elf64_Half vn_version;
Elf64_Half vn_cnt;
Elf64_Word vn_file;
Elf64_Word vn_aux;
Elf64_Word vn_next;
} Elf64_Verneed;
#define VER_NEED_NONE 0
#define VER_NEED_CURRENT 1
#define VER_NEED_NUM 2
typedef struct {
Elf32_Word vna_hash;
Elf32_Half vna_flags;
Elf32_Half vna_other;
Elf32_Word vna_name;
Elf32_Word vna_next;
} Elf32_Vernaux;
typedef struct {
Elf64_Word vna_hash;
Elf64_Half vna_flags;
Elf64_Half vna_other;
Elf64_Word vna_name;
Elf64_Word vna_next;
} Elf64_Vernaux;
#define VER_FLG_WEAK 0x2
typedef struct {
Elf32_Word n_namesz;
Elf32_Word n_descsz;
Elf32_Word n_type;
} Elf32_Nhdr;
typedef struct {
Elf64_Word n_namesz;
Elf64_Word n_descsz;
Elf64_Word n_type;
} Elf64_Nhdr;
#define ELF_NOTE_CORE "CORE"
#define ELF_NOTE_HAIKU "Haiku"
#define NT_FILE 0x46494c45
#define NT_TEAM 0x7465616d
#define NT_AREAS 0x61726561
#define NT_IMAGES 0x696d6167
#define NT_THREADS 0x74687264
#define NT_SYMBOLS 0x73796d73
typedef struct {
int32 nt_id;
int32 nt_uid;
int32 nt_gid;
} Elf32_Note_Team;
typedef Elf32_Note_Team Elf64_Note_Team;
typedef struct {
int32 na_id;
uint32 na_lock;
uint32 na_protection;
uint32 na_base;
uint32 na_size;
uint32 na_ram_size;
} Elf32_Note_Area_Entry;
typedef struct {
int32 na_id;
uint32 na_lock;
uint32 na_protection;
uint32 na_pad1;
uint64 na_base;
uint64 na_size;
uint64 na_ram_size;
} Elf64_Note_Area_Entry;
typedef struct {
int32 ni_id;
int32 ni_type;
uint32 ni_init_routine;
uint32 ni_term_routine;
int32 ni_device;
int64 ni_node;
uint32 ni_text_base;
uint32 ni_text_size;
int32 ni_text_delta;
uint32 ni_data_base;
uint32 ni_data_size;
uint32 ni_symbol_table;
uint32 ni_symbol_hash;
uint32 ni_string_table;
} Elf32_Note_Image_Entry;
typedef struct {
int32 ni_id;
int32 ni_type;
uint64 ni_init_routine;
uint64 ni_term_routine;
uint32 ni_pad1;
int32 ni_device;
int64 ni_node;
uint64 ni_text_base;
uint64 ni_text_size;
int64 ni_text_delta;
uint64 ni_data_base;
uint64 ni_data_size;
uint64 ni_symbol_table;
uint64 ni_symbol_hash;
uint64 ni_string_table;
} Elf64_Note_Image_Entry;
typedef struct {
int32 nth_id;
int32 nth_state;
int32 nth_priority;
uint32 nth_stack_base;
uint32 nth_stack_end;
} Elf32_Note_Thread_Entry;
typedef struct {
int32 nth_id;
int32 nth_state;
int32 nth_priority;
uint32 nth_pad1;
uint64 nth_stack_base;
uint64 nth_stack_end;
} Elf64_Note_Thread_Entry;
#ifdef __cplusplus
inline bool
Elf32_Ehdr::IsHostEndian() const
{
#if B_HOST_IS_LENDIAN
return e_ident[EI_DATA] == ELFDATA2LSB;
#elif B_HOST_IS_BENDIAN
return e_ident[EI_DATA] == ELFDATA2MSB;
#endif
}
inline bool
Elf64_Ehdr::IsHostEndian() const
{
#if B_HOST_IS_LENDIAN
return e_ident[EI_DATA] == ELFDATA2LSB;
#elif B_HOST_IS_BENDIAN
return e_ident[EI_DATA] == ELFDATA2MSB;
#endif
}
inline bool
Elf32_Phdr::IsReadWrite() const
{
return !(~p_flags & (PF_READ | PF_WRITE));
}
inline bool
Elf32_Phdr::IsExecutable() const
{
return (p_flags & PF_EXECUTE) != 0;
}
inline bool
Elf64_Phdr::IsReadWrite() const
{
return !(~p_flags & (PF_READ | PF_WRITE));
}
inline bool
Elf64_Phdr::IsExecutable() const
{
return (p_flags & PF_EXECUTE) != 0;
}
inline uint8
Elf32_Sym::Bind() const
{
return ELF32_ST_BIND(st_info);
}
inline uint8
Elf32_Sym::Type() const
{
return ELF32_ST_TYPE(st_info);
}
inline void
Elf32_Sym::SetInfo(uint8 bind, uint8 type)
{
st_info = ELF32_ST_INFO(bind, type);
}
inline uint8
Elf64_Sym::Bind() const
{
return ELF64_ST_BIND(st_info);
}
inline uint8
Elf64_Sym::Type() const
{
return ELF64_ST_TYPE(st_info);
}
inline void
Elf64_Sym::SetInfo(uint8 bind, uint8 type)
{
st_info = ELF64_ST_INFO(bind, type);
}
inline uint8
Elf32_Rel::SymbolIndex() const
{
return ELF32_R_SYM(r_info);
}
inline uint8
Elf32_Rel::Type() const
{
return ELF32_R_TYPE(r_info);
}
inline uint8
Elf64_Rel::SymbolIndex() const
{
return ELF64_R_SYM(r_info);
}
inline uint8
Elf64_Rel::Type() const
{
return ELF64_R_TYPE(r_info);
}
#endif
#endif