#ifndef ELF_H
#define ELF_H

#define  EI_NIDENT 16

typedef short Elf32_Half;
typedef int Elf32_SWord;
typedef unsigned Elf32_Word;
typedef unsigned Elf32_Addr;
typedef unsigned Elf32_Off;

struct Elf32_Ehdr {
    unsigned char ident[EI_NIDENT];
    Elf32_Half type;
    Elf32_Half machine;
    Elf32_Word version;
    Elf32_Addr entry;
    Elf32_Off phoff;
    Elf32_Off shoff;
    Elf32_Word flags;
    Elf32_Half ehsize;
    Elf32_Half phentsize;
    Elf32_Half phnum;
    Elf32_Half shentsize;
    Elf32_Half shnum;
    Elf32_Half shstrndx;
};

// Elf32_Ehdr::ident

#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 ELFCLASSNONE 	0
#define ELFCLASS32   	1
#define ELFCLASS64   	2

#define ELFDATANONE	0
#define ELFDATA2LSB	1
#define ELFDATA2MSB	2

// Elf32_Ehdr::type

#define ET_NONE		0
#define ET_REL		1
#define ET_EXEC		2
#define ET_DYN		3
#define ET_CORE		4
#define ET_LOPROC	0xff00
#define ET_HIPROC	0xffff

// Elf32_Ehdr::machine

#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_860		7
#define EM_MIPS		8
#define EM_POWERPC32	20

// Elf32_Ehdr::version
#define EV_NONE		0
#define EV_CURRENT	1


struct Elf32_Shdr {
    Elf32_Word name;
    Elf32_Word type;
    Elf32_Word flags;
    Elf32_Addr addr;
    Elf32_Off offset;
    Elf32_Word size;
    Elf32_Word link;
    Elf32_Word info;
    Elf32_Word addralign;
    Elf32_Word entsize;
};

#define STN_UNDEF	0

// Elf32_Shdr::type
#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_LOPROC	0x70000000
#define SHT_HIPROC	0x7fffffff
#define SHT_LOUSER	0x80000000
#define SHT_HIUSER	0xffffffff

// Elf32_Shdr::flags
#define SHF_WRITE	1
#define SHF_ALLOC	2
#define SHF_EXECINSTR	4
#define SHF_MASKPROC	0xf0000000

struct Elf32_Sym {
    Elf32_Word name;
    Elf32_Addr value;
    Elf32_Word size;
    unsigned char info;
    unsigned char other;
    Elf32_Half shndx;
};

#define ST_BIND(i)	((i) >> 4)
#define ST_TYPE(i)	((i) & 15)
#define ST_INFO(b,t)	((unsigned char)(((b)<<4)|((t)&15)))

#define STB_LOCAL	0
#define STB_GLOBAL	1
#define STB_WEAK	2
#define STB_LOPROC	13
#define STB_HIPROC	15

#define STT_NOTYPE	0
#define STT_OBJECT	1
#define STT_FUNC	2
#define STT_SECTION	3
#define STT_FILE	4
#define STT_LOPROC	13
#define STT_HIPROC	15

#define SHN_ABS		((Elf32_Half)0xfff1)
#define SHN_COMMON	((Elf32_Half)0xfff2)
#define SHN_UNDEF	0

struct Elf32_Rel {
    Elf32_Addr offset;
    Elf32_Word info;
};

struct Elf32_Rela {
    Elf32_Addr offset;
    Elf32_Word info;
    Elf32_SWord addend;
};

#define R_SYM(i)	((i)>>8)
#define R_TYPE(i)	((unsigned char)(i))
#define R_INFO(s,t)	(((s)<<8)|(unsigned char)(t))

#define R_NONE			0
#define R_PPC_ADDR32		1
#define R_PPC_ADDR24		2
#define R_PPC_ADDR16		3
#define R_PPC_ADDR16_LO		4
#define R_PPC_ADDR16_HI		5
#define R_PPC_ADDR16_HA		6
#define R_PPC_ADDR14		7
#define R_PPC_ADDR14_BRTAKEN	8
#define R_PPC_ADDR14_BRNTAKEN	9
#define R_PPC_REL24		10
#define R_PPC_REL14		11
#define R_PPC_REL14_BRTAKEN	12
#define R_PPC_REL14_BRNTAKEN	13
#define R_PPC_GOT16		14
#define R_PPC_GOT16_LO		15
#define R_PPC_GOT16_HI		16
#define R_PPC_GOT16_HA		17
#define R_PPC_PLTREL24		18
#define R_PPC_COPY		19
#define R_PPC_GLOB_DAT		20
#define R_PPC_JMP_SLOT		21
#define R_PPC_RELATIVE		22
#define R_PPC_LOCAL24PC		23
#define R_PPC_UADDR32		24
#define R_PPC_UADDR16		25
#define R_PPC_REL32		26
#define R_PPC_PLT32		27
#define R_PPC_PLTREL32		28
#define R_PPC_PLT16_LO		29
#define R_PPC_PLT16_HI		30
#define R_PPC_PLT16_HA		31
#define R_PPC_SDAREL16		32
#define R_PPC_SECTOFF		33
#define R_PPC_SECTOFF_LO	34
#define R_PPC_SECTOFF_HI	35
#define R_PPC_SECTOFF_HA	36
#define R_PPC_TOC16		63


struct Elf32_Phdr {
    Elf32_Word type;
    Elf32_Off  offset;
    Elf32_Addr vaddr;
    Elf32_Addr paddr;
    Elf32_Word filesz;
    Elf32_Word memsz;
    Elf32_Word flags;
    Elf32_Word align;
};

#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_LOPROC	0x70000000
#define PT_HIPROC	0x7fffffff

#endif

