/*
 * elf.h  -  Definitions for ELF file handling
 *
 * Copyright (C) 2004-2007 Gero Kuhlmann <gero@gkminix.han.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **************************************************************************
 *
 * This file has been compiled from information found in the GNU BFD
 * library source code. However, it has been extensively modified. The
 * original sources carry the following copyright:
 *
 *   ELF support for BFD.
 *   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
 *   2001, 2002, 2003, 2004
 *   Free Software Foundation, Inc.
 *
 *   Written by Fred Fish @ Cygnus Support, from information published
 *   in "UNIX System V Release 4, Programmers Guide: ANSI C and
 *   Programming Support Tools".
 *
 **************************************************************************
 *
 * $Id: elf.h,v 1.7 2007/01/06 18:31:08 gkminix Exp $
 */

#ifndef ELF_H
#define ELF_H


/*
 * Everything in this file has to be in packed structures.
 */
#include <common.h>
#define PACK_ENABLED
#ifdef USE_PRAGMA_PACK
#pragma pack(1)
#endif
#ifdef USE_PRAGMA_ALIGN
#pragma options align=packed
#endif



/*
 * Fields in e_ident[] and their possible values
 */
#define EI_NIDENT	16	/* Size of e_ident[] */

#define EI_MAG0		0	/* File identification byte 0 index */
#define ELFMAG0		   0x7F	/* Magic number byte 0 */

#define EI_MAG1		1	/* File identification byte 1 index */
#define ELFMAG1		    'E'	/* Magic number byte 1 */

#define EI_MAG2		2	/* File identification byte 2 index */
#define ELFMAG2		    'L'	/* Magic number byte 2 */

#define EI_MAG3		3	/* File identification byte 3 index */
#define ELFMAG3		    'F'	/* Magic number byte 3 */

#define EI_CLASS	4	/* File class */
#define ELFCLASSNONE	     0	/* Invalid class */
#define ELFCLASS32	     1	/* 32-bit objects */
#define ELFCLASS64	     2	/* 64-bit objects */

#define EI_DATA		5	/* Data encoding */
#define ELFDATANONE	     0	/* Invalid data encoding */
#define ELFDATA2LSB	     1	/* 2's complement, little endian */
#define ELFDATA2MSB	     2	/* 2's complement, big endian */



/*
 * Values for e_type, which identifies the object file type
 */
#define ET_NONE		0	/* No file type */
#define ET_REL		1	/* Relocatable file */
#define ET_EXEC		2	/* Executable file */
#define ET_DYN		3	/* Shared object file */
#define ET_CORE		4	/* Core file */



/*
 * Values for e_machine, which identifies the architecture
 */
#define EM_NONE		0	/* No machine */
#define EM_386		3	/* Intel 80386 */
#define EM_486		6	/* Intel 80486 */



/*
 * Values for e_version
 */
#define EV_NONE		0		/* Invalid ELF version */
#define EV_CURRENT	1		/* Current version */



/*
 * Values for program header, p_type field
 */
#define PT_NULL		0		/* Program header table entry unused */
#define PT_LOAD		1		/* Loadable program segment */
#define PT_DYNAMIC	2		/* Dynamic linking information */
#define PT_INTERP	3		/* Program interpreter */
#define PT_NOTE		4		/* Auxiliary information */
#define PT_SHLIB	5		/* Reserved, unspecified semantics */
#define PT_PHDR		6		/* Entry for header table itself */
#define PT_TLS		7		/* Thread local storage segment */



/*
 * Program segment permissions, in program header p_flags field
 */
#define PF_X		(1 << 0)	/* Segment is executable */
#define PF_W		(1 << 1)	/* Segment is writable */
#define PF_R		(1 << 2)	/* Segment is readable */

#define PF_MASK		(PF_R | PF_W | PF_X)



/*
 * Values for section header, sh_type field
 */
