/* coff_gnu.h
   Copyright (C) 1987, 1992 Free Software Foundation, Inc.

   This file is part of GAS, the GNU Assembler.

   GAS 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, or (at your option)
   any later version.

   GAS 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 GAS; see the file COPYING.  If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/*
 * At this point I'm sure this file is right for i960 and I'm pretty sure it's
 * right for a29k, although it hasn't been tested rigorously.  Please feel free
 * to add your own machine's description here.  Without that info, it isn't
 * possible to build cross development tools from elsewhere nor is it easy to
 * continue to support your machines format.
 *
 * The TC_foo ifdef's are mine.  They are what gas uses.  The other ifdef's
 * remain for documentation from other scavenged files.   xoxorich.
 */

/********************** FILE HEADER **********************/

struct filehdr
  {
    unsigned short f_magic;	/* magic number			*/
    unsigned short f_nscns;	/* number of sections		*/
    long f_timdat;		/* time & date stamp		*/
    long f_symptr;		/* file pointer to symtab	*/
    long f_nsyms;		/* number of symtab entries	*/
    unsigned short f_opthdr;	/* sizeof(optional hdr)		*/
    unsigned short f_flags;	/* flags			*/
  };

/* Bits for f_flags:
 *	F_RELFLG	relocation info stripped from file
 *	F_EXEC		file is executable (no unresolved externel references)
 *	F_LNNO		line nunbers stripped from file
 *	F_LSYMS		local symbols stripped from file
 *	F_AR32WR	file has byte ordering of an AR32WR machine (e.g. vax)
 */
#define F_RELFLG	(0x0001)
#define F_EXEC		(0x0002)
#define F_LNNO		(0x0004)
#define F_LSYMS		(0x0008)

#ifdef TC_I960
#define F_AR32WR	(0x0010)/* File has 32 bits per word, least
				    significant byte first. */
#else /* TC_I960 */
#define F_AR32WR	(0x0100)
#endif /* TC_I960 */

#define F_MINMAL	(0x0010)/* ??? */
#define F_UPDATE	(0x0020)/* ??? */
#define F_SWABD		(0x0040)/* ??? */
#define F_AR16WR	(0x0080)/* File has the byte ordering used by
				    the PDP*-11/70 processor. */
#define F_AR32W		(0x0200)/* File has 32 bits per word, most
				    significant byte first. */

/*
 *	Intel 80960 (I960) processor flags.
 *	F_I960TYPE == mask for processor type field.
 */

#define	F_I960TYPE	(0xf000)
#define	F_I960CORE	(0x1000)
#define	F_I960KB	(0x2000)
#define	F_I960SB	(0x2000)
#define	F_I960MC	(0x3000)
#define	F_I960XA	(0x4000)
#define	F_I960CA	(0x5000)
#define	F_I960KA	(0x6000)
#define	F_I960SA	(0x6000)

/*
 * i80960 Magic Numbers
 */

#define I960ROMAGIC	(0x160)	/* read-only text segments */
#define I960RWMAGIC	(0x161)	/* read-write text segments */

#define I960BADMAG(x) (((x).f_magic != I960ROMAGIC) && ((x).f_magic != I960RWMAGIC))

#define	SIPFBOMAGIC	(0x17a)	/* Am29000 (Byte 0 is MSB - Big Endian) */
#define	SIPRBOMAGIC	(0x17b)	/* Am29000 (Byte 0 is LSB - Little Endian) */

#define A29KBADMAG(x)	(((x).f_magic != SIPFBOMAGIC) && ((x).f_magic != SIPRBOMAGIC))

#ifdef TE_I386AIX
# define I386MAGIC	(0x175)	/* Danbury AIX C compiler 	*/
# define I386SVMAGIC	(0x14c)	/* System V C Compiler 		*/
# define I386BADMAG(x)  (((x).f_magic!=I386MAGIC) && \
			 ((x).f_magic!=I386SVMAGIC))
