/* This file defines standard ELF types, structures, and macros.
   Copyright (C) 1995-2003,2004,2005,2006,2007,2008,2009
	Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef _ELF_H_
#define	_ELF_H_ 1

#include <hal_types.h>

/*
 * Standard ELF types.
 */

/* Type for a 16-bit quantity. */
typedef uint16_t Elf32_Half;

/* Types for signed and unsigned 32-bit quantities. */
typedef uint32_t Elf32_Word;
typedef	int32_t  Elf32_Sword;

/* Type of addresses. */
typedef uint32_t Elf32_Addr;

/* Type of file offsets. */
typedef uint32_t Elf32_Off;

/* Type for section indices, which are 16-bit quantities. */
typedef uint16_t Elf32_Section;

/* Type for version symbol information. */
typedef Elf32_Half Elf32_Versym;

/*************************************************************************************
 * This structure defines the ELF file header (first bytes in the file)
 *************************************************************************************/

#define EI_NIDENT (16)

typedef struct
{
	unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
	Elf32_Half      e_type;             /* Object file type */
	Elf32_Half      e_machine;          /* Architecture */
	Elf32_Word      e_version;          /* Object file version */
	Elf32_Addr	    e_entry;            /* Entry point virtual address */
	Elf32_Off	    e_phoff;            /* Program header table file offset */
	Elf32_Off	    e_shoff;            /* Section header table file offset */
	Elf32_Word      e_flags;            /* Processor-specific flags */
	Elf32_Half      e_ehsize;           /* ELF header size in bytes */
	Elf32_Half      e_phentsize;        /* Program header table entry size */
	Elf32_Half      e_phnum;            /* Program header table entry count */
	Elf32_Half      e_shentsize;        /* Section header table entry size */
	Elf32_Half      e_shnum;            /* Section header table entry count */
	Elf32_Half      e_shstrndx;         /* Section header string table index */
}
Elf32_Ehdr;

/*
 * Fields in the e_ident array. The EI_* macros are indices into the
 * array. The macros under each EI_* macro are the values the byte
 * may have.
 */
#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 byte index */
#define ELFCLASSNONE	0		/* Invalid class */
#define ELFCLASS32	1		/* 32-bit objects */
#define ELFCLASSNUM	3

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

#define EI_VERSION	6		/* File version byte index */
					/* Value must be EV_CURRENT */

#define EI_OSABI	7		/* OS ABI identification */
#define ELFOSABI_NONE		0	/* UNIX System V ABI */

/* Legal values for e_type (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 */
#define	ET_NUM		5		/* Number of defined types */
#define ET_LOOS		0xfe00		/* OS-specific range start */
#define ET_HIOS		0xfeff		/* OS-specific range end */
#define ET_LOPROC	0xff00		/* Processor-specific range start */
#define ET_HIPROC	0xffff		/* Processor-specific range end */

/* Legal values for e_machine (architecture).  */
#define EM_NONE		 0		/* No machine */
#define EM_MIPS		 8		/* MIPS R3000 big-endian */
#define EM_MIPS_RS3_LE	10		/* MIPS R3000 little-endian */
#define EM_PPC		20		/* PowerPC */
#define EM_PPC64	21		/* PowerPC 64-bit */
#define EM_ARM		40		/* ARM */
#define EM_X86_64	62		/* AMD x86-64 architecture */

/* Legal values for e_version (version).  */
#define EV_NONE		0		/* Invalid ELF version */
#define EV_CURRENT	1		/* Current version */
#define EV_NUM		2

/* Program segment header.  */

typedef struct
{
	Elf32_Word	p_type;		/* Segment type */
	Elf32_Off	p_offset;	/* Segment file offset */
	Elf32_Addr	p_vaddr;	/* Segment virtual address */
	Elf32_Addr	p_paddr;	/* Segment physical address */
	Elf32_Word	p_filesz;	/* Segment size in file */
	Elf32_Word	p_memsz;	/* Segment size in memory */
	Elf32_Word	p_flags;	/* Segment flags */
	Elf32_Word	p_align;    /* Segment alignment */
}
Elf32_Phdr;

/* Legal values for p_type (segment type).  */
#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 */
#define PT_PHDR		6		/* Entry for header table itself */
#define PT_TLS		7		/* Thread-local storage segment */
#define	PT_NUM		8		/* Number of defined types */
#define PT_LOOS		0x60000000	/* Start of OS-specific */
#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
#define PT_LOSUNW	0x6ffffffa
#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
#define PT_HISUNW	0x6fffffff
#define PT_HIOS		0x6fffffff	/* End of OS-specific */
#define PT_LOPROC	0x70000000	/* Start of processor-specific */
#define PT_HIPROC	0x7fffffff	/* End of processor-specific */

/* Legal values for p_flags (segment flags).  */
#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_MASKOS	0x0ff00000	/* OS-specific */
#define PF_MASKPROC	0xf0000000	/* Processor-specific */


/****************************************************************************************
 * This function registers in VMM the CODE and DATA vsegs defined in the .elf file.
 * The segments are not loaded in memory.
 * It also registers the process entry point in VMM.
 ****************************************************************************************
 * @ pathname : .elf file pathname (in user space => must use hal_uspace API).
 * @ process  : local pointer on target process descriptor.
 ***************************************************************************************/
error_t elf_load_process( char      * pathname,
                          process_t * process);

#endif	/* elf.h */