#define SHT_NULL	   0		/* Section header table entry unused */
#define SHT_PROGBITS	   1		/* Program specific (private) 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_INIT_ARRAY	  14		/* Array of ptrs to init functions */
#define SHT_FINI_ARRAY	  15		/* Array of ptrs to finish functions */
#define SHT_PREINIT_ARRAY 16		/* Array of ptrs to pre-init funcs */
#define SHT_GROUP	  17		/* Section contains a section group */
#define SHT_SYMTAB_SHNDX  18		/* Indicies for SHN_XINDEX entries */



/*
 * Values for section header, sh_flags field
 */
#define SHF_WRITE	(1 << 0)	/* Writable data during execution */
#define SHF_ALLOC	(1 << 1)	/* Occupies memory during execution */
#define SHF_EXECINSTR	(1 << 2)	/* Executable machine instructions */
#define SHF_MERGE	(1 << 4)	/* Data in this section can be merged */
#define SHF_STRINGS	(1 << 5)	/* Contains null terminated character strings */
#define SHF_INFO_LINK	(1 << 6)	/* sh_info holds section header table index */
#define SHF_LINK_ORDER	(1 << 7)	/* Preserve section ordering when linking */
#define SHF_OS_NONCONFORMING (1 << 8)	/* OS specific processing required */
#define SHF_GROUP	(1 << 9)	/* Member of a section group */
#define SHF_TLS		(1 << 10)	/* Thread local storage section */



/*
 * These three macros disassemble and assemble a symbol table st_info field,
 * which contains the symbol binding and symbol type.  The STB_ and STT_
 * defines identify the binding and type.
 */
#define ELF_ST_BIND(val)		(((unsigned int)(val)) >> 4)
#define ELF_ST_TYPE(val)		(((unsigned int)(val)) & 0xF)
#define ELF_ST_INFO(bind,type)		(((bind) << 4) + ((type) & 0xF))



/*
 * Symbol table bind values
 */
#define STB_LOCAL	0		/* Symbol not visible outside obj */
#define STB_GLOBAL	1		/* Symbol visible outside obj */
#define STB_WEAK	2		/* Like globals, lower precedence */



/*
 * Symbol table type values
 */
#define STT_NOTYPE	0		/* Symbol type is unspecified */
#define STT_OBJECT	1		/* Symbol is a data object */
#define STT_FUNC	2		/* Symbol is a code object */
#define STT_SECTION	3		/* Symbol associated with a section */
#define STT_FILE	4		/* Symbol gives a file name */
#define STT_COMMON	5		/* An uninitialised common block */
#define STT_TLS		6		/* Thread local data object */



/*
 * Special section indices, which may show up in st_shndx fields
 */
#define SHN_UNDEF	0		/* Undefined section reference */
#define SHN_LORESERVE	0xFF00		/* Begin range of reserved indices */
#define SHN_LOPROC	0xFF00		/* Begin range of appl-specific */
#define SHN_HIPROC	0xFF1F		/* End range of appl-specific */
#define SHN_LOOS	0xFF20		/* OS specific semantics, lo */
#define SHN_HIOS	0xFF3F		/* OS specific semantics, hi */
#define SHN_ABS		0xFFF1		/* Associated symbol is absolute */
#define SHN_COMMON	0xFFF2		/* Associated symbol is in common */
#define SHN_XINDEX	0xFFFF		/* Section index is held elsewhere */
#define SHN_HIRESERVE	0xFFFF		/* End range of reserved indices */



/*
 * Relocation info handling macros
 */
#define ELF_R_SYM(i)		((i) >> 8)
#define ELF_R_TYPE(i)		((i) & 0xff)
#define ELF_R_INFO(s,t)		(((s) << 8) + ((t) & 0xff))



/*
 * i386 relocs
 */
#define R_386_NONE	   0		/* No reloc */
#define R_386_32	   1		/* Direct 32 bit  */
#define R_386_PC32	   2		/* PC relative 32 bit */
#define R_386_RELATIVE	   8		/* Adjust by program base */
#define R_386_16	   20
#define R_386_PC16	   21
#define R_386_8		   22
#define R_386_PC8	   23



/*
 * Dynamic section tags
 */
#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	31