#else /* not TE_I386AIX */
# define I386MAGIC	0x14c
# define I386BADMAG(x) (((x).f_magic!=I386MAGIC))
#endif /* not TE_I386AIX */


#define	FILHDR	struct filehdr
#define	FILHSZ	sizeof(FILHDR)


/********************** AOUT "OPTIONAL HEADER" **********************/

typedef struct
  {
    unsigned long phys_addr;
    unsigned long bitarray;
  }

TAGBITS;

/*  These appear to be used only by exec(2).  I don't know who cares
    about them in a cross development environment.  In any case, this
    is my collection after researching the issue for a few hours.
    Apparently, most have these have remained essentially unchanged
    since v7 days, although a few new ones have been added.  xoxorich. */

#define BAD0MAGIC	(0401)	/* (?) "lpd (UNIX/RT)" */
#define BAD1MAGIC	(0405)	/* (?) overlay */
#define	OMAGIC		(0407)	/* old impure format. data immediately
				  follows text. both sections are rw. */
#define	NMAGIC		(0410)	/* split i&d, read-only text */
#define A_MAGIC3	(0411)	/* (?) "separated I&D" */
#define	ZMAGIC		(0413)	/* like NMAGIC, but demand loaded */
#define PAGEMAGIC2	(0414)	/* (?) like ZMAGIC, but address zero
				  explicitly unmapped. */
#define REGMAGIC	(0414)	/* (?) a PAGEMAGIC2 alias? */
#define PAGEMAGIC3	(0415)	/* (?) like ZMAGIC, but address zero mapped. */
#define A_MAGIC5	(0437)	/* (?) "system overlay, separated I&D" */
/* intended for non-unix cross development */
#define SASMAGIC	(010000)/* Single Address Space */
#define MASMAGIC	(020000)/* (?) "Multiple (separate I & D) Address Spaces" */

typedef struct aouthdr
  {
    short magic;		/* type of file				*/
    short vstamp;		/* version stamp			*/
    unsigned long tsize;	/* text size in bytes, padded to FW bdry*/
    unsigned long dsize;	/* initialized data "  "		*/
    unsigned long bsize;	/* uninitialized data "   "		*/
#if U3B
    unsigned long dum1;
    unsigned long dum2;		/* pad to entry point	*/
#endif
    unsigned long entry;	/* entry pt.				*/
    unsigned long text_start;	/* base of text used for this file */
    unsigned long data_start;	/* base of data used for this file */
    /* CAREFUL: some formats omit the tagentries member. */
    unsigned long tagentries;	/* number of tag entries to
					   follow (always zero for i960) */
  }

AOUTHDR;

/* return a pointer to the tag bits array */

#define TAGPTR(aout) ((TAGBITS *) (&(aout.tagentries)+1))

/* compute size of a header */

/*#define AOUTSZ(aout) (sizeof(AOUTHDR)+(aout.tagentries*sizeof(TAGBITS)))*/
#define AOUTSZ (sizeof(AOUTHDR))


/********************** STORAGE CLASSES **********************/

#define C_EFCN		-1	/* physical end of function */
#define C_NULL		0
#define C_AUTO		1	/* automatic variable */
#define C_EXT		2	/* external symbol */
#define C_STAT		3	/* static */
#define C_REG		4	/* register variable */
#define C_EXTDEF	5	/* external definition */
#define C_LABEL		6	/* label */
#define C_ULABEL	7	/* undefined label */
#define C_MOS		8	/* member of structure */
#define C_ARG		9	/* function argument */
#define C_STRTAG	10	/* structure tag */
#define C_MOU		11	/* member of union */
#define C_UNTAG		12	/* union tag */
#define C_TPDEF		13	/* type definition */
#define C_USTATIC	14	/* undefined static */
#define C_ENTAG		15	/* enumeration tag */
#define C_MOE		16	/* member of enumeration */
#define C_REGPARM	17	/* register parameter */
#define C_FIELD		18	/* bit field */

