text: #ifndef _PH_EXLF_H
  #define _PH_EXLF_H
  
  /*
   * This file contains the required types for ELF bianires. 
   *
   * References:
   * http://man7.org/linux/man-pages/man5/elf.5.html
   * http://www.skyfree.org/linux/references/ELF_Format.pdf
   * https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h
   * https://chromium.googlesource.com/chromiumos/chromite/+/HEAD/lib/parseelf.py
   */
  
  #define EI_NIDENT 16
  
  // e_ident[] indexes
  #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_OSABI	7
  #define	EI_PAD		8
  
  // EI_MAG
  #define	ELFMAG0 0x7f
  #define	ELFMAG1	'E'
  #define	ELFMAG2	'L'
  #define	ELFMAG3 'F'
  // EI_CLASS 
  #define	ELFCLASSNONE 0
  #define	ELFCLASS32 1
  #define	ELFCLASS64 2
  
  // EI_DATA
  #define ELFDATANONE 0
  #define ELFDATA2LSB	1
  #define ELFDATA2MSB	2
  
  // EI_VERSION and e_version
  #define EV_NONE	0
  #define EV_CURRENT 1
  
  #define ELFOSABI_NONE 0
  #define ELFOSABI_LINUX 3
  
  // e_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
  
  // e_machine
  #define EM_386 3
  #define EM_X86_64 62
  
  /* segment types */
  #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               /* Thread local storage segment */
  #define PT_LOOS    0x60000000      /* OS-specific */
  #define PT_HIOS    0x6fffffff      /* OS-specific */
  #define PT_LOPROC  0x70000000
  #define PT_HIPROC  0x7fffffff
  #define PT_GNU_EH_FRAME		0x6474e550
  #define PT_GNU_STACK	(PT_LOOS + 0x474e551)
  
  /* permissions on sections in the program header, p_flags. */
  #define PF_NONE 0x0
  #define PF_X 0x1
  #define PF_W 0x2
  #define PF_R 0x4
  
  // sh_type
  #define SHT_NULL 0     // Section header table entry (unused).
  #define SHT_PROGBITS 1 // Program data.
  #define SHT_SYMTAB 2   // Link editing symbol table.
  #define SHT_STRTAB 3   // A string table.
  #define SHT_RELA 4     // Relocation entries with addends.
  #define SHT_HASH 5     // A symbol hash table.
  #define SHT_DYNAMIC 6  // Information for dynamic linking.
  #define SHT_NOTE 7     // Information that marks file.
  #define SHT_NOBITS 8   // Section occupies no space in file.
  #define SHT_REL 9      // Relocation entries, no addends.
  #define SHT_SHLIB 10   // Reserved, unspecified semantics.
  #define SHT_DYNSYM 11  // Dynamic linking symbol table.
  //#define SHT_NUM 12
  #define SHT_INIT_ARRAY 14    // Array of constructors.
  #define SHT_FINI_ARRAY 15    // Array of destructors.
  #define SHT_PREINIT_ARRAY 16 // Array of pre-constructors.
  #define SHT_GROUP 17         // Section group.
  #define SHT_SYMTAB_SHNDX 18  // Extended section indeces.
  #define SHT_NUM 19           // Number of defined types. (dmex: Some tools define this as 19 and others as 12???)
  #define SHT_LOOS 0x60000000	// First of OS specific semantics.
  #define SHT_HIOS 0x6fffffff	// Last of OS specific semantics.
  #define SHT_GNU_INCREMENTAL_INPUTS 0x6fff4700 // incremental build data.
  #define SHT_GNU_ATTRIBUTES 0x6ffffff5 // Object attributes.
  #define SHT_GNU_HASH 0x6ffffff6 // GNU style symbol hash table.
  #define SHT_GNU_LIBLIST	0x6ffffff7 // List of prelink dependencies.
  #define SHT_LOPROC 0x70000000
  #define SHT_HIPROC 0x7fffffff
  #define SHT_LOUSER 0x80000000
  #define SHT_HIUSER 0xffffffff
  #define SHT_SUNW_verdef	0x6ffffffd	// Versions defined by file.
  #define SHT_SUNW_verneed 0x6ffffffe	// Versions needed by file.
  #define SHT_SUNW_versym	0x6fffffff	// Symbol versions.
  
  // sh_flags
  #define SHF_WRITE 0x1	/* Section contains writable data. */
  #define SHF_ALLOC 0x2	/* Section occupies memory. */
  #define SHF_EXECINSTR 0x4	/* Section contains instructions. */
  #define SHF_MERGE 0x10	/* Section may be merged. */
  #define SHF_STRINGS	0x20	/* Section contains strings. */
  #define SHF_INFO_LINK 0x40	/* sh_info holds section index. */
  #define SHF_LINK_ORDER 0x80	/* Special ordering requirements. */
  #define SHF_OS_NONCONFORMING 0x100	/* OS-specific processing required. */
  #define SHF_GROUP 0x200	/* Member of section group. */
  #define SHF_TLS 0x400	/* Section contains TLS data. */
  #define SHF_MASKOS	0x0ff00000	/* OS-specific semantics. */
  #define SHF_MASKPROC	0xf0000000	/* Processor-specific semantics. */
  
  // special section indexes.
  #define SHN_UNDEF 0 // An undefined symbol.
  #define SHN_LORESERVE 0xff00
  #define SHN_LOPROC 0xff00
  #define SHN_HIPROC 0xff1f
  #define SHN_LIVEPATCH 0xff20
  #define SHN_ABS 0xfff1
  #define SHN_COMMON 0xfff2
  #define SHN_HIRESERVE 0xffff
  
  // dynamic section
  #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_ENCODING	32
  #define OLD_DT_LOOS	0x60000000
  #define DT_LOOS		0x6000000d
  #define DT_HIOS		0x6ffff000
  #define DT_VALRNGLO	0x6ffffd00
  #define DT_VALRNGHI	0x6ffffdff
  #define DT_ADDRRNGLO	0x6ffffe00
  #define DT_ADDRRNGHI	0x6ffffeff
  #define DT_VERSYM	0x6ffffff0
  #define DT_RELACOUNT	0x6ffffff9
  #define DT_RELCOUNT	0x6ffffffa
  #define DT_FLAGS_1	0x6ffffffb
  #define DT_VERDEF	0x6ffffffc
  #define	DT_VERDEFNUM	0x6ffffffd
  #define DT_VERNEED	0x6ffffffe
  #define	DT_VERNEEDNUM	0x6fffffff
  #define OLD_DT_HIOS     0x6fffffff
  #define DT_LOPROC	0x70000000
  #define DT_HIPROC	0x7fffffff
  
  // symbol table section
  #define STB_LOCAL 0 /* Local symbol */
  #define STB_GLOBAL 1 /* Global symbol */
  #define STB_WEAK 2 /* Weak symbol */
  #define STB_NUM 3 /* Number of defined types.  */
  #define STB_LOOS 10 /* Start of OS-specific */
  #define STB_GNU_UNIQUE 10 /* Unique symbol.  */
  #define STB_HIOS 12 /* End of OS-specific */
  #define STB_LOPROC 13 /* Start of processor-specific */
  #define STB_HIPROC 15 /* End of processor-specific */
  
  #define STT_NOTYPE  0
  #define STT_OBJECT  1
  #define STT_FUNC    2
  #define STT_SECTION 3
  #define STT_FILE    4
  #define STT_COMMON  5
  #define STT_TLS     6
  #define STT_GNU_IFUNC 10
  #define STT_LOOS      10
  #define STT_HIOS      12
  #define STT_LOPROC    13
  #define STT_HIPROC    15
  
  #define STV_DEFAULT	0 /* Default symbol visibility rules */
  #define STV_INTERNAL 1 /* Processor specific hidden class */
  #define STV_HIDDEN 2 /* Sym unavailable in other modules */
  #define STV_PROTECTED 3 /* Not preemptible, not exported */
  
  #define ELF_ST_BIND(x) ((x) >> 4)
  #define ELF_ST_TYPE(x) ((x) & 0xF)
  #define ELF_ST_VISIBILITY(x) ((x) & 0x03)
  
  #define ELF32_ST_BIND(x) ELF_ST_BIND(x)
  #define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
  #define ELF32_ST_VIS(a)	ELF_ST_VISIBILITY(a)
  #define ELF64_ST_BIND(x) ELF_ST_BIND(x)
  #define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
  #define ELF64_ST_VIS(a)	ELF_ST_VISIBILITY(a)
  
  // Non-standard ELF definitions (dmex)
  
  #define	IMAGE_ELF_SIGNATURE 0x457f // "\x7fELF"
  #define	ELFMAG ((BYTE[4]){ELFMAG0,ELFMAG1,ELFMAG2,ELFMAG3})
  
  typedef struct _ELF_IMAGE_HEADER
  {
      union
      {
          unsigned char e_ident[EI_NIDENT];
          struct
          {
              unsigned char MagicNumber[4];
              unsigned char Class;
              unsigned char Data;
              unsigned char Version;
              unsigned char Abi;
              unsigned char AbiVersion;
              unsigned char Unused[7];
          };
      };
      unsigned short e_type;
      unsigned short e_machine;
      unsigned int e_version;
      //union {
      //    PELF_IMAGE_HEADER32 Headers32;
      //    PELF_IMAGE_HEADER64 Headers64;
      //};
  } ELF_IMAGE_HEADER, *PELF_IMAGE_HEADER;
  
  typedef struct _ELF_IMAGE_HEADER32
  {
      // ELF_IMAGE_HEADER Header;
      unsigned int e_entry; // Entry point virtual address.
      unsigned int e_phoff; // Program header table file offset.
      unsigned int e_shoff; // Section header table file offset.
      unsigned int e_flags; // Processor-specific flags.
      unsigned short e_ehsize; // ELF header size in bytes.
      unsigned short e_phentsize; // Program header table entry size.
      unsigned short e_phnum; // Program header table entry count.
      unsigned short e_shentsize; // Section header table entry size.
      unsigned short e_shnum; // Section header table entry count.
      unsigned short e_shstrndx; // Section header string table index.
  } ELF_IMAGE_HEADER32, *PELF_IMAGE_HEADER32;
  
  typedef struct _ELF_IMAGE_HEADER64
  {
      // ELF_IMAGE_HEADER Header;
      unsigned long long e_entry; // Entry point virtual address.
      unsigned long long e_phoff; // Program header table file offset.
      unsigned long long e_shoff; // Section header table file offset.
      unsigned int e_flags; // Processor-specific flags.
      unsigned short e_ehsize; // ELF header size in bytes.
      unsigned short e_phentsize; // Program header table entry size.
      unsigned short e_phnum; // Program header table entry count.
      unsigned short e_shentsize; // Section header table entry size.
      unsigned short e_shnum; // Section header table entry count.
      unsigned short e_shstrndx; // Section header string table index.
  } ELF_IMAGE_HEADER64, *PELF_IMAGE_HEADER64;
  
  typedef struct _ELF32_IMAGE_SEGMENT_HEADER
  {
      unsigned int p_type; // Segment type.
      unsigned int p_offset; // Segment file offset.
      unsigned int p_vaddr; // Segment virtual address.
      unsigned int p_paddr; // Segment physical address.
      unsigned int p_filesz; // Segment size in file.
      unsigned int p_memsz; // Segment size in memory.
      unsigned int p_flags; // Segment flags.
      unsigned int p_align; // Segment alignment.
  } ELF32_IMAGE_SEGMENT_HEADER;
  
  typedef struct _ELF64_IMAGE_SEGMENT_HEADER
  {
      unsigned int p_type; // Segment type.
      unsigned int p_flags; // Segment flags.
      unsigned long long p_offset; // Segment file offset.
      unsigned long long p_vaddr; // Segment virtual address.
      unsigned long long p_paddr; // Segment physical address.
      unsigned long long p_filesz; // Segment size in file.
      unsigned long long p_memsz;	// Segment size in memory.
      unsigned long long p_align; // Segment alignment.
  } ELF64_IMAGE_SEGMENT_HEADER, *PELF64_IMAGE_SEGMENT_HEADER;
  
  #define IMAGE_FIRST_ELF64_SEGMENT(MappedWslImage) \
      ((PELF64_IMAGE_SEGMENT_HEADER)PTR_ADD_OFFSET(MappedWslImage->Header, MappedWslImage->Headers64->e_phoff))
  
  #define IMAGE_ELF64_SEGMENT_BY_INDEX(SegmentHeader, Index) \
      ((PELF64_IMAGE_SEGMENT_HEADER)PTR_ADD_OFFSET(SegmentHeader, sizeof(ELF64_IMAGE_SEGMENT_HEADER) * Index))
      //((PELF64_IMAGE_SEGMENT_HEADER)&SegmentHeaderTable[Index])
  
  typedef struct _ELF32_IMAGE_SECTION_HEADER
  {
      unsigned int sh_name;
      unsigned int sh_type;
      unsigned int sh_flags;
      unsigned int sh_addr;
      unsigned int sh_offset;
      unsigned int sh_size;
      unsigned int sh_link;
      unsigned int sh_info;
      unsigned int sh_addralign;
      unsigned int sh_entsize;
  } ELF32_IMAGE_SECTION_HEADER;
  
  typedef struct _ELF64_IMAGE_SECTION_HEADER
  {
      unsigned int sh_name;            /* Section name, index in string tbl */
      unsigned int sh_type;            /* Type of section */
      unsigned long long sh_flags;     /* Miscellaneous section attributes */
      unsigned long long sh_addr;      /* Section virtual addr at execution */
      unsigned long long sh_offset;    /* Section file offset */
      unsigned long long sh_size;      /* Size of section in bytes */
      unsigned int sh_link;            /* Index of another section */
      unsigned int sh_info;            /* Additional section information */
      unsigned long long sh_addralign; /* Section alignment */
      unsigned long long sh_entsize;   /* Entry size if section holds table */
  } ELF64_IMAGE_SECTION_HEADER, *PELF64_IMAGE_SECTION_HEADER;
  
  #define IMAGE_FIRST_ELF64_SECTION(MappedWslImage) \
      ((PELF64_IMAGE_SECTION_HEADER)PTR_ADD_OFFSET(MappedWslImage->Header, MappedWslImage->Headers64->e_shoff))
  
  #define IMAGE_ELF64_SECTION_BY_INDEX(SectionHeader, Index) \
      ((PELF64_IMAGE_SECTION_HEADER)PTR_ADD_OFFSET(SectionHeader, sizeof(ELF64_IMAGE_SECTION_HEADER) * Index))
      // ((PELF64_IMAGE_SECTION_HEADER)&SectionHeaderTable[Index])
  
  // ELF dynamic entries
  
  typedef struct _ELF32_IMAGE_DYNAMIC_ENTRY // Elf32_Dyn
  {
      int d_tag;
      unsigned int d_val;
  } ELF32_IMAGE_DYNAMIC_ENTRY, *PELF32_IMAGE_DYNAMIC_ENTRY;
  
  typedef struct _ELF64_IMAGE_DYNAMIC_ENTRY // Elf64_Dyn
  {
      long long d_tag;
      unsigned long long d_val;
  } ELF64_IMAGE_DYNAMIC_ENTRY, *PELF64_IMAGE_DYNAMIC_ENTRY;
  
  // ELF symbol entries 
  
  typedef struct _ELF_IMAGE_SYMBOL_ENTRY // Elf_Sym
  {
      unsigned int st_name;
      unsigned char st_info;
      unsigned char st_other;
      unsigned short st_shndx;
      unsigned long long st_value;
      unsigned long long st_size;
  } ELF_IMAGE_SYMBOL_ENTRY, *PELF_IMAGE_SYMBOL_ENTRY;
  
  // ELF version entires
  
  typedef struct _ELF_VERSION_TABLE // Elf_Versym
  {
      unsigned short vs_vers;
  } ELF_VERSION_TABLE, *PELF_VERSION_TABLE;
  
  typedef struct 
  {
      unsigned short vd_version;
      unsigned short vd_flags; // flags (VER_FLG_*).
      unsigned short vd_ndx; // version index.
      unsigned short vd_cnt; // number of verdaux entries.
      unsigned int vd_hash; // hash of name.
      unsigned int vd_aux; // offset to verdaux entries.
      unsigned int vd_next; // offset to next verdef.
  } Elf_Verdef;
  
  typedef struct 
  {
      unsigned int vda_name;	/* string table offset of name */
      unsigned int vda_next;	/* offset to verdaux */
  } Elf_Verdaux;
  
  // vn_version
  #define VER_NEED_NONE    0 /* No version */
  #define VER_NEED_CURRENT 1 /* Current version */
  #define VER_NEED_NUM     2 /* Given version number */
  
  typedef struct _ELF_VERSION_NEED // Elf_Verneed
  {
      unsigned short vn_version;
      unsigned short vn_cnt;
      unsigned int vn_file;
      unsigned int vn_aux;
      unsigned int vn_next;
  } ELF_VERSION_NEED, *PELF_VERSION_NEED;
  
  typedef struct _ELF_VERSION_AUX // Elf_Vernaux
  {
      unsigned int vna_hash; // dependency name hash.
      unsigned short vna_flags; // flags (VER_FLG_*).
      unsigned short vna_other;
      unsigned int vna_name;
      unsigned int vna_next;
  } ELF_VERSION_AUX, *PELF_VERSION_AUX;
  
  #endif
  