/*
 * ELF Header (32-bit implementations)
 */
struct s_Elf_Ehdr {
  __u8     e_ident[16];		/* ELF "magic number" */
  __u16    e_type;		/* Identifies object file type */
  __u16    e_machine;		/* Specifies required architecture */
  __long   e_version;		/* Identifies object file version */
  __long   e_entry;		/* Entry point virtual address */
  __long   e_phoff;		/* Program header table file offset */
  __long   e_shoff;		/* Section header table file offset */
  __long   e_flags;		/* Processor-specific flags */
  __u16    e_ehsize;		/* ELF header size in bytes */
  __u16    e_phentsize;		/* Program header table entry size */
  __u16    e_phnum;		/* Program header table entry count */
  __u16    e_shentsize;		/* Section header table entry size */
  __u16    e_shnum;		/* Section header table entry count */
  __u16    e_shstrndx;		/* Section header string table index */
} PACKED;

typedef struct s_Elf_Ehdr Elf_Ehdr;



/*
 * Program header
 */
struct s_Elf_Phdr {
  __long   p_type;		/* Identifies program segment type */
  __long   p_offset;		/* Segment file offset */
  __long   p_vaddr;		/* Segment virtual address */
  __long   p_paddr;		/* Segment physical address */
  __long   p_filesz;		/* Segment size in file */
  __long   p_memsz;		/* Segment size in memory */
  __long   p_flags;		/* Segment flags */
  __long   p_align;		/* Segment alignment, file & memory */
} PACKED;

typedef struct s_Elf_Phdr Elf_Phdr;



/*
 * Section header
 */
struct s_Elf_Shdr {
  __long   sh_name;		/* Section name, index in string tbl */
  __long   sh_type;		/* Type of section */
  __long   sh_flags;		/* Miscellaneous section attributes */
  __long   sh_addr;		/* Section virtual addr at execution */
  __long   sh_offset;		/* Section file offset */
  __long   sh_size;		/* Size of section in bytes */
  __long   sh_link;		/* Index of another section */
  __long   sh_info;		/* Additional section information */
  __long   sh_addralign;	/* Section alignment */
  __long   sh_entsize;		/* Entry size if section holds table */
} PACKED;

typedef struct s_Elf_Shdr Elf_Shdr;



/*
 * Symbol table entry
 */
struct s_Elf_Sym {
  __long   st_name;		/* Symbol name, index in string tbl */
  __long   st_value;		/* Value of the symbol */
  __long   st_size;		/* Associated symbol size */
  __u8     st_info;		/* Type and binding attributes */
  __u8     st_other;		/* No defined meaning, 0 */
  __u16    st_shndx;		/* Associated section index */
} PACKED;

typedef struct s_Elf_Sym Elf_Sym;


struct s_Elf_Sym_Shndx {
  __long   est_shndx;		/* Section index */
} PACKED;

typedef struct s_Elf_Sym_Shndx Elf_Sym_Shndx;



/*
 * Relocation Entries
 */
struct s_Elf_Rel {
  __long   r_offset;		/* Location at which to apply the action */
  __long   r_info;		/* index and type of relocation */
} PACKED;

typedef struct s_Elf_Rel Elf_Rel;


struct s_Elf_Rela {
  __long   r_offset;		/* Location at which to apply the action */
  __long   r_info;		/* index and type of relocation */
  __long   r_addend;		/* Constant addend used to compute value */
} PACKED;

typedef struct s_Elf_Rela Elf_Rela;



/*
 * Dynamic section structure
 */
struct s_Elf_Dyn {
  __long   d_tag;		/* entry tag value */
  union {
    __long   d_val;
    __long   d_ptr;
  } d_un;
} PACKED;

typedef struct s_Elf_Dyn Elf_Dyn;



/*
 * Turnoff structure packing and return to normal data alignment.
 */
#ifdef USE_PRAGMA_PACK
#pragma pack()
#endif
#ifdef USE_PRAGMA_ALIGN
#pragma options align=reset
#endif
#undef PACK_ENABLED

#endif