#ifdef TC_I960
#define C_AUTOARG	19	/* auto argument */
#define C_LASTENT	20	/* dummy entry (end of block) */
#endif /* TC_I960 */

#ifdef TC_A29K
#define C_GLBLREG	19	/* global register */
#define C_EXTREG	20	/* external global register */
#define	C_DEFREG	21	/* ext. def. of global register */
#define C_STARTOF	22	/* as29 $SIZEOF and $STARTOF symbols */
#endif /* TC_A29K */

#define C_BLOCK		100	/* ".bb" or ".eb" */
#define C_FCN		101	/* ".bf" or ".ef" */
#define C_EOS		102	/* end of structure */
#define C_FILE		103	/* file name */
#define C_LINE		104	/* line # reformatted as symbol table entry */
#define C_ALIAS	 	105	/* duplicate tag */
#define C_HIDDEN	106	/* ext symbol in dmert public lib. like static,
				   used to avoid name conflicts. */

#ifdef TC_I960
/* New storage classes for 80960 */
#define C_SCALL		107	/* Procedure reachable via system call	*/
/* C_LEAFPROC is obsolete.  Use C_LEAFEXT or C_LEAFSTAT */
#define C_LEAFPROC	108	/* Leaf procedure, "call" via BAL */
#define C_LEAFEXT       108
#define C_OPTVAR	109	/* Optimized variable */
#define C_DEFINE	110	/* Preprocessor #define */
#define C_PRAGMA	111	/* Advice to compiler or linker	*/
#define C_SEGMENT	112	/* 80960 segment name */
#define C_LEAFSTAT      113	/* Static leaf */
#endif /* TC_I960 */

#ifdef TC_A29K
#define C_SHADOW	107	/* shadow symbol */
#endif /* TC_A29K */

/********************** SECTION HEADER **********************/

struct scnhdr
  {
    char s_name[8];		/* section name */
    long s_paddr;		/* physical address, aliased s_nlib */
    long s_vaddr;		/* virtual address */
    long s_size;		/* section size */
    long s_scnptr;		/* file ptr to raw data for section */
    long s_relptr;		/* file ptr to relocation */
    long s_lnnoptr;		/* file ptr to line numbers */
    unsigned short s_nreloc;	/* number of relocation entries	*/
    unsigned short s_nlnno;	/* number of line number entries */
    long s_flags;		/* flags */

#ifdef TC_I960
    unsigned long s_align;	/* section alignment */
#endif /* TC_I960 */
  };

#define	SCNHDR	struct scnhdr
#define	SCNHSZ	sizeof(SCNHDR)

/*
 * names of "special" sections
 */
#define _TEXT    ".text"	/* executable code section	*/
#define _DATA    ".data"	/* initialized data		*/
#define _BSS     ".bss"		/* un-initialized data		*/
#define _DEBUG   ".debug"	/* special section used by dbx	*/
#define _COMMENT ".comment"	/* version info			*/
#define _LIB     ".lib"		/* shared lib info section	*/
#define _TV      ".tv"

/*
 * s_flags "type"
 */

/*
 * In instances where it is necessary for a linker to
 * produce an output file which contains text or data not
 * based at virtual address 0, e.g. for a ROM, then the
 * linker should accept address base information as command
 * input and use PAD sections to skip over unused addresses.
 * (at least for a29k.  Maybe others.)
 */

#define STYP_REG	 (0x0000)	/* "regular" section: allocated, relocated, loaded */
#define STYP_DSECT	 (0x0001)	/* "dummy" section: not allocated, relocated, not loaded */
#define STYP_NOLOAD	 (0x0002)	/* "noload" section: allocated, relocated, not loaded */
#define STYP_GROUP	 (0x0004)	/* "grouped" section: formed of input sections */
#define STYP_PAD	 (0x0008)	/* "padding" section: not allocated, not relocated, loaded */
#define STYP_COPY	 (0x0010)	/* "copy" section: for decision function used by field update;  not allocated, not relocated,
				     loaded; reloc & lineno entries processed normally */
