/*
 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
 *	The President and Fellows of Harvard College.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _ELF_H_
#define _ELF_H_

/*
 * Simplified ELF definitions for OS/161 and System/161.
 *
 * Restrictions:
 *     32-bit only
 *     No support for .o files or linker structures
 *     Does not define all the random symbols a standard elf header would.
 */

/* Get MD bits */
#include <machine/elf.h>

/*
 * ELF file header. This appears at the very beginning of an ELF file.
 */
#define ELF_NIDENT 16
typedef struct {
  unsigned char e_ident[ELF_NIDENT]; /* magic number et al. */
  uint16_t e_type;                   /* type of file this is */
  uint16_t e_machine;                /* processor type file is for */
  uint32_t e_version;                /* ELF version */
  uint32_t e_entry;                  /* address of program entry point */
  uint32_t e_phoff;                  /* location in file of phdrs */
  uint32_t e_shoff;                  /* ignore */
  uint32_t e_flags;                  /* ignore */
  uint16_t e_ehsize;                 /* actual size of file header */
  uint16_t e_phentsize;              /* actual size of phdr */
  uint16_t e_phnum;                  /* number of phdrs */
  uint16_t e_shentsize;              /* ignore */
  uint16_t e_shnum;                  /* ignore */
  uint16_t e_shstrndx;               /* ignore */
} Elf32_Ehdr;

/* Offsets for the 1-byte fields within e_ident[] */
#define EI_MAG0 0       /* '\177' */
#define EI_MAG1 1       /* 'E'    */
#define EI_MAG2 2       /* 'L'    */
#define EI_MAG3 3       /* 'F'    */
#define EI_CLASS 4      /* File class - always ELFCLASS32 */
#define EI_DATA 5       /* Data encoding - ELFDATA2LSB or ELFDATA2MSB*/
#define EI_VERSION 6    /* ELF version - EV_CURRENT*/
#define EI_OSABI 7      /* OS/syscall ABI identification */
#define EI_ABIVERSION 8 /* syscall ABI version */
#define EI_PAD 9        /* Start of padding bytes up to EI_NIDENT*/

/* Values for these fields */

/* For e_ident[EI_MAG0..3] */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'

/* For e_ident[EI_CLASS] */
#define ELFCLASSNONE 0 /* Invalid class */
#define ELFCLASS32 1   /* 32-bit objects */
#define ELFCLASS64 2   /* 64-bit objects */

/* e_ident[EI_DATA] */
#define ELFDATANONE 0 /* Invalid data encoding */
#define ELFDATA2LSB 1 /* 2's complement values, LSB first */
#define ELFDATA2MSB 2 /* 2's complement values, MSB first */

/* e_ident[EI_VERSION] */
#define EV_NONE 0    /* Invalid version */
#define EV_CURRENT 1 /* Current version */

/* e_ident[EI_OSABI] */
#define ELFOSABI_SYSV 0         /* UNIX System V ABI */
#define ELFOSABI_HPUX 1         /* HP-UX operating system */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */

/*
 * Values for e_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

/*
 * Values for e_machine
 */
#define EM_NONE 0          /* No machine */
#define EM_M32 1           /* AT&T WE 32100 */
#define EM_SPARC 2         /* SPARC */
#define EM_386 3           /* Intel 80386 */
#define EM_68K 4           /* Motorola 68000 */
#define EM_88K 5           /* Motorola 88000 */
#define EM_486 6           /* Intel 80486 */
#define EM_860 7           /* Intel 80860 */
#define EM_MIPS 8          /* MIPS I Architecture */
#define EM_S370 9          /* Amdahl UTS on System/370 */
#define EM_MIPS_RS3_LE 10  /* MIPS RS3000 Little-endian */
#define EM_RS6000 11       /* IBM RS/6000 XXX reserved */
#define EM_PARISC 15       /* Hewlett-Packard PA-RISC */
#define EM_NCUBE 16        /* NCube XXX reserved */
#define EM_VPP500 17       /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18  /* Enhanced instruction set SPARC */
#define EM_960 19          /* Intel 80960 */
#define EM_PPC 20          /* PowerPC */
#define EM_V800 36         /* NEC V800 */
#define EM_FR20 37         /* Fujitsu FR20 */
#define EM_RH32 38         /* TRW RH-32 */
#define EM_RCE 39          /* Motorola RCE */
#define EM_ARM 40          /* Advanced RISC Machines ARM */
#define EM_ALPHA 41        /* DIGITAL Alpha */
#define EM_SH 42           /* Hitachi Super-H */
#define EM_SPARCV9 43      /* SPARC Version 9 */
#define EM_TRICORE 44      /* Siemens Tricore */
#define EM_ARC 45          /* Argonaut RISC Core */
#define EM_H8_300 46       /* Hitachi H8/300 */
#define EM_H8_300H 47      /* Hitachi H8/300H */
#define EM_H8S 48          /* Hitachi H8S */
#define EM_H8_500 49       /* Hitachi H8/500 */
#define EM_IA_64 50        /* Intel Merced Processor */
#define EM_MIPS_X 51       /* Stanford MIPS-X */
#define EM_COLDFIRE 52     /* Motorola Coldfire */
#define EM_68HC12 53       /* Motorola MC68HC12 */
#define EM_VAX 75          /* DIGITAL VAX */
#define EM_ALPHA_EXP 36902 /* used by NetBSD/alpha; obsolete */
#define EM_NUM 36903

/*
 * "Program Header" - runtime segment header.
 * There are Ehdr.e_phnum of these located at one position within the file.
 *
 * Note: if p_memsz > p_filesz, the leftover space should be zero-filled.
 */
typedef struct {
  uint32_t p_type;   /* Type of segment */
  uint32_t p_offset; /* Location of data within file */
  uint32_t p_vaddr;  /* Virtual address */
  uint32_t p_paddr;  /* Ignore */
  uint32_t p_filesz; /* Size of data within file */
  uint32_t p_memsz;  /* Size of data to be loaded into memory*/
  uint32_t p_flags;  /* Flags */
  uint32_t p_align;  /* Required alignment - can ignore */
} Elf32_Phdr;

/* values for p_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, unspecified semantics */
#define PT_PHDR 6    /* Entry for header table itself */
#define PT_NUM 7
#define PT_MIPS_REGINFO 0x70000000

/* values for p_flags */
#define PF_R 0x4 /* Segment is readable */
#define PF_W 0x2 /* Segment is writable */
#define PF_X 0x1 /* Segment is executable */

typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Phdr Elf_Phdr;

#endif /* _ELF_H_ */
