#ifndef ELF_H
#define ELF_H
#include <stdint.h>
#include <stddef.h>
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT];
uint16_t e_type;
uint16_t e_machine;
uint32_t e_version;
uint32_t e_entry;
uint32_t e_phoff;
uint32_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;
} elf32_ehdr_t;
typedef struct {
uint32_t p_type;
uint32_t p_offset;
uint32_t p_vaddr;
uint32_t p_paddr;
uint32_t p_filesz;
uint32_t p_memsz;
uint32_t p_flags;
uint32_t p_align;
} elf32_phdr_t;
#define ELF_MAGIC0 0x7F
#define ELF_MAGIC1 'E'
#define ELF_MAGIC2 'L'
#define ELF_MAGIC3 'F'
#define ELFCLASS32 1
#define ELFDATA2LSB 1
#define ET_EXEC 2
#define EM_386 3
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_PHDR 6
#define ET_DYN 3
#define PF_X 0x1
#define PF_W 0x2
#define PF_R 0x4
/* Dynamic section entry */
typedef struct {
int32_t d_tag;
uint32_t d_val;
} elf32_dyn_t;
#define DT_NULL 0
#define DT_NEEDED 1
#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_REL 17
#define DT_RELSZ 18
#define DT_RELENT 19
#define DT_PLTGOT 3
#define DT_JMPREL 23
#define DT_PLTRELSZ 2
#define DT_PLTREL 20
/* Relocation entry (without addend) */
typedef struct {
uint32_t r_offset;
uint32_t r_info;
} elf32_rel_t;
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char)(i))
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_386_GLOB_DAT 6
#define R_386_JMP_SLOT 7
#define R_386_RELATIVE 8
/* Symbol table entry */
typedef struct {
uint32_t st_name;
uint32_t st_value;
uint32_t st_size;
uint8_t st_info;
uint8_t st_other;
uint16_t st_shndx;
} elf32_sym_t;
/* Auxiliary vector (passed on user stack after envp) */
typedef struct {
uint32_t a_type;
uint32_t a_val;
} elf32_auxv_t;
#define AT_NULL 0
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_BASE 7 /* Interpreter base address */
#define AT_ENTRY 9 /* Program entry point */
int elf32_load_user_from_initrd(const char* filename, uintptr_t* entry_out, uintptr_t* user_stack_top_out, uintptr_t* addr_space_out, uintptr_t* heap_break_out);
/* Retrieve and consume pending auxv entries (set by elf32_load_user_from_initrd
* when an interpreter is present). Returns number of entries copied, 0 if none. */
int elf32_pop_pending_auxv(elf32_auxv_t* out, int max);
#endif