#define STYP_TEXT	 (0x0020)	/* section contains text only */
#define S_SHRSEG	 (0x0020)	/* In 3b Update files (output of ogen), sections which appear in SHARED segments of the Pfile
				     will have the S_SHRSEG flag set by ogen, to inform dufr that updating 1 copy of the proc. will
				     update all process invocations. */
#define STYP_DATA	 (0x0040)	/* section contains data only */
#define STYP_BSS	 (0x0080)	/* section contains bss only */
#define S_NEWFCN	 (0x0100)	/* In a minimal file or an update file, a new function (as compared with a replaced function) */
#define STYP_INFO	 (0x0200)	/* comment section : not allocated not relocated, not loaded */
#define STYP_OVER	 (0x0400)	/* overlay section : relocated not allocated or loaded */
#define STYP_LIB	 (0x0800)	/* for .lib section : same as INFO */
#define STYP_MERGE	 (0x2000)	/* merge section -- combines with text, data or bss sections only */
#define STYP_REVERSE_PAD (0x4000)	/* section will be padded with no-op instructions wherever padding is necessary and there is a
				     word of contiguous bytes beginning on a word boundary. */

#ifdef TC_A29K
/* NOTE:  The use of STYP_BSSREG for relocation is not yet defined. */
#define	STYP_BSSREG	0x1200	/* Global register area (like STYP_INFO) */
#define STYP_ENVIR	0x2200	/* Environment (like STYP_INFO) */
#define STYP_ABS	0x4000	/* Absolute (allocated, not reloc, loaded) */
#define STYP_LIT	0x8020	/* Literal data (like STYP_TEXT) */
#endif /* TC_A29K */

/********************** LINE NUMBERS **********************/

/* 1 line number entry for every "breakpointable" source line in a section.
 * Line numbers are grouped on a per function basis; first entry in a function
 * grouping will have l_lnno = 0 and in place of physical address will be the
 * symbol table index of the function name.
 */
struct lineno
  {
    union
      {
	long l_symndx;		/* symbol index of function name, iff l_lnno == 0*/
	long l_paddr;		/* (physical) address of line number */
      }
    l_addr;
    unsigned short l_lnno;	/* line number */
#ifdef TC_I960
    /* not used on a29k */
    char padding[2];		/* force alignment */
#endif /* TC_I960 */
  };

#define	LINENO	struct lineno
#define	LINESZ	sizeof(LINENO)


/********************** SYMBOLS **********************/

#define SYMNMLEN	8	/* # characters in a symbol name */
#define FILNMLEN	14	/* # characters in a file name */
#define DIMNUM		4	/* # array dimensions in auxiliary entry */

struct syment
  {
    union
      {
	char _n_name[SYMNMLEN];	/* old COFF version */
	struct
	  {
	    long _n_zeroes;	/* new == 0 */
	    long _n_offset;	/* offset into string table */
	  }
	_n_n;
	char *_n_nptr[2];	/* allows for overlaying */
      }
    _n;
    long n_value;		/* value of symbol */
    short n_scnum;		/* section number */

#ifdef TC_I960
    /* This isn't yet used on the i960.  In some formats this
	   is two bytes of padding.  In others, it is missing entirely. */
    unsigned short n_flags;	/* copy of flags from filhdr */
#endif /* TC_I960 */

#ifdef TC_A29K
    unsigned short n_type;	/* type and derived type */
#else /* TC_A29K */
    /* at least i960 uses long */
    unsigned long n_type;	/* type and derived type */
#endif /* TC_A29K */

    char n_sclass;		/* storage class */
    char n_numaux;		/* number of aux. entries */

#ifndef TC_A29K
    char pad2[2];		/* force alignment */
#endif /* TC_A29K */
  };

#define	SYMENT	struct syment
#define	SYMESZ	sizeof(SYMENT)	/* This had better also be sizeof(AUXENT) */

#define n_name		_n._n_name
#define n_ptr		_n._n_nptr[1]
#define n_zeroes	_n._n_n._n_zeroes
#define n_offset	_n._n_n._n_offset

/*
     * Relocatable symbols have number of the section in which they are defined,
     * or one of the following:
     */

#define N_SCNUM	((short) 1-65535)	/* section num where symbol defined */
#define N_UNDEF	((short)0)	/* undefined symbol */
#define N_ABS	((short)-1)	/* value of symbol is absolute */
#define N_DEBUG	((short)-2)	/* debugging symbol -- symbol value is meaningless */
#define N_TV	((short)-3)	/* indicates symbol needs preload transfer vector */
#define P_TV	((short)-4)	/* indicates symbol needs transfer vector (postload) */

/*
 * Type of a symbol, in low 4 bits of the word
 */
#define T_NULL		0	/* type not assigned */
#define T_VOID		1	/* function argument (only used by compiler) (but now real void). */
#define T_CHAR		2	/* character */
#define T_SHORT		3	/* short integer */
#define T_INT		4	/* integer */
#define T_LONG		5	/* long integer */
#define T_FLOAT		6	/* floating point */
#define T_DOUBLE	7	/* double word */
#define T_STRUCT	8	/* structure */
#define T_UNION		9	/* union */
#define T_ENUM		10	/* enumeration */
#define T_MOE		11	/* member of enumeration */
#define T_UCHAR		12	/* unsigned character */
#define T_USHORT	13	/* unsigned short */
#define T_UINT		14	/* unsigned integer */
#define T_ULONG		15	/* unsigned long */

#ifdef TC_I960
#define T_LNGDBL	16	/* long double */
#endif /* TC_I960 */

/*
 * derived types, in n_type
 */
#define DT_NON		(0)	/* no derived type */
#define DT_PTR		(1)	/* pointer */
#define DT_FCN		(2)	/* function */
#define DT_ARY		(3)	/* array */

#ifndef TC_I960

#define N_BTMASK	(0x0f)
#define N_TMASK		(0x30)
#define N_BTSHFT	(4)
#define N_TSHIFT	(2)

#else /* TC_I960 */

#define N_BTMASK	(0x1f)
#define N_TMASK		(0x60)
#define N_BTSHFT	(5)
#define N_TSHIFT	(2)

#endif /* TC_I960 */

#define BTYPE(x)	((x) & N_BTMASK)

#define ISPTR(x)	(((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
#define ISFCN(x)	(((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
#define ISARY(x)	(((x) & N_TMASK) == (DT_ARY << N_BTSHFT))

#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))

union auxent
  {
    struct
      {
	long x_tagndx;		/* str, un, or enum tag indx */
	union
	  {
	    struct
	      {
		unsigned short x_lnno;	/* declaration line number */
		unsigned short x_size;	/* str/union/array size */
	      }
	    x_lnsz;
	    long x_fsize;	/* size of function */
	  }
	x_misc;
	union
	  {
	    struct
	      {			/* if ISFCN, tag, or .bb */
		long x_lnnoptr;	/* ptr to fcn line # */
		long x_endndx;	/* entry ndx past block end */
	      }
	    x_fcn;
	    struct
	      {			/* if ISARY, up to 4 dimen. */
		unsigned short x_dimen[DIMNUM];
	      }
	    x_ary;
	  }
	x_fcnary;
	unsigned short x_tvndx;	/* tv index */
      }
    x_sym;

    /* This was just a struct x_file with x_fname only in a29k.  xoxorich. */
    union
      {
	char x_fname[FILNMLEN];
	struct
	  {
	    long x_zeroes;
	    long x_offset;
	  }
	x_n;
      }
    x_file;

    struct
      {
	long x_scnlen;		/* section length */
	unsigned short x_nreloc;/* # relocation entries */
	unsigned short x_nlinno;/* # line numbers */
      }
    x_scn;

    struct
      {
	long x_tvfill;		/* tv fill value */
	unsigned short x_tvlen;	/* length of .tv */

	/* This field was typo'd x_tvrna on a29k. xoxorich. */
	unsigned short x_tvran[2];	/* tv range */
      }
    x_tv;			/* info about .tv section (in auxent of symbol .tv)) */

#ifdef TC_I960
    /******************************************
	 *  I960-specific *2nd* aux. entry formats
	 ******************************************/
    struct
      {
	/* This is a very old typo that keeps getting propogated. */
#define x_stdindx x_stindx
	long x_stindx;		/* sys. table entry */
      }
    x_sc;			/* system call entry */

    struct
      {
	unsigned long x_balntry;/* BAL entry point */
      }
    x_bal;			/* BAL-callable function */

    struct
      {
	unsigned long x_timestamp;	/* time stamp */
	char x_idstring[20];	/* producer identity string */
      }
    x_ident;			/* Producer ident info */

    char a[sizeof (struct syment)];	/* force auxent/syment sizes to match */
#endif /* TC_I960 */
  };

#define	AUXENT	union auxent
#define	AUXESZ	sizeof(AUXENT)	/* This had better also be sizeof(SYMENT) */

#if VAX || I960
#	define _ETEXT	"_etext"
#else
#	define _ETEXT	"etext"
#endif

/********************** RELOCATION DIRECTIVES **********************/

struct reloc
  {
    long r_vaddr;		/* Virtual address of reference */
    long r_symndx;		/* Index into symbol table */
    unsigned short r_type;	/* Relocation type */
#ifdef TC_I960
    /* not used for a29k */
    char pad[2];		/* Unused */
#endif /* TC_I960 */
  };

#define RELOC struct reloc
#define RELSZ sizeof(RELOC)

#define	R_ABS		(0x00)	/* reference is absolute */

#ifdef TC_I860
#define RM_DIR32	(0x06)
#define R_IPAIR		(0x1c)
#define R_N10PAIR	(0x1d)
#define R_N10HIGH	(0x1e)
#define R_N10LOW0	(0x1f)
#define R_N10LOW1	(0x20)
#define R_N10LOW2	(0x21)
#define R_N10LOW3	(0x22)
#define R_N10LOW4	(0x23)
#define R_N10SPLIT0	(0x24)
#define R_N10SPLIT1	(0x25)
#define R_N10SPLIT2	(0x26)
#define R_N10HIGHADJ	(0x27)
#define R_N10BRADDR	(0x28)
#endif /* TC_I860 */

#ifdef TC_I960
#define R_RELLONG	(0x11)	/* Direct 32-bit relocation */
#define R_IPRSHORT	(0x18)
#define R_IPRMED 	(0x19)	/* 24-bit ip-relative relocation */
#define R_IPRLONG	(0x1a)
#define R_OPTCALL	(0x1b)	/* 32-bit optimizable call (leafproc/sysproc) */
#define R_OPTCALLX	(0x1c)	/* 64-bit optimizable call (leafproc/sysproc) */
#define R_GETSEG	(0x1d)
#define R_GETPA		(0x1e)
#define R_TAGWORD	(0x1f)
#endif /* TC_I960 */

#ifdef TC_A29K
/*
 * NOTE: All the "I" forms refer to Am29000 instruction
 * formats.  The linker is expected to know how the numeric
 * information is split and/or aligned within the
 * instruction word(s).  R_BYTE works for instructions, too.
 *
 * If the parameter to a CONSTH instruction is a relocatable
 * type, two relocation records are written.  The first has
 * an r_type of R_IHIHALF (33 octal) and a normal r_vaddr
 * and r_symndx.  The second relocation record has an r_type
 * of R_IHCONST (34 octal), a normal r_vaddr (which is
 * redundant), and an r_symndx containing the 32-bit
 * constant offset to the relocation instead of the actual
 * symbol table index.  This second record is always
 * written, even if the constant offset is zero.  The
 * constant fields of the instruction are set to zero.
 */

#define	R_IREL		(0x18)	/* instruction relative (jmp/call) */
#define	R_IABS		(0x19)	/* instruction absolute (jmp/call) */
#define	R_ILOHALF	(0x1a)	/* instruction low half  (const)  */
#define	R_IHIHALF	(0x1b)	/* instruction high half (consth) part 1 */
#define	R_IHCONST	(0x1c)	/* instruction high half (consth) part 2
				  constant offset of R_IHIHALF relocation */
#define	R_BYTE		(0x1d)	/* relocatable byte value */
#define R_HWORD		(0x1e)	/* relocatable halfword value */
#define R_WORD		(0x1f)	/* relocatable word value */
#define	R_IGLBLRC	(0x20)	/* instruction global register RC */
#define	R_IGLBLRA	(0x21)	/* instruction global register RA */
#define	R_IGLBLRB	(0x22)	/* instruction global register RB */
#endif /* TC_A29K */


#define DEFAULT_DATA_SECTION_ALIGNMENT 4
#define DEFAULT_BSS_SECTION_ALIGNMENT 4
#define DEFAULT_TEXT_SECTION_ALIGNMENT 16
/* For new sections we haven't heard of before */
#define DEFAULT_SECTION_ALIGNMENT 4

#if defined(TC_I386)
/*
 * X86 generic
 *	8-bit offset reference in 8-bits
 *	8-bit offset reference in 16-bits
 *	12-bit segment reference
 *	auxiliary relocation entry
 */
#define	R_OFF8		07
#define R_OFF16		010
#define	R_SEG12		011
#define	R_AUX		013

/*
 * B16 and X86 generics
 *	16-bit direct reference
 *	16-bit "relative" reference
 *	16-bit "indirect" (TV) reference
 */
#define  R_DIR16	01
#define  R_REL16	02
#define  R_IND16	03

/*
 * 3B generic
 *	24-bit direct reference
 *	24-bit "relative" reference
 *	16-bit optimized "indirect" TV reference
 *	24-bit "indirect" TV reference
 *	32-bit "indirect" TV reference
 */
#define  R_DIR24	04
#define  R_REL24	05
#define  R_OPT16	014
#define  R_IND24	015
#define  R_IND32	016

/*
 * XL generics
 *	10-bit direct reference
 *	10-bit "relative" reference
 *	32-bit "relative" reference
 */
#define	R_DIR10		025
#define R_REL10		026
#define R_REL32		027

/*
 * 3B and M32 generics
 *	32-bit direct reference
 */
#define  R_DIR32	06

/*
 * M32 generic
 *	32-bit direct reference with bytes swapped
 */
#define  R_DIR32S	012

#endif /* TC_I386 */

#if defined(TE_I386AIX)

#define UINFOSIZ        64	/* size of user info buffer */
typedef char uinfo_t[UINFOSIZ];

struct env387
  {
    unsigned short control;
    unsigned short r0;
    unsigned short status;
    unsigned short r1;
    unsigned short tag;
    unsigned short r2;
    unsigned long eip;
    unsigned short code_seg;
    unsigned short opcode;
    unsigned long operand;
    unsigned short operand_seg;
    unsigned short r3;
    unsigned char regs[8][10];
  };

#define	CD_NAMELEN 16		/* length of most names in this header */
#define	CORHDRSIZ	2048	/* size to which header is padded out */
#define	MAX_CORE_SEGS	32	/* maximum segments in a core dump */
#define NUM_FREGS	1	/* # of saved FP regs */

/*
 * These are defined such that 286 and 386 kernels can produce
 * compatible dumps.
 */
#define CD_AX	0
#define CD_BX	1
#define CD_CX	2
#define CD_DX	3
#define CD_SI	4
#define CD_DI	5
#define CD_BP	6
#define CD_SP	7
#define CD_FL	8
#define CD_IP	9
#define CD_CS	10
#define CD_DS	11
#define CD_ES	12
#define CD_FS	13
#define CD_GS	14
#define CD_SS	15
#define NUM_REGS	16

#ifndef SPATHLEN
# define SPATHLEN 16		/* sys/param.h */
#endif
#ifndef NSIG
# define NSIG 63		/* sys/signal.h */
# define SIGSETSZ ((NSIG+31)/32)
typedef struct ksigmask
  {
    unsigned long sigs[SIGSETSZ];
  }

ksigmask_t;
#endif

struct corehdr
  {
    char cd_magic[4];		/* COR_MAGIC = "core" */

    /* general information about the dump itself */
    struct dumpseg
      {				/* table of contents for dump */
	long cs_type;		/* seg. type; see below */
	long cs_len;		/* length (in bytes) of segment */
	long cs_offset;		/* offset (in dump) of segment */
	long cs_address;	/* address segment had in mem */
      }
    cd_segs[MAX_CORE_SEGS];

    /* general information about the process */
    char cd_comm[CD_NAMELEN];	/* command being run */
    char cd_mach[CD_NAMELEN];	/* type of machine it ran on */
    char cd_site[CD_NAMELEN];	/* name of site it ran on */
    long cd_ldtype;		/* type of load module running */
    char cd_intsize;		/* sizeof(int) */
    char cd_dptrsize;		/* sizeof(char *) */
    char cd_tptrsize;		/* sizeof(int (*)()) */
    char cd_unused;

    /* user-mode program state */
    long cd_regs[NUM_REGS];	/* user-mode general registers	*/
    struct env387 cd_fpregs;	/* user-mode floating-point state */

    /* kernel-mode program state */
    int (*cd_sig[NSIG]) ();	/* disposition of signals */
    ksigmask_t cd_sigmask;	/* signals to be blocked	*/
    ksigmask_t cd_sigpend;	/* signals currently pending */
    long cd_cursig;		/* signal that caused the dump */

    long cd_pid;		/* process ID of the corpse */
    long cd_ppid;		/* parent process ID of corpse */
    short cd_uid;		/* process effective user ID */
    short cd_ruid;		/* process real user ID */
    short cd_gid;		/* process effective group ID */
    short cd_rgid;		/* process real group ID	*/

    uinfo_t cd_uinfo;		/* buffer of user information	*/
    char cd_locname[32];	/* name of /local */
    char cd_uvers[CD_NAMELEN];	/* user version string */
    unsigned short cd_spath[SPATHLEN];	/* sitepath */
  };

#ifndef NOCHECKS
/* this will generate an error if sizeof(struct corehdr) > CORHDRSIZ */
struct
  {
    char xxcdxx[CORHDRSIZ + 1 - sizeof (struct corehdr)];
  };

#endif /* ! NOCHECKS */

/*
 * segment types (in cs_type)
 *	each segment in the address space appears here, whether or not it
 *	is actually dumped.  Read/only segments will not actually be dumped.
 *	A segment that is not in the dump will have a cs_offset of zero.
 */
#define	COR_TYPE_CODE		'x'	/* process code - NOT IN DUMP	*/
#define	COR_TYPE_DATA		'd'	/* process data segment		*/
#define	COR_TYPE_STACK		's'	/* process stack segment	*/
#define COR_TYPE_LIBCODE	'X'	/* shared lib code - NOT IN DUMP*/
#define COR_TYPE_LIBDATA	'D'	/* shared lib data		*/
#define COR_TYPE_READ		'r'	/* other read/only - NOT IN DUMP*/
#define COR_TYPE_WRITE		'w'	/* other writeable		*/
#define	COR_TYPE_MSC		'?'	/* other, mapped in segment	*/

#endif /* TE_I386AIX */

/*
 * Local Variables:
 * comment-column: 0
 * End:
 */

/* end of coff_gnu.